Beispiel #1
0
    private bool LoadTextureIndicesChunk()
    {
        PrimitiveState primitiveState = m_primitiveStates[m_currentPrimitiveStateIndex];

        primitiveState.TextureIndexCount = m_chunkReader.ReadInt();
        primitiveState.TextureIndices    = new int[primitiveState.TextureIndexCount];
        for (int k = 0; k < primitiveState.TextureIndexCount; k++)
        {
            primitiveState.TextureIndices[k] = m_chunkReader.ReadInt();
        }
        return(true);
    }
Beispiel #2
0
 protected internal virtual void copy(PrimitiveState from)
 {
     p1x               = from.p1x;
     p1y               = from.p1y;
     p1z               = from.p1z;
     p1w               = from.p1w;
     p1wInverted       = from.p1wInverted;
     p2x               = from.p2x;
     p2y               = from.p2y;
     p2z               = from.p2z;
     p2w               = from.p2w;
     p2wInverted       = from.p2wInverted;
     p3x               = from.p3x;
     p3y               = from.p3y;
     p3z               = from.p3z;
     p3w               = from.p3w;
     p3wInverted       = from.p3wInverted;
     pxMin             = from.pxMin;
     pxMax             = from.pxMax;
     pyMin             = from.pyMin;
     pyMax             = from.pyMax;
     pzMin             = from.pzMin;
     pzMax             = from.pzMax;
     t1u               = from.t1u;
     t1v               = from.t1v;
     t2u               = from.t2u;
     t2v               = from.t2v;
     t3u               = from.t3u;
     t3v               = from.t3v;
     tuMin             = from.tuMin;
     tuMax             = from.tuMax;
     tvMin             = from.tvMin;
     tvMax             = from.tvMax;
     uStart            = from.uStart;
     uStep             = from.uStep;
     vStart            = from.vStart;
     vStep             = from.vStep;
     destinationWidth  = from.destinationWidth;
     destinationHeight = from.destinationHeight;
     diff13x           = from.diff13x;
     diff13y           = from.diff13y;
     diff32x           = from.diff32x;
     diff23y           = from.diff23y;
     denomInverted     = from.denomInverted;
 }
Beispiel #3
0
    private bool LoadPrimitiveStateChunk()
    {
        var primitiveState = new PrimitiveState();

        m_currentPrimitiveStateIndex = m_primitiveStates.Count;
        m_primitiveStates.Add(primitiveState);

        primitiveState.Flags       = m_chunkReader.ReadInt();
        primitiveState.ShaderIndex = m_chunkReader.ReadInt();
//			Console.WriteLine("ShaderIndex = " + primitiveState.ShaderIndex);

        LoadChunk();

        primitiveState.Zbias                   = m_chunkReader.ReadInt();
        primitiveState.VertexStateIndex        = m_chunkReader.ReadInt();
        primitiveState.AlphaTestMode           = m_chunkReader.ReadInt();
        primitiveState.LightConfigurationIndex = m_chunkReader.ReadInt();
        primitiveState.ZBufferMode             = m_chunkReader.ReadInt();

        // Tell loadchunk not to read the end of the chunk
        return(true);
    }
