bum*_*ack 14 actionscript-3 away3d
我正在将3D资产加载到Away3D场景中,我想在代码中移动骨骼的位置.
资产负荷一切顺利的话,我抢的指针Mesh和Skeleton加载时:
private function onAssetComplete(evt:AssetEvent):void
{
if(evt.asset.assetType == AssetType.SKELETON){
_skeleton = evt.asset as Skeleton;
} else if (evt.asset.assetType == AssetType.MESH) {
_mesh = evt.asset as Mesh;
}
}
Run Code Online (Sandbox Code Playgroud)
资产(一个或多个)加载完成后,我有一个有效的Skeleton和Mesh实例,模型也是我的场景中可见.我接下来要尝试的是以下内容.
// create a matrix with the desired joint (bone) position
var pos:Matrix3D = new Matrix3D();
pos.position = new Vector3D(60, 0, 0);
pos.invert();
// get the joint I'd like to modifiy. The bone is named "left"
var joint:SkeletonJoint = _skeleton.jointFromName("left");
// assign joint position
joint.inverseBindPose = pos.rawData;
Run Code Online (Sandbox Code Playgroud)
此代码运行时没有错误,但新位置未应用于可见几何体,例如.骨骼的位置根本不会改变.
我在这里缺少一个额外的步骤吗?我是否必须以Mesh某种方式重新分配骨架?或者我是否必须明确告诉网格骨骼位置已经改变?
这可能不是解决这个问题的最佳方法,但这是我发现的:
当存在动画时,Away3D 仅对几何体应用关节变换。为了应用变换,您的几何图形必须具有动画,否则您必须在代码中创建动画。以下是执行此操作的方法(最好在LoaderEvent.RESOURCE_COMPLETE处理程序方法中:
// create a new pose for the skeleton
var rootPose:SkeletonPose = new SkeletonPose();
// add all the joints to the pose
// the _skeleton member is being assigned during the loading phase where you
// look for AssetType.SKELETON inside a AssetEvent.ASSET_COMPLETE listener
for each(var joint:SkeletonJoint in _skeleton.joints){
var m:Matrix3D = new Matrix3D(joint.inverseBindPose);
m.invert();
var p:JointPose = new JointPose();
p.translation = m.transformVector(p.translation);
p.orientation.fromMatrix(m);
rootPose.jointPoses.push(p);
}
// create idle animation clip by adding the root pose twice
var clip:SkeletonClipNode = new SkeletonClipNode();
clip.addFrame(rootPose, 1000);
clip.addFrame(rootPose, 1000);
clip.name = "idle";
// build animation set
var animSet:SkeletonAnimationSet = new SkeletonAnimationSet(3);
animSet.addAnimation(clip);
// setup animator with set and skeleton
var animator:SkeletonAnimator = new SkeletonAnimator(animSet, _skeleton);
// assign the newly created animator to your Mesh.
// This example assumes that you grabbed the pointer to _myMesh during the
// asset loading stage (by looking for AssetType.MESH)
_myMesh.animator = animator;
// run the animation
animator.play("idle");
// it's best to keep a member that points to your pose for
// further modification
_myPose = rootPose;
Run Code Online (Sandbox Code Playgroud)
在初始化步骤之后,您可以动态修改关节姿势(通过修改属性来更改位置translation,通过更改属性来更改旋转orientation)。例子:
_myPose.jointPoses[2].translation.x = 100;
Run Code Online (Sandbox Code Playgroud)
如果您不知道关节的索引,而是通过名称来寻址骨骼,那么这应该可行:
var jointIndex:int = _skeleton.jointIndexFromName("myBoneName");
_myPose.jointPoses[jointIndex].translation.y = 10;
Run Code Online (Sandbox Code Playgroud)
如果您经常使用名称查找(例如每帧)并且模型中有很多骨骼,建议建立一个Dictionary可以按名称查找骨骼索引的位置。原因是 的实现jointIndexFromName对所有关节执行线性搜索,如果多次执行此操作会造成浪费。