Пример #1
0
        private void reloadStartRecordPointer(Int64 sectionStartPointer)
        {
            Int64 position = 0;

            for (int i = 0; i < this.maxJumpTableLevel; i++)
            {
                position = sectionStartPointer + i * sectionlen + 46;  //46 is the start 46 bytes for counter, etc.
                byte[] nextpointer = new byte[8];

                lock (_object)
                {
                    IndexStream.Position = position + 11;   //warning, 11 is the next pointer position, it might change.
                    IndexStream.Read(nextpointer, 0, 8);
                }

                if (BitConverter.ToInt64(nextpointer, 0) > 0)
                {
                    break;
                }
            }

            lock (_object)
            {
                IndexStream.Position = sectionStartPointer + this.startRecordPointerPositionIndex;
                IndexStream.Write(BitConverter.GetBytes(position), 0, 8);
            }
        }
Пример #2
0
        private void updateNavigator(Int64 recorddiskposition, Int64 PointerDiskPosition, enumPosition position)
        {
            int relativeposition = 0;

            switch (position)
            {
            case enumPosition.next:
                relativeposition = 11;
                break;

            case enumPosition.previous:
                relativeposition = 3;
                break;

            case enumPosition.top:
                relativeposition = 19;
                break;

            case enumPosition.bottom:
                relativeposition = 27;
                break;

            default:
                relativeposition = 11;
                break;
            }

            lock (_object)
            {
                IndexStream.Position = recorddiskposition + relativeposition;
                IndexStream.Write(BitConverter.GetBytes(PointerDiskPosition), 0, 8);
            }
        }
Пример #3
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Initialisation
        //---------------------------------------------------------------
        /// <summary>
        /// Creates a new instance of a <see cref="SubSet"/> and prefills it with data.
        /// </summary>
        /// <param name="vertexUnit">Vertex data to use.</param>
        /// <param name="indexStream">Indices to use.</param>
        /// <param name="indexBufferStart">Start index for <see cref="IndexStream"/>.</param>
        /// <param name="primitiveCount">Number of primitives to draw.</param>
        public SubSet(VertexUnit vertexUnit, IndexStream indexStream,
                      int indexBufferStart, int primitiveCount)
        {
            this.indexStream      = indexStream;
            this.vertexUnit       = vertexUnit;
            this.indexBufferStart = indexBufferStart;
            this.primitiveCount   = primitiveCount;
        }
Пример #4
0
        private void markAsDeleted(Int64 diskposition)
        {
            Int64 fixedposition = diskposition + 2;

            IndexStream.Position = fixedposition;
            IndexStream.WriteByte((byte)enumSectionType.DeletedAvailable);
            _freespace.Add(diskposition);
        }
Пример #5
0
 private void ResizeIndexStream(IndexStream indexStream, int size)
 {
     if (indexStream.Size < size)
     {
         size = System.Math.Max(size, indexStream.Size * 2);
         Purple.Log.Spam("ShadowVolume - Resize index stream from: " + indexStream.Size + " to: " + size);
         indexStream.Resize(size);
     }
 }
Пример #6
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Methods
        //---------------------------------------------------------------
        /// <summary>
        /// Fills the indexStream with the data.
        /// </summary>
        /// <param name="indexStream">Fills the quad data into the passed indexStream.</param>
        /// <param name="index">The start index in the index buffer.</param>
        /// <param name="vertexIndex">The start in the vertex buffer.</param>
        public virtual void FillIndexStream(IndexStream indexStream, int index, int vertexIndex)
        {
            indexStream[index]     = (vertexIndex + 0);
            indexStream[index + 1] = (vertexIndex + 1);
            indexStream[index + 2] = (vertexIndex + 2);
            indexStream[index + 3] = (vertexIndex + 2);
            indexStream[index + 4] = (vertexIndex + 1);
            indexStream[index + 5] = (vertexIndex + 3);
        }
Пример #7
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Methods
        //---------------------------------------------------------------
        /// <summary>
        /// Generates a heightmap from a Bitmap.
        /// </summary>
        /// <param name="bmp">The bitmap to use.</param>
        public Mesh Generate(Bitmap bmp)
        {
            VertexUnit     vertexUnit     = new VertexUnit(VertexFormat.PositionTexture, bmp.Width * bmp.Height);
            PositionStream positionStream = (PositionStream)vertexUnit[typeof(PositionStream)];
            TextureStream  textureStream  = (TextureStream)vertexUnit[typeof(TextureStream)];

            BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            byte[] data = new byte[bitmapData.Stride * bitmapData.Height];
            System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, data, 0, data.Length);
            int     quadsX = bmp.Width - 1;
            int     quadsY = bmp.Height - 1;
            Vector3 scale  = new Vector3(0.1f, 0.02f, 0.1f);

            //Vector3 scale = new Vector3(5.0f, 0.1f, 5.0f);
            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    int  byteOffset = x * 4 + y * bitmapData.Stride;
                    byte b          = data[byteOffset];
                    byte g          = data[byteOffset + 1];
                    byte r          = data[byteOffset + 2];
                    byte a          = data[byteOffset + 3];

                    Vector3 vec = Vector3.Scale(new Vector3(x - quadsX * 0.5f, r, -y + quadsY * 0.5f), scale);
                    positionStream[x + y * bmp.Width] = vec;

                    Vector2 texVec = new Vector2((float)x / quadsX, (float)y / quadsY);
                    textureStream[x + y * bmp.Width] = texVec;
                }
            }
            bmp.UnlockBits(bitmapData);

            IndexStream indexStream = IndexStream.Create(quadsX * quadsY * 6, (quadsX + 1) * (quadsY + 1));
            int         offset      = 0;

            for (int y = 0; y < quadsY; y++)
            {
                for (int x = 0; x < quadsX; x++)
                {
                    indexStream[offset]     = (x + y * bmp.Width);
                    indexStream[offset + 1] = (x + 1 + y * bmp.Width);
                    indexStream[offset + 2] = (x + (y + 1) * bmp.Width);
                    indexStream[offset + 3] = (x + 1 + y * bmp.Width);
                    indexStream[offset + 4] = (x + 1 + (y + 1) * bmp.Width);
                    indexStream[offset + 5] = (x + (y + 1) * bmp.Width);
                    offset += 6;
                }
            }

            Mesh mesh = new Mesh();

            mesh.SubSets.Add(new SubSet(vertexUnit, indexStream));
            return(mesh);
        }