Beispiel #4
0
        private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vertex, ref int[] intArray)
        {
            float       x, y, z;
            Vector3     point;
            KujuTokenID currentToken = KujuTokenID.error;
            Block       newBlock;
            uint        flags;

            switch (block.Token)
            {
            case KujuTokenID.shape:
                newBlock = block.ReadSubBlock(KujuTokenID.shape_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.volumes);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.shader_names);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.texture_filter_names);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.points);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.uv_points);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.normals);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.sort_vectors);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.colours);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.matrices);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.images);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.textures);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.light_materials);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.light_model_cfgs);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.vtx_states);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.prim_states);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.lod_controls);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.shape_header:
            case KujuTokenID.volumes:
            case KujuTokenID.texture_filter_names:
            case KujuTokenID.sort_vectors:
            case KujuTokenID.colours:
            case KujuTokenID.light_materials:
            case KujuTokenID.light_model_cfgs:
                //Unsupported stuff, so just read to the end at the minute
                block.Skip((int)block.Length());
                break;

            case KujuTokenID.vtx_state:
                flags = block.ReadUInt32();
                int  matrix1          = block.ReadInt32();
                int  lightMaterialIdx = block.ReadInt32();
                int  lightStateCfgIdx = block.ReadInt32();
                uint lightFlags       = block.ReadUInt32();
                int  matrix2          = -1;
                if ((block is BinaryBlock && block.Length() - block.Position() > 1) || (!(block is BinaryBlock) && block.Length() - block.Position() > 2))
                {
                    matrix2 = block.ReadInt32();
                }

                VertexStates vs = new VertexStates();
                vs.flags             = flags;
                vs.hierarchyID       = matrix1;
                vs.lightingMatrixID  = lightMaterialIdx;
                vs.lightingConfigIdx = lightStateCfgIdx;
                vs.lightingFlags     = lightFlags;
                vs.matrix2ID         = matrix2;
                shape.vtx_states.Add(vs);
                break;

            case KujuTokenID.vtx_states:
                int vtxStateCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (vtxStateCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vtx_state);
                    ParseBlock(newBlock, ref shape);
                    vtxStateCount--;
                }

                break;

            case KujuTokenID.prim_state:
                flags = block.ReadUInt32();
                int   shader  = block.ReadInt32();
                int[] texIdxs = {};
                newBlock = block.ReadSubBlock(KujuTokenID.tex_idxs);
                ParseBlock(newBlock, ref shape, ref texIdxs);

                float          zBias         = block.ReadSingle();
                int            vertexStates  = block.ReadInt32();
                int            alphaTestMode = block.ReadInt32();
                int            lightCfgIdx   = block.ReadInt32();
                int            zBufferMode   = block.ReadInt32();
                PrimitiveState p             = new PrimitiveState();
                p.Name          = block.Label;
                p.Flags         = flags;
                p.Shader        = shader;
                p.Textures      = texIdxs;
                p.ZBias         = zBias;
                p.vertexStates  = vertexStates;
                p.alphaTestMode = alphaTestMode;
                p.lightCfgIdx   = lightCfgIdx;
                p.zBufferMode   = zBufferMode;
                shape.prim_states.Add(p);
                break;

            case KujuTokenID.tex_idxs:
                int texIdxCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                Array.Resize(ref intArray, texIdxCount);
                int idx = 0;
                while (texIdxCount > 0)
                {
                    intArray[idx] = block.ReadUInt16();
                    idx++;
                    texIdxCount--;
                }
                break;

            case KujuTokenID.prim_states:
                int primStateCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (primStateCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.prim_state);
                    ParseBlock(newBlock, ref shape);
                    primStateCount--;
                }

                break;

            case KujuTokenID.texture:
                int   imageIDX      = block.ReadInt32();
                int   filterMode    = (int)block.ReadUInt32();
                float mipmapLODBias = block.ReadSingle();
                uint  borderColor   = 0xff000000U;
                if (block.Length() - block.Position() > 1)
                {
                    borderColor = block.ReadUInt32();
                }

                //Unpack border color
                float r, g, b, a;
                r = borderColor % 256;
                g = (borderColor / 256) % 256;
                b = (borderColor / 256 / 256) % 256;
                a = (borderColor / 256 / 256 / 256) % 256;
                Texture t = new Texture();
                t.fileName      = shape.images[imageIDX];
                t.filterMode    = filterMode;
                t.mipmapLODBias = (int)mipmapLODBias;
                t.borderColor   = new Color32((byte)r, (byte)g, (byte)b, (byte)a);
                shape.textures.Add(t);
                break;

            case KujuTokenID.textures:
                int textureCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (textureCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.texture);
                    ParseBlock(newBlock, ref shape);
                    textureCount--;
                }

                break;

            case KujuTokenID.image:
                shape.images.Add(block.ReadString());
                break;

            case KujuTokenID.images:
                int imageCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (imageCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.image);
                    ParseBlock(newBlock, ref shape);
                    imageCount--;
                }

                break;

            case KujuTokenID.cullable_prims:
                int numPrims        = block.ReadInt32();
                int numFlatSections = block.ReadInt32();
                int numPrimIdxs     = block.ReadInt32();
                break;

            case KujuTokenID.geometry_info:
                int faceNormals      = block.ReadInt32();
                int txLightCommands  = block.ReadInt32();
                int nodeXTrilistIdxs = block.ReadInt32();
                int trilistIdxs      = block.ReadInt32();
                int lineListIdxs     = block.ReadInt32();
                nodeXTrilistIdxs = block.ReadInt32();                         //Duped, or is the first one actually something else?
                int trilists      = block.ReadInt32();
                int lineLists     = block.ReadInt32();
                int pointLists    = block.ReadInt32();
                int nodeXTrilists = block.ReadInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.geometry_nodes);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.geometry_node_map);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.geometry_node_map:
                int[] geometryNodes = new int[block.ReadInt32()];
                for (int i = 0; i < geometryNodes.Length; i++)
                {
                    geometryNodes[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.geometry_node:
                int n_txLightCommands  = block.ReadInt32();
                int n_nodeXTxLightCmds = block.ReadInt32();
                int n_trilists         = block.ReadInt32();
                int n_lineLists        = block.ReadInt32();
                int n_pointLists       = block.ReadInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.cullable_prims);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.geometry_nodes:
                int geometryNodeCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (geometryNodeCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.geometry_node);
                    ParseBlock(newBlock, ref shape);
                    geometryNodeCount--;
                }

                break;

            case KujuTokenID.point:
                x     = block.ReadSingle();
                y     = block.ReadSingle();
                z     = block.ReadSingle();
                point = new Vector3(x, y, z);
                shape.points.Add(point);
                break;

            case KujuTokenID.vector:
                x     = block.ReadSingle();
                y     = block.ReadSingle();
                z     = block.ReadSingle();
                point = new Vector3(x, y, z);
                shape.normals.Add(point);
                break;

            case KujuTokenID.points:
                int pointCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (pointCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.point);
                    ParseBlock(newBlock, ref shape);
                    pointCount--;
                }

                break;

            case KujuTokenID.uv_point:
                x = block.ReadSingle();
                y = block.ReadSingle();
                var uv_point = new Vector2(x, y);
                shape.uv_points.Add(uv_point);
                break;

            case KujuTokenID.uv_points:
                int uvPointCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (uvPointCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.uv_point);
                    ParseBlock(newBlock, ref shape);
                    uvPointCount--;
                }

                break;

            case KujuTokenID.matrices:
                int matrixCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (matrixCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.matrix);
                    ParseBlock(newBlock, ref shape);
                    matrixCount--;
                }
                break;

            case KujuTokenID.matrix:
                Matrix currentMatrix = new Matrix();
                currentMatrix.Name = block.Label;
                currentMatrix.A    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                currentMatrix.B    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                currentMatrix.C    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                currentMatrix.D    = new Vector3(block.ReadSingle(), block.ReadSingle(), block.ReadSingle());
                shape.matrices.Add(currentMatrix);
                break;

            case KujuTokenID.normals:
                int normalCount = block.ReadUInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (normalCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vector);
                    ParseBlock(newBlock, ref shape);
                    normalCount--;
                }

                break;

            case KujuTokenID.distance_levels_header:
                int DLevBias = block.ReadInt16();
                break;

            case KujuTokenID.distance_levels:
                int distanceLevelCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (distanceLevelCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.distance_level);
                    ParseBlock(newBlock, ref shape);
                    distanceLevelCount--;
                }

                break;

            case KujuTokenID.distance_level_header:
                newBlock = block.ReadSubBlock(KujuTokenID.dlevel_selection);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.hierarchy);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.distance_level:
                newBlock = block.ReadSubBlock(KujuTokenID.distance_level_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.sub_objects);
                ParseBlock(newBlock, ref shape);
                shape.LODs.Add(currentLOD);
                break;

            case KujuTokenID.dlevel_selection:
                currentLOD = new LOD(block.ReadSingle());
                break;

            case KujuTokenID.hierarchy:
                currentLOD.hierarchy = new int[block.ReadInt32()];
                for (int i = 0; i < currentLOD.hierarchy.Length; i++)
                {
                    currentLOD.hierarchy[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.lod_control:
                newBlock = block.ReadSubBlock(KujuTokenID.distance_levels_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.distance_levels);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.lod_controls:
                int lodCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (lodCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.lod_control);
                    ParseBlock(newBlock, ref shape);
                    lodCount--;
                }

                break;

            case KujuTokenID.primitives:
                int capacity = block.ReadInt32();                         //Count of the number of entries in the block, not the number of primitives
                while (capacity > 0)
                {
                    newBlock = block.ReadSubBlock(new KujuTokenID[] { KujuTokenID.prim_state_idx, KujuTokenID.indexed_trilist });
                    switch (newBlock.Token)
                    {
                    case KujuTokenID.prim_state_idx:
                        ParseBlock(newBlock, ref shape);
                        string txF = null;
                        try
                        {
                            txF = OpenBveApi.Path.CombineFile(currentFolder, shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName);
                            if (!File.Exists(txF))
                            {
                                Interface.AddMessage(MessageType.Warning, true, "Texture file " + shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName + " was not found.");
                                txF = null;
                            }
                        }
                        catch
                        {
                            Interface.AddMessage(MessageType.Warning, true, "Texture file path " + shape.textures[shape.prim_states[shape.currentPrimitiveState].Textures[0]].fileName + " was invalid.");
                        }
                        currentLOD.subObjects[currentLOD.subObjects.Count - 1].materials.Add(new Material(txF));
                        break;

                    case KujuTokenID.indexed_trilist:
                        ParseBlock(newBlock, ref shape);
                        break;

                    default:
                        throw new Exception("Unexpected primitive type, got " + currentToken);
                    }

                    capacity--;
                }

                break;

            case KujuTokenID.prim_state_idx:
                shape.currentPrimitiveState = block.ReadInt32();
                break;

            case KujuTokenID.indexed_trilist:
                newBlock = block.ReadSubBlock(KujuTokenID.vertex_idxs);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.normal_idxs);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.sub_object:
                newBlock = block.ReadSubBlock(KujuTokenID.sub_object_header);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.vertices);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.vertex_sets);
                ParseBlock(newBlock, ref shape);
                newBlock = block.ReadSubBlock(KujuTokenID.primitives);
                ParseBlock(newBlock, ref shape);
                break;

            case KujuTokenID.sub_objects:
                int subObjectCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (subObjectCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.sub_object);
                    ParseBlock(newBlock, ref shape);
                    subObjectCount--;
                }

                break;

            case KujuTokenID.sub_object_header:
                currentLOD.subObjects.Add(new SubObject());
                shape.totalObjects++;
                flags = block.ReadUInt32();
                int  sortVectorIdx                = block.ReadInt32();
                int  volIdx                       = block.ReadInt32();
                uint sourceVertexFormatFlags      = block.ReadUInt32();
                uint destinationVertexFormatFlags = block.ReadUInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.geometry_info);
                ParseBlock(newBlock, ref shape);

                /*
                 * Optional stuff, need to check if we're running off the end of the stream before reading each block
                 */
                if (block.Length() - block.Position() > 1)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.subobject_shaders);
                    ParseBlock(newBlock, ref shape);
                }

                if (block.Length() - block.Position() > 1)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.subobject_light_cfgs);
                    ParseBlock(newBlock, ref shape);
                }

                if (block.Length() - block.Position() > 1)
                {
                    int subObjectID = block.ReadInt32();
                }

                break;

            case KujuTokenID.subobject_light_cfgs:
                int[] subobject_light_cfgs = new int[block.ReadInt32()];
                for (int i = 0; i < subobject_light_cfgs.Length; i++)
                {
                    subobject_light_cfgs[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.subobject_shaders:
                int[] subobject_shaders = new int[block.ReadInt32()];
                for (int i = 0; i < subobject_shaders.Length; i++)
                {
                    subobject_shaders[i] = block.ReadInt32();
                }

                break;

            case KujuTokenID.vertices:
                int vertexCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (vertexCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vertex);
                    ParseBlock(newBlock, ref shape);
                    vertexCount--;
                }

                break;

            case KujuTokenID.vertex:
                flags = block.ReadUInt32();                         //Various control variables, not supported
                int myPoint  = block.ReadInt32();                   //Index to points array
                int myNormal = block.ReadInt32();                   //Index to normals array

                Vertex v = new Vertex(shape.points[myPoint], shape.normals[myNormal]);

                uint Color1 = block.ReadUInt32();
                uint Color2 = block.ReadUInt32();
                newBlock = block.ReadSubBlock(KujuTokenID.vertex_uvs);
                ParseBlock(newBlock, ref shape, ref v);
                currentLOD.subObjects[currentLOD.subObjects.Count - 1].verticies.Add(v);
                break;

            case KujuTokenID.vertex_idxs:
                int remainingVertex = block.ReadInt32() / 3;
                while (remainingVertex > 0)
                {
                    int v1 = block.ReadInt32();
                    int v2 = block.ReadInt32();
                    int v3 = block.ReadInt32();

                    currentLOD.subObjects[currentLOD.subObjects.Count - 1].faces.Add(new Face(new int[] { v1, v2, v3 }, currentLOD.subObjects[currentLOD.subObjects.Count - 1].materials.Count - 1));
                    remainingVertex--;
                }

                break;

            case KujuTokenID.vertex_set:
                int       vertexStateIndex    = block.ReadInt32();                              //Index to the vtx_states member
                int       hierarchy           = shape.vtx_states[vertexStateIndex].hierarchyID; //Now pull the hierachy ID out
                int       setStartVertexIndex = block.ReadInt32();                              //First vertex
                int       setVertexCount      = block.ReadInt32();                              //Total number of vert
                VertexSet vts = new VertexSet();
                vts.hierarchyIndex = hierarchy;
                vts.startVertex    = setStartVertexIndex;
                vts.numVerticies   = setVertexCount;
                currentLOD.subObjects[currentLOD.subObjects.Count - 1].vertexSets.Add(vts);
                break;

            case KujuTokenID.vertex_sets:
                int vertexSetCount = block.ReadInt16();
                if (block is BinaryBlock)
                {
                    block.ReadUInt16();
                }
                while (vertexSetCount > 0)
                {
                    newBlock = block.ReadSubBlock(KujuTokenID.vertex_set);
                    ParseBlock(newBlock, ref shape);
                    vertexSetCount--;
                }

                //We now need to transform our verticies
                currentLOD.subObjects[currentLOD.subObjects.Count - 1].TransformVerticies(shape.matrices);
                break;

            case KujuTokenID.vertex_uvs:
                int[] vertex_uvs = new int[block.ReadInt32()];
                for (int i = 0; i < vertex_uvs.Length; i++)
                {
                    vertex_uvs[i] = block.ReadInt32();
                }

                //Looks as if vertex_uvs should always be of length 1, thus:
                vertex.TextureCoordinates = shape.uv_points[vertex_uvs[0]];
                break;
            }
        }
