public static void GetVertexAndIndexData(ModelGeometry modelGeometry, out VertexPositionNormalTexture[] vertexData, out short[] indexData) { if (modelGeometry.Meshes.Length != 1) throw new NotImplementedException("Multiple meshes"); var mesh = modelGeometry.Meshes[0]; if (mesh.MeshParts.Length != 1) throw new NotImplementedException("Multiple mesh parts"); var meshPartToworldMatrix = Matrix.Identity; for (var bone = mesh.ParentBone; bone != null; bone = bone.Parent) meshPartToworldMatrix *= bone.Transform; var meshPart = mesh.MeshParts[0]; vertexData = meshPart.VertexBuffer.Vertices .Select(vertex => new VertexPositionNormalTexture( position: Vector3.Transform(vertex.Position, meshPartToworldMatrix), normal: Vector3.TransformNormal(vertex.Normal, meshPartToworldMatrix), textureCoordinate: vertex.TextureCoordinate)) .ToArray(); indexData = new short[meshPart.PrimitiveCount * 3]; Array.Copy(meshPart.IndexBuffer.Indices, meshPart.StartIndex, indexData, 0, indexData.Length); }
protected override void CopyAbsoluteBoneTransformsTo(ModelGeometry skeleton, Matrix[] transforms) { if (transforms == null) throw new ArgumentNullException("Null transformation matrix array"); if (transforms.Length < skeleton.Bones.Length) throw new ArgumentException("Too short transformation matrix array"); float[] tailTurnDeltas = new float[skeleton.Bones.Length]; float prevTailTurn = Rotation + DrawRotationOffset; foreach (int i in _tailIndices) { tailTurnDeltas[i] = MathHelper.WrapAngle(_tailTurns[i].Current - prevTailTurn); prevTailTurn = _tailTurns[i].Current; } foreach (var bone in skeleton.Bones) { if (bone.Parent == null) transforms[bone.Index] = bone.Transform; else { if (bone.Parent.Index >= bone.Index) throw new Exception("Unexpected situation: bone parent doesn't precede the bone itself"); if (_tailPhases[bone.Index] < 0) transforms[bone.Index] = bone.Transform * transforms[bone.Parent.Index]; else { float wigglePhase = _wiggleMainPhase + _tailPhases[bone.Index]; float turnDamping = 1 - Math.Abs(tailTurnDeltas[bone.Index]) / MAX_TAIL_TURN; // wiggle less when bent float tailAmplitude = MIN_TAIL_AMPLITUDE + turnDamping * (_tailAmplitudes[bone.Index] - MIN_TAIL_AMPLITUDE); float wiggleAngle = tailTurnDeltas[bone.Index] + tailAmplitude * (float)Math.Sin(wigglePhase); var extraTransform = Matrix.CreateRotationZ(wiggleAngle); transforms[bone.Index] = extraTransform * bone.Transform * transforms[bone.Parent.Index]; } } } }