void UpdateBone(BasicMotion motion) { float weight = 1.0f; float[] value = new float[4]; foreach (var fcurve in motion.FCurves) { if (fcurve.TargetType == BasicFCurveTargetType.Bone) { EvalFCurve(fcurve, motion.Frame, value); BasicBone bone = Bones[fcurve.TargetIndex]; switch (fcurve.ChannelType) { case BasicFCurveChannelType.Translation: Vector3 translation = new Vector3(value[0], value[1], value[2]); bone.Translation = bone.Translation.Lerp(translation, weight); break; case BasicFCurveChannelType.Rotation: Quaternion rotation; if (fcurve.DimCount == 4) { rotation = new Quaternion(value[0], value[1], value[2], value[3]); } else { Vector3 angles = new Vector3(value[0], value[1], value[2]); // [note] 旧API // rotation = Quaternion.FromEulerAnglesZYX( angles ) ; rotation = Quaternion.RotationZyx(angles); } // [note] 旧API // bone.Rotation = Quaternion.Slerp( bone.Rotation, rotation, weight, 0.0f ) ; bone.Rotation = bone.Rotation.Slerp(rotation, weight); break; case BasicFCurveChannelType.Scaling: Vector3 scaling = new Vector3(value[0], value[1], value[2]); bone.Scaling = bone.Scaling.Lerp(scaling, weight); break; } } else if (fcurve.TargetType == BasicFCurveTargetType.Material) { EvalFCurve(fcurve, motion.Frame, value); BasicMaterial material = Materials[fcurve.TargetIndex]; switch (fcurve.ChannelType) { // 追加 case BasicFCurveChannelType.Diffuse: material.Diffuse.X = value[0]; material.Diffuse.Y = value[1]; material.Diffuse.Z = value[2]; material.Diffuse.W = value[3]; break; } } } }
/// Motion の長さをフレームで取得 public float GetMotionFrameMax(int idx) { if (Motions.Length > idx) { BasicMotion motion = Motions[idx]; return(motion.FrameEnd); } return(0.0f); }
/// Motion の長さを秒で取得 public float GetMotionLength(int idx) { if (Motions.Length > idx) { BasicMotion motion = Motions[idx]; return(motion.FrameEnd / motion.FrameRate); } return(0.0f); }
/// step秒 分だけアニメーションを進める public void Animate(int idx, float step) { if (Motions.Length > idx) { BasicMotion motion = Motions[idx]; motion.Frame += step * motion.FrameRate; if (motion.Frame > motion.FrameEnd) { motion.Frame = motion.FrameStart; } UpdateBone(motion); } }
/// 指定フレームのアニメーションを適用する public void SetAnimFrame(int idx, float frame) { if (Motions.Length > idx) { BasicMotion motion = Motions[idx]; motion.Frame = frame; if (motion.Frame > motion.FrameEnd) { motion.Frame = motion.FrameStart; } UpdateBone(motion); } }
void LoadMotion(Chunk chunk, BasicMotion motion) { int nFCurves = CountChild(chunk, ChunkType.Animate); motion.FCurves = new BasicFCurve[nFCurves]; for (int i = 0; i < nFCurves; i++) { motion.FCurves[i] = new BasicFCurve(); } int iFCurve = 0; Chunk child; for (int pos = chunk.Child; pos < chunk.Next; pos = child.Next) { child = ReadChunk(pos); int args = child.Args; switch (child.Type) { case ChunkType.Animate: LoadFCurve(child, chunk, motion.FCurves[iFCurve++]); break; case ChunkType.FrameRate: motion.FrameRate = ReadFloat(args); break; case ChunkType.FrameLoop: motion.FrameStart = ReadFloat(args + 0); motion.FrameEnd = ReadFloat(args + 4); break; case ChunkType.FrameRepeat: motion.FrameRepeat = (BasicMotionRepeatMode)ReadInt32(args); break; } } }
void UpdateBone( BasicMotion motion ) { float weight = 1.0f ; float[] value = new float[ 4 ] ; foreach ( var fcurve in motion.FCurves ) { if ( fcurve.TargetType == BasicFCurveTargetType.Bone ){ EvalFCurve( fcurve, motion.Frame, value ) ; BasicBone bone = Bones[ fcurve.TargetIndex ] ; switch ( fcurve.ChannelType ) { case BasicFCurveChannelType.Translation : Vector3 translation = new Vector3( value[ 0 ], value[ 1 ], value[ 2 ] ) ; bone.Translation = bone.Translation.Lerp( translation, weight ) ; break ; case BasicFCurveChannelType.Rotation : Quaternion rotation ; if ( fcurve.DimCount == 4 ) { rotation = new Quaternion( value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] ) ; } else { Vector3 angles = new Vector3( value[ 0 ], value[ 1 ], value[ 2 ] ) ; // [note] 旧API // rotation = Quaternion.FromEulerAnglesZYX( angles ) ; rotation = Quaternion.RotationZyx( angles ) ; } // [note] 旧API // bone.Rotation = Quaternion.Slerp( bone.Rotation, rotation, weight, 0.0f ) ; bone.Rotation = bone.Rotation.Slerp( rotation, weight ) ; break ; case BasicFCurveChannelType.Scaling : Vector3 scaling = new Vector3( value[ 0 ], value[ 1 ], value[ 2 ] ) ; bone.Scaling = bone.Scaling.Lerp( scaling, weight ) ; break ; } }else if( fcurve.TargetType == BasicFCurveTargetType.Material ){ EvalFCurve( fcurve, motion.Frame, value ) ; BasicMaterial material = Materials[ fcurve.TargetIndex ]; switch ( fcurve.ChannelType ) { // 追加 case BasicFCurveChannelType.Diffuse: material.Diffuse.X = value[ 0 ]; material.Diffuse.Y = value[ 1 ]; material.Diffuse.Z = value[ 2 ]; material.Diffuse.W = value[ 3 ]; break; } } } }
private float getFrame( BasicMotion motion ) { return motion.Frame; }
private float getFrame(BasicMotion motion) { return(motion.Frame); }
void LoadMotion( Chunk chunk, BasicMotion motion ) { int nFCurves = CountChild( chunk, ChunkType.Animate ) ; motion.FCurves = new BasicFCurve[ nFCurves ] ; for ( int i = 0 ; i < nFCurves ; i ++ ) motion.FCurves[ i ] = new BasicFCurve() ; int iFCurve = 0 ; Chunk child ; for ( int pos = chunk.Child ; pos < chunk.Next ; pos = child.Next ) { child = ReadChunk( pos ) ; int args = child.Args ; switch ( child.Type ) { case ChunkType.Animate : LoadFCurve( child, chunk, motion.FCurves[ iFCurve ++ ] ) ; break ; case ChunkType.FrameRate : motion.FrameRate = ReadFloat( args ) ; break ; case ChunkType.FrameLoop : motion.FrameStart = ReadFloat( args + 0 ) ; motion.FrameEnd = ReadFloat( args + 4 ) ; break ; case ChunkType.FrameRepeat : motion.FrameRepeat = (BasicMotionRepeatMode)ReadInt32( args ) ; break ; } } }