Beispiel #5
0
    private bool LoadIndexedTrilistChunk()
    {
        m_geometryVertexIndices.Clear();

        LoadChildChunks();

        if (m_currentDistanceLevelIndex == 0)
        {
            // Each indexed trilist becomes a geometry node

            // We only add the vertices that are actually used in this geometry node.
            // This also means that the indices must be renumbered.
            int uniqueIndexCount  = 0;
            var indexRenumbering  = new Dictionary <int, int>();
            var usedVertexIndices = new List <int>();
            for (int indexIndex = 0; indexIndex < m_geometryVertexIndices.Count; indexIndex++)
            {
                int index = m_geometryVertexIndices[indexIndex];
                if (!indexRenumbering.ContainsKey(index))
                {
                    indexRenumbering.Add(index, uniqueIndexCount);                      // original index, renumbered index
                    usedVertexIndices.Add(index);
                    uniqueIndexCount++;
                }
            }

            Debug.Assert(m_geometryVertexUVs.Count <= 2);

            int vertexCount = uniqueIndexCount;
            var positions   = new Vector3[vertexCount];
            var normals     = new Vector3[vertexCount];
            var uv1         = m_geometryVertexUVs.Count >= 1 ? new Vector2[vertexCount] : null;
            var uv2         = m_geometryVertexUVs.Count == 2 ? new Vector2[vertexCount] : null;

            for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++)
            {
                int sourceVertexIndex = usedVertexIndices[vertexIndex];
                positions[vertexIndex] = m_geometryVertexPositions[sourceVertexIndex];
                normals[vertexIndex]   = m_geometryVertexNormals[sourceVertexIndex];

                if (m_geometryVertexUVs.Count == 1)
                {
                    uv1[vertexIndex] = new Vector2(m_geometryVertexUVs[0][sourceVertexIndex].x, 1 - m_geometryVertexUVs[0][sourceVertexIndex].y);
                }
                else if (m_geometryVertexUVs.Count == 2)
                {
                    uv2[vertexIndex] = new Vector2(m_geometryVertexUVs[1][sourceVertexIndex].x, 1 - m_geometryVertexUVs[1][sourceVertexIndex].y);
                }
            }

            var indices       = new int[m_geometryVertexIndices.Count];
            int triangleCount = m_geometryVertexIndices.Count / 3;
            for (int triangleIndex = 0; triangleIndex < triangleCount; triangleIndex++)
            {
                indices[3 * triangleIndex + 0] = indexRenumbering[m_geometryVertexIndices[3 * triangleIndex + 0]];
                indices[3 * triangleIndex + 1] = indexRenumbering[m_geometryVertexIndices[3 * triangleIndex + 1]];
                indices[3 * triangleIndex + 2] = indexRenumbering[m_geometryVertexIndices[3 * triangleIndex + 2]];
            }

            PrimitiveState primitiveState = m_primitiveStates[m_currentPrimitiveStateIndex];
            VertexState    vertexState    = m_vertexStates[primitiveState.VertexStateIndex];
            var            gameObject     = m_gameObjects[vertexState.MatrixIndex];

            var mesh = new Mesh
            {
                name      = gameObject.name,
                vertices  = positions,
                normals   = normals,
                triangles = indices,
                uv        = uv1,
//				uv2			= uv2
            };

            if (gameObject.GetComponent <MeshFilter>() != null)
            {
                gameObject = new GameObject(gameObject.name);
                AddChildToGameObject(vertexState.MatrixIndex, gameObject.transform);
            }

            var meshFilter = gameObject.AddComponent <MeshFilter>();
            meshFilter.mesh = mesh;

            var meshRenderer = gameObject.AddComponent <MeshRenderer>();
            Debug.Assert(primitiveState.TextureIndexCount == 1);
            meshRenderer.sharedMaterial = m_materials[primitiveState.TextureIndices[0]];
        }
        return(false);
    }
