Example #1
0
            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;
                    }
                }
                 */
            }
Example #2
0
            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);
            }