Ejemplo n.º 1
0
    private static void WriteSkinnedMeshJson(SkinnedMeshRenderer skinnedRenderer, WebGLBone[] bones, Stream outStream, Dictionary <Material, WebGLModel> materialModels)
    {
        Mesh mesh = skinnedRenderer.sharedMesh;
        int  i;

        // Map the bones used by each sub-mesh
        foreach (WebGLModel model in materialModels.Values)
        {
            for (i = 0; i < model.meshes.Count; ++i)
            {
                WebGLMesh subMesh = model.meshes[i];

                // Eventually this will have to change, but for now let's just keep things simple:
                subMesh.boneOffset = 0;
                subMesh.boneCount  = bones.Length;

                model.meshes[i] = subMesh;
            }
        }

        StringTemplateGroup templateGroup = new StringTemplateGroup("MG", templatePath, typeof(DefaultTemplateLexer));
        StringTemplate      modelTemplate = templateGroup.GetInstanceOf("WebGLModel");

        modelTemplate.SetAttribute("name", mesh.name);
        modelTemplate.SetAttribute("models", materialModels.Values);
        modelTemplate.SetAttribute("bones", bones);

        string content = modelTemplate.ToString();

        Byte[] bytes = new UTF8Encoding(true).GetBytes(CleanJSON(content));
        outStream.Write(bytes, 0, bytes.Length);
    }