Пример #8
0
            public void addNewIndexStream(List <IndexStream.Triangle> l)
            {
                IndexStream tri = new IndexStream(l);

                tri.fixOrientedBox();
                indstrm.Add(tri);
                XmlNode indexstreamparent = shapeNode.SelectSingleNode("PrimitiveSets/PrimitiveSetCtr/Primitives/PrimitiveCtr/IndexStreams");

                indexstreamparent.AppendChild(tri.generateNode(xml, Vertices.Count));
            }
Пример #9
0
 private void ResizeIndexStream(int newCap)
 {
     if (indexStream != null)
     {
         indexStream.Resize(newCap);
         Purple.Log.Spam("IndexStream resized: " + newCap * 3);
     }
     else
     {
         indexStream = new IndexStream16(newCap);
     }
 }
Пример #10
0
        private void CalcVisibilityInfo(ref int j, int iSubSet, Vector4 osLight)
        {
            IndexStream    iStream        = mesh.SubSets[iSubSet].IndexStream;
            PositionStream positionStream = (PositionStream)mesh.SubSets[iSubSet].VertexUnit[typeof(PositionStream)];

            // sad but true the following variables are for optimization
            bool[]    currentBackFace    = backface[iSubSet];
            Vector3[] currentFaceNormals = faceNormals[iSubSet];
            Vector3   osLight3           = osLight.Vector3;
            float     w    = osLight.W;
            int       size = iStream.Size / 3;

            Vector3[] posStreamData    = (Vector3[])positionStream.Data;
            ushort[]  iStreamDataShort = iStream.Data as ushort[];
            int[]     iStreamDataInt   = iStream.Data as int[];

            // fill backface array with visibility information
            for (int i = 0; i < size; i++)
            {
                int     index0 = iStream[i * 3];
                Vector3 v0     = posStreamData[index0];

                Vector3 lightDirection = v0 * w - osLight3;
                bool    back           = currentFaceNormals[i] * lightDirection > 0.0f;
                currentBackFace[i] = back;

                // for the zFail method - add the front and back caps
                if (currentMethod == StencilMethod.ZFail)
                {
                    int index1 = iStream[i * 3 + 1];
                    int index2 = iStream[i * 3 + 2];
                    if (!back)
                    {
                        ResizeIndexStream(indexStream, j + 3);
                        indexStream[j]     = (index0 + positionStream.Size / 2);
                        indexStream[j + 2] = (index1 + positionStream.Size / 2);
                        indexStream[j + 1] = (index2 + positionStream.Size / 2);
                        j += 3;

                        ResizeIndexStream(indexStream, j + 3);
                        indexStream[j]     = index0;
                        indexStream[j + 1] = index1;
                        indexStream[j + 2] = index2;
                        j += 3;
                    }
                }
            }
        }
Пример #11
0
        private JumpRecord insertNewRecord(Int64 blockposition)
        {
            JumpRecord record = new JumpRecord();

            record.BlockPosition = blockposition;

            record.Indicator = enumSectionType.Record;

            Int64 insertposition = getInsertPosition();

            IndexStream.Position = insertposition;
            IndexStream.Write(record.ToBytes(), 0, sectionlen);

            record.diskLocation = insertposition;
            return(record);
        }
Пример #12
0
 /// <summary>
 /// Fills the indexStream with the data.
 /// </summary>
 /// <param name="indexStream">Fills the quad data into the passed indexStream.</param>
 /// <param name="index">The start index in the index buffer.</param>
 /// <param name="vertexIndex">The start in the vertex buffer.</param>
 public override void FillIndexStream(IndexStream indexStream, int index, int vertexIndex)
 {
     for (int y = 0; y < vertices.GetLength(1) - 1; y++)
     {
         for (int x = 0; x < vertices.GetLength(0) - 1; x++)
         {
             int offset = x + y * vertices.GetLength(0);
             indexStream[index]     = (vertexIndex + x + 0 + (y + 0) * vertices.GetLength(0));
             indexStream[index + 1] = (vertexIndex + x + 1 + (y + 0) * vertices.GetLength(0));
             indexStream[index + 2] = (vertexIndex + x + 0 + (y + 1) * vertices.GetLength(0));
             indexStream[index + 3] = (vertexIndex + x + 0 + (y + 1) * vertices.GetLength(0));
             indexStream[index + 4] = (vertexIndex + x + 1 + (y + 0) * vertices.GetLength(0));
             indexStream[index + 5] = (vertexIndex + x + 1 + (y + 1) * vertices.GetLength(0));
             index += 6;
         }
     }
 }