Beispiel #6
0
        private void AddPolygon(PrimitiveState state, ObjModel objModel, Polygon poly)
        {
            var v1      = poly.Vertices[0];
            var v2      = poly.Vertices[1];
            var v3      = poly.Vertices[2];
            var v1Index = (int)(v1.V - 1);
            var v2Index = (int)(v2.V - 1);
            var v3Index = (int)(v3.V - 1);
            var v1v     = objModel.Positions[v1Index];
            var v2v     = objModel.Positions[v2Index];
            var v3v     = objModel.Positions[v3Index];

            UpdateMinMax(state.VertexXMM, v1v.X, v2v.X, v3v.X);
            UpdateMinMax(state.VertexYMM, v1v.Y, v2v.Y, v3v.Y);
            UpdateMinMax(state.VertexZMM, v1v.Z, v2v.Z, v3v.Z);

            var hasNormal = v1.VN.HasValue;
            var hasUV     = v1.VT.HasValue;

            Normal n1, n2, n3;

            if (hasNormal)
            {
                var n1Index = (int)(v1.VN.Value - 1);
                var n2Index = (int)(v2.VN.Value - 1);
                var n3Index = (int)(v3.VN.Value - 1);
                n1 = objModel.Normals[n1Index];
                n2 = objModel.Normals[n2Index];
                n3 = objModel.Normals[n3Index];
                UpdateMinMax(state.NormalXMM, n1.X, n2.X, n3.X);
                UpdateMinMax(state.NormalYMM, n1.Y, n2.Y, n3.Y);
                UpdateMinMax(state.NormalZMM, n1.Z, n2.Z, n3.Z);
            }
            else
            {
                n1 = new Normal();
                n2 = n1;
                n3 = n1;
            }

            Uv t1, t2, t3;

            if (hasUV)
            {
                var t1Index = (int)(v1.VT.Value - 1);
                var t2Index = (int)(v2.VT.Value - 1);
                var t3Index = (int)(v3.VT.Value - 1);
                t1 = objModel.TextureCoords[t1Index];
                t2 = objModel.TextureCoords[t2Index];
                t3 = objModel.TextureCoords[t3Index];
                UpdateMinMax(state.UvUMM, t1.U, t2.U, t3.U);
                UpdateMinMax(state.UvVMM, 1 - t1.V, 1 - t2.V, 1 - t3.V);
            }
            else
            {
                t1 = new Uv();
                t2 = t1;
                t3 = t1;
            }

            if (state.AddVertex(v1))
            {
                state.VertexCount++;
                FillBytes(state.VertexBuffers, v1v.ToArray());
                if (hasNormal)
                {
                    state.NormalCount++;
                    FillBytes(state.NormalBuffers, n1.ToArray());
                }
                if (hasUV)
                {
                    state.UvCount++;
                    FillBytes(state.TextureBuffers, new Uv(t1.U, 1 - t1.V).ToArray());
                }
            }

            if (state.AddVertex(v2))
            {
                state.VertexCount++;
                FillBytes(state.VertexBuffers, v2v.ToArray());
                if (hasNormal)
                {
                    state.NormalCount++;
                    FillBytes(state.NormalBuffers, n2.ToArray());
                }
                if (hasUV)
                {
                    state.UvCount++;
                    FillBytes(state.TextureBuffers, new Uv(t2.U, 1 - t2.V).ToArray());
                }
            }

            if (state.AddVertex(v3))
            {
                state.VertexCount++;
                FillBytes(state.VertexBuffers, v3v.ToArray());
                if (hasNormal)
                {
                    state.NormalCount++;
                    FillBytes(state.NormalBuffers, n3.ToArray());
                }
                if (hasUV)
                {
                    state.UvCount++;
                    FillBytes(state.TextureBuffers, new Uv(t3.U, 1 - t3.V).ToArray());
                }
            }

            var correctWinding = CheckWindingCorrect(v1v, v2v, v3v, n1);

            if (correctWinding)
            {
                state.Indices.AddRange(new[] {
                    state.PolyVertexCache[v1], state.PolyVertexCache[v2], state.PolyVertexCache[v3]
                });
            }
            else
            {
                state.Indices.AddRange(new[] {
                    state.PolyVertexCache[v1], state.PolyVertexCache[v3], state.PolyVertexCache[v2]
                });
            }
        }