Ejemplo n.º 2
0
    private static void WriteMeshBinary(Mesh mesh, VertexFormat vertexFormat, Material[] materials, int[] boneIdLookup, Stream outStream, out Dictionary <Material, WebGLModel> models)
    {
        int i, j;

        Dictionary <string, MemoryStream> lumps = new Dictionary <string, MemoryStream>();

        Vector3[]    verts       = mesh.vertices;
        Vector2[]    uv          = mesh.uv;
        Vector2[]    uv2         = mesh.uv2;
        Vector3[]    normals     = mesh.normals;
        Vector4[]    tangents    = mesh.tangents;
        Color[]      colors      = mesh.colors;
        BoneWeight[] boneWeights = mesh.boneWeights;

        // Check for some attributes that may not be present. Remove them from the mask if they have no data
        if (uv2.Length == 0 && (vertexFormat & VertexFormat.UV2) == VertexFormat.UV2)
        {
            vertexFormat &= ~VertexFormat.UV2;
        }
        if (colors.Length == 0 && (vertexFormat & VertexFormat.Color) == VertexFormat.Color)
        {
            vertexFormat &= ~VertexFormat.Color;
        }
        if (boneWeights.Length == 0 && (vertexFormat & VertexFormat.BoneWeights) == VertexFormat.BoneWeights)
        {
            vertexFormat &= ~VertexFormat.BoneWeights;
        }

        // Build the vertex buffer
        UInt32 vertStride = 0;

        if ((vertexFormat & VertexFormat.Position) == VertexFormat.Position)
        {
            vertStride += 12;
        }
        if ((vertexFormat & VertexFormat.UV) == VertexFormat.UV)
        {
            vertStride += 8;
        }
        if ((vertexFormat & VertexFormat.UV2) == VertexFormat.UV2)
        {
            vertStride += 8;
        }
        if ((vertexFormat & VertexFormat.Normal) == VertexFormat.Normal)
        {
            vertStride += 12;
        }
        if ((vertexFormat & VertexFormat.Tangent) == VertexFormat.Tangent)
        {
            vertStride += 16;
        }
        if ((vertexFormat & VertexFormat.Color) == VertexFormat.Color)
        {
            vertStride += 4;
        }
        if ((vertexFormat & VertexFormat.BoneWeights) == VertexFormat.BoneWeights)
        {
            vertStride += 24;
        }

        MemoryStream vertStream = new MemoryStream();
        BinaryWriter vertBuf    = new BinaryWriter(vertStream);

        vertBuf.Write((UInt32)vertexFormat);
        vertBuf.Write(vertStride);

        for (i = 0; i < verts.Length; ++i)
        {
            if ((vertexFormat & VertexFormat.Position) == VertexFormat.Position)
            {
                vertBuf.Write(verts[i].x); // Apparently Unity does it's X axis "backwards" from most other apps
                vertBuf.Write(verts[i].y);
                vertBuf.Write(verts[i].z);
            }

            if ((vertexFormat & VertexFormat.UV) == VertexFormat.UV)
            {
                vertBuf.Write(uv[i].x);
                vertBuf.Write(uv[i].y);
            }

            if ((vertexFormat & VertexFormat.UV2) == VertexFormat.UV2)
            {
                vertBuf.Write(uv2[i].x);
                vertBuf.Write(uv2[i].y);
            }

            if ((vertexFormat & VertexFormat.Normal) == VertexFormat.Normal)
            {
                vertBuf.Write(-normals[i].x);
                vertBuf.Write(normals[i].y);
                vertBuf.Write(normals[i].z);
            }

            if ((vertexFormat & VertexFormat.Tangent) == VertexFormat.Tangent)
            {
                vertBuf.Write(tangents[i].x);
                vertBuf.Write(tangents[i].y);
                vertBuf.Write(tangents[i].z);
                vertBuf.Write(tangents[i].w);
            }

            if ((vertexFormat & VertexFormat.Color) == VertexFormat.Color)
            {
                vertBuf.Write((Byte)(colors[i].r * 255.0));
                vertBuf.Write((Byte)(colors[i].g * 255.0));
                vertBuf.Write((Byte)(colors[i].b * 255.0));
                vertBuf.Write((Byte)(colors[i].a * 255.0));
            }

            if ((vertexFormat & VertexFormat.BoneWeights) == VertexFormat.BoneWeights)
            {
                // We're only going to be tracking 3 bones per vertex, so we need to find
                // the lowest weight and average the other weights out across it
                int   lowestWeightId = 0;
                float lowestWeight   = boneWeights[i].weight0;

                if (boneWeights[i].weight1 < lowestWeight)
                {
                    lowestWeightId = 1; lowestWeight = boneWeights[i].weight1;
                }
                if (boneWeights[i].weight2 < lowestWeight)
                {
                    lowestWeightId = 2; lowestWeight = boneWeights[i].weight2;
                }
                if (boneWeights[i].weight3 < lowestWeight)
                {
                    lowestWeightId = 3; lowestWeight = boneWeights[i].weight3;
                }

                float weightAdjustment = 1.0f + lowestWeight;

                if (lowestWeightId != 0)
                {
                    vertBuf.Write(boneWeights[i].weight0 * weightAdjustment);
                }
                if (lowestWeightId != 1)
                {
                    vertBuf.Write(boneWeights[i].weight1 * weightAdjustment);
                }
                if (lowestWeightId != 2)
                {
                    vertBuf.Write(boneWeights[i].weight2 * weightAdjustment);
                }
                if (lowestWeightId != 3)
                {
                    vertBuf.Write(boneWeights[i].weight3 * weightAdjustment);
                }

                if (lowestWeightId != 0)
                {
                    vertBuf.Write((float)boneIdLookup[boneWeights[i].boneIndex0]);
                }
                if (lowestWeightId != 1)
                {
                    vertBuf.Write((float)boneIdLookup[boneWeights[i].boneIndex1]);
                }
                if (lowestWeightId != 2)
                {
                    vertBuf.Write((float)boneIdLookup[boneWeights[i].boneIndex2]);
                }
                if (lowestWeightId != 3)
                {
                    vertBuf.Write((float)boneIdLookup[boneWeights[i].boneIndex3]);
                }
            }
        }
        lumps.Add("vert", vertStream);

        // Build the index buffer
        UInt32 indexCount = 0;

        models = new Dictionary <Material, WebGLModel>();

        MemoryStream indexStream = new MemoryStream();
        BinaryWriter indexBuf    = new BinaryWriter(indexStream);

        for (i = 0; i < mesh.subMeshCount; ++i)
        {
            int[]    triangles = mesh.GetTriangles(i);
            Material material  = materials[i];

            WebGLModel model;
            if (!models.TryGetValue(material, out model))
            {
                model          = new WebGLModel();
                model.meshes   = new List <WebGLMesh>();
                model.material = material;
                if (material.mainTexture)
                {
                    model.defaultTexture = CreateWebTexture(material.mainTexture as Texture2D);
                }
                models[material] = model;
            }

            WebGLMesh webGLMesh = new WebGLMesh();
            webGLMesh.indexOffset = (UInt16)indexCount;
            webGLMesh.indexCount  = (UInt16)triangles.Length;
            indexCount           += webGLMesh.indexCount;

            model.meshes.Add(webGLMesh);

            for (j = 0; j < triangles.Length; ++j)
            {
                indexBuf.Write((UInt16)triangles[j]);
            }
        }
        lumps.Add("indx", indexStream);

        WriteLumpFile(vertBinaryVersion, "wglv", lumps, outStream);
    }