Пример #13
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Initialisation
        //---------------------------------------------------------------
        /// <summary>
        /// Creates a new instance of a particle system.
        /// </summary>
        /// <param name="size">The max number of particles.</param>
        public LineParticleSystem(int size) : base( )
        {
            textures  = new Textures();
            particles = new FixedRoundBuffer(size);

            // Create a new format
            VertexFormat format = new VertexFormat(
                new Type[] { typeof(PositionStream), typeof(ColorStream), typeof(TextureStream) });

            // create VertexUnit and IndexStream
            vertexUnit  = new VertexUnit(format, 2 + size * 2);
            indexStream = IndexStream.FromChain(size - 1);

            // load shaders from the resource files
            using (System.IO.Stream fxStream = Purple.IO.ResourceFileSystem.Instance.Open("Purple/Graphics/Particles/LineParticle.fx")) {
                Effect = EffectCompiler.Instance.Compile(fxStream);
            }
        }
Пример #14
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Initialisation
        //---------------------------------------------------------------
        /// <summary>
        /// Creates a new instance of a particle system.
        /// </summary>
        /// <param name="size">The max number of particles.</param>
        public ParticleSystem2d(int size) : base( )
        {
            textures  = new Textures();
            particles = new Purple.Collections.FixedBag(size);

            // Create a new format
            VertexFormat format = new VertexFormat(
                new Type[] { typeof(PositionStream2), typeof(ColorStream), typeof(TextureStream) });

            // create VertexUnit and IndexStream
            vertexUnit  = new VertexUnit(format, size * 4);
            indexStream = IndexStream.FromQuads(size);

            // load shaders from the resource files
            using (System.IO.Stream fxStream = Purple.IO.ResourceFileSystem.Instance.Open("Purple/Graphics/Particles/Particle2d.fx")) {
                Effect = EffectCompiler.Instance.Compile(fxStream);
            }
        }
Пример #15
0
        bool ReadTriangles()
        {
            // triangles
            Advance("numtris");
            int triNum = int.Parse(NextToken);

            indexStream = new IndexStream16(triNum * 3);
            for (int j = 0; j < triNum; j++)
            {
                Advance("tri");
                // sanity check
                int currentTriNum = int.Parse(NextToken);
                System.Diagnostics.Debug.Assert(j == currentTriNum, "Invalid tri num!");
                indexStream[j * 3]     = int.Parse(NextToken);
                indexStream[j * 3 + 1] = int.Parse(NextToken);
                indexStream[j * 3 + 2] = int.Parse(NextToken);
            }
            return(true);
        }
 /// <summary>
 /// Reorder the database and index rows with the dictionary of row - location in <param name="rowsToMove">.
 /// </summary>
 /// <param name="rowsToMove">
 /// Dictionary of row - location.
 /// </param>
 private void RearrangeRowsAndIndex(Dictionary <Row, int> rowsToMove)
 {
     // Set the new sizes of both the index and database file.
     DataBaseStream.SetLength(((RowCount - DeletedRowCount) * ROW_BYTE_SIZE) + HEADER_BYTE_SIZE);
     IndexStream.SetLength((RowCount - DeletedRowCount) * INDEX_ROW_BYTE_SIZE);
     // Write each row to it's new location. Write each index keyvalue pair of primary key location to the index file.
     // Update the object index.
     foreach (KeyValuePair <Row, int> data in rowsToMove)
     {
         Index [data.Key.PrimaryKey] = data.Value;
         WriteRow(data.Key, data.Key.PrimaryKey, WriteType.RowMove);
         WriteIndexRow(data.Key.PrimaryKey, data.Value, WriteType.IndexRowMove);
     }
     // Update the row count accordingly and reassign deleted rows the value of 0. We've just compacted!
     RowCount               -= DeletedRowCount;
     DeletedRowCount         = 0;
     DataBaseStream.Position = HEADER_INFO_NUM_ROWS;
     // Write that to the database header.
     DataBaseWriter.Write(RowCount);
     DataBaseWriter.Write(DeletedRowCount);
 }
Пример #17
0
        /// <summary>
        /// Merges two subsets.
        /// </summary>
        /// <param name="subSet">Subset to merge with.</param>
        public void Merge(SubSet subSet)
        {
            if (!CanMerge(subSet))
            {
                throw new GraphicsException("Subsets can't be merged!");
            }

            // Merge vertex unit
            VertexUnit unit = new VertexUnit(VertexUnit.Format, VertexUnit.Size + subSet.VertexUnit.Size);

            VertexUnit.Copy(VertexUnit, 0, unit, 0, VertexUnit.Size);
            VertexUnit.Copy(subSet.VertexUnit, 0, unit, VertexUnit.Size, subSet.VertexUnit.Size);

            VertexUnit.Dispose();
            VertexUnit = unit;

            // Merge index streams
            IndexStream index = IndexStream.Create(IndexStream.Size + subSet.IndexStream.Size, IndexStream.GetType());

            VertexStreams.IndexStream.Copy(IndexStream, 0, index, 0, IndexStream.Size, 0);
            VertexStreams.IndexStream.Copy(subSet.IndexStream, 0, index, IndexStream.Size, subSet.IndexStream.Size, VertexUnit.Size);
            IndexStream.Dispose();
            IndexStream = index;
        }