Beispiel #7
0
        private void AddNodes(Model model, ObjModel objModel)
        {
            var u32Indices = RequiresU32Indices(objModel);

            var scene = new Scene();

            model.Scenes.Add(scene);
            var nodeName = objModel.Name;

            if (String.IsNullOrEmpty(nodeName))
            {
                nodeName = "default";
            }
            var node = new Node {
                Name = nodeName
            };

            model.Nodes.Add(node);
            scene.Nodes.Add(0);
            var polyMatDict = GetPolygonMatDict(objModel);

            foreach (var gd in objModel.GetGroups())
            {
                var key  = gd.Key;
                var g    = gd.Value;
                var mesh = new Mesh {
                    Name = key
                };
                var faceList = new SortedList <int, List <int> >();
                foreach (var pp in g.Polygons)
                {
                    for (var i = pp.Start; i < pp.End; i++)
                    {
                        var pIndex  = (int)i;
                        var matName = polyMatDict[pIndex];
                        var matId   = _matDict[matName];
                        if (!faceList.ContainsKey(matId))
                        {
                            faceList.Add(matId, new List <int>());
                        }
                        faceList[matId].Add(pIndex);
                    }
                }
                var faceIndex = 0;
                foreach (var fd in faceList)
                {
                    var    matIndex = fd.Key;
                    var    polygons = fd.Value;
                    string faceName;
                    if (faceIndex > 0)
                    {
                        faceName = key + "_" + faceIndex;
                    }
                    else
                    {
                        faceName = key;
                    }
                    var p = new Primitive {
                        Material = matIndex, Mode = new CheckedValue <Mode, int>(Mode.Triangles)
                    };
                    p.Attributes = new Dictionary <Semantic, int>();
                    var state = new PrimitiveState();

                    foreach (var pIndex in polygons)
                    {
                        var poly = objModel.Polygons[pIndex];
                        if (poly.Vertices.Count == 3)
                        {
                            AddPolygon(state, objModel, poly);
                        }
                        else if (poly.Vertices.Count == 4)
                        {
                            var v1 = poly.Vertices[0];
                            var v2 = poly.Vertices[1];
                            var v3 = poly.Vertices[2];
                            var v4 = poly.Vertices[3];
                            var p1 = new Polygon();
                            p1.Vertices.AddRange(new[] { v1, v2, v3 });
                            AddPolygon(state, objModel, p1);
                            var p2 = new Polygon();
                            p2.Vertices.AddRange(new[] { v1, v3, v4 });
                            AddPolygon(state, objModel, p2);
                        }
                        else if (poly.Vertices.Count > 4)
                        {
                            //TODO:
                            var polys = SplitPolygons(poly, objModel);
                            foreach (var pp in polys)
                            {
                                AddPolygon(state, objModel, pp);
                            }
                        }
                    }

                    // Accessors
                    // Position Accessors
                    var accessorIndex  = model.Accessors.Count;
                    var accessorVertex = new Accessor
                    {
                        Min           = new float[] { state.VertexXMM.Min, state.VertexYMM.Min, state.VertexZMM.Min },
                        Max           = new float[] { state.VertexXMM.Max, state.VertexYMM.Max, state.VertexZMM.Max },
                        AccessorType  = new CheckedValue <AccessorType, string>(AccessorType.VEC3),
                        Count         = state.VertexCount,
                        ComponentType = new CheckedValue <ComponentType, int>(ComponentType.F32)
                    };
                    p.Attributes.Add(Semantic.POSITION, accessorIndex);
                    model.Accessors.Add(accessorVertex);
                    _buffers.Positions.Add(state.VertexBuffers);
                    _buffers.PositionAccessors.Add(accessorIndex);
                    // Normal Accessors
                    if (state.NormalCount > 0)
                    {
                        accessorIndex = model.Accessors.Count;
                        var accessorNormal = new Accessor
                        {
                            Min           = new float[] { state.NormalXMM.Min, state.NormalYMM.Min, state.NormalZMM.Min },
                            Max           = new float[] { state.NormalXMM.Max, state.NormalYMM.Max, state.NormalZMM.Max },
                            AccessorType  = new CheckedValue <AccessorType, string>(AccessorType.VEC3),
                            Count         = state.NormalCount,
                            ComponentType = new CheckedValue <ComponentType, int>(ComponentType.F32)
                        };
                        p.Attributes.Add(Semantic.NORMAL, accessorIndex);
                        model.Accessors.Add(accessorNormal);
                        _buffers.Normals.Add(state.NormalBuffers);
                        _buffers.NormalAccessors.Add(accessorIndex);
                    }
                    // UV Accessors
                    if (state.UvCount > 0)
                    {
                        accessorIndex = model.Accessors.Count;
                        var accessorUV = new Accessor
                        {
                            Min           = new float[] { state.UvUMM.Min, state.UvVMM.Min },
                            Max           = new float[] { state.UvUMM.Max, state.UvVMM.Max },
                            AccessorType  = new CheckedValue <AccessorType, string>(AccessorType.VEC2),
                            ComponentType = new CheckedValue <ComponentType, int>(ComponentType.F32),
                            Count         = state.UvCount
                        };
                        p.Attributes.Add(Semantic.TEXCOORD_0, accessorIndex);
                        model.Accessors.Add(accessorUV);
                        _buffers.Uvs.Add(state.TextureBuffers);
                        _buffers.UvAccessors.Add(accessorIndex);
                    }
                    else
                    {
                        model.Materials[matIndex].PbrMetallicRoughness.BaseColorTexture = null;
                    }
                    // Index Accessors
                    accessorIndex = model.Accessors.Count;
                    var componentType = u32Indices ? ComponentType.U32 : ComponentType.U16;
                    var mm            = new MinMax();
                    UpdateMinMax(mm, state.Indices);
                    var accessor = new Accessor
                    {
                        Min           = new float[] { mm.Min },
                        Max           = new float[] { mm.Max },
                        AccessorType  = new CheckedValue <AccessorType, string>(AccessorType.SCALAR),
                        ComponentType = new CheckedValue <ComponentType, int>(componentType),
                        Count         = state.Indices.Count
                    };
                    model.Accessors.Add(accessor);
                    _buffers.Indices.Add(GetBytes(state.Indices, u32Indices));
                    _buffers.IndexAccessors.Add(accessorIndex);
                    p.Indices = accessorIndex;
                    mesh.Primitives.Add(p);
                }
                var meshIndex = model.Meshes.Count;
                model.Meshes.Add(mesh);
                var nodeIndex = model.Nodes.Count;
                var cNode     = new Node {
                    Name = key, Mesh = meshIndex
                };
                model.Nodes.Add(cNode);
                node.Children.Add(nodeIndex);
            }
            AddBuffers(model);
        }