private void LoadFromColladaSceneNode(ColladaSceneNodeBase node) { if (node.Type != ColladaSceneNodeBase.NodeType.Node && node.Type != ColladaSceneNodeBase.NodeType.Scene) { return; } // This is not correct. When using a skin there is an 'instance_controller' if (node.Instance_Geometry != null) { ColladaMesh mesh = node.Instance_Geometry; for (int iPart = 0; iPart < mesh.Parts.Count; iPart++) { ColladaMesh.PrimitiveList meshPart = mesh.Parts[iPart]; SkinnedMesh skinnedMesh = new SkinnedMesh(skinnedModel); Matrix objectMatrix = node.GetFullMatrix() * Matrix.CreateRotationX(-MathHelper.PiOver2); LoadMesh(skinnedMesh, mesh, meshPart, objectMatrix); skinnedModel.Meshes.Add(skinnedMesh); //model.FullData.ObjectMatrix = node.GetFullMatrix(); // TODO: this only counts when model is from max! //model.FullData.ObjectMatrix = model.FullData.ObjectMatrix * Matrix.CreateRotationX( -MathHelper.PiOver2 ); } } for (int iNode = 0; iNode < node.Nodes.Count; iNode++) { LoadFromColladaSceneNode(node.Nodes[iNode]); } }
private void LoadMesh(SkinnedMesh mesh, ColladaMesh colladaMesh, ColladaMesh.PrimitiveList primitives, Matrix objectMatrix) { //EDIT: the vertices now include the objectmatrix, so this is always identity objectMatrix = colladaMesh.objectMatrix; mesh.Shader.World = Matrix.Identity; mesh.Primitives = new Primitives(); mesh.Primitives.PrimitiveCount = primitives.PrimitiveCount; mesh.Primitives.VertexCount = primitives.PrimitiveCount * 3; if (primitives.PrimitiveCount * 3 >= int.MaxValue) { throw new Exception("Too many vertices"); } int numVertices = primitives.PrimitiveCount * 3; // TODO check if all inputs are available /*if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.Position ) ) positions = new Vector3[ numVertices ]; * if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.Normal ) ) normals = new Vector3[ numVertices ]; * if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.Texcoord, 1 ) ) texCoords = new Vector3[ numVertices ]; * if ( meshPart.ContainsInput( ColladaMesh.Input.InputSemantics.TexTangent, 1 ) ) tangents = new Vector3[ numVertices ];*/ SkinnedTangentVertex[] vertices = new SkinnedTangentVertex[numVertices]; for (int i = 0; i < numVertices; i++) { SkinnedTangentVertex v = new SkinnedTangentVertex(); v.pos = primitives.GetVector3(ColladaMesh.Input.InputSemantics.Position, i); //GetPosition( i ); v.normal = primitives.GetVector3(ColladaMesh.Input.InputSemantics.Normal, i); // Texture Coordinates Vector3 texcoord = Vector3.Zero; if (primitives.ContainsInput(ColladaMesh.Input.InputSemantics.Texcoord, 1)) { texcoord = primitives.GetVector3(ColladaMesh.Input.InputSemantics.Texcoord, 1, i); texcoord.Y = 1.0f - texcoord.Y; // V coordinate is inverted in max } v.uv = new Vector2(texcoord.X, texcoord.Y); // Tangent Vector3 tangent = Vector3.Zero; if (primitives.ContainsInput(ColladaMesh.Input.InputSemantics.TexTangent, 1)) { v.tangent = primitives.GetVector3(ColladaMesh.Input.InputSemantics.TexTangent, 1, i); } // Bone weights and joint indices int positionIndex = primitives.GetSourceIndex( primitives.GetInput(ColladaMesh.Input.InputSemantics.Position), i); // WARNING: THIS IS EXTREMELY IMPORTANT AND COSTED MORE THAN 6 HOURS DEBUGGING // Indexes are PREMULTIPLIED BY 3!!! v.blendIndices = colladaMesh.vertexSkinJoints[positionIndex]; //v.blendIndices = Vector3.One; v.blendIndices = v.blendIndices * 3; v.blendWeights = colladaMesh.vertexSkinWeights[positionIndex]; v.pos = Vector3.Transform(v.pos, objectMatrix); v.normal = Vector3.Transform(v.normal, objectMatrix); vertices[i] = v; } //vertices[ 0 ].pos = Vector3.Transform( Vector3.Zero, Matrix.Invert( objectMatrix ) ); //vertices[ 0 ].pos = Vector3.Zero; mesh.Primitives.InitializeFromVertices(skinnedModel.Game, vertices, SkinnedTangentVertex.SizeInBytes); //CalculateBoundingBox(); //CalculateBoundingSphere(); //TODO: Material, maybe not really a good way of doing this //LoadDataFromColladaMaterial( meshPart.Material ); }