Пример #18
0
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Methods
        //---------------------------------------------------------------
        private void UpdateMetaInfo()
        {
            faceNormals       = new Vector3[mesh.SubSets.Count][];
            backface          = new bool[mesh.SubSets.Count][];
            edges             = new Edge[mesh.SubSets.Count][];
            this.shadowVolume = new Mesh();

            int maxIndex = 0;

            for (int iSubSet = 0; iSubSet < mesh.SubSets.Count; iSubSet++)
            {
                maxIndex = System.Math.Min(mesh.SubSets[iSubSet].VertexUnit.Size, maxIndex);
            }
            indexStream = IndexStream.Create(1024 * 16, maxIndex);

            for (int iSubSet = 0; iSubSet < mesh.SubSets.Count; iSubSet++)
            {
                SubSet subSet = mesh.SubSets[iSubSet];
                faceNormals[iSubSet] = subSet.CalcFaceNormals();
                backface[iSubSet]    = new bool[subSet.PrimitiveCount];
                edges[iSubSet]       = subSet.CalcEdges();
                shadowVolume.SubSets.Add(new SubSet(subSet.VertexUnit, indexStream));
            }
        }
Пример #19
0
        private MD3Part LoadMD3(string part)
        {
            using (Stream stream = fileSystem.Open(path + part + ".md3")) {
                // get header and check if it is ok
                MD3_Header header = (MD3_Header)RawSerializer.Deserialize(stream, typeof(MD3_Header));
                if (header.Id != 860898377 || header.Version != 15)
                {
                    return(null);
                }

                // load bone frames
                MD3_Frame[] frames = (MD3_Frame[])RawSerializer.DeserializeArray(stream, typeof(MD3_Frame), header.NumFrames);

                // load tags
                SortedList links = GetLinks((MD3_Tag[])RawSerializer.DeserializeArray(stream, typeof(MD3_Tag), header.NumTags * header.NumFrames));

                long meshOffset = stream.Position;

                // one mesh for every frame
                BlendMesh mesh = new BlendMesh(header.NumFrames);

                // load meshes
                for (int iMesh = 0; iMesh < header.NumMeshes; iMesh++)
                {
                    stream.Position = meshOffset;
                    MD3_MeshHeader meshHeader = (MD3_MeshHeader)RawSerializer.Deserialize(stream, typeof(MD3_MeshHeader));

                    MD3_Skin[] skins = (MD3_Skin[])RawSerializer.DeserializeArray(stream, typeof(MD3_Skin), meshHeader.NumSkins);

                    stream.Position = meshOffset + meshHeader.TriangleOffset;
                    MD3_Triangle[] triangles = (MD3_Triangle[])RawSerializer.DeserializeArray(stream, typeof(MD3_Triangle), meshHeader.NumTriangles);

                    stream.Position = meshOffset + meshHeader.TexCoordOffset;
                    MD3_TexCoord[] texCoords = (MD3_TexCoord[])RawSerializer.DeserializeArray(stream, typeof(MD3_TexCoord), meshHeader.NumVertices);

                    stream.Position = meshOffset + meshHeader.VertexOffset;
                    MD3_Vertex[] vertices = (MD3_Vertex[])RawSerializer.DeserializeArray(stream, typeof(MD3_Vertex), meshHeader.NumFrames * meshHeader.NumVertices);

                    float    scale = 64.0f;
                    string   name  = StringHelper.Convert(meshHeader.Name);
                    ITexture tx    = (ITexture)textures[name];

                    Triangle[] tris = new Triangle[triangles.Length];
                    for (int i = 0; i < triangles.Length; i++)
                    {
                        tris[i].A = (triangles[i]).A;
                        tris[i].B = (triangles[i]).B;
                        tris[i].C = (triangles[i]).C;
                    }
                    IndexStream indexStream = IndexStream16.FromTriangles(tris);

                    int vertCount = meshHeader.NumVertices; // *meshHeader.NumFrames;

                    for (int iFrame = 0; iFrame < meshHeader.NumFrames; iFrame++)
                    {
                        VertexUnit     vertexUnit = new VertexUnit(VertexFormat.PositionNormalTexture, vertCount);
                        PositionStream pos        = (PositionStream)vertexUnit[typeof(PositionStream)];
                        NormalStream   normal     = (NormalStream)vertexUnit[typeof(NormalStream)];
                        TextureStream  tex        = (TextureStream)vertexUnit[typeof(TextureStream)];

                        for (int i = 0; i < vertCount; i++)
                        {
                            int vertIndex = iFrame * meshHeader.NumVertices + i;
                            pos[i] = new Vector3(vertices[vertIndex].X / scale,
                                                 vertices[vertIndex].Z / scale,
                                                 -vertices[vertIndex].Y / scale);

                            int texIndex = i % meshHeader.NumVertices;
                            tex[i] = new Vector2(texCoords[texIndex].U,
                                                 texCoords[texIndex].V);

                            //Normal vector
                            int   compressedNormal = ((MD3_Vertex)vertices[vertIndex]).Normal;
                            float lng = (compressedNormal & 0xFF) * Math.Basic.PI / 128;
                            float lat = ((compressedNormal >> 8) & 0xFF) * Math.Basic.PI / 128;

                            normal[i] = new Vector3(Math.Trigonometry.Cos(lat) * Math.Trigonometry.Sin(lng),
                                                    Math.Trigonometry.Cos(lng),
                                                    -Math.Trigonometry.Sin(lat) * Math.Trigonometry.Sin(lng));
                        }
                        if (mesh.Meshes[iFrame] == null)
                        {
                            mesh.Meshes[iFrame] = new Mesh();
                        }
                        mesh.Meshes[iFrame].SubSets.Add(new SubSet(vertexUnit, indexStream));
                        mesh.Meshes[iFrame].Textures.Add(new Textures("color", tx));
                    }

                    // Increase the offset into the file
                    meshOffset += meshHeader.MeshSize;
                }

                return(new MD3Part(mesh, links));
            }
        }
