private static STBone LoadBoneHiearchy(node daeNode, STGenericModel model, STBone boneParent, ref Matrix4 parentTransform) { STBone bone = new STBone(model.Skeleton, daeNode.name); model.Skeleton.Bones.Add(bone); var transform = DaeUtility.GetMatrix(daeNode.Items) * parentTransform; bone.Position = transform.ExtractTranslation(); bone.Scale = transform.ExtractScale(); bone.Rotation = transform.ExtractRotation(); bone.Parent = boneParent; Console.WriteLine("NODE " + bone.Name + " " + bone.Transform); //Reset the parent transform for children. We only need to apply the parent root transform parentTransform = Matrix4.Identity; if (daeNode.node1 != null) { foreach (node child in daeNode.node1) { bone.Children.Add(LoadBoneHiearchy(child, model, bone, ref parentTransform)); } } return(bone); }
public static Node LoadHiearchy(Node parent, node daeNode, STGenericModel model, ColladaScene colladaScene) { Node node = new Node(parent); node.Name = daeNode.name; node.Type = daeNode.type; node.Transform = DaeUtility.GetMatrix(daeNode.Items) * parent.Transform; if (daeNode.instance_geometry != null) { geometry geom = DaeUtility.FindGeoemertyFromNode(daeNode, colladaScene.geometries); model.Meshes.Add(LoadMeshData(colladaScene, node, geom, colladaScene.materials)); } if (daeNode.instance_controller != null) { controller controller = DaeUtility.FindControllerFromNode(daeNode, colladaScene.controllers); geometry geom = DaeUtility.FindGeoemertyFromController(controller, colladaScene.geometries); model.Meshes.Add(LoadMeshData(colladaScene, node, geom, colladaScene.materials, controller)); } try { } catch (Exception ex) { throw new Exception($"Failed to convert mesh {daeNode.name} \n {ex.ToString()}"); } //Find the root bone if (node.Type == NodeType.JOINT) { //Apply axis rotation Matrix4 boneTransform = Matrix4.Identity; if (colladaScene.UpAxisType == UpAxisType.Y_UP) { // boneTransform = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(90)); } if (colladaScene.UintSize != null && colladaScene.UintSize.meter != 1) { var scale = ApplyUintScaling(colladaScene, new Vector3(1)); boneTransform *= Matrix4.CreateScale(scale); } LoadBoneHiearchy(daeNode, model, null, ref boneTransform); } else if (daeNode.node1 != null) { foreach (node child in daeNode.node1) { node.Children.Add(LoadHiearchy(node, child, model, colladaScene)); } } return(node); }
private static List <BoneWeight[]> ParseWeightController(controller controller, ColladaScene scene) { if (controller == null) { return(new List <BoneWeight[]>()); } List <BoneWeight[]> boneWeights = new List <BoneWeight[]>(); skin skin = controller.Item as skin; string[] skinningCounts = skin.vertex_weights.vcount.Trim(' ').Split(' '); string[] indices = skin.vertex_weights.v.Trim(' ').Split(' '); int maxSkinning = (int)scene.Settings.MaxSkinningCount; int stride = skin.vertex_weights.input.Length; int indexOffset = 0; for (int v = 0; v < skinningCounts.Length; v++) { int numSkinning = Convert.ToInt32(skinningCounts[v]); BoneWeight[] boneWeightsArr = new BoneWeight[Math.Min(maxSkinning, numSkinning)]; for (int j = 0; j < numSkinning; j++) { if (j < scene.Settings.MaxSkinningCount) { boneWeightsArr[j] = new BoneWeight(); foreach (var input in skin.vertex_weights.input) { int offset = (int)input.offset; var source = DaeUtility.FindSourceFromInput(input, skin.source); int index = Convert.ToInt32(indices[indexOffset + offset]); if (input.semantic == "WEIGHT") { var weights = source.Item as float_array; boneWeightsArr[j].Weight = (float)weights.Values[index]; } if (input.semantic == "JOINT") { var bones = source.Item as Name_array; boneWeightsArr[j].Bone = bones.Values[index]; } } } indexOffset += stride; } boneWeightsArr = RemoveZeroWeights(boneWeightsArr); boneWeights.Add(boneWeightsArr); } return(boneWeights); }
static OpenTK.Matrix4 CreateBindMatrix(string text) { if (text == null || text == "") { return(OpenTK.Matrix4.Identity); } Matrix4 mat = Matrix4.CreateScale(1, 1, 1); string[] strArray = text.Trim().Replace("\n", "").Split(' '); strArray = strArray.Where(x => !string.IsNullOrEmpty(x)).ToArray(); float[] data = strArray.Select(s => Single.Parse(s)).ToArray(); return(DaeUtility.FloatToMatrix(data)); }
private static Node LoadBoneNodeHiearchy(Node parent, node daeNode, ref Matrix4 parentTransform) { Node node = new Node(parent); node.Name = daeNode.name; node.Type = daeNode.type; node.ID = daeNode.id; node.Transform = DaeUtility.GetMatrix(daeNode.Items) * parentTransform; if (daeNode.node1 != null) { foreach (node child in daeNode.node1) { node.Children.Add(LoadBoneNodeHiearchy(node, child, ref parentTransform)); } } return(node); }
private static void ConvertPolygon(ColladaScene scene, STGenericMesh mesh, mesh daeMesh, InputLocalOffset[] inputs, List <BoneWeight[]> boneWeights, library_materials materials, string material, string polys, int polyCount, string vcount = "") { List <uint> faces = new List <uint>(); STPolygonGroup group = new STPolygonGroup(); mesh.PolygonGroups.Add(group); group.MaterialIndex = DaeUtility.FindMaterialIndex(materials, material); string[] indices = polys.Trim(' ').Split(' '); string[] vertexCount = new string[0]; if (vcount != string.Empty) { vertexCount = vcount.Trim(' ').Split(' '); } int stride = 0; for (int i = 0; i < inputs.Length; i++) { stride = Math.Max(0, (int)inputs[i].offset + 1); } //Create a current list of all the vertices //Use a list to expand duplicate indices List <Vertex> vertices = new List <Vertex>(); var vertexSource = DaeUtility.FindSourceFromInput(daeMesh.vertices.input[0], daeMesh.source); var floatArr = vertexSource.Item as float_array; for (int v = 0; v < (int)floatArr.count / 3; v++) { vertices.Add(new Vertex(vertices.Count, new List <int>())); } var indexStride = (indices.Length / 3) / polyCount; for (int i = 0; i < polyCount; i++) { int count = 3; if (vertexCount.Length > i) { count = Convert.ToInt32(vertexCount[i]); } for (int v = 0; v < count; v++) { List <int> semanticIndices = new List <int>(); for (int j = 0; j < inputs.Length; j++) { int faceOffset = (indexStride * 3) * i; int index = Convert.ToInt32(indices[faceOffset + (v * indexStride) + (int)inputs[j].offset]); semanticIndices.Add(index); } BoneWeight[] boneWeightData = new BoneWeight[0]; if (boneWeights?.Count > semanticIndices[0]) { boneWeightData = boneWeights[semanticIndices[0]]; } VertexLoader.LoadVertex(ref faces, ref vertices, semanticIndices, boneWeightData); } } int numTexCoordChannels = 0; int numColorChannels = 0; //Find them in both types of inputs for (int i = 0; i < inputs.Length; i++) { if (inputs[i].semantic == "TEXCOORD") { numTexCoordChannels++; } if (inputs[i].semantic == "COLOR") { numColorChannels++; } } for (int i = 0; i < daeMesh.vertices.input.Length; i++) { if (daeMesh.vertices.input[i].semantic == "TEXCOORD") { numTexCoordChannels++; } if (daeMesh.vertices.input[i].semantic == "COLOR") { numColorChannels++; } } for (int i = 0; i < vertices.Count; i++) { if (!vertices[i].IsSet) { vertices.Remove(vertices[i]); } } bool hasNormals = false; foreach (var daeVertex in vertices) { if (daeVertex.semanticIndices.Count == 0) { continue; } STVertex vertex = new STVertex(); vertex.TexCoords = new Vector2[numTexCoordChannels]; vertex.Colors = new Vector4[numColorChannels]; foreach (var boneWeight in daeVertex.BoneWeights) { vertex.BoneIndices.Add(boneWeight.Index); vertex.BoneWeights.Add(boneWeight.Weight); vertex.BoneNames.Add(boneWeight.Bone); } mesh.Vertices.Add(vertex); //DAE has 2 inputs. Vertex and triangle inputs //Triangle inputs use indices over vertex inputs which only use one //Triangle inputs allow multiple color/uv sets unlike vertex inputs //Certain programs ie Noesis DAEs use vertex inputs. Most programs use triangle inputs for (int j = 0; j < daeMesh.vertices.input.Length; j++) { //Vertex inputs only use the first index var vertexInput = daeMesh.vertices.input[j]; source source = DaeUtility.FindSourceFromInput(vertexInput, daeMesh.source); if (source == null) { continue; } if (vertexInput.semantic == "NORMAL") { hasNormals = true; } int dataStride = (int)source.technique_common.accessor.stride; int index = daeVertex.semanticIndices[0] * dataStride; ParseVertexSource(ref vertex, scene, source, numTexCoordChannels, numColorChannels, dataStride, index, 0, vertexInput.semantic); } for (int i = 0; i < inputs.Length; i++) { var input = inputs[i]; source source = DaeUtility.FindSourceFromInput(input, daeMesh.source); if (source == null) { continue; } if (input.semantic == "NORMAL") { hasNormals = true; } int dataStride = (int)source.technique_common.accessor.stride; int index = daeVertex.semanticIndices[i] * dataStride; ParseVertexSource(ref vertex, scene, source, numTexCoordChannels, numColorChannels, dataStride, index, (int)input.set, input.semantic); } } group.Faces = faces; if (!hasNormals) { CalculateNormals(mesh.Vertices, faces); } if (scene.Settings.RemoveDuplicateVerts) { RemoveDuplicateVerts(mesh.Vertices, faces); } }