I am trying to apply some position constraints to a very simple scene. What I would like to do is have an initial node, then use a constraint to position a second node relative to the first. Then position a third node relative to the second etc. I realise I can nest the nodes but that is not what I ultimately want. Moving the first node would move all 3. What I have noticed having applied a constraint to the the second node is that the position is still 0,0,0 even though the constraint has positioned my node correctly. This has a knock on effect to the third node as the position of the second node is 0,0,0 therefore the third node is positioned relative to the first... I hope this makes sense? :-s
I have also noticed this effects the getBoundingBoxMin of the entire scene, as I need to establish the dimensions of the entire scene.
Is what I am trying to achieve even possible with constraints?
Thanks
Constraints are applied at render time, so it won't change your model (i.e it won't modify the positions of your nodes in your model tree).
That said you can retrieve the presentation positions of your nodes like this:
node.presentationNode.position
Related
I can't wrap my head around this and was hoping someone might be able to help me. I have an object3D which is being placed on a terrain (plane mesh). I create a Ray, positioned at the object but really high, and find the intersection point into the terrain (essentially the Y intersection). Once I have that I position the object on the terrain at that position.
From the intersect object function I also get the Face which contains the normal at that point. What I'd like to do is align the mesh so that it has the same rotation as the point its standing on.
Once the object is aligned with the world I also need it to face a target its heading towards. Currently I'm using the lookAt function to achieve this.
So I guess my question is two parts. The first is how to align the object with the world. And the second is, how to get that object to face a target without messing up the calculation of the first? (I guess this could be achieved with a child node? The parent node aligned to the world and the sub-mesh node looking at the target?)
Thanks guys
Mat
I have a Force Directed Graph that I've generated with D3 and within each node (which are represented as large circles) I'd like to pack in a bunch of smaller circles using D3's Circle Packing. Is it possible to use both of these layouts in one visualization? How does one insert a layout into a node?
I figured it out once I realized that svg elements were just regular dom nodes and I could manipulate them with jquery. I ended up created two svg locations, one for display and one for creation of svg objects. I built one object at a time in the builder location and then moved it off to somewhere else in order to work on the next guy. When I was ready I built the force graph on the main display and populated the nodes there with the circle packed nodes that I had saved off somewhere else.
I am having trouble using Ray.intersectObjects within a hierarchy of Object3D transforms. Essentially, intersectObjects seems to be ignoring the rotation at the top level of the hierarchy. I have tried to reproduce this problem by modifying the webgl_interactive_cubes.html demo, with no luck. Unfortunately I can't post what I'm working on. I am going to try to reproduce the problem so I can share it, but maybe somebody has a suggestion for what's wrong. This is using THREE.js r52.
Here are what I believe to be the relevant pieces:
I have a root THREE.Object3D element that holds a top-level rotation. This is the rotation that seems to be ignored.
This root element has two children, both THREE.Object3D objects. They each have a (fixed) rotation and position transformation.
I am looking for intersections among the children of these two elements. These children are all clones of THREE.Mesh objects from another heirarchy, created using THREE.Mesh.clone().
When the top-level rotation is zeroed out, the intersections all work perfectly.
As soon as a top-level rotation is applied, the intersections act as though there were no rotation... the object moves on the screen, but I get intersections returned as though the object had not moved.
I have tried calling updateMatrixWorld(true) on the root before checking for intersections, but that makes no difference.
I am trying to create a scene graph for my 3D game in which every object's transformations are relative to it's parent. Each node of the graph has a Rotation, Scaling and Translation vector.
What is the correct way of combining the relative transformation matrices to get the absolute transformation of an object? I would be glad if you could also explain your solution.
Here is an example of to do it WRONG:
This actually turned out to be the solution:
Matrix GetAbsoluteTransformation()
{
if (!this.IsRoot())
{
return this.Transformation * this.Parent.GetAbsoluteTransformation();
}
else
{
return this.Transformation;
}
}
In this case, when the parent node is rotated, scaled or moved, the child is transformed the same amount, which is a correct behaviour!
But the child will only rotate around its own origin and does not move around the parent's origin.
Applications:
There is a car model with four wheels. The wheels are relative positioned around the car's origin. The wheels can rotate just like real wheels do. If I now rotate the car, the wheels should at all time stay attached to it. In this case the car is the root and the wheels are the child nodes.
Another example would be a model of the solar system. Planets rotate around their own axis, move around the sun, and moons move around planets.
With regards to your "how to do it wrong", I hate to break it to you, but it's not wrong; rather, it's incomplete. You need to do those kinds of work independently of the parent child relationship.
Here's an example of that: The wheel is attached to the car just like you mentioned. If you translate or rotate the car, you don't need to touch the wheels - they're in the same location relative to the car. However, when you try to get the wheel's new location in the 'real world', you have to traverse down the tree, applying the matrix transformations as you go. That all works, right?
When you rotate an object, it rotates around its OWN origin. So a wheel should probably be rotating around its y axis, and a planet around its z axis. But now if you need to move a planet "around the sun", you're doing something completely different. This has to be calculated separately. That's not to say it's not going to be eased by using some of the same match you already have, (although I can't say for sure without doing the math myself) but it's entirely different.
You're looking at actually changing the state of the object. That's the beauty of the scene graph! If you didn't have a scene graph, you would have to figure out all the various values all the way back to the main scene and then do all kinds of math. Here, you just have to do a little bit of trig and algebra to move around the planet (you can google the celestial mechanics) and move the planet relative to its star. The next time the main scene asks where the planet is, it will just go down the scene graph! :-D
I think this is the correct behavior.
I don't think rotating around the parent's origin is something that can be accomplished with a simple matrix stack. I think you can only propagate from parents to children.
You could try instead setting the relative rotation and transformation based on offsets from the parent's absolute origin, though that's a lot more calculations than simply pushing onto a matrix stack.
Here's a similar question: Getting absolute position and rotation from inside a scene graph?
It depends on whether you are using OpenGL or Direct3D. In OpenGL, transforms are applied right-to-left, whereas in Direct3D, they apply left-to-right. They are both perfectly valid ways of designing the transform system, but it means you have to think about them differently.
I find it easiest to think in OpenGL's system, but in reverse. Instead of thinking about how the vertices of an object move around as transforms are applied right-to-left, I imagine the coordinate system of the object being transformed in a left-to-right order. Each transform is applied relative to the new local coordinate system, not relative to the world.
In the case of the wheels on the car, there are three transforms involved: the car's position in space, a wheel's origin relative to the car, and the wheel's orientation relative to its neutral position. Simply apply these in left-to-right order (or vice-versa for Direct3D). To draw four wheels, first apply the car's transform, then remember the current transform, then apply the location and orientation transforms in turn, going back to the remembered car transform after each.
I have been reading articles about clipping now for hours now but I dont seem to find a solution for my problem.
This is my scenario:
Within an OpenGL ES environment (IOS,Android) I am having a 2D scene graph consisting of drawable objects, forming a tree.
Each tree node has its own spatial room with it's own transformation matrix, and each node inherits its coordinate space to its children. Each node has a rectangular bounding box, but these bounding boxes are not axis aligned.
This setup works perfect to render a 2D scene graph, iterating through the tree, rendering each object and then it's children.
Now comes my problem: I am looking for a way enable clipping on a node. With clipping enabled, children of a node should be clipped when leaving the area of the parent's bounding box.
For example I wand to have a node containing a set of text nodes as children, which can be scrolled up and down withing it's parents bounding box, and should be clipped when leaving the area of the parent's bounding box.
Since bounding boxes are not axis aligned, I cannot use glScissor, which would be the easiest way.
I was thinking about using the stencil buffer and draw the filled bounding rectangle into it, when clipping is enabled and then enable the stencil buffer. This might workd but leads to another problem: What happens if a child inside a clipped node has clipping again ? - The stencil mask would have to be setup for the child, erasing the parents stencil mask.
Another solution I was thinking of, is to do the clipping in software. This would be possible, because within each node, clipping could be done relative easily in it's own local coordinate space. The backdraw of this solution would be that clipping has to be implemented for each new node type that is implemented.
Can anybody here point me into the right direction?
What I am looking for is something like the functionality of glscissor for clipping non axis aligned rectangular areas.
The scissor box is a simple tool for simple needs. If you have less simple needs, then you're going to have to use the less simple OpenGL mechanism for clipping: the stencil buffer.
Assuming that you aren't using the stencil buffer for anything else at present, you have access to 8 stencil bits. By giving each level in your scene graph a higher number than the last, you can assign each level its own stencil mask. Of course, if two siblings at the same depth level overlap, or simply are too close, then you've got a problem.
Another alternative is to assign each node a number from 1 to 255. Using a stencil test of GL_EQUAL, you will be able to prevent the overlap issue above. However, this means that you can have no more than 255 nodes in your entire scene graph. Depending on your particular needs, this may be too much of a restriction.
You can of course clear the stencil (and depth. Don't try to clear just one of them) when you run out of bits via either method. But that can be somewhat costly, and it requires that you clear the depth, which you may not want to do.
Another method is to use the increasing number and GL_EQUAL test only for non-axis-aligned nodes. You use the scissor box for most nodes, but if there is some rotation (whether on that node or inherited), then you use the stencil mask instead, bumping the mask counter as you process the graph. Again, you are limited to 256 nodes, but at least these are only for rotated nodes. Depending on your needs and how many rotated nodes there are, that may be sufficient.