Пример #20
0
 /// <summary>
 /// Creates a new instance of a <see cref="SubSet"/>.
 /// </summary>
 /// <remarks>
 /// Assumes usage of complete VertexUnit/IndexSteram.
 /// </remarks>
 /// <param name="vertexUnit">Vertex data to use.</param>
 /// <param name="indexStream">Indices to use.</param>
 public SubSet(VertexUnit vertexUnit, IndexStream indexStream) :
     this(vertexUnit, indexStream, 0, indexStream.Size / 3)
 {
 }
Пример #21
0
        /// <summary>
        /// loads a quake3 level from a stream
        /// </summary>
        /// <param name="stream">stream to load from</param>
        /// <returns>level as a mesh</returns>
        public Mesh Load(Stream stream)
        {
            Mesh mesh = new Mesh();

            this.stream = stream;

            // get header and check if it is ok
            QuakeHeader header = (QuakeHeader)RawSerializer.Deserialize(stream, typeof(QuakeHeader));

            if (header.ID != 1347633737 || header.Version != 0x2e)
            {
                return(null);
            }

            // get locations of lumps
            locations = RawSerializer.DeserializeArray(stream, typeof(LumpLocation), (int)QuakeLumps.LumpNumber);

            // get lumps
            IList quakeVertices  = LoadLump(QuakeLumps.Vertices, typeof(QuakeVertex));
            IList quakeFaces     = LoadLump(QuakeLumps.Faces, typeof(QuakeFace));
            IList quakeTextures  = LoadLump(QuakeLumps.Textures, typeof(QuakeTexture));
            IList quakeLightMaps = LoadLump(QuakeLumps.Lightmaps, typeof(QuakeLightMap));


            // Load all texture images and put into array
            IList textures = LoadTextures(quakeTextures);
            // Load lightMaps, create texture and put into array
            IList lightMaps = LoadLightMaps(quakeLightMaps);

            // create list from vertices
            VertexUnit     vertexUnit = new VertexUnit(VertexFormat.PositionTexture2, quakeVertices.Count);
            PositionStream pos        = (PositionStream)vertexUnit[typeof(PositionStream)];
            TextureStream  texStream  = (TextureStream)vertexUnit[typeof(TextureStream)];
            TextureStream  light      = (TextureStream)vertexUnit[typeof(TextureStream), 1];

            int i = 0;

            foreach (QuakeVertex v in quakeVertices)
            {
                pos[i]       = new Math.Vector3(v.Position[0], v.Position[2], -v.Position[1]);
                texStream[i] = new Math.Vector2(v.TextureCoord[0], v.TextureCoord[1]);
                light[i]     = new Math.Vector2(v.LightmapCoord[0], v.LightmapCoord[1]);
                i++;
            }

            // presort faces
            Array.Sort(((Array)quakeFaces));

            // create mesh
            int       oldLightMap = ((QuakeFace)quakeFaces[0]).LightmapID;
            int       oldTexture  = ((QuakeFace)quakeFaces[0]).TextureID;
            ArrayList indices     = new ArrayList();

            for (i = 0; i < quakeFaces.Count; ++i)
            {
                QuakeFace qf = (QuakeFace)quakeFaces[i];
                if (qf.Type == 1)
                {
                    if (qf.TextureID != oldTexture || qf.LightmapID != oldLightMap)
                    {
                        mesh.SubSets.Add(new SubSet(vertexUnit, IndexStream.Create(indices, vertexUnit.Size)));
                        Textures texs = new Textures("color", (ITexture)textures[oldTexture]);
                        if (oldLightMap == -1)
                        {
                            texs["lightMap"] = null;
                        }
                        else
                        {
                            texs["lightMap"] = (ITexture)lightMaps[oldLightMap];
                        }
                        mesh.Textures.Add(texs);
                        indices.Clear();
                    }

                    // add indices => convert from fan to list
                    for (int j = 2; j < qf.NumOfVerts; j++)
                    {
                        indices.Add(qf.VertexIndex);
                        indices.Add(qf.VertexIndex + j - 1);
                        indices.Add(qf.VertexIndex + j);
                    }

                    oldTexture  = qf.TextureID;
                    oldLightMap = qf.LightmapID;
                }
            }
            return(mesh);
        }
