public CSkinnedMesh(Model model, Document.Geometry geo, Document.Skin skin) : base(model, geo) { this.geo = geo; this.model = model; this.skin = skin; /* foreach (Document.Input input in skin.joint.inputs) { if (input.semantic == "JOINT") { Document.Source source = (Document.Source) input.source; boneCount = ((Document.Array<string>) source.array).Count; } } */ }
public CMesh(Model model, Document.Geometry geo) { this.geo = geo; Document doc = model.Doc; bool first = true; int vertexIndex = 0; List<int> indexBuffer = new List<int>(); List<float> vertexBuffer = new List<float>(); List<int> invVertexMappingList = new List<int>(); Dictionary<string, int> mapping = new Dictionary<string, int>(); List<float> tempValues = new List<float>(); foreach (Document.Primitive primitive in geo.mesh.primitives) { // Skip non-triangle primitives if (!(primitive is Document.Triangle)) { // Display a warning COLLADAUtil.Log(COLLADALogType.Warning, "Skipping part of geometry '" + geo.id + "'! Make sure all primitives are triangles."); continue; } #region vertex declaration // Take the first primitive and use its inputs to build the // vertex declaration and a dictionary to describe a mapping // of n source/p_index pairs to one index in the vertex buffer. // TODO: for now we assume that all primitives have the same // inputs in equal order. if (first) { first = false; short deltaOffset = 0; short offset = 0; short streamOffset = 0; DeclarationType vertexElementFormat; DeclarationUsage vertexElementUsage; byte usageIndex; byte texcoordUsageIndex = 0; foreach (Document.Input input in COLLADAUtil.GetAllInputs(primitive)) { switch (input.semantic) { case "POSITION": vertexElementUsage = DeclarationUsage.Position; usageIndex = 0; break; case "NORMAL": vertexElementUsage = DeclarationUsage.Normal; usageIndex = 0; break; case "COLOR": vertexElementUsage = DeclarationUsage.Color; usageIndex = 0; break; case "TEXCOORD": vertexElementUsage = DeclarationUsage.TextureCoordinate; usageIndex = texcoordUsageIndex++; break; case "TEXTANGENT": vertexElementUsage = DeclarationUsage.Tangent; usageIndex = 0; break; case "TEXBINORMAL": vertexElementUsage = DeclarationUsage.Binormal; usageIndex = 0; break; default: throw new Exception("Unexeptected vertexElementUsage=" + input.semantic); } // assuming floats !o switch (((Document.Source)input.source).accessor.ParameterCount) { case 2: vertexElementFormat = DeclarationType.Float2; deltaOffset = 2 * 4; vertexStride += 2; break; case 3: vertexElementFormat = DeclarationType.Float3; deltaOffset = 3 * 4; vertexStride += 3; break; case 4: vertexElementFormat = DeclarationType.Float4; deltaOffset = 4 * 4; vertexStride += 4; break; default: throw new Exception("Unexpected vertexElementFormat"); } vertexElements.Add(new VertexElement(streamOffset /* stream */, offset /* offset */, vertexElementFormat, DeclarationMethod.Default, vertexElementUsage, usageIndex)); offset += deltaOffset; } } #endregion // Build vertex and index array for (int v = 0; v < primitive.count * 3; v++) { int positionIndex = 0; string indexKey = ""; tempValues.Clear(); foreach (Document.Input input in COLLADAUtil.GetAllInputs(primitive)) { // Get index into source array of this input for this triangle t int index = COLLADAUtil.GetPValue(input, primitive, v); // Save index of position array for later inverse mapping if (input.semantic == "POSITION") positionIndex = index; // Build key out of all indices for later lookup indexKey += index + ","; // Get values this index is referencing float[] values = COLLADAUtil.GetSourceElement(doc, input, index); // Add the values to temporary storage tempValues.AddRange(values); } // Add this combination of inputs to the vertex buffer if (mapping.ContainsKey(indexKey)) indexBuffer.Add(mapping[indexKey]); else { mapping[indexKey] = vertexIndex; indexBuffer.Add(vertexIndex); vertexBuffer.AddRange(tempValues); // Inverse mapping of vertex buffer index to index of original array invVertexMappingList.Add(positionIndex); // Increment index of vertex buffer vertexIndex++; } } primitives.Add(primitive); faceCount += primitive.count; } vertexCount = vertexIndex; indexArray = indexBuffer.ToArray(); vertexArray = vertexBuffer.ToArray(); invVertexMapping = invVertexMappingList.ToArray(); // Reverse triangle order for DirectX for (int i = 0; i < indexArray.Length; i += 3) { int swap = indexArray[i]; indexArray[i] = indexArray[i + 2]; indexArray[i + 2] = swap; } foreach (VertexElement vertexElement in VertexElements) { // Reverse texture 'T' coordinate for DirectX if (vertexElement.Usage == DeclarationUsage.TextureCoordinate) { for (int i = 0; i < vertexCount; i++) { int offsetT = i * VertexStride + vertexElement.Offset / 4 + 1; if (offsetT < vertexArray.Length) vertexArray[offsetT] = 1.0f - vertexArray[offsetT]; else throw new IndexOutOfRangeException(); } } } FinalizeVertexDeclaration(vertexElements); }