Ejemplo n.º 1
0
 public ReplicatorImpl(IStorageBasedDataObjectAccessor <TDataType> accessor, IStore target)
 {
     _info     = GetAccessorInfo(accessor.GetType(), new Lazy <Expression>(() => accessor.GetSource().Expression));
     _accessor = accessor;
     _target   = target;
 }
Ejemplo n.º 2
0
        private Mesh CreateGltfMesh(string meshName, VMesh vmesh, ModelRoot model)
        {
            ProgressDialog.SetProgress($"Creating mesh: {meshName}");

            var data = vmesh.GetData();
            var vbib = vmesh.VBIB;

            var mesh = model.CreateMesh(meshName);

            mesh.Name = meshName;

            foreach (var sceneObject in data.GetArray("m_sceneObjects"))
            {
                foreach (var drawCall in sceneObject.GetArray("m_drawCalls"))
                {
                    var vertexBufferInfo  = drawCall.GetArray("m_vertexBuffers")[0]; // In what situation can we have more than 1 vertex buffer per draw call?
                    var vertexBufferIndex = (int)vertexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var vertexBuffer      = vbib.VertexBuffers[vertexBufferIndex];

                    var indexBufferInfo  = drawCall.GetSubCollection("m_indexBuffer");
                    var indexBufferIndex = (int)indexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var indexBuffer      = vbib.IndexBuffers[indexBufferIndex];

                    // Create one primitive per draw call
                    var primitive = mesh.CreatePrimitive();

                    // Avoid duplicate attribute names
                    var uniqueAttributes = vertexBuffer.Attributes.GroupBy(a => a.Name).Select(g => g.First());

                    // Set vertex attributes
                    foreach (var attribute in uniqueAttributes)
                    {
                        if (AccessorInfo.TryGetValue(attribute.Name, out var accessorInfo))
                        {
                            var buffer = ReadAttributeBuffer(vbib, vertexBuffer, attribute);

                            if (accessorInfo.NumComponents == 4)
                            {
                                var vectors = ToVector4Array(buffer);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                            else if (attribute.Name == "NORMAL" && DrawCall.IsCompressedNormalTangent(drawCall))
                            {
                                var vectors = ToVector4Array(buffer);
                                var(normals, tangents) = DecompressNormalTangents(vectors);
                                primitive.WithVertexAccessor("NORMAL", normals);
                                primitive.WithVertexAccessor("TANGENT", tangents);
                            }
                            else if (accessorInfo.NumComponents == 3)
                            {
                                var vectors = ToVector3Array(buffer, true, accessorInfo.Resize);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                            else if (accessorInfo.NumComponents == 2)
                            {
                                var vectors = ToVector2Array(buffer);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                        }
                    }

                    // Set index buffer
                    var indices = ReadIndices(indexBuffer);

                    // For triangle primitives, the front face has to be in counter-clockwise (CCW) winding order.
                    for (var i = 0; i < indices.Length; i += 3)
                    {
                        var b = indices[i + 2];
                        indices[i + 2] = indices[i + 1];
                        indices[i + 1] = b;
                    }

                    primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indices);

                    // Add material
                    var materialPath = drawCall.GetProperty <string>("m_material");

                    ProgressDialog.SetProgress($"Loading material: {materialPath}");

                    var materialResource = GuiContext.LoadFileByAnyMeansNecessary(materialPath + "_c");

                    if (materialResource == null)
                    {
                        continue;
                    }

                    var renderMaterial = (VMaterial)materialResource.DataBlock;

                    var materialNameTrimmed = Path.GetFileNameWithoutExtension(materialPath);
                    var bestMaterial        = GenerateGLTFMaterialFromRenderMaterial(renderMaterial, model, materialNameTrimmed);
                    primitive.WithMaterial(bestMaterial);
                }
            }

            return(mesh);
        }