Пример #22
0
        private Int64 createNewStartSection()
        {
            /// in the format of
            /// [8] start search pointer. Pointer to the highest jump table.
            /// [2] * = number of counter of each level.  start pointer =

            // header section + number levels.
            int totallen = sectionlen + this.maxJumpTableLevel * sectionlen;

            byte[] totalbytes = new byte[totallen];

            byte[] header = new byte[sectionlen];

            header[0] = startbyteone;
            header[1] = startbytetwo;

            header[44] = startbyteone;
            header[45] = startbytetwo;

            header[2] = (byte)enumSectionType.StartSection;

            List <JumpRecord> tablelist = new List <JumpRecord>();

            for (int i = 0; i < this.maxJumpTableLevel; i++)
            {
                JumpRecord newrecord = new JumpRecord();
                newrecord.BlockPosition = Int64.MinValue;
                newrecord.Indicator     = enumSectionType.Record;
                newrecord.level         = (byte)i;

                tablelist.Add(newrecord);
            }

            for (int i = 0; i < tablelist.Count; i++)
            {
                if (i == 0)
                {
                    updateNavigator(tablelist[i].diskLocation, tablelist[i + 1].diskLocation, enumPosition.next);
                }
                else if (i == tablelist.Count - 1)
                {
                    updateNavigator(tablelist[i].diskLocation, tablelist[i - 1].diskLocation, enumPosition.previous);
                }
                else
                {
                    // in the middle.
                    updateNavigator(tablelist[i].diskLocation, tablelist[i - 1].diskLocation, enumPosition.previous);
                    updateNavigator(tablelist[i].diskLocation, tablelist[i + 1].diskLocation, enumPosition.next);
                }
            }


            Int64 writeposition = getInsertPosition();

            //write position for each start of level table.
            for (int i = 0; i < tablelist.Count; i++)
            {
                tablelist[i].diskLocation = writeposition + 46 + i * 46;
            }

            Int64 lastitemindex = tablelist[tablelist.Count - 1].diskLocation;

            System.Buffer.BlockCopy(BitConverter.GetBytes(lastitemindex), 0, header, 3, 8);

            lock (_object)
            {
                IndexStream.Position = writeposition;
                IndexStream.Write(header, 0, sectionlen);

                foreach (var item in tablelist)
                {
                    IndexStream.Position = item.diskLocation;
                    IndexStream.Write(item.ToBytes(), 0, sectionlen);
                }
            }

            return(writeposition);
        }
Пример #23
0
        /// <summary>
        /// Import a mesh from a stream.
        /// </summary>
        /// <param name="stream">Stream containing mesh data.</param>
        public void Import(Stream stream)
        {
            Profiler.Instance.Begin("Import binary mesh");
            // Header
            BinaryReader reader = new BinaryReader(stream);

            if (ReadString(reader) != "mesh" || ReadString(reader) != "v0.3")
            {
                throw new NotSupportedException("Can't load mesh, file not supported!");
            }

            // Joints
            int jointNum = ReadInt(reader);

            Joint[]   joints     = new Joint[jointNum];
            Matrix4[] jointArray = new Matrix4[jointNum];
            Hashtable jointTable = new Hashtable(joints.Length);

            for (int i = 0; i < joints.Length; i++)
            {
                string name   = ReadString(reader);
                string parent = ReadString(reader);

                reader.Read(matrixBytes, 0, matrixBytes.Length);
                Matrix4 m = Matrix4.From(matrixBytes);

                Joint parentJoint = null;
                if (parent != null && jointTable.Contains(parent))
                {
                    parentJoint = (Joint)jointTable[parent];
                }
                joints[i]        = new Joint(name, i, parentJoint);
                jointArray[i]    = m;
                jointTable[name] = joints[i];
            }
            skeleton = new Skeleton(jointArray, joints);

            // SubSet
            int subSetNum = ReadInt(reader);

            for (int i = 0; i < subSetNum; i++)
            {
                ArrayList streams = new ArrayList(10);
                // Header
                if (ReadString(reader) != "subset")
                {
                    throw new NotSupportedException("Error on loading subSet!");
                }
                string name        = ReadString(reader);
                string parentJoint = ReadString(reader);

                int attributeCount          = ReadInt(reader);
                StringDictionary attributes = new StringDictionary();
                for (int t = 0; t < attributeCount; t++)
                {
                    attributes.Add(ReadString(reader), ReadString(reader));
                }

                // IndexStream
                // Todo Replace ushort.MaxValue with size of vertex unit
                IndexStream indexStream = IndexStream.Create(ReadInt(reader), ushort.MaxValue);
                byte[]      indexBuffer = new byte[indexStream.Size * 4];
                reader.Read(indexBuffer, 0, indexStream.Size * 4);
                for (int t = 0; t < indexStream.Size; t++)
                {
                    indexStream[t] = BitConverter.ToInt32(indexBuffer, t * 4);
                }

                int            vertexSize = ReadInt(reader);
                PositionStream posStream  = new PositionStream(vertexSize);
                streams.Add(posStream);
                byte[] vertexBuffer = new byte[vertexSize * 12];
                reader.Read(vertexBuffer, 0, vertexSize * 12);
                for (int t = 0; t < vertexSize; t++)
                {
                    posStream[t] = Vector3.From(vertexBuffer, 12 * t);
                }

                NormalStream normalStream = new NormalStream(vertexSize);
                streams.Add(normalStream);
                reader.Read(vertexBuffer, 0, vertexSize * 12);
                for (int t = 0; t < vertexSize; t++)
                {
                    normalStream[t] = Vector3.From(vertexBuffer, t * 12);
                }

                ColorStream colorStream = new ColorStream(vertexSize);
                streams.Add(colorStream);
                reader.Read(vertexBuffer, 0, vertexSize * 12);
                for (int t = 0; t < vertexSize; t++)
                {
                    int r = Math.Basic.Clamp((int)(System.BitConverter.ToSingle(vertexBuffer, t * 12) * 255 + 0.5f), 0, 255);
                    int g = Math.Basic.Clamp((int)(System.BitConverter.ToSingle(vertexBuffer, 4 + t * 12) * 255 + 0.5f), 0, 255);
                    int b = Math.Basic.Clamp((int)(System.BitConverter.ToSingle(vertexBuffer, 8 + t * 12) * 255 + 0.5f), 0, 255);
                    colorStream[t] = System.Drawing.Color.FromArgb(r, g, b).ToArgb();
                }

                TextureStream[] textureStreams = new TextureStream[ReadInt(reader)];
                for (int t = 0; t < textureStreams.Length; t++)
                {
                    TextureStream texStream = new TextureStream(vertexSize);
                    streams.Add(texStream);
                    reader.Read(vertexBuffer, 0, vertexSize * 8);
                    for (int j = 0; j < vertexSize; j++)
                    {
                        texStream[j] = Vector2.From(vertexBuffer, j * 8);
                    }
                    textureStreams[t] = texStream;
                }

                IBoneIndicesStream boneStream    = null;
                IBoneWeightsStream weightsStream = null;
                int weightNum = ReadInt(reader);
                if (weightNum != 0)
                {
                    if (HardwareSkinning)
                    {
                        boneStream    = new BoneIndicesStream(vertexSize);
                        weightsStream = new BoneWeightsStream(vertexSize);
                    }
                    else
                    {
                        boneStream    = new SoftwareBoneIndicesStream(vertexSize);
                        weightsStream = new SoftwareBoneWeightsStream(vertexSize);
                    }
                    streams.Add(boneStream);
                    streams.Add(weightsStream);
                    ArrayList[] indicesList = new ArrayList[vertexSize];
                    ArrayList[] weightsList = new ArrayList[vertexSize];
                    for (int t = 0; t < vertexSize; t++)
                    {
                        indicesList[t] = new ArrayList(8);
                        weightsList[t] = new ArrayList(8);
                    }


                    byte[] weightBuffer = new byte[weightNum * 12];
                    reader.Read(weightBuffer, 0, weightNum * 12);
                    for (int t = 0; t < weightNum; t++)
                    {
                        int   vertexIndex = BitConverter.ToInt32(weightBuffer, t * 12);
                        int   jointIndex  = BitConverter.ToInt32(weightBuffer, 4 + t * 12);
                        float weight      = BitConverter.ToSingle(weightBuffer, 8 + t * 12);
                        indicesList[vertexIndex].Add((byte)jointIndex);
                        weightsList[vertexIndex].Add(weight);
                    }

                    for (int t = 0; t < vertexSize; t++)
                    {
                        boneStream.SetIndices(t, (byte[])indicesList[t].ToArray(typeof(byte)));
                        weightsStream.SetWeights(t, (float[])weightsList[t].ToArray(typeof(float)));
                    }
                }

                VertexUnit vertexUnit = new VertexUnit(streams);
                Mesh       mesh       = new Mesh(new SubSet(vertexUnit, indexStream));
                if (model == null)
                {
                    if (skeleton.Joints.Length != 0)
                    {
                        model = new Model(new SkinnedMesh(mesh, skeleton), skeleton);
                    }
                    else
                    {
                        model = new Model(mesh, skeleton);
                    }
                }
                else
                {
                    Joint attachTo = skeleton.RootJoint;
                    if (parentJoint != "")
                    {
                        attachTo = (jointTable[parentJoint] as Joint);
                    }
                    model.AttachModel(new Model(mesh, skeleton), attachTo);
                }
            }
            reader.Close();

            Profiler.Instance.End("Import binary mesh");
        }
Пример #24
0
        /// <summary>
        /// import a mesh from a stream
        /// </summary>
        /// <param name="stream">stream containing mesh data</param>
        public void Import(Stream stream)
        {
            model    = null;
            skeleton = null;
            IndexStream      indexStream   = null;
            IVertexStream    currentStream = null;
            ArrayList        streams       = new ArrayList();
            StringDictionary attributes    = new StringDictionary();
            XmlTextReader    reader        = new XmlTextReader(stream);

            Matrix4[] jointArray   = null;
            Joint[]   joints       = null;
            Hashtable jointTable   = null;
            int       index        = 0;
            int       currentJoint = 0;
            int       vertexCount  = 0;
            int       binding      = -1;

            ArrayList[] indicesList = null;
            ArrayList[] weightsList = null;

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                    // <mesh>
                    case "mesh":
                        if (model != null)
                        {
                            throw new GraphicsException("Only one mesh allowed in mesh stream!");
                        }
                        model = new Model();
                        break;

                    // <subset>
                    case "subset":
                        string parentJoint = reader.GetAttribute("parentJoint");
                        if (parentJoint != null && parentJoint != "")
                        {
                            binding = (jointTable[parentJoint] as Joint).Index;
                        }
                        else
                        {
                            binding = -1;
                        }
                        break;

                    // <attributes>
                    case "attributes":
                        break;

                    case "attribute":
                        // todo !!!
                        attributes.Add(reader.GetAttribute("name"), reader.GetAttribute("value"));
                        break;

                    //<indexStream>
                    case "indexStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        indexStream = new IndexStream16(size);
                    }
                    break;

                    //<triangle>
                    case "triangle": {
                        int a = int.Parse(reader.GetAttribute("a"), culture);
                        int b = int.Parse(reader.GetAttribute("b"), culture);
                        int c = int.Parse(reader.GetAttribute("c"), culture);
                        indexStream[index++] = a;
                        indexStream[index++] = b;
                        indexStream[index++] = c;
                    }
                    break;

                    //<positionStream>
                    case "positionStream": {
                        index         = 0;
                        vertexCount   = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new PositionStream(vertexCount);
                        streams.Add(currentStream);
                    }
                    break;

                    //<vector3>
                    case "vector3": {
                        float x = float.Parse(reader.GetAttribute("x"), culture);
                        float y = float.Parse(reader.GetAttribute("y"), culture);
                        float z = float.Parse(reader.GetAttribute("z"), culture);
                        (currentStream as PositionStream)[index++] = new Vector3(x, y, z);
                    }
                    break;

                    //<normalStream>
                    case "normalStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new NormalStream(size);
                        streams.Add(currentStream);
                    }
                    break;

                    //<colorStream>
                    case "colorStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new ColorStream(size);
                        streams.Add(currentStream);
                    }
                    break;

                    //<color>
                    case "color": {
                        int r = (int)((float.Parse(reader.GetAttribute("r"), culture)) * 255.0f + 0.5f);
                        int g = (int)((float.Parse(reader.GetAttribute("g"), culture)) * 255.0f + 0.5f);
                        int b = (int)((float.Parse(reader.GetAttribute("b"), culture)) * 255.0f + 0.5f);
                        (currentStream as ColorStream)[index++] = System.Drawing.Color.FromArgb(r, g, b).ToArgb();
                    }
                    break;

                    //<textureStream>
                    case "textureStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new TextureStream(size);
                        streams.Add(currentStream);
                    }
                    break;

                    //<vector2>
                    case "vector2": {
                        float x = float.Parse(reader.GetAttribute("x"), culture);
                        float y = float.Parse(reader.GetAttribute("y"), culture);
                        (currentStream as TextureStream)[index++] = new Vector2(x, y);
                    }
                    break;

                    case "joints": {
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        jointArray   = new Matrix4[size];
                        joints       = new Joint[size];
                        jointTable   = new Hashtable();
                        currentJoint = 0;
                    }
                    break;

                    case "joint": {
                        string  jointName  = reader.GetAttribute("name");
                        string  parentName = reader.GetAttribute("parent");
                        Matrix4 m          = new Matrix4(float.Parse(reader.GetAttribute("a1"), culture),
                                                         float.Parse(reader.GetAttribute("a2"), culture),
                                                         float.Parse(reader.GetAttribute("a3"), culture),
                                                         float.Parse(reader.GetAttribute("a4"), culture),
                                                         float.Parse(reader.GetAttribute("b1"), culture),
                                                         float.Parse(reader.GetAttribute("b2"), culture),
                                                         float.Parse(reader.GetAttribute("b3"), culture),
                                                         float.Parse(reader.GetAttribute("b4"), culture),
                                                         float.Parse(reader.GetAttribute("c1"), culture),
                                                         float.Parse(reader.GetAttribute("c2"), culture),
                                                         float.Parse(reader.GetAttribute("c3"), culture),
                                                         float.Parse(reader.GetAttribute("c4"), culture),
                                                         float.Parse(reader.GetAttribute("d1"), culture),
                                                         float.Parse(reader.GetAttribute("d2"), culture),
                                                         float.Parse(reader.GetAttribute("d3"), culture),
                                                         float.Parse(reader.GetAttribute("d4"), culture));
                        jointArray[currentJoint] = m; //new Joint(jointName, m);
                        Joint parent = null;
                        if (parentName != null && jointTable.Contains(parentName))
                        {
                            parent = (Joint)jointTable[parentName];
                        }
                        joints[currentJoint]  = new Joint(jointName, currentJoint, parent);
                        jointTable[jointName] = joints[currentJoint];
                        currentJoint++;
                    }
                    break;

                    case "weights": {
                        index = 0;
                        //vertexCount = int.Parse(reader.GetAttribute("size"), culture);
                        indicesList = new ArrayList[vertexCount];
                        weightsList = new ArrayList[vertexCount];
                        for (int i = 0; i < vertexCount; i++)
                        {
                            indicesList[i] = new ArrayList(8);
                            weightsList[i] = new ArrayList(8);
                        }
                    }
                    break;

                    case "weight": {
                        int   vertexIndex = int.Parse(reader.GetAttribute("vertexIndex"));
                        byte  jointIndex  = byte.Parse(reader.GetAttribute("jointIndex"));
                        float value       = float.Parse(reader.GetAttribute("weight"), culture);
                        indicesList[vertexIndex].Add(jointIndex);
                        weightsList[vertexIndex].Add(value);
                    }
                    break;
                    }
                }

                if (reader.NodeType == XmlNodeType.EndElement)
                {
                    if (reader.Name.Equals("weights"))
                    {
                        IBoneIndicesStream bis = null;
                        IBoneWeightsStream bws = null;
                        if (HardwareSkinning)
                        {
                            bis = new BoneIndicesStream(vertexCount);
                            bws = new BoneWeightsStream(vertexCount);
                        }
                        else
                        {
                            bis = new SoftwareBoneIndicesStream(vertexCount);
                            bws = new SoftwareBoneWeightsStream(vertexCount);
                        }
                        for (int i = 0; i < vertexCount; i++)
                        {
                            bis.SetIndices(i, (byte[])indicesList[i].ToArray(typeof(byte)));
                            bws.SetWeights(i, (float[])weightsList[i].ToArray(typeof(float)));
                        }
                        streams.Add(bis);
                        streams.Add(bws);
                    }
                    else if (reader.Name.Equals("subset"))
                    {
                        VertexUnit vertexUnit = new VertexUnit(streams);
                        if (binding == -1)
                        {
                            model.Mesh = new Mesh(new SubSet(vertexUnit, indexStream));
                        }
                        else
                        {
                            model.AttachModel(new Model(new Mesh(new SubSet(vertexUnit, indexStream)), null), binding);
                        }
                        streams.Clear();
                    }
                }
            }
            ;

            reader.Close();
            if (jointArray != null && joints != null)
            {
                skeleton = new Skeleton(jointArray, joints);
            }
            model.Skeleton = skeleton;
        }