|
geekay, Jr. Member
Posted: 17 February 2013 01:18 AM Total Posts: 40
As the title suggests, I am wondering if there is any way to attach a mesh (or objectcontainer etc.) to another mesh (objectcontainer, etc.) and have it ‘stick’ to it, so that even if the ‘stuck to’ mesh is moved or animated, that the attached mesh will move with it. A good way to think about this question would be: How can I shoot an arrow into a biped that is walking, and make it so that the arrow sticks as it should at the location of impact?
Thanks so very much for your time on this issue, and I hope you forgive me if my question is incorrectly worded or sophomoric, I am very new to all of this 3d stuff (I have tried searching for the answer to this question, but unfortunately I do not even know where to start or what terms to use). Thanks!
|
César, Newbie
Posted: 17 February 2013 10:23 AM Total Posts: 11
[ # 1 ]
The simple solution I see is to do something like :
body.addChild(arrow)
Maybe you have to recalculate the relative arrow position when you addChild on the body by using the transform Matrix3D.
Something like that should work :
// Get your arrow from where you want var arrowObject:ObjectContainer3D = arrowContainer.getChildAt(0);
// Recalculate his matrix arrowObject.transform = arrowObject.sceneTransform.clone(); var matrice:Matrix3D = bodyContainer.sceneTransform.clone(); matrice.invert(); arrowObject.transform.append(matrice);
// Add it to the body of your character bodyContainer.addChild(arrowObject);
|
geekay, Jr. Member
Posted: 17 February 2013 06:43 PM Total Posts: 40
[ # 2 ]
That does not seem to work with an animation.
Here is an example of what I have:
http://craigavenue.com/AwayTest/test.html
(I would expect that the wireframe box in the middle would animate with the other moving parts.)
The code I am generally using is as follows:
main{ //setup scene //use AssetLibrary to load an awd with mesh, bone and animation. AssetLibrary.addEventListener(resourceComplete, onResourceComplete);}
private function onResourceComplete(e:LoaderEvent):void {
var skeleton:Skeleton = AssetLibrary.getAsset("Bone001") as Skeleton; var hero:Mesh = Mesh(AssetLibrary.getAsset("Box001")); _view.scene.addChild(hero); var animationSet:SkeletonAnimationSet = new SkeletonAnimationSet(2); animationSet.addAnimation(AssetLibrary.getAsset("Animation") as AnimationNodeBase); var skanim:SkeletonAnimator = new SkeletonAnimator(animationSet, skeleton); hero.animator = skanim; var arrowObject:WireframeCube = new WireframeCube();
//new bit attaching arrowObject to the animating mesh arrowObject.transform = arrowObject.sceneTransform.clone(); var matrice:Matrix3D = hero.sceneTransform.clone(); matrice.invert(); arrowObject.transform.append(matrice); hero.addChild(arrowObject); skanim.play("Animation"); }
If you need the actual .as file, let me know and I can share that too.
Thanks so very much for your time.
|
César, Newbie
Posted: 17 February 2013 08:40 PM Total Posts: 11
[ # 3 ]
If you just create the wireframe cube, you don’t have to use the matrix transform to convert his matrix because his position and rotation are null by default, so normally just the hero.addChild(arrowObject) is needed if you keep it at the center of the scene.
Yes about the as file, could you share it ?
|
geekay, Jr. Member
Posted: 17 February 2013 08:51 PM Total Posts: 40
[ # 4 ]
The files I am using for this test can be found here: http://craigavenue.com/AwayTest/
Thanks so very much for your time and help!
|
César, Newbie
Posted: 17 February 2013 09:44 PM Total Posts: 11
[ # 5 ]
Ok I see, it’s because you use a skeleton wich don’t move the object but his vertexes, so it’s normal the cube don’t move because it’s attached to the mesh position and not his vertexes.
In your case, it’s more simple to animate without skeleton and just by rotation, wich simplify the code :
Add the mesh on the class var to get it in the enterFrame function :
private var hero:Mesh;
It’s better to add the enterFrame listener after build the objects, to no refer to null objects.
private function onResourceComplete(e:LoaderEvent):void { hero = Mesh(AssetLibrary.getAsset("Box001")); _view.scene.addChild(hero); var cube:WireframeCube = new WireframeCube(); hero.addChild(cube);
addEventListener(Event.ENTER_FRAME, _onEnterFrame); } private function _onEnterFrame(e:Event):void{ hero.rotationY += 10; _view.render(); }
I don’t know if it’s you really want, here : hero rotate with the box.
If you want to keep the skeleton, I am not an expert, but I will said that the solution will be to use the matrix skeleton or theses poses. I am not really familiar with skeleton.
Edit :
I find the way If you want to keep the skeleton : get the matrix bone with skanim.globalPose.jointPoses[0].toMatrix3D(), where jointPoses[0] is the bone number 0.
import away3d.animators.data.JointPose;
private var cube:WireframeCube;
private function onResourceComplete(e:LoaderEvent):void { var skeleton:Skeleton = AssetLibrary.getAsset("Bone001") as Skeleton; hero = Mesh(AssetLibrary.getAsset("Box001")); _view.scene.addChild(hero); var animationSet:SkeletonAnimationSet = new SkeletonAnimationSet(2); animationSet.addAnimation(AssetLibrary.getAsset("Animation") as AnimationNodeBase); skanim = new SkeletonAnimator(animationSet, skeleton); hero.animator = skanim; cube = new WireframeCube(); hero.addChild(cube); skanim.play("Animation"); addEventListener(Event.ENTER_FRAME, _onEnterFrame); } private function _onEnterFrame(e:Event):void{ cube.transform = skanim.globalPose.jointPoses[0].toMatrix3D(); _view.render(); }
|
geekay, Jr. Member
Posted: 17 February 2013 11:01 PM Total Posts: 40
[ # 6 ]
This is very very close to what I had in mind.
From what it looks like we can ‘look’ at a specific joint in the bone, and place an object there;
But is there a way to place an item anywhere on the mesh (and not just on a joint)?
In any case, this (the prior post) helps me immensely, and if I can’t figure our another way to do it, I most likely will be able to use this to get the effect I am looking for.
However, if anyone knows another way to get this effect (taking an animated bone or mesh, and attaching a mesh to it at a specific location), I would love to hear it!
Ps. Thanks César for all of your help thus far!!
|
|
PabloCr, Newbie
Posted: 19 February 2013 07:36 PM Total Posts: 9
[ # 8 ]
that’s interesting, and I guess all this is some kind of workaround, what is the proper approach? hope to get answer from away3d authors
|
geekay, Jr. Member
Posted: 20 February 2013 04:22 AM Total Posts: 40
[ # 9 ]
@PabloCr
I am very interested in hearing this too
|
geekay, Jr. Member
Posted: 26 February 2013 07:37 PM Total Posts: 40
[ # 10 ]
I still need help with this issue. Can anyone please help?
|
Chen Jue, Newbie
Posted: 10 June 2013 09:29 AM Total Posts: 1
[ # 11 ]
I’m facing the same problem too, till I find something interesting to this question.
In the official examples provided by the Away3D team, the example that is named “Intermediate_OnkbaAWDAnimation.as”, shows a pair of eyes moving with head bone. The eyes mesh is created in the program, not in the models, and updated it’s positions during an enter frame event.
I tried to change the head bone to another index, the eyes moved with the hero’s hand. So I think this is what you want.
|
CyrilM, Newbie
Posted: 14 June 2013 06:25 PM Total Posts: 15
[ # 12 ]
I worked on something like this recently. My solution was to update the transform of the object to match the transform of one of the bones.
for example
var jointIndex : int = (mesh.animator as SkeletonAnimator).skeleton.jointIndexFromName("arm_01"); var newTransform : Matrix3D = (mesh.animator as SkeletonAnimator).globalPose.jointPoses[jointIndex].toMatrix3D();
Then you apply that transform over the object you are attaching. I think you still have to add that object as a child though.
Seems to work for me so long as there is an animation. Obviously you would have to check to make sure first
|