Example #1
0
        public void CanInitializePropertiesByConstructor()
        {
            SubMesh subMesh = new SubMesh();

            Assert.That(subMesh.Faces, Is.Not.Null.And.Empty);
            Assert.That(subMesh.Normals, Is.Not.Null.And.Empty);
            Assert.That(subMesh.Textures, Is.Not.Null.And.Empty);
            Assert.That(subMesh.Vertices, Is.Not.Null.And.Empty);
        }
Example #2
0
    // Use this for initialization
    void Start()
    {
        this.block = this.GetComponent<BlockObject>();

        if ( block != null )
        {
            var mesh = this.GetComponentInChildren<MeshFilter>();
            if ( meshLookup.ContainsKey(mesh.sharedMesh) == false )
            {
                SubMesh[] subMesh = new SubMesh[6];

                Vector3[] directions = new Vector3[]{ Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back};
                for ( int i = 0; i < directions.Length; i++ )
                {
                    subMesh[i] = new SubMesh();
                    List<int> triangles = new List<int>();

                    for ( int t = 0; t < mesh.sharedMesh.triangles.Length; t+=3)
                    {
                        int indexA = mesh.sharedMesh.triangles[t+0];
                        int indexB = mesh.sharedMesh.triangles[t+1];
                        int indexC = mesh.sharedMesh.triangles[t+2];

                        Vector3 a = mesh.sharedMesh.vertices[indexA];
                        Vector3 b = mesh.sharedMesh.vertices[indexB];
                        Vector3 c = mesh.sharedMesh.vertices[indexC];

                        Vector3 normal = Vector3.Cross( (c-a), (c-b));
                        float angle = Vector3.Angle(directions[i], normal);

                        if ( Mathf.Approximately( angle, 0) )
                        {
                            triangles.Add( indexA);
                            triangles.Add( indexB);
                            triangles.Add( indexC);
                        }
                    }

                    subMesh[i].triangles = triangles.ToArray();
                    meshLookup[mesh.sharedMesh] = subMesh;
                }
            }

            SubMesh[] submesh = meshLookup[mesh.sharedMesh];

            mesh.mesh.triangles = submesh[4].triangles;

        }
    }
Example #3
0
        public MeshBuilderHelper(String name, String resourcegroup,
            bool usesharedvertices, uint vertexstart, uint vertexcount)
        {
            mName = name;
            mResourceGroup = resourcegroup;
            mVertextStart = vertexstart;
            mVertexCount = vertexcount;

            if (MeshManager.Singleton.ResourceExists(name))
                throw (new ArgumentNullException("mesh name already used"));

            mMeshPtr = MeshManager.Singleton.CreateManual(mName, mResourceGroup);
            mSubMesh = mMeshPtr.CreateSubMesh();
            mSubMesh.useSharedVertices = usesharedvertices;
            mSubMesh.vertexData = new VertexData();
            mSubMesh.vertexData.vertexStart = mVertextStart;
            mSubMesh.vertexData.vertexCount = mVertexCount;
            offset = 0;
            mIndexType = HardwareIndexBuffer.IndexType.IT_16BIT;
        }
            //
            public Item( SubMesh subMesh )
            {
                this.subMesh = subMesh;

                subMesh.GetSomeGeometry( out positions, out indices );

                Bounds bounds = Bounds.Cleared;
                foreach( Vec3 pos in positions )
                    bounds.Add( pos );
                bounds.Expand( bounds.GetSize() * .001f );

                OctreeContainer.InitSettings initSettings = new OctreeContainer.InitSettings();
                initSettings.InitialOctreeBounds = bounds;
                initSettings.OctreeBoundsRebuildExpand = Vec3.Zero;
                initSettings.MinNodeSize = bounds.GetSize() / 50;
                octreeContainer = new OctreeContainer( initSettings );

                for( int nTriangle = 0; nTriangle < indices.Length / 3; nTriangle++ )
                {
                    Vec3 vertex0 = positions[ indices[ nTriangle * 3 + 0 ] ];
                    Vec3 vertex1 = positions[ indices[ nTriangle * 3 + 1 ] ];
                    Vec3 vertex2 = positions[ indices[ nTriangle * 3 + 2 ] ];

                    Bounds triangleBounds = new Bounds( vertex0 );
                    triangleBounds.Add( vertex1 );
                    triangleBounds.Add( vertex2 );

                    int octreeIndex = octreeContainer.AddObject( triangleBounds, 1 );
                }
            }
Example #5
0
    public void Rebuild()
    {
        if (!IsValid())
        {
            Debug.LogError("The card definition is not valid. " + this.name);
            return;
        }

        Stock.Validate();

        Dictionary <Texture2D, SubMesh> table = new Dictionary <Texture2D, SubMesh>();

        CardMesh  card  = new CardMesh();
        CardShape paper = Definition.Atlas.FindById(Definition.Stock.Paper);

        if (paper == null)
        {
            Debug.LogError("Paper does not exist in atlas = " + Definition.Atlas.name + "::" + Definition.Stock.Paper);
            return;
        }
        SubMesh data = GetMesh(card, table, paper);

        float x = Stock.Size.x * Stock.Scale / 2;
        float y = Stock.Size.y * Stock.Scale / 2;

        float bx = Mathf.Max(Stock.CornerSize, Stock.Border.x) * Stock.Scale;
        float by = Mathf.Max(Stock.CornerSize, Stock.Border.y) * Stock.Scale;

        //float cx = x-bx;
        //float cy = y-by;

        //   4  5
        // B 0  1 6
        //   C  D
        // A 3  2 7
        //   9  8
        float   crad = Stock.CornerSize;
        Vector2 cxy  = new Vector2(crad, crad);

        Vector3[] v = RectPoints(Stock.Size * Stock.Scale, Stock.Scale * cxy);

        Vector3 c0 = new Vector3(-x + bx, +y - by, 0);
        Vector3 c1 = new Vector3(+x - bx, +y - by, 0);
        Vector3 c2 = new Vector3(+x - bx, -y + by, 0);
        Vector3 c3 = new Vector3(-x + bx, -y + by, 0);

        if (Stock.Smooth > 0)
        {
            // middle
            Square4(data, paper, v[0], v[1], v[2], v[3], Color.white, false, false);
            // top
            Square4(data, paper, v[4], v[5], v[1], v[0], Color.white, false, false);
            // right
            Square4(data, paper, v[1], v[6], v[7], v[2], Color.white, false, false);
            // bottom
            Square4(data, paper, v[3], v[2], v[8], v[9], Color.white, false, false);
            // left
            Square4(data, paper, v[11], v[0], v[3], v[10], Color.white, false, false);

            BuildCorner3(data, paper, v[0], v[11], v[4]);
            BuildCorner3(data, paper, v[1], v[5], v[6]);
            BuildCorner3(data, paper, v[2], v[7], v[8]);
            BuildCorner3(data, paper, v[3], v[9], v[10]);
        }
        else // simple rectangle
        {
            Vector3 p1 = new Vector3(-x, +y, 0);
            Vector3 p2 = new Vector3(+x, +y, 0);
            Vector3 p3 = new Vector3(+x, -y, 0);
            Vector3 p4 = new Vector3(-x, -y, 0);
            Square4(data, paper, p1, p2, p3, p4, Color.white, false, false);
        }

        Vector2 textSize = Stock.TextSize * Stock.Scale;

        float s1 = Stock.BigSymbolSize * Stock.Scale;
        float s2 = Stock.SymbolSize * Stock.Scale;
        float s3 = Stock.CornerSymbolSize * Stock.Scale;
        //float symW = s2;
        //float symH = s2;
        //float rimX = Mathf.Max(textSize.x,symW);
        //float rimY = Mathf.Max(textSize.y,symH);

        CardShape symbol = Atlas.FindById(Definition.Symbol);

        if (symbol == null && !string.IsNullOrEmpty(Definition.Symbol))
        {
            Debug.LogError(string.Format("Symbol shape '{0}' is not defined in atlas.", Definition.Symbol));
        }

        // Full Image is used by cards like ACE/JOKER that might want a fully unique face image
        // Half Image is used by cards like JQK where half image is flipped and reflected for the top/bottom of the face image
        // Pattern is used to form standard layout of suit symbols for 2-10 cards
        CardShape fullImage = Definition.FullImage ? Atlas.FindById(Definition.Image) : null;
        CardShape halfImage = !Definition.FullImage ? Atlas.FindById(Definition.Image) : null;

        if (fullImage != null)
        {
            SubMesh core = GetMesh(card, table, fullImage);
            //Square4 (core,fullImage,v[0],v[1],v[2],v[3],Color.white,false,false);
            Square4(core, fullImage, c0, c1, c2, c3, Color.white, false, false);
        }
        else if (halfImage != null)
        {
            SubMesh core = GetMesh(card, table, halfImage);
            Vector3 lift = new Vector3(0, 0, -0.01f);
            Square4(core, halfImage, v[0] + lift, v[1] + lift, v[13] + lift, v[12] + lift, Color.white, false, false);
            Square4(core, halfImage, v[12] + lift, v[13] + lift, v[2] + lift, v[3] + lift, Color.white, true, true);
        }
        else if (Definition.Pattern != 0 && symbol != null)
        {
            if (Definition.Pattern >= 1 && Definition.Pattern < patternBits.Length)
            {
                SubMesh core = GetMesh(card, table, symbol);
                int     bits = patternBits[Definition.Pattern];
                float   x0   = -x + bx;
                float   x1   = +x - bx;
                float   y0   = +y - by;
                float   y1   = -y + by;
                for (int b = 0; b < 17; b++)
                {
                    if ((bits & (1 << b)) != 0)
                    {
                        float   px      = Mathf.Lerp(x0, x1, patternPos[b].x);
                        float   py      = Mathf.Lerp(y0, y1, patternPos[b].y);
                        Vector2 symSize = (Definition.Pattern == 1) ? new Vector2(s1, s1) : new Vector2(s2, s2);
                        if (Stock.AlwaysUpright || patternUpper[b])
                        {
                            Square(core, symbol, new Vector3(px, py, -0.01f), symSize, Color.white);
                        }
                        else
                        {
                            SquareFlip(core, symbol, new Vector3(px, py, -0.01f), symSize, Color.white, true, true);
                        }
                    }
                }
            }
            else
            {
                Debug.LogError(string.Format("Pattern value '{0}' is not valid.", Definition.Pattern));
            }
        }

        // Text is used for number/letter in corner of card (ex. A for Ace)
        CardShape text = Atlas.FindById(Definition.Text);

        if (text == null && !string.IsNullOrEmpty(Definition.Text))
        {
            Debug.LogError(string.Format("Text shape '{0}' is not defined in atlas.", Definition.Text));
        }
        if (text != null)
        {
            float   tx    = Stock.TextOffset.x * Stock.Scale;
            float   ty    = Stock.TextOffset.y * Stock.Scale;
            SubMesh sub   = GetMesh(card, table, text);
            float   x0    = -x + tx; // + (bx+rimX)*0.5f;
            float   x1    = +x - tx; // - (bx+rimX)*0.5f;
            float   y0    = +y - ty; //by;
            float   y1    = -y + ty; //by;
            Color   color = GetSymbolColor(Definition.Symbol);
            Square(sub, text, new Vector3(x0, y0, -0.01f), textSize, color);
            if (Stock.AlwaysUpright)
            {
                Square(sub, text, new Vector3(x1, y1, -0.01f), textSize, color);
            }
            else
            {
                SquareFlip(sub, text, new Vector3(x1, y1, -0.01f), textSize, color, true, true);
            }
        }

        // Symbol is used for corner suit icons (heart,diamond,spade,club)
        if (symbol != null)
        {
            float   sx  = Stock.SymbolOffset.x * Stock.Scale;
            float   sy  = Stock.SymbolOffset.y * Stock.Scale;
            SubMesh sub = GetMesh(card, table, symbol);
            //float gapY = s3/3;
            float   x0      = -x + sx; //(bx+rimX)*0.5f;
            float   x1      = +x - sx; //(bx+rimX)*0.5f;
            float   y0      = +y - sy; //by - textSize.y - gapY - rad;
            float   y1      = -y + sy; //by + textSize.y + gapY + rad;
            Color   color   = GetSymbolColor(Definition.Symbol);
            Vector2 halfSym = new Vector2(s3, s3);

            // Top-left corner symbol
            Square(sub, symbol, new Vector3(x0, y0, -0.01f), halfSym, color);

            // Bottom-right symbol can be up-right or upside-down depending on preferences
            if (Stock.AlwaysUpright)
            {
                Square(sub, symbol, new Vector3(x1, y1, -0.01f), halfSym, color);
            }
            else
            {
                SquareFlip(sub, symbol, new Vector3(x1, y1, -0.01f), halfSym, color, true, true);
            }
        }

        if (Stock.TwoSided)
        {
            BuildBack(card, table, paper);

            /*
             *          CardShape back = Atlas.FindById(Stock.Back);
             *          if (back != null)
             *          {
             *                  Vector3 [] v = RectPoints(Stock.Size*Stock.Scale,Stock.BackBorder*Stock.Scale);
             *
             *                  SubMesh core = GetMesh(card,table,back);
             *                  // middle
             *                  if (Stock.HalfBack)
             *                  {
             *                          Square4(core,back,v[1],v[0],v[12],v[13],Color.white,false,false);
             *                          Square4(core,back,v[13],v[12],v[3],v[2],Color.white,true,true);
             *                  }
             *                  else
             *                  {
             *                          Square4(core,back,v[1],v[0],v[3],v[2],Color.white,false,false);
             *                  }
             *                  // top
             *                  Square4(core,paper,v[5],v[4],v[0],v[1],Color.white,false,false);
             *                  // back-left
             *                  Square5(core,paper,v[2],v[7],v[6],v[1],v[13],Color.white,false);
             *                  // bottom
             *                  Square4(core,paper,v[2],v[3],v[9],v[8],Color.white,false,false);
             *                  // back-right
             *                  Square5(core,paper,v[0],v[11],v[10],v[3],v[12],Color.white,false);
             *
             *                  BuildCorner3(core, paper, v[1],v[6],v[5]);
             *                  BuildCorner3(core, paper, v[2],v[8],v[7]);
             *                  BuildCorner3(core, paper, v[3],v[10],v[9]);
             *                  BuildCorner3(core, paper, v[0],v[4],v[11]);
             *          }
             */
        }

        Mesh mesh = SetupMesh();

        mesh.vertices  = card.GetCombinedVertices().ToArray();
        mesh.triangles = data.IndexList.ToArray();
        mesh.uv        = card.GetCombinedTexCoords().ToArray();
        mesh.colors    = card.GetCombinedColors().ToArray();

        if (card.MeshList.Count > 1)
        {
            mesh.subMeshCount = card.MeshList.Count;
            int vbase = 0;
            for (int i = 1; i < card.MeshList.Count; ++i)
            {
                SubMesh sub  = card.MeshList[i];
                int[]   tris = sub.IndexList.ToArray();
                vbase += card.MeshList[i - 1].VertexList.Count;
                for (int t = 0; t < tris.Length; ++t)
                {
                    tris[t] += vbase;
                }
                mesh.SetTriangles(tris, i);
            }
        }

        mesh.RecalculateBounds();
        mesh.Optimize();
        mesh.RecalculateNormals();

        this.GetComponent <Renderer>().sharedMaterials = card.Materials.ToArray();

        // Setup Collider
        this.gameObject.AddComponent <BoxCollider2D>();

        // Mark as not clicked
        this.Clicked = false;
    }
        private void VerticesToOutline(List <Vector2f[]> outlines, Vector3f[] vertices, SubMesh submesh)
        {
            int             triangleCount = submesh.IndexCount / 3;
            List <Vector3i> triangles     = new List <Vector3i>(triangleCount);

            using (MemoryStream memStream = new MemoryStream(m_indexBuffer))
            {
                using (BinaryReader reader = new BinaryReader(memStream))
                {
                    memStream.Position = submesh.FirstByte;
                    for (int i = 0; i < triangleCount; i++)
                    {
                        int x = reader.ReadInt16();
                        int y = reader.ReadInt16();
                        int z = reader.ReadInt16();
                        triangles.Add(new Vector3i(x, y, z));
                    }
                }
            }

            MeshOutlineGenerator outlineGenerator = new MeshOutlineGenerator(vertices, triangles);
            List <Vector2f[]>    outline          = outlineGenerator.GenerateOutlines();

            outlines.AddRange(outline);
        }
Example #7
0
        public override void DoPostProcess()
        {
            base.DoPostProcess();

            shaders = new shader[gbxmodelValues.Shaders.Count];
            for (int i = 0; i < shaders.Length; i++)
            {
                shaders[i] = OpenShader(gbxmodelValues.Shaders[i].Shader.Value, gbxmodelValues.Shaders[i].Shader.TagGroup);
            }

            meshes = new EnhancedMesh[gbxmodelValues.Geometries.Count][];
            for (int i = 0; i < meshes.Length; i++)
            {
                meshes[i] = new EnhancedMesh[gbxmodelValues.Geometries[i].Parts.Count];
                for (int j = 0; j < meshes[i].Length; j++)
                {
                    ushort[] strip    = new ushort[gbxmodelValues.Geometries[i].Parts[j].Triangles.Count * 3];
                    Vertex[] vertices = new Vertex[gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices.Count];

                    for (int k = 0; k < vertices.Length; k++)
                    {
                        vertices[k].position.X = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Position.X;
                        vertices[k].position.Y = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Position.Y;
                        vertices[k].position.Z = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Position.Z;
                        vertices[k].normal.X   = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Normal.I;
                        vertices[k].normal.Y   = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Normal.J;
                        vertices[k].normal.Z   = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Normal.K;
                        vertices[k].u1         = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].TextureCoords.X * ((gbxmodelValues.BaseMap.Value == 0.0f) ? 1.0f : gbxmodelValues.BaseMap.Value);
                        vertices[k].v1         = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].TextureCoords.Y * ((gbxmodelValues.BaseMap2.Value == 0.0f) ? 1.0f : gbxmodelValues.BaseMap2.Value);
                        vertices[k].u2         = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Node0Weight.Value;
                        vertices[k].v2         = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Node1Weight.Value;
                        vertices[k].nodeIndex1 = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Node0Index.Value;
                        vertices[k].nodeIndex2 = gbxmodelValues.Geometries[i].Parts[j].UncompressedVertices[k].Node1Index.Value;
                        bounds.Update(vertices[k].position.X, vertices[k].position.Y, vertices[k].position.Z);
                    }
                    for (int k = 0; k < gbxmodelValues.Geometries[i].Parts[j].Triangles.Count; k++)
                    {
                        strip[k * 3]     = (ushort)gbxmodelValues.Geometries[i].Parts[j].Triangles[k].Vertex0Index.Value;
                        strip[k * 3 + 1] = (ushort)gbxmodelValues.Geometries[i].Parts[j].Triangles[k].Vertex1Index.Value;
                        strip[k * 3 + 2] = (ushort)gbxmodelValues.Geometries[i].Parts[j].Triangles[k].Vertex2Index.Value;
                    }

                    try
                    {
                        SubMesh[] sub = new SubMesh[1];
                        sub[0]       = new SubMesh(0, (ushort)(strip.Length - 2), 0);
                        meshes[i][j] = new EnhancedMesh(vertices, strip, sub, true, false, true);
                        meshes[i][j].DefaultShader = shaders[gbxmodelValues.Geometries[i].Parts[j].ShaderIndex.Value];
                    }
                    catch (Exception ex)
                    {
                        LogError("Model tag {0}.{1} failed to create Mesh: {2}", Name, "gbxmodel", ex.Message);
                    }

                    //instances.Add(new ObjectInstance(meshes[i][j], new Vector3(gbxmodelValues.Geometries[i].Parts[j].Centroid.X, gbxmodelValues.Geometries[i].Parts[j].Centroid.Y, gbxmodelValues.Geometries[i].Parts[j].Centroid.Z)));
                    //instances.Add(new PartInstance(meshes[i][j], new Vector3(gbxmodelValues.Geometries[i].Parts[j].Centroid.X, gbxmodelValues.Geometries[i].Parts[j].Centroid.Y, gbxmodelValues.Geometries[i].Parts[j].Centroid.Z)));
                }
            }

            int[] regionPermutationCounts = new int[gbxmodelValues.Regions.Count];
            for (int i = 0; i < gbxmodelValues.Regions.Count; i++)
            {
                regionPermutationCounts[i] = gbxmodelValues.Regions[i].Permutations.Count;
            }

            superLow  = new InstanceCollection[regionPermutationCounts.Length][];
            low       = new InstanceCollection[regionPermutationCounts.Length][];
            medium    = new InstanceCollection[regionPermutationCounts.Length][];
            high      = new InstanceCollection[regionPermutationCounts.Length][];
            superHigh = new InstanceCollection[regionPermutationCounts.Length][];

            for (int i = 0; i < regionPermutationCounts.Length; i++)
            {
                superLow[i]  = new InstanceCollection[regionPermutationCounts[i]];
                low[i]       = new InstanceCollection[regionPermutationCounts[i]];
                medium[i]    = new InstanceCollection[regionPermutationCounts[i]];
                high[i]      = new InstanceCollection[regionPermutationCounts[i]];
                superHigh[i] = new InstanceCollection[regionPermutationCounts[i]];
            }

            int geometry;

            for (int i = 0; i < regionPermutationCounts.Length; i++)
            {
                for (int j = 0; j < regionPermutationCounts[i]; j++)
                {
                    geometry       = gbxmodelValues.Regions[i].Permutations[j].SuperLow.Value;
                    superLow[i][j] = new InstanceCollection();
                    for (int k = 0; k < meshes[geometry].Length; k++)
                    {
                        superLow[i][j].Add(new PartInstance(meshes[geometry][k],
                                                            meshes[geometry][k].DefaultShader,
                                                            new Vector3(gbxmodelValues.Geometries[geometry].Parts[k].Centroid.X,
                                                                        gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Y,
                                                                        gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Z),
                                                            meshes[geometry][k].BoundingBox));
                    }

                    geometry  = gbxmodelValues.Regions[i].Permutations[j].Low.Value;
                    low[i][j] = new InstanceCollection();
                    for (int k = 0; k < meshes[geometry].Length; k++)
                    {
                        low[i][j].Add(new PartInstance(meshes[geometry][k],
                                                       meshes[geometry][k].DefaultShader,
                                                       new Vector3(gbxmodelValues.Geometries[geometry].Parts[k].Centroid.X,
                                                                   gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Y,
                                                                   gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Z),
                                                       meshes[geometry][k].BoundingBox));
                    }

                    geometry     = gbxmodelValues.Regions[i].Permutations[j].Medium.Value;
                    medium[i][j] = new InstanceCollection();
                    for (int k = 0; k < meshes[geometry].Length; k++)
                    {
                        medium[i][j].Add(new PartInstance(meshes[geometry][k],
                                                          meshes[geometry][k].DefaultShader,
                                                          new Vector3(gbxmodelValues.Geometries[geometry].Parts[k].Centroid.X,
                                                                      gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Y,
                                                                      gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Z),
                                                          meshes[geometry][k].BoundingBox));
                    }

                    geometry   = gbxmodelValues.Regions[i].Permutations[j].High.Value;
                    high[i][j] = new InstanceCollection();
                    for (int k = 0; k < meshes[geometry].Length; k++)
                    {
                        high[i][j].Add(new PartInstance(meshes[geometry][k],
                                                        meshes[geometry][k].DefaultShader,
                                                        new Vector3(gbxmodelValues.Geometries[geometry].Parts[k].Centroid.X,
                                                                    gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Y,
                                                                    gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Z),
                                                        meshes[geometry][k].BoundingBox));
                    }

                    geometry        = gbxmodelValues.Regions[i].Permutations[j].SuperHigh.Value;
                    superHigh[i][j] = new InstanceCollection();
                    for (int k = 0; k < meshes[geometry].Length; k++)
                    {
                        superHigh[i][j].Add(new PartInstance(meshes[geometry][k],
                                                             meshes[geometry][k].DefaultShader,
                                                             new Vector3(gbxmodelValues.Geometries[geometry].Parts[k].Centroid.X,
                                                                         gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Y,
                                                                         gbxmodelValues.Geometries[geometry].Parts[k].Centroid.Z),
                                                             meshes[geometry][k].BoundingBox));
                    }
                }
            }
        }
Example #8
0
        private unsafe void createCube(string name, Mogre.Vector3 gpose, double d)
        {
            MeshPtr msh  = MeshManager.Singleton.CreateManual(name, "General");
            SubMesh sub1 = msh.CreateSubMesh("1");

            const float sqrt13    = 0.577350269f; /* sqrt(1/3) */
            const int   nVertices = 8;
            const int   vbufCount = 3 * 2 * nVertices;

            float[] vertices = new float[vbufCount] {
                (float)(gpose.x - d / 2), (float)(gpose.y + d / 2), (float)(gpose.z - d / 2), //0 position
                -sqrt13, sqrt13, -sqrt13,                                                     //0 normal A
                (float)(gpose.x + d / 2), (float)(gpose.y + d / 2), (float)(gpose.z - d / 2), //1 position
                sqrt13, sqrt13, -sqrt13,                                                      //1 normal B
                (float)(gpose.x + d / 2), (float)(gpose.y - d / 2), (float)(gpose.z - d / 2), //2 position
                sqrt13, -sqrt13, -sqrt13,                                                     //2 normal F
                (float)(gpose.x - d / 2), (float)(gpose.y - d / 2), (float)(gpose.z - d / 2), //3 position
                -sqrt13, -sqrt13, -sqrt13,                                                    //3 normal H
                (float)(gpose.x - d / 2), (float)(gpose.y + d / 2), (float)(gpose.z + d / 2),
                -sqrt13, sqrt13, sqrt13,                                                      //4 normal C
                (float)(gpose.x + d / 2), (float)(gpose.y + d / 2), (float)(gpose.z + d / 2),
                sqrt13, sqrt13, sqrt13,                                                       //5 normal D
                (float)(gpose.x + d / 2), (float)(gpose.y - d / 2), (float)(gpose.z + d / 2),
                sqrt13, -sqrt13, sqrt13,                                                      //6 normal E
                (float)(gpose.x - d / 2), (float)(gpose.y - d / 2), (float)(gpose.z + d / 2),
                -sqrt13, -sqrt13, sqrt13,                                                     //7 normal G
            };

            const int ibufCount = 36;

            ushort[] faces = new ushort[ibufCount] {
                //back
                0, 2, 3,
                0, 1, 2,
                //right
                1, 6, 2,
                1, 5, 6,
                //front
                4, 6, 5,
                4, 7, 6,
                //left
                0, 7, 4,
                0, 3, 7,
                //top
                0, 5, 1,
                0, 4, 5,
                //bottom
                2, 7, 3,
                2, 6, 7
            };

            sub1.vertexData             = new VertexData();
            sub1.vertexData.vertexCount = nVertices;

            VertexDeclaration decl = sub1.vertexData.vertexDeclaration;
            uint offset            = 0;

            //position
            decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
            //normal
            decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);

            HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, sub1.vertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);
            VertexBufferBinding           bind = sub1.vertexData.vertexBufferBinding;

            void *pVertices;

            fixed(float *pFVertice = vertices)
            {
                pVertices = (void *)pFVertice;
            }

            vbuf.WriteData(0, vbuf.SizeInBytes, pVertices, true);
            bind.SetBinding(0, vbuf);

            void *pFaces;

            fixed(ushort *pUFaces = faces)
            {
                pFaces = (void *)pUFaces;
            }

            HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, ibufCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);

            ibuf.WriteData(0, ibuf.SizeInBytes, pFaces, true);

            sub1.useSharedVertices     = false;
            sub1.indexData.indexBuffer = ibuf;
            sub1.indexData.indexCount  = ibufCount;
            sub1.indexData.indexStart  = 0;

            sub1.SetMaterialName("Examples/10PointBlock");

            msh._setBounds(new AxisAlignedBox(-100, -100, -100, 100, 100, 100));
            msh._setBoundingSphereRadius(Mogre.Math.Sqrt(3 * 100 * 100));

            msh.Load();
        }
 public static void CalculateSubMeshVertexRangeAndBounds(Version version, Mesh mesh, ref SubMesh submesh)
 {
     UpdateSubMeshVertexRange(version, mesh, ref submesh);
     RecalculateSubmeshBounds(version, mesh, ref submesh);
 }
        private static CollisionShape ExtractBox_Old(SubMesh subMesh)
        {
            if (DoLog)
            {
                Log("");
                Log(string.Format("Extracting box for submesh {0}", subMesh.Name));
            }
            MeshTriangle[] triangles = ExtractSubmeshTriangles(subMesh);
            int            count     = triangles.Length;

            Plane[] planesUnsorted = new Plane[6];
            int     planeCount     = 0;

            // Iterate through the triangles.  For each triangle,
            // determine the plane it belongs to, and find the plane
            // in the array of planes, or if it's not found, add it.
            for (int i = 0; i < count; i++)
            {
                MeshTriangle t     = triangles[i];
                bool         found = false;
                Plane        p     = new Plane(t.vertPos[0], t.vertPos[1], t.vertPos[2]);
                NormalizePlane(ref p);
                if (DoLog)
                {
                    Log(string.Format(" {0} => plane {1}", t.ToString(), p.ToString()));
                }
                for (int j = 0; j < planeCount; j++)
                {
                    Plane pj = planesUnsorted[j];
                    if (SamePlane(pj, p))
                    {
                        if (DoLog)
                        {
                            Log(string.Format(" plane {0} same as plane {1}", p.ToString(), pj.ToString()));
                        }
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    if (planeCount < 6)
                    {
                        if (DoLog)
                        {
                            Log(string.Format(" plane[{0}] = plane {1}", planeCount, p.ToString()));
                        }
                        planesUnsorted[planeCount++] = p;
                    }
                    else
                    {
                        Debug.Assert(false,
                                     string.Format("In the definition of box {0}, more than 6 planes were found",
                                                   subMesh.Name));
                    }
                }
            }
            Debug.Assert(planeCount == 6,
                         string.Format("In the definition of box {0}, fewer than 6 planes were found",
                                       subMesh.Name));
            // Now recreate the planes array, making sure that
            // opposite faces are 3 planes apart
            Plane[] planes    = new Plane[6];
            bool[]  planeUsed = new bool[6];
            for (int i = 0; i < 6; i++)
            {
                planeUsed[i] = false;
            }
            int planePair = 0;

            for (int i = 0; i < 6; i++)
            {
                if (!planeUsed[i])
                {
                    Plane p1 = planesUnsorted[i];
                    planes[planePair] = p1;
                    planeUsed[i]      = true;
                    for (int j = 0; j < 6; j++)
                    {
                        Plane p2 = planesUnsorted[j];
                        if (!planeUsed[j] && !Orthogonal(p2, p1))
                        {
                            planes[3 + planePair++] = p2;
                            planeUsed[j]            = true;
                            break;
                        }
                    }
                }
            }
            Debug.Assert(planePair == 3, "Didn't find 3 pairs of parallel planes");
            // Make sure that the sequence of planes follows the
            // right-hand rule
            if (planes[0].Normal.Cross(planes[1].Normal).Dot(planes[3].Normal) < 0)
            {
                // Swap the first two plane pairs
                Plane p = planes[0];
                planes[0]     = planes[1];
                planes[1]     = p;
                p             = planes[0 + 3];
                planes[0 + 3] = planes[1 + 3];
                planes[1 + 3] = p;
                Debug.Assert(planes[0].Normal.Cross(planes[1].Normal).Dot(planes[3].Normal) > 0,
                             "Even after swapping, planes don't obey the right-hand rule");
            }
            // Now we have our 6 planes, sorted so that opposite
            // planes are 3 planes apart, and so they obey the
            // right-hand rule.  This guarantees that corners
            // correspond.  Find the 8 intersections that define the
            // corners.
            Vector3[] corners     = new Vector3[8];
            int       cornerCount = 0;

            for (int i = 0; i <= 3; i += 3)
            {
                Plane p1 = planes[i];
                for (int j = 1; j <= 4; j += 3)
                {
                    Plane p2 = planes[j];
                    for (int k = 2; k <= 5; k += 3)
                    {
                        Plane   p3     = planes[k];
                        Vector3 corner = -1 * ((p1.D * (p2.Normal.Cross(p3.Normal)) +
                                                p2.D * (p3.Normal.Cross(p1.Normal)) +
                                                p3.D * (p1.Normal.Cross(p2.Normal))) /
                                               p1.Normal.Dot(p2.Normal.Cross(p3.Normal)));
                        Debug.Assert(cornerCount < 8,
                                     string.Format("In the definition of box {0}, more than 8 corners were found",
                                                   subMesh.Name));
                        if (DoLog)
                        {
                            Log(string.Format("  corner#{0}: {1}", cornerCount, corner.ToString()));
                        }
                        corners[cornerCount++] = corner;
                    }
                }
            }
            Debug.Assert(cornerCount == 8,
                         string.Format("In the definition of box {0}, fewer than 8 corners were found",
                                       subMesh.Name));
            // We know that corners correspond.  Now find the center
            Vector3 center = (corners[0] + corners[7]) / 2;

            Debug.Assert((center - (corners[1] + corners[5]) / 2.0f).Length > geometryEpsilon ||
                         (center - (corners[2] + corners[6]) / 2.0f).Length > geometryEpsilon ||
                         (center - (corners[3] + corners[7]) / 2.0f).Length > geometryEpsilon,
                         string.Format("In the definition of box {0}, center definition {0} is not consistent",
                                       subMesh.Name, center.ToString()));
            // Find the extents
            Vector3 extents = new Vector3(Math.Abs((corners[1] - corners[0]).Length / 2.0f),
                                          Math.Abs((corners[3] - corners[1]).Length / 2.0f),
                                          Math.Abs((corners[4] - corners[0]).Length / 2.0f));

            if (DoLog)
            {
                Log(string.Format(" extents {0}", extents.ToString()));
            }
            // Find the axes
            Vector3[] axes = new Vector3[3] {
                (corners[1] - corners[0]).ToNormalized(),
                (corners[3] - corners[1]).ToNormalized(),
                (corners[4] - corners[0]).ToNormalized()
            };
            if (DoLog)
            {
                for (int i = 0; i < 3; i++)
                {
                    Log(string.Format(" axis[{0}] {1}", i, axes[i]));
                }
            }
            // Now, is it an obb or an aabb?  Figure out if the axes
            // point in the same direction as the basis vectors, and
            // if so, the order of the axes
            int[] mapping = new int[3] {
                -1, -1, -1
            };
            int foundMapping = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (axes[i].Cross(Primitives.UnitBasisVectors[j]).Length < geometryEpsilon)
                    {
                        mapping[i] = j;
                        foundMapping++;
                        break;
                    }
                }
            }
            CollisionShape shape;

            if (foundMapping == 3)
            {
                // It's an AABB, so build the min and max vectors, in
                // the order that matches the unit basis vector order
                Vector3 min = Vector3.Zero;
                Vector3 max = Vector3.Zero;
                for (int i = 0; i < 3; i++)
                {
                    float e = extents[i];
                    int   j = mapping[i];
                    min[j] = center[j] - e;
                    max[j] = center[j] + e;
                }
                shape = new CollisionAABB(min, max);
            }
            else
            {
                Vector3 ruleTest = axes[0].Cross(axes[1]);
                if (axes[2].Dot(ruleTest) < 0)
                {
                    axes[2] = -1 * axes[2];
                }
                // Return the OBB
                shape = new CollisionOBB(center, axes, extents);
            }
            if (DoLog)
            {
                Log(string.Format("Extraction result: {0}", shape));
            }
            return(shape);
        }
Example #11
0
        private void ReadSubMesh(XmlReader reader, Mesh mesh)
        {
            var subReader = reader.ReadSubtree();

            var subMesh = new SubMesh();
            subMesh.BoundingSphereRadius = 0;
            bool hasBones = false;
            int vertexCount = 0;
            Vertex[] vertices = null;

            subMesh.Material = reader.GetAttribute("material");

            while (subReader.Read())
            {
                if (subReader.NodeType != XmlNodeType.Element)
                    continue;

                // Read faces
                if (subReader.Name == "faces")
                {
                    int faceCount = StringConverter.Parse<int>(subReader.GetAttribute("count"));
                    subMesh.TriangleCount = faceCount;

                    using (var memStream = new MemoryStream(faceCount * sizeof(int) * 3))
                    {
                        using (var writer = new BinaryWriter(memStream))
                        {
                            for (int i = 0; i < faceCount; i++)
                            {
                                subReader.ReadToFollowing("face");

                                writer.Write(StringConverter.Parse<int>(subReader.GetAttribute("v1")));
                                writer.Write(StringConverter.Parse<int>(subReader.GetAttribute("v2")));
                                writer.Write(StringConverter.Parse<int>(subReader.GetAttribute("v3")));
                            }

                            subMesh.Indices = memStream.GetBuffer();
                        }
                    }
                }
                // Read geometry
                else if (subReader.Name == "geometry")
                {
                    if (vertexCount == 0)
                    {
                        vertexCount = StringConverter.Parse<int>(subReader.GetAttribute("vertexcount"));
                        vertices = new Vertex[vertexCount];
                    }

                    var geometryReader = subReader.ReadSubtree();

                    // Read vertex buffers
                    while (geometryReader.Read())
                    {
                        if (geometryReader.NodeType != XmlNodeType.Element || geometryReader.Name != "vertexbuffer")
                            continue;

                        for (int i = 0; i < vertexCount; i++)
                        {
                            var vertex = vertices[i];

                            if (!geometryReader.ReadToFollowing("vertex"))
                                break;

                            var vertexReader = geometryReader.ReadSubtree();

                            while (vertexReader.Read())
                            {
                                if (vertexReader.NodeType != XmlNodeType.Element)
                                    continue;

                                if (vertexReader.Name == "position")
                                    vertex.Position = ReadVector3(geometryReader);
                                else if (vertexReader.Name == "normal")
                                    vertex.Normal = ReadVector3(geometryReader);
                                else if (vertexReader.Name == "tangent")
                                    vertex.Tangent = ReadVector3(geometryReader);
                                else if (vertexReader.Name == "texcoord")
                                    vertex.TexCoord = ReadUV(geometryReader);
                            }

                            vertices[i] = vertex;

                            var length = vertex.Position.Length;
                            if (subMesh.BoundingSphereRadius < length)
                                subMesh.BoundingSphereRadius = length;
                        }
                    }
                }
                // Read bone assignments
                else if (subReader.Name == "boneassignments")
                {
                    hasBones = true;

                    var bonesReader = subReader.ReadSubtree();

                    while (bonesReader.Read())
                    {
                        if (bonesReader.NodeType != XmlNodeType.Element || bonesReader.Name != "vertexboneassignment")
                            continue;

                        var index = StringConverter.Parse<int>(bonesReader.GetAttribute("vertexindex"));
                        var vertex = vertices[index];

                        var boneIndex = StringConverter.Parse<float>(bonesReader.GetAttribute("boneindex"));
                        var boneWeight = StringConverter.Parse<float>(bonesReader.GetAttribute("weight"));

                        if (vertex.BoneCount == 0)
                        {
                            vertex.BoneIndex.X = boneIndex;
                            vertex.BoneWeight.X = boneWeight;
                        }
                        else if (vertex.BoneCount == 1)
                        {
                            vertex.BoneIndex.Y = boneIndex;
                            vertex.BoneWeight.Y = boneWeight;
                        }
                        else if (vertex.BoneCount == 2)
                        {
                            vertex.BoneIndex.Z = boneIndex;
                            vertex.BoneWeight.Z = boneWeight;
                        }
                        else if (vertex.BoneCount == 3)
                        {
                            vertex.BoneIndex.W = boneIndex;
                            vertex.BoneWeight.W = boneWeight;
                        }

                        vertex.BoneCount++;
                        vertices[index] = vertex;
                    }
                }
            }

            if (hasBones)
            {
                subMesh.VertexFormat = new Renderer.VertexFormat(new Renderer.VertexFormatElement[]
                        {
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Position, Renderer.VertexPointerType.Float, 3, 0),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Normal, Renderer.VertexPointerType.Float, 3, sizeof(float) * 3),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Tangent, Renderer.VertexPointerType.Float, 3, sizeof(float) * 6),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.TexCoord, Renderer.VertexPointerType.Float, 2, sizeof(float) * 9),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.BoneIndex, Renderer.VertexPointerType.Float, 4, sizeof(float) * 11),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.BoneWeight, Renderer.VertexPointerType.Float, 4, sizeof(float) * 15),
                        });
            }
            else
            {
                subMesh.VertexFormat = new Renderer.VertexFormat(new Renderer.VertexFormatElement[]
                        {
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Position, Renderer.VertexPointerType.Float, 3, 0),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Normal, Renderer.VertexPointerType.Float, 3, sizeof(float) * 3),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Tangent, Renderer.VertexPointerType.Float, 3, sizeof(float) * 6),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.TexCoord, Renderer.VertexPointerType.Float, 2, sizeof(float) * 9),
                        });
            }

            using (var memStream = new MemoryStream(vertexCount * subMesh.VertexFormat.Size))
            {
                using (var writer = new BinaryWriter(memStream))
                {
                    for (int i = 0; i < vertexCount; i++)
                    {
                        writer.Write(vertices[i].Position);
                        writer.Write(vertices[i].Normal);
                        writer.Write(vertices[i].Tangent);
                        writer.Write(vertices[i].TexCoord);

                        if (hasBones)
                        {
                            writer.Write(vertices[i].BoneIndex);
                            writer.Write(vertices[i].BoneWeight);
                        }
                    }

                    subMesh.Vertices = memStream.GetBuffer();
                }
            }

            mesh.SubMeshes.Add(subMesh);
        }
Example #12
0
        public WaterMesh(String meshName, float planeSize, int cmplx)           // najak R-F
        // Assign Fields to the Initializer values
        {
            this.meshName = meshName;
            this.size     = planeSize;
            this.cmplx    = cmplx;                         // Number of Rows/Columns in the Water Grid representation
            cmplxAdj      = (float)Math.Pow((cmplx / 64f), 1.4f) * 2;
            numFaces      = 2 * (int)Math.Pow(cmplx, 2);   // Each square is split into 2 triangles.
            numVertices   = (int)Math.Pow((cmplx + 1), 2); // Vertex grid is (Complexity+1) squared

            // Allocate and initialize space for calculated Normals
            vNorms = new Vector3[cmplx + 1, cmplx + 1];        // vertex Normals for each grid point
            fNorms = new Vector3[cmplx, cmplx, 2];             // face Normals for each triangle

            // Create mesh and submesh to represent the Water
            mesh    = (Mesh)MeshManager.Instance.CreateManual(meshName);
            subMesh = mesh.CreateSubMesh();
            subMesh.useSharedVertices = false;

            // Construct metadata to describe the buffers associated with the water submesh
            subMesh.vertexData             = new VertexData();
            subMesh.vertexData.vertexStart = 0;
            subMesh.vertexData.vertexCount = numVertices;

            // Define local variables to point to the VertexData Properties
            VertexDeclaration   vdecl = subMesh.vertexData.vertexDeclaration;            // najak: seems like metadata
            VertexBufferBinding vbind = subMesh.vertexData.vertexBufferBinding;          // najak: pointer to actual buffer

            //najak: Set metadata to describe the three vertex buffers that will be accessed.
            vdecl.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position);
            vdecl.AddElement(1, 0, VertexElementType.Float3, VertexElementSemantic.Normal);
            vdecl.AddElement(2, 0, VertexElementType.Float2, VertexElementSemantic.TexCoords);

            // Prepare buffer for positions - todo: first attempt, slow
            // Create the Position Vertex Buffer and Bind it index 0 - Write Only
            posVBuf = HwBufMgr.CreateVertexBuffer(3 * 4, numVertices, BufferUsage.DynamicWriteOnly);
            vbind.SetBinding(0, posVBuf);

            // Prepare buffer for normals - write only
            // Create the Normals Buffer and Bind it to index 1 - Write only
            normVBuf = HwBufMgr.CreateVertexBuffer(3 * 4, numVertices, BufferUsage.DynamicWriteOnly);
            vbind.SetBinding(1, normVBuf);

            // Prepare Texture Coordinates buffer (static, written only once)
            // Creates a 2D buffer of 2D coordinates: (Complexity X Complexity), pairs.
            //    Each pair indicates the normalized coordinates of the texture to map to.
            //    (0,1.00), (0.02, 1.00), (0.04, 1.00), ... (1.00,1.00)
            //    (0,0.98), (0.02, 0.98), (0.04, 1.00), ... (1.00,0.98)
            //    ...
            //    (0,0.00), (0.02, 0.00), (0.04, 0.00), ... (1.00,0.00)
            // This construct is simple and is used to calculate the Texture map.
            // Todo: Write directly to the buffer, when Axiom supports this in safe manner
            float[,,] tcBufDat = new float[cmplx + 1, cmplx + 1, 2];
            for (int i = 0; i <= cmplx; i++)
            {
                // 2D column iterator for texture map
                for (int j = 0; j <= cmplx; j++)
                {
                    // 2D row iterator for texture map
                    // Define the normalized(0..1) X/Y-coordinates for this element of the 2D grid
                    tcBufDat[i, j, 0] = (float)i / cmplx;
                    tcBufDat[i, j, 1] = 1.0f - ((float)j / (cmplx));
                }
            }

            // Now Create the actual hardware buffer to contain the Texture Coordinate 2d map.
            //   and Bind it to buffer index 2
            tcVBuf = HwBufMgr.CreateVertexBuffer(2 * 4, numVertices, BufferUsage.StaticWriteOnly);
            tcVBuf.WriteData(0, tcVBuf.Size, tcBufDat, true);
            vbind.SetBinding(2, tcVBuf);

            // Create a Graphics Buffer on non-shared vertex indices (3 points for each triangle).
            //  Since the water grid consist of [Complexity x Complexity] squares, each square is
            //  split into 2 right triangles 45-90-45.  That is how the water mesh is constructed.
            //  Therefore the number of faces = 2 * Complexity * Complexity
            ushort[,,] idxBuf = new ushort[cmplx, cmplx, 6];
            for (int i = 0; i < cmplx; i++)                // iterate the rows
            {
                for (int j = 0; j < cmplx; j++)            // iterate the columns
                // Define 4 corners of each grid
                {
                    ushort p0 = (ushort)(i * (cmplx + 1) + j);                 // top left point on square
                    ushort p1 = (ushort)(i * (cmplx + 1) + j + 1);             // top right
                    ushort p2 = (ushort)((i + 1) * (cmplx + 1) + j);           // bottom left
                    ushort p3 = (ushort)((i + 1) * (cmplx + 1) + j + 1);       // bottom right

                    // Split Square Grid element into 2 adjacent triangles.
                    idxBuf[i, j, 0] = p2; idxBuf[i, j, 1] = p1; idxBuf[i, j, 2] = p0;               // top-left triangle
                    idxBuf[i, j, 3] = p2; idxBuf[i, j, 4] = p3; idxBuf[i, j, 5] = p1;               // bottom-right triangle
                }
            }
            // Copy Index Buffer to the Hardware Index Buffer
            HardwareIndexBuffer hdwrIdxBuf = HwBufMgr.CreateIndexBuffer(IndexType.Size16, 3 * numFaces, BufferUsage.StaticWriteOnly, true);

            hdwrIdxBuf.WriteData(0, numFaces * 3 * 2, idxBuf, true);

            // Set index buffer for this submesh
            subMesh.indexData.indexBuffer = hdwrIdxBuf;
            subMesh.indexData.indexStart  = 0;
            subMesh.indexData.indexCount  = 3 * numFaces;

            //Prepare Vertex Position Buffers (Note: make 3, since each frame is function of previous two)
            vBufs = new Vector3[3][, ];
            for (int b = 0; b < 3; b++)
            {
                vBufs[b] = new Vector3[cmplx + 1, cmplx + 1];
                for (int y = 0; y <= cmplx; y++)
                {
                    for (int x = 0; x <= cmplx; x++)
                    {
                        vBufs[b][y, x].x = (float)(x) / (float)(cmplx) * (float)size;
                        vBufs[b][y, x].y = 0;
                        vBufs[b][y, x].z = (float)(y) / (float)(cmplx) * (float)size;
                    }
                }
            }

            curBufNum = 0;
            vBuf      = vBufs[curBufNum];
            posVBuf.WriteData(0, posVBuf.Size, vBufs[0], true);

            AxisAlignedBox meshBounds = new AxisAlignedBox(new Vector3(0, 0, 0), new Vector3(size, 0, size));

            mesh.BoundingBox = meshBounds;              //	mesh->_setBounds(meshBounds); // najak: can't find _setBounds()

            mesh.Load();
            mesh.Touch();
        }         // end WaterMesh Constructor
Example #13
0
 public Model(SubMesh mesh)
 {
     _subMesh = mesh;
 }
Example #14
0
        // Get the mesh information for the given mesh.
        // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData
        private static unsafe void GetMeshInformation(MeshPtr mesh, out Vector3[] vertices, out int[] indices, Vector3 position, Quaternion orient, Vector3 scale)
        {
            bool addedShared = false;
            int  currentOffset = 0, sharedOffset = 0, nextOffset = 0, indexOffset = 0;

            int vertexCount = 0, indexCount = 0;

            // Calculate how many vertices and indices we're going to need
            for (ushort i = 0; i < mesh.NumSubMeshes; ++i)
            {
                SubMesh submesh = mesh.GetSubMesh(i);

                // We only need to add the shared vertices once
                if (submesh.useSharedVertices)
                {
                    if (!addedShared)
                    {
                        vertexCount += (int)mesh.sharedVertexData.vertexCount;
                        addedShared  = true;
                    }
                }
                else
                {
                    vertexCount += (int)submesh.vertexData.vertexCount;
                }

                // Add the indices
                indexCount += (int)submesh.indexData.indexCount;
            }

            // Allocate space for the vertices and indices
            vertices = new Vector3[vertexCount];
            indices  = new int[indexCount];

            addedShared = false;

            // Run through the submeshes again, adding the data into the arrays
            for (ushort i = 0; i < mesh.NumSubMeshes; ++i)
            {
                SubMesh submesh = mesh.GetSubMesh(i);

                VertexData vertexData = submesh.useSharedVertices ? mesh.sharedVertexData : submesh.vertexData;

                if ((!submesh.useSharedVertices) || (submesh.useSharedVertices && !addedShared))
                {
                    if (submesh.useSharedVertices)
                    {
                        addedShared  = true;
                        sharedOffset = currentOffset;
                    }

                    VertexElement posElem = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
                    System.Diagnostics.Debug.Assert(posElem.Type == VertexElementType.VET_FLOAT3);

                    using (HardwareVertexBufferSharedPtr vbuf = vertexData.vertexBufferBinding.GetBuffer(posElem.Source))
                    {
                        byte * vertex = (byte *)vbuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
                        float *preal;

                        for (uint j = 0; j < vertexData.vertexCount; ++j, vertex += vbuf.VertexSize)
                        {
                            posElem.BaseVertexPointerToElement(vertex, &preal);
                            Vector3 pt = new Vector3(preal[0], preal[1], preal[2]);

                            vertices[currentOffset + j] = (orient * (pt * scale)) + position;
                        }

                        vbuf.Unlock();
                    }

                    nextOffset += (int)vertexData.vertexCount;
                }

                IndexData indexData = submesh.indexData;

                using (HardwareIndexBufferSharedPtr ibuf = indexData.indexBuffer)
                {
                    bool use32bitindexes = ibuf.Type == HardwareIndexBuffer.IndexType.IT_32BIT;

                    int *   plong  = (int *)ibuf.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
                    ushort *pshort = (ushort *)plong;
                    int     offset = submesh.useSharedVertices ? sharedOffset : currentOffset;

                    if (use32bitindexes)
                    {
                        for (uint k = 0; k < indexData.indexCount; ++k)
                        {
                            indices[indexOffset++] = plong[k] + offset;
                        }
                    }
                    else
                    {
                        for (uint k = 0; k < indexData.indexCount; ++k)
                        {
                            indices[indexOffset++] = pshort[k] + offset;
                        }
                    }

                    ibuf.Unlock();
                }

                currentOffset = nextOffset;
            }
        }
        public static void ExtractCollisionShapes(Mesh mesh, string path)
        {
            PhysicsData   physicsData = null;
            List <string> deleteEm    = new List <string>();
            int           count       = mesh.SubMeshCount;

            for (int i = 0; i < count; i++)
            {
                SubMesh        subMesh    = mesh.GetSubMesh(i);
                CollisionShape shape      = null;
                string         targetName = null;
                bool           cv         = String.Compare(subMesh.Name.Substring(0, 5), "mvcv_", false) == 0;
                bool           rg         = String.Compare(subMesh.Name.Substring(0, 5), "mvrg_", false) == 0;
                int            firstIndex = 0;
                if (cv)
                {
                    firstIndex = 5;
                }
                else if (rg)
                {
                    string rest = subMesh.Name.Substring(5);
                    firstIndex = rest.IndexOf("_") + 1 + 5;
                }
                if (cv || rg)
                {
                    // It's probably a collision volume - - check the
                    // shape type to make sure
                    if (String.Compare(subMesh.Name.Substring(firstIndex, 4), "obb_", false) == 0)
                    {
                        shape = ExtractBox(subMesh);
                    }
                    else if (String.Compare(subMesh.Name.Substring(firstIndex, 5), "aabb_", false) == 0)
                    {
                        shape = ExtractBox(subMesh);
                    }
                    else if (String.Compare(subMesh.Name.Substring(firstIndex, 7), "sphere_", false) == 0)
                    {
                        shape = ExtractSphere(subMesh);
                    }
                    else if (String.Compare(subMesh.Name.Substring(firstIndex, 8), "capsule_", false) == 0)
                    {
                        shape = ExtractCapsule(subMesh);
                    }
                    if (shape != null)
                    {
                        targetName = GetTargetSubmesh(mesh, subMesh.Name);
                    }
                }
                if (shape != null)
                {
                    deleteEm.Add(subMesh.Name);
                    if (physicsData == null)
                    {
                        physicsData = new PhysicsData();
                    }
                    physicsData.AddCollisionShape(targetName, shape);
                }
            }
            for (int i = 0; i < deleteEm.Count; i++)
            {
                mesh.RemoveSubMesh(deleteEm[i]);
            }
            if (physicsData != null)
            {
                PhysicsSerializer serializer = new PhysicsSerializer();
                serializer.ExportPhysics(physicsData, path + ".physics");
            }

            if (DoLog)
            {
                CloseLog();
            }
        }
        // Take a different approach, based on an idea of Robin's:
        // Find the farthest point pair, and use that to identify the
        // triangles with one of the points as a vertex.  Then take
        // the normals of the triangles, adjust to object the
        // right-hand rule, and they are the axes.  Compute the center
        // from the average of the farthest points, and extents by
        // dotting farthest - center with the axes.
        private static CollisionShape ExtractBox(SubMesh subMesh)
        {
            if (DoLog)
            {
                Log("");
                Log(string.Format("Extracting box for submesh {0}", subMesh.Name));
            }
            MeshTriangle[] triangles = ExtractSubmeshTriangles(subMesh);
            int            count     = triangles.Length;

            // Find the two farthest vertices across all triangle
            Vector3[] farthestPoints = new Vector3[2] {
                Vector3.Zero, Vector3.Zero
            };
            float farthestDistanceSquared = 0.0f;

            for (int i = 0; i < count; i++)
            {
                MeshTriangle t1 = triangles[i];
                for (int j = 0; j < 3; j++)
                {
                    Vector3 p1 = t1.vertPos[j];
                    for (int r = i; r < count; r++)
                    {
                        MeshTriangle t2 = triangles[r];
                        for (int s = 0; s < 3; s++)
                        {
                            Vector3 p2   = t2.vertPos[s];
                            Vector3 diff = (p1 - p2);
                            float   d    = diff.LengthSquared;
                            //                          if (DoLog)
                            //                              Log(string.Format(" TriVert {0} {1} {2} / {3} {4} {5} dist {6}", i, j, p1, r, s, p2, d));
                            if (d > farthestDistanceSquared)
                            {
                                if (DoLog)
                                {
                                    Log(string.Format(" Largest! TriVert {0} {1} {2} / {3} {4} {5} dist {6}",
                                                      i, j, p1, r, s, p2, d));
                                }
                                farthestDistanceSquared = d;
                                farthestPoints[0]       = p1;
                                farthestPoints[1]       = p2;
                            }
                        }
                    }
                }
            }
            // The center is the average of the farthest points
            Vector3 center = (farthestPoints[0] + farthestPoints[1]) * 0.5f;

            if (DoLog)
            {
                Log(string.Format("The farthest points are {0} and {1}",
                                  farthestPoints[0], farthestPoints[1]));
                Log(string.Format("The center is {0}", center));
            }
            // Now find the three triangles that have the
            // farthestPoints[0] as a vertex
            Vector3[] axes       = new Vector3[] { Vector3.Zero, Vector3.Zero, Vector3.Zero };
            int       foundCount = 0;

            for (int i = 0; i < count; i++)
            {
                MeshTriangle t = triangles[i];
                for (int j = 0; j < 3; j++)
                {
                    Vector3 p = t.vertPos[j];
                    if ((p - farthestPoints[0]).LengthSquared < geometryEpsilon)
                    {
                        Vector3 side1 = t.vertPos[1] - t.vertPos[0];
                        Vector3 side2 = t.vertPos[2] - t.vertPos[1];
                        Vector3 axis  = side1.Cross(side2).ToNormalized();
                        // Ignore this triangle if his normal matches one we already have
                        bool ignore = false;
                        for (int k = 0; k < foundCount; k++)
                        {
                            if (Math.Abs(axis.Cross(axes[k]).LengthSquared) < geometryEpsilon)
                            {
                                ignore = true;
                                break;
                            }
                        }
                        if (!ignore)
                        {
                            Debug.Assert(foundCount < 3, "Found more than three triangles with distinct normals and vertex = farthest point");
                            axes[foundCount] = axis;
                            foundCount++;
                        }
                    }
                }
            }
            // Put the axes in coordinate order
            for (int i = 0; i < 3; i++)
            {
                float largest      = float.MinValue;
                int   largestIndex = i;
                for (int j = 0; j < 3; j++)
                {
                    float v = Math.Abs(axes[j][i]);
                    if (v > largest)
                    {
                        largestIndex = j;
                        largest      = v;
                    }
                }
                if (largestIndex != i)
                {
                    Vector3 t = axes[i];
                    axes[i]            = axes[largestIndex];
                    axes[largestIndex] = t;
                }
                if (axes[i][i] < 0)
                {
                    axes[i] = -axes[i];
                }
            }

            // Put the axes in right-hand-rule order
            if (axes[0].Cross(axes[1]).Dot(axes[2]) < 0)
            {
                axes[2] = -axes[2];
            }
            Debug.Assert(axes[0].Cross(axes[1]).Dot(axes[2]) > 0,
                         "After swapping axes, still don't obey right-hand rule");
            // The extents are just the abs of the dot products of
            // farthest point minus the center with the axes
            Vector3 f       = farthestPoints[0] - center;
            Vector3 extents = new Vector3(Math.Abs(f.Dot(axes[0])),
                                          Math.Abs(f.Dot(axes[1])),
                                          Math.Abs(f.Dot(axes[2])));

            if (DoLog)
            {
                for (int i = 0; i < 3; i++)
                {
                    Log(string.Format(" axis[{0}] {1}, extent[{2}] {3}", i, axes[i], i, extents[i]));
                }
                int[] sign = new int[3] {
                    0, 0, 0
                };
                for (int i = -1; i < 2; i += 2)
                {
                    sign[0] = i;
                    for (int j = -1; j < 2; j += 2)
                    {
                        sign[1] = j;
                        for (int k = -1; k < 2; k += 2)
                        {
                            sign[2] = k;
                            Vector3 corner = center;
                            for (int a = 0; a < 3; a++)
                            {
                                corner += axes[a] * extents[a] * sign[a];
                            }
                            Log(string.Format(" corner[{0},{1},{2}] = {3}", i, j, k, corner));
                        }
                    }
                }
            }
            // Now, is it an obb or an aabb?  Figure out if the axes
            // point in the same direction as the basis vectors, and
            // if so, the order of the axes
            int[] mapping = new int[3] {
                -1, -1, -1
            };
            int foundMapping = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (Math.Abs(axes[i].Dot(Primitives.UnitBasisVectors[j]) - 1.0f) < .0001f)
                    {
                        if (DoLog)
                        {
                            Log(string.Format(" foundMapping[{0}], basis vector {1}", i, Primitives.UnitBasisVectors[j]));
                        }
                        mapping[i] = j;
                        foundMapping++;
                        break;
                    }
                }
            }
            CollisionShape shape;

            if (foundMapping == 3)
            {
                // It's an AABB, so build the min and max vectors, in
                // the order that matches the unit basis vector order
                Vector3 min = Vector3.Zero;
                Vector3 max = Vector3.Zero;
                for (int i = 0; i < 3; i++)
                {
                    float e = extents[i];
                    int   j = mapping[i];
                    min[j] = center[j] - e;
                    max[j] = center[j] + e;
                }
                shape = new CollisionAABB(min, max);
            }
            else
            {
                // Return the OBB
                shape = new CollisionOBB(center, axes, extents);
            }
            if (DoLog)
            {
                Log(string.Format("Extraction result: {0}", shape));
            }
            return(shape);
        }
        private static SubMesh Convert(IExportContainer container, Mesh instanceMesh, ref SubMesh origin)
        {
            SubMesh instance = new SubMesh();

            instance.FirstByte  = origin.FirstByte;
            instance.IndexCount = origin.IndexCount;
            instance.Topology   = origin.GetTopology(container.Version);
            if (SubMesh.HasTriangleCount(container.ExportVersion))
            {
                instance.TriangleCount = origin.TriangleCount;
            }
            if (SubMesh.HasBaseVertex(container.ExportVersion))
            {
                instance.BaseVertex = GetBaseVertex(container, ref origin);
            }
            if (SubMesh.HasVertex(container.ExportVersion))
            {
                SetVertex(container, instanceMesh, ref origin, ref instance);
            }
            return(instance);
        }
        unsafe void UpdateGeometry(float time)
        {
            //generate geometry
            Vertex[] vertices = new Vertex[tesselation * tesselation];
            ushort[] indices  = new ushort[(tesselation - 1) * (tesselation - 1) * 6];
            {
                //vertices
                int vertexPosition = 0;
                for (int y = 0; y < tesselation; y++)
                {
                    for (int x = 0; x < tesselation; x++)
                    {
                        Vertex vertex = new Vertex();

                        Vec2 pos2 = new Vec2(
                            (float)x / (float)(tesselation - 1) - .5f,
                            (float)y / (float)(tesselation - 1) - .5f);
                        float posZ = MathFunctions.Sin(pos2.Length() * 30 - time * 2) / 2;
                        MathFunctions.Clamp(ref posZ, -5f, .5f);

                        vertex.position = new Vec3(pos2.X, pos2.Y, posZ) * Scale;
                        vertex.normal   = Vec3.Zero;
                        vertex.texCoord = new Vec2(pos2.X + .5f, pos2.Y + .5f);
                        //vertex.tangents = Vec4.Zero;

                        vertices[vertexPosition] = vertex;
                        vertexPosition++;
                    }
                }

                //indices
                int indexPosition = 0;
                for (int y = 0; y < tesselation - 1; y++)
                {
                    for (int x = 0; x < tesselation - 1; x++)
                    {
                        indices[indexPosition] = (ushort)(tesselation * y + x);
                        indexPosition++;
                        indices[indexPosition] = (ushort)(tesselation * y + x + 1);
                        indexPosition++;
                        indices[indexPosition] = (ushort)(tesselation * (y + 1) + x + 1);
                        indexPosition++;

                        indices[indexPosition] = (ushort)(tesselation * (y + 1) + x + 1);
                        indexPosition++;
                        indices[indexPosition] = (ushort)(tesselation * (y + 1) + x);
                        indexPosition++;
                        indices[indexPosition] = (ushort)(tesselation * y + x);
                        indexPosition++;
                    }
                }

                //calculate vertex normals
                fixed(Vertex *pVertices = vertices)
                {
                    int triangleCount = indices.Length / 3;

                    for (int n = 0; n < triangleCount; n++)
                    {
                        int index0 = indices[n * 3 + 0];
                        int index1 = indices[n * 3 + 1];
                        int index2 = indices[n * 3 + 2];

                        Vec3 pos0 = pVertices[index0].position;
                        Vec3 pos1 = pVertices[index1].position;
                        Vec3 pos2 = pVertices[index2].position;

                        Vec3 normal = Vec3.Cross(pos1 - pos0, pos2 - pos0);
                        normal.Normalize();

                        pVertices[index0].normal += normal;
                        pVertices[index1].normal += normal;
                        pVertices[index2].normal += normal;
                    }

                    //normalize
                    for (int n = 0; n < vertices.Length; n++)
                    {
                        pVertices[n].normal = pVertices[n].normal.GetNormalize();
                    }
                }
            }

            SubMesh subMesh = mesh.SubMeshes[0];

            //copy data to vertex buffer
            {
                HardwareVertexBuffer vertexBuffer = subMesh.VertexData.VertexBufferBinding.GetBuffer(0);

                IntPtr buffer = vertexBuffer.Lock(HardwareBuffer.LockOptions.Discard);
                fixed(Vertex *pVertices = vertices)
                {
                    NativeUtils.CopyMemory(buffer, (IntPtr)pVertices, vertices.Length * sizeof(Vertex));
                }

                vertexBuffer.Unlock();
            }

            //copy data to index buffer
            {
                HardwareIndexBuffer indexBuffer = subMesh.IndexData.IndexBuffer;
                IntPtr buffer = indexBuffer.Lock(HardwareBuffer.LockOptions.Discard);
                fixed(ushort *pIndices = indices)
                {
                    NativeUtils.CopyMemory(buffer, (IntPtr)pIndices, indices.Length * sizeof(ushort));
                }

                indexBuffer.Unlock();
            }

            ////calculate mesh tangent vectors
            //mesh.BuildTangentVectors( VertexElementSemantic.Tangent, 0, 0, true );
        }
        private static MeshTriangle[] ExtractSubmeshTriangles(SubMesh subMesh)
        {
            int[]                vertIdx   = new int[3];
            Vector3[]            vertPos   = new Vector3[3];
            VertexElement        posElem   = subMesh.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Position);
            HardwareVertexBuffer posBuffer = posBuffer = subMesh.vertexData.vertexBufferBinding.GetBuffer(posElem.Source);
            IntPtr               indexPtr  = subMesh.indexData.indexBuffer.Lock(BufferLocking.ReadOnly);
            IntPtr               posPtr    = posBuffer.Lock(BufferLocking.ReadOnly);
            int posOffset = posElem.Offset / sizeof(float);
            int posStride = posBuffer.VertexSize / sizeof(float);
            int numFaces  = subMesh.indexData.indexCount / 3;

            MeshTriangle[] triangles = new MeshTriangle[numFaces];
            unsafe
            {
                int *  pIdxInt32 = null;
                short *pIdxShort = null;
                float *pVPos     = (float *)posPtr.ToPointer();
                if (subMesh.indexData.indexBuffer.Type == IndexType.Size32)
                {
                    pIdxInt32 = (int *)indexPtr.ToPointer();
                }
                else
                {
                    pIdxShort = (short *)indexPtr.ToPointer();
                }

                // loop through all faces to calculate the tangents
                for (int n = 0; n < numFaces; n++)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        // get indices of vertices that form a polygon in the position buffer
                        if (subMesh.indexData.indexBuffer.Type == IndexType.Size32)
                        {
                            vertIdx[i] = pIdxInt32[3 * n + i];
                        }
                        else
                        {
                            vertIdx[i] = pIdxShort[3 * n + i];
                        }
                        vertPos[i].x = pVPos[vertIdx[i] * posStride + posOffset];
                        vertPos[i].y = pVPos[vertIdx[i] * posStride + posOffset + 1];
                        vertPos[i].z = pVPos[vertIdx[i] * posStride + posOffset + 2];
                    }
                    triangles[n] = new MeshTriangle(vertPos[0], vertPos[1], vertPos[2]);
                }
            }
            posBuffer.Unlock();
            subMesh.indexData.indexBuffer.Unlock();
            if (DoLog)
            {
                int count = triangles.Length;
                Log(string.Format(" extracted {0} triangles", count));
                for (int i = 0; i < count; i++)
                {
                    Log(string.Format("  {0}", triangles[i].ToString()));
                }
            }
            return(triangles);
        }
Example #20
0
        private void CreateGrassMesh()
        {
            // Each grass section is 3 planes at 60 degrees to each other
            // Normals point straight up to simulate correct lighting
            Mesh msh = MeshManager.Singleton.CreateManual(GRASS_MESH_NAME, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, null);

            SubMesh sm = msh.CreateSubMesh();

            sm.useSharedVertices      = false;
            sm.vertexData             = new VertexData();
            sm.vertexData.vertexStart = 0;
            sm.vertexData.vertexCount = 12;

            VertexDeclaration dcl = sm.vertexData.vertexDeclaration;
            uint offset           = 0;

            dcl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
            dcl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
            dcl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2);

            HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, 12, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);

            int i;

            unsafe {
                float *pData = (float *)(vbuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD));

                Vector3    baseVec = new Vector3(GRASS_WIDTH / 2, 0, 0);
                Vector3    vec     = baseVec;
                Quaternion rot     = new Quaternion();
                rot.FromAngleAxis(Math.DegreesToRadians(60), Vector3.UNIT_Y);

                for (i = 0; i < 3; ++i)
                {
                    //position
                    *pData++ = -vec.x;
                    *pData++ = GRASS_HEIGHT;
                    *pData++ = -vec.z;
                    // normal
                    *pData++ = 0;
                    *pData++ = 1;
                    *pData++ = 0;
                    // uv
                    *pData++ = 0;
                    *pData++ = 0;

                    // position
                    *pData++ = vec.x;
                    *pData++ = GRASS_HEIGHT;
                    *pData++ = vec.z;
                    // normal
                    *pData++ = 0;
                    *pData++ = 1;
                    *pData++ = 0;
                    // uv
                    *pData++ = 1;
                    *pData++ = 0;

                    // position
                    *pData++ = -vec.x;
                    *pData++ = 0;
                    *pData++ = -vec.z;
                    // normal
                    *pData++ = 0;
                    *pData++ = 1;
                    *pData++ = 0;
                    // uv
                    *pData++ = 0;
                    *pData++ = 1;

                    // position
                    *pData++ = vec.x;
                    *pData++ = 0;
                    *pData++ = vec.z;
                    // normal
                    *pData++ = 0;
                    *pData++ = 1;
                    *pData++ = 0;
                    // uv
                    *pData++ = 1;
                    *pData++ = 1;

                    vec = rot * vec;
                } //for
            }     //unsafe

            vbuf.Unlock();

            sm.vertexData.vertexBufferBinding.SetBinding(0, vbuf);
            sm.indexData.indexCount  = 6 * 3;
            sm.indexData.indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, 6 * 3, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);

            unsafe {
                ushort *pI = (ushort *)(sm.indexData.indexBuffer.Lock(HardwareBuffer.LockOptions.HBL_DISCARD));

                for (i = 0; i < 3; ++i)
                {
                    int off  = i * 4;
                    *   pI++ = (ushort)(off);
                    *   pI++ = (ushort)(off + 3);
                    *   pI++ = (ushort)(off + 1);

                    *pI++ = (ushort)(off + 0);
                    *pI++ = (ushort)(off + 2);
                    *pI++ = (ushort)(off + 3);
                }
            }

            sm.indexData.indexBuffer.Unlock();
            sm.SetMaterialName(GRASS_MATERIAL);

            msh.Load();
        }
Example #21
0
        /// <summary>
        /// createGrassMesh
        /// This demonstrates how to create a manual mesh
        ///  only use static members of MeshBuilderHelper to help set vertex and index data.
        /// </summary>
        void createGrassMesh()
        {
            OgreDotNet.MeshPtr mp = MeshManager.Instance.CreateManual(GRASS_MESH_NAME, "General");
            SubMesh            sm = mp.Get().CreateSubMesh();

            sm.useSharedVertices      = false;
            sm.vertexData             = new VertexData();
            sm.vertexData.vertexStart = 0;
            sm.vertexData.vertexCount = 12;
            //mIndexType = HardwareIndexBuffer::IT_16BIT;

            VertexDeclaration dcl    = sm.vertexData.vertexDeclaration;
            UInt32            offset = 0;

            UInt32 offPos = dcl.addElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION).getOffset();

            offset = VertexElement.getTypeSize(VertexElementType.VET_FLOAT3);

            UInt32 offNorm = dcl.addElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL).getOffset();

            offset += VertexElement.getTypeSize(VertexElementType.VET_FLOAT3);

            UInt32 offUV = dcl.addElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES).getOffset();

            offset += VertexElement.getTypeSize(VertexElementType.VET_FLOAT2);

            UInt32 vertexsize = offset;

            mLog.LogMessage(string.Format("createGrassMesh vertexsize={0}", vertexsize));

            HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.getSingleton().createVertexBuffer(
                vertexsize, 12, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);

            IntPtr pV = vbuf.Get().Lock(HardwareBuffer.LockOptions.HBL_DISCARD);

            Vector3    vec = new Vector3(GRASS_WIDTH / 2.0f, 0.0f, 0.0f);
            Quaternion rot = Quaternion.FromAngleAxis(60, Vector3.UnitY);
            uint       i;

            for (i = 0; i < 3; ++i)
            {
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 0, offPos, -vec.x, GRASS_HEIGHT, -vec.z);                         //position
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 0, offNorm, 0.0f, 1.0f, 0.0f);                                    //normal
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 0, offUV, 0.0f, 0.0f);                                            //uv

                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 1, offPos, vec.x, GRASS_HEIGHT, vec.z);                           //position
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 1, offNorm, 0.0f, 1.0f, 0.0f);                                    //normal
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 1, offUV, 1.0f, 0.0f);                                            //uv

                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 2, offPos, -vec.x, 0.0f, -vec.z);                                 //position
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 2, offNorm, 0.0f, 1.0f, 0.0f);                                    //normal
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 2, offUV, 0.0f, 1.0f);                                            //uv

                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 3, offPos, vec.x, 0.0f, vec.z);                                   //position
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 3, offNorm, 0.0f, 1.0f, 0.0f);                                    //normal
                OgreDotNet.MeshBuilderHelper.SetVertexFloat(pV, vertexsize, (i * 4) + 3, offUV, 1.0f, 1.0f);                                            //uv

                vec = rot * vec;
            }

            vbuf.Get().Unlock();
            sm.vertexData.vertexBufferBinding.setBinding(0, vbuf);
            sm.indexData.indexCount  = 6 * 3;
            sm.indexData.indexBuffer = HardwareBufferManager.getSingleton().createIndexBuffer(
                HardwareIndexBuffer.IndexType.IT_16BIT, 6 * 3, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);

            IntPtr pI = sm.indexData.indexBuffer.Get().Lock(HardwareBuffer.LockOptions.HBL_DISCARD);

            for (i = 0; i < 3; ++i)
            {
                UInt16 off = (UInt16)(i * 4);
                OgreDotNet.MeshBuilderHelper.SetIndex16bit(pI, (i * 2) + 0, (UInt16)(0 + off), (UInt16)(3 + off), (UInt16)(1 + off));
                OgreDotNet.MeshBuilderHelper.SetIndex16bit(pI, (i * 2) + 1, (UInt16)(0 + off), (UInt16)(2 + off), (UInt16)(3 + off));
            }

            sm.indexData.indexBuffer.Get().Unlock();
            sm.SetMaterialName(GRASS_MATERIAL);
            mp.Get().Load();
        }
 private static void SetVertex(IExportContainer container, Mesh instanceMesh, ref SubMesh origin, ref SubMesh instance)
 {
     if (SubMesh.HasVertex(container.Version))
     {
         instance.FirstVertex = origin.FirstVertex;
         instance.VertexCount = origin.VertexCount;
         instance.LocalAABB   = origin.LocalAABB;
     }
     else
     {
         CalculateSubMeshVertexRangeAndBounds(container.ExportVersion, instanceMesh, ref instance);
     }
 }
Example #23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="page"></param>
        /// <param name="layer"></param>
        /// <param name="grassPostions"></param>
        /// <param name="grassCount"></param>
        /// <returns></returns>
        private Mesh GenerateGrassCrossQuads(PageInfo page, GrassLayer layer, IntPtr grassPostions, int grassCount)
        {
            //Calculate the number of quads to be added
            int quadCount = grassCount * 2;

            //Create manual mesh to store grass quads
            Mesh    mesh    = (Mesh)MeshManager.Instance.CreateManual(GetUniqueID(), ResourceGroupManager.DefaultResourceGroupName, null);
            SubMesh subMesh = mesh.CreateSubMesh();

            subMesh.useSharedVertices = false;

            //Setup vertex format information
            subMesh.vertexData             = new VertexData();
            subMesh.vertexData.vertexStart = 0;
            subMesh.vertexData.vertexCount = 4 * quadCount;

            VertexDeclaration dcl = subMesh.vertexData.vertexDeclaration;
            int offset            = 0;

            dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            dcl.AddElement(0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse);
            offset += VertexElement.GetTypeSize(VertexElementType.Color);
            dcl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);

            //Populate a new vertex buffer with grass
            HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
                /*offset*/ dcl, subMesh.vertexData.vertexCount, BufferUsage.DynamicWriteOnly, false);

            unsafe
            {
                float *pReal = (float *)vbuf.Lock(BufferLocking.Discard);
                //Calculate size variance
                float  rndWidth = layer.mMaxWidth - layer.mMinWidth;
                float  rndHeight = layer.mMaxHeight - layer.mMinHeight;
                float  minY = float.PositiveInfinity, maxY = float.NegativeInfinity;
                float *posPtr = (float *)grassPostions; //Position array "iterator"
                for (int i = 0; i < grassCount; i++)
                {
                    //Get the x and z positions from the position array
                    float x = *posPtr++;
                    float z = *posPtr++;


                    //Get the color at the grass position
                    uint color = 0;
                    if (layer.ColorMap != null)
                    {
                        color = layer.ColorMap.GetColorAt(x, z);
                    }
                    else
                    {
                        color = 0xFFFFFFFF;
                    }

                    //Calculate size
                    float rnd        = MogreLibMath.Utility.UnitRandom();//The same rnd value is used for width and height to maintain aspect ratio
                    float halfXScale = (layer.mMinWidth + rndWidth * rnd) * 0.5f;
                    float scaleY     = (layer.mMinWidth + rndHeight * rnd);

                    //Calculate rotation
                    float angle  = MogreLibMath.Utility.RangeRandom(0, MogreLibMath.Utility.TWO_PI);
                    float xTrans = MogreLibMath.Utility.Cos(angle) * halfXScale;
                    float zTrans = MogreLibMath.Utility.Sin(angle) * halfXScale;


                    //Calculate heights and edge positions
                    float x1 = x - xTrans, z1 = z - zTrans;
                    float x2 = x + xTrans, z2 = z + zTrans;

                    float y1, y2;
                    if (mHeightFunction != null)
                    {
                        y1 = mHeightFunction.GetHeightAt(x1, z1, mHeightFunctionUserData);
                        y2 = mHeightFunction.GetHeightAt(x2, z2, mHeightFunctionUserData);
                    }
                    else
                    {
                        y1 = 0;
                        y2 = 0;
                    }

                    //Add vertices
                    *pReal++ = (x1 - page.CenterPoint.x); *pReal++ = (y1 + scaleY); *pReal++ = (z1 - page.CenterPoint.z); //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 0; *pReal++ = 0;                                                                           //uv

                    *pReal++ = (x2 - page.CenterPoint.x); *pReal++ = (y2 + scaleY); *pReal++ = (z2 - page.CenterPoint.z); //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 1; *pReal++ = 0;                                                                           //uv

                    *pReal++ = (x1 - page.CenterPoint.x); *pReal++ = (y1); *pReal++ = (z1 - page.CenterPoint.z);          //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 0; *pReal++ = 1;                                                                           //uv

                    *pReal++ = (x2 - page.CenterPoint.x); *pReal++ = (y2); *pReal++ = (z2 - page.CenterPoint.z);          //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 1; *pReal++ = 1;                                                                           //uv

                    //Update bounds
                    if (y1 < minY)
                    {
                        minY = y1;
                    }
                    if (y2 < minY)
                    {
                        minY = y2;
                    }
                    if (y1 + scaleY > maxY)
                    {
                        maxY = y1 + scaleY;
                    }
                    if (y2 + scaleY > maxY)
                    {
                        maxY = y2 + scaleY;
                    }

                    //Calculate heights and edge positions
                    float x3 = x + zTrans, z3 = z - xTrans;
                    float x4 = x - zTrans, z4 = z + xTrans;

                    float y3, y4;
                    if (mHeightFunction != null)
                    {
                        y3 = mHeightFunction.GetHeightAt(x3, z3, mHeightFunctionUserData);
                        y4 = mHeightFunction.GetHeightAt(x4, z4, mHeightFunctionUserData);
                    }
                    else
                    {
                        y3 = 0;
                        y4 = 0;
                    }

                    //Add vertices
                    *pReal++ = (x3 - page.CenterPoint.x); *pReal++ = (y3 + scaleY); *pReal++ = (z3 - page.CenterPoint.z); //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 0; *pReal++ = 0;                                                                           //uv

                    *pReal++ = (x4 - page.CenterPoint.x); *pReal++ = (y4 + scaleY); *pReal++ = (z4 - page.CenterPoint.z); //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 1; *pReal++ = 0;                                                                           //uv

                    *pReal++ = (x3 - page.CenterPoint.x); *pReal++ = (y3); *pReal++ = (z3 - page.CenterPoint.z);          //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 0; *pReal++ = 1;                                                                           //uv

                    *pReal++ = (x4 - page.CenterPoint.x); *pReal++ = (y4); *pReal++ = (z4 - page.CenterPoint.z);          //pos
                    *((uint *)pReal++) = color;                                                                           //color
                    *pReal++ = 1; *pReal++ = 1;                                                                           //uv

                    //Update bounds
                    if (y3 < minY)
                    {
                        minY = y1;
                    }
                    if (y4 < minY)
                    {
                        minY = y2;
                    }
                    if (y3 + scaleY > maxY)
                    {
                        maxY = y3 + scaleY;
                    }
                    if (y4 + scaleY > maxY)
                    {
                        maxY = y4 + scaleY;
                    }
                }

                vbuf.Unlock();
                subMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf);

                //Populate index buffer
                subMesh.indexData.indexStart  = 0;
                subMesh.indexData.indexCount  = 6 * quadCount;
                subMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(
                    IndexType.Size16, subMesh.indexData.indexCount, BufferUsage.DynamicWriteOnly);
                ushort *pI = (ushort *)subMesh.indexData.indexBuffer.Lock(BufferLocking.Discard);
                for (ushort i = 0; i < quadCount; i++)
                {
                    ushort ofset = (ushort)(i * 4);
                    *      pI++  = (ushort)(0 + ofset);
                    *      pI++  = (ushort)(2 + ofset);
                    *      pI++  = (ushort)(1 + ofset);

                    *pI++ = (ushort)(1 + ofset);
                    *pI++ = (ushort)(2 + ofset);
                    *pI++ = (ushort)(3 + ofset);
                }

                subMesh.indexData.indexBuffer.Unlock();
                //Finish up mesh
                AxisAlignedBox bounds = new AxisAlignedBox(
                    new Vector3(page.Bounds.Left - page.CenterPoint.x, minY, page.Bounds.Top - page.CenterPoint.z),
                    new Vector3(page.Bounds.Right - page.CenterPoint.x, maxY, page.Bounds.Bottom - page.CenterPoint.z));

                mesh.BoundingBox = bounds;
                Vector3 tmp = bounds.Maximum - bounds.Minimum;
                mesh.BoundingSphereRadius = tmp.Length * 0.5f;
                mesh.Load();
                //Apply grass material to mesh
                subMesh.MaterialName = layer.Material.Name;

                //Return the mesh
                return(mesh);
            }
        }
Example #24
0
        unsafe void DeformationMeshParallel()
        {
            Vertex[] vertices = new Vertex[vertex_count];
            ushort[] indices  = new ushort[index_count];
            mesh.SubMeshes[0].VertexData.GetSomeGeometry(ref changeable_vertex_pos, ref changeable_vertex_norm);

            if (first_init_mesh == false)
            {
                /*for (int i = 0; i < vertex_count; i++)
                 * {
                 *  Vertex vertex = new Vertex();
                 *  vertex.position = original_vertex_pos[i];
                 *  vertex.normal = original_vertex_norm[i];
                 *  vertex.texCoord = original_vertex_tc[i];
                 *  vertices[i] = vertex;
                 * }
                 * for (int i = 0; i < index_count; i++)
                 * {
                 *  indices[i] = (ushort)(original_vertex_ind[i]);
                 * }*/

                ParallelLoopResult parallel_result = Parallel.For(0, vertex_count, i =>
                {
                    Vertex vertex   = new Vertex();
                    vertex.position = original_vertex_pos[i];
                    vertex.normal   = original_vertex_norm[i];
                    vertex.texCoord = original_vertex_tc[i];
                    vertices[i]     = vertex;
                });

                if (parallel_result.IsCompleted)
                {
                    for (int i = 0; i < index_count; i++)
                    {
                        indices[i] = (ushort)(original_vertex_ind[i]);
                    }
                }

                SubMesh sub_mesh = mesh.SubMeshes[0];
                {
                    HardwareVertexBuffer vertex_buffer = sub_mesh.VertexData.VertexBufferBinding.GetBuffer(0);

                    IntPtr buffer = vertex_buffer.Lock(HardwareBuffer.LockOptions.Discard);
                    fixed(Vertex *pvertices = vertices)
                    {
                        NativeUtils.CopyMemory(buffer, (IntPtr)pvertices, vertices.Length * sizeof(Vertex));
                    }

                    vertex_buffer.Unlock();
                }
                {
                    HardwareIndexBuffer index_buffer = sub_mesh.IndexData.IndexBuffer;
                    IntPtr buffer = index_buffer.Lock(HardwareBuffer.LockOptions.Discard);
                    fixed(ushort *pindices = indices)
                    {
                        NativeUtils.CopyMemory(buffer, (IntPtr)pindices, indices.Length * sizeof(ushort));
                    }

                    index_buffer.Unlock();
                }
                first_init_mesh = true;
            }

            else
            {
                if (hit_other != null)
                {
                    ParallelLoopResult parallel_result = Parallel.For(0, vertex_count, i =>
                    {
                        Vertex vertex = new Vertex();
                        Vec3 p        = ((original_vertex_pos[i] * attached_mesh.ScaleOffset) * Rotation) +
                                        (Position + attached_mesh.PositionOffset);
                        Vec3 pp    = hit_pos;
                        Sphere sp  = new Sphere(pp, Type.CONF.DeformationRadius);
                        Vec3 nvec  = Vec3.Zero;
                        Vec3 nnorm = Vec3.Zero;

                        if (sp.IsContainsPoint(p))
                        {
                            Ray ray = new Ray(p, changeable_vertex_norm[i] * .01f);
                            if (!Single.IsNaN(ray.Direction.X) && !Single.IsNaN(ray.Origin.X))
                            {
                                RayCastResult[] piercingResult = PhysicsWorld.Instance.RayCastPiercing(
                                    ray, (int)ContactGroup.CastOnlyDynamic);/*(int)ContactGroup.CastOnlyContact);*/

                                Vec3 collision_pos = Vec3.Zero;
                                Vec3 collision_nor = Vec3.Zero;
                                bool collision     = false;

                                foreach (RayCastResult result in piercingResult)
                                {
                                    if (Array.IndexOf(PhysicsModel.Bodies, result.Shape.Body) != -1)
                                    {
                                        continue;
                                    }
                                    collision     = true;
                                    collision_pos = result.Position;
                                    collision_nor = result.Normal;
                                    break;
                                }
                                if (collision)
                                {
                                    float old_x       = 0, old_y = 0, old_z = 0, new_x = 0, new_y = 0, new_z = 0;
                                    float deformation = 0, force = 0, max_deformation = Type.CONF.MaxStrengthDeformation, mass = 0, vel = 0;

                                    mass = hit_other.Body.Mass;
                                    vel  = hit_other.Body.LastStepLinearVelocity.Length();

                                    force = (((hit_this.Body.Mass * hit_this.Body.LastStepLinearVelocity.Length()) +
                                              (mass * vel)) / hit_this.Body.Mass) / 100.0f;

                                    if (force > max_deformation)
                                    {
                                        deformation = max_deformation;
                                    }
                                    else
                                    {
                                        deformation = force;
                                    }

                                    //Deform X
                                    if (changeable_vertex_pos[i].X > 0)
                                    {
                                        old_x = original_vertex_pos[i].X - deformation;
                                        if (old_x < changeable_vertex_pos[i].X)
                                        {
                                            new_x = old_x;
                                        }
                                        else
                                        {
                                            new_x = changeable_vertex_pos[i].X;
                                        }
                                    }
                                    else
                                    {
                                        old_x = original_vertex_pos[i].X + deformation;
                                        if (old_x > changeable_vertex_pos[i].X)
                                        {
                                            new_x = old_x;
                                        }
                                        else
                                        {
                                            new_x = changeable_vertex_pos[i].X;
                                        }
                                    }

                                    //Deform Y
                                    if (changeable_vertex_pos[i].Y > 0)
                                    {
                                        old_y = original_vertex_pos[i].Y - deformation;
                                        if (old_y < changeable_vertex_pos[i].Y)
                                        {
                                            new_y = old_y;
                                        }
                                        else
                                        {
                                            new_y = changeable_vertex_pos[i].Y;
                                        }
                                    }
                                    else
                                    {
                                        old_y = original_vertex_pos[i].Y + deformation;
                                        if (old_y > changeable_vertex_pos[i].Y)
                                        {
                                            new_y = old_y;
                                        }
                                        else
                                        {
                                            new_y = changeable_vertex_pos[i].Y;
                                        }
                                    }

                                    //Deform Z
                                    if (changeable_vertex_pos[i].Z > 0)
                                    {
                                        old_z = original_vertex_pos[i].Z - deformation;
                                        if (old_z < changeable_vertex_pos[i].Z)
                                        {
                                            new_z = old_z;
                                        }
                                        else
                                        {
                                            new_z = changeable_vertex_pos[i].Z;
                                        }
                                    }
                                    else
                                    {
                                        old_z = original_vertex_pos[i].Z + deformation;
                                        if (old_z > changeable_vertex_pos[i].Z)
                                        {
                                            new_z = old_z;
                                        }
                                        else
                                        {
                                            new_z = changeable_vertex_pos[i].Z;
                                        }
                                    }

                                    nvec  = new Vec3(new_x, new_y, new_z);
                                    nnorm = -collision_nor;
                                }
                                else
                                {
                                    nvec  = changeable_vertex_pos[i];
                                    nnorm = changeable_vertex_norm[i];
                                }
                            }
                        }
                        else
                        {
                            nvec  = changeable_vertex_pos[i];
                            nnorm = changeable_vertex_norm[i];
                        }
                        vertex.position = nvec;
                        vertex.normal   = nnorm;
                        vertex.texCoord = original_vertex_tc[i];
                        vertices[i]     = vertex;
                    });

                    if (parallel_result.IsCompleted)
                    {
                        for (int i = 0; i < index_count; i++)
                        {
                            indices[i] = (ushort)(original_vertex_ind[i]);
                        }

                        SubMesh sub_mesh = mesh.SubMeshes[0];
                        {
                            HardwareVertexBuffer vertex_buffer = sub_mesh.VertexData.VertexBufferBinding.GetBuffer(0);

                            IntPtr buffer = vertex_buffer.Lock(HardwareBuffer.LockOptions.Discard);
                            fixed(Vertex *pvertices = vertices)
                            {
                                NativeUtils.CopyMemory(buffer, (IntPtr)pvertices, vertices.Length * sizeof(Vertex));
                            }

                            vertex_buffer.Unlock();
                        }
                        {
                            HardwareIndexBuffer index_buffer = sub_mesh.IndexData.IndexBuffer;
                            IntPtr buffer = index_buffer.Lock(HardwareBuffer.LockOptions.Discard);
                            fixed(ushort *pindices = indices)
                            {
                                NativeUtils.CopyMemory(buffer, (IntPtr)pindices, indices.Length * sizeof(ushort));
                            }

                            index_buffer.Unlock();
                        }
                    }
                }
                hit_other = null;
            }
        }
Example #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="page"></param>
        /// <param name="layer"></param>
        /// <param name="grassPostions"></param>
        /// <param name="grassCount"></param>
        /// <returns></returns>
        private Mesh GenerateGrassSprite(PageInfo page, GrassLayer layer, IntPtr grassPostions, int grassCount)
        {
            //Calculate the number of quads to be added
            int quadCount = grassCount;

            //Create manual mesh to store grass quads
            Mesh    mesh    = (Mesh)MeshManager.Instance.CreateManual(GetUniqueID(), ResourceGroupManager.DefaultResourceGroupName, null);
            SubMesh subMesh = mesh.CreateSubMesh();

            subMesh.useSharedVertices = false;

            //Setup vertex format information
            subMesh.vertexData             = new VertexData();
            subMesh.vertexData.vertexStart = 0;
            subMesh.vertexData.vertexCount = 4 * quadCount;

            VertexDeclaration dcl = subMesh.vertexData.vertexDeclaration;
            int offset            = 0;

            dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            dcl.AddElement(0, offset, VertexElementType.Float4, VertexElementSemantic.Normal);
            offset += VertexElement.GetTypeSize(VertexElementType.Float4);
            dcl.AddElement(0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse);
            offset += VertexElement.GetTypeSize(VertexElementType.Color);
            dcl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);

            //Populate a new vertex buffer with grass
            HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
                /*offset*/ dcl, subMesh.vertexData.vertexCount, BufferUsage.DynamicWriteOnly, false);

            unsafe
            {
                float *pReal = (float *)vbuf.Lock(BufferLocking.Discard);
                //Calculate size variance
                float  rndWidth = layer.mMaxWidth - layer.mMinWidth;
                float  rndHeight = layer.mMaxHeight - layer.mMinHeight;
                float  minY = float.PositiveInfinity, maxY = float.NegativeInfinity;
                float *posPtr = (float *)grassPostions; //Position array "iterator"
                for (int i = 0; i < grassCount; i++)
                {
                    //Get the x and z positions from the position array
                    float x = *posPtr++;
                    float z = *posPtr++;


                    //Calculate height
                    float y = 0;
                    if (mHeightFunction != null)
                    {
                        y = mHeightFunction.GetHeightAt(x, z, mHeightFunctionUserData);
                    }
                    else
                    {
                        y = 0;
                    }

                    float x1 = (x - page.CenterPoint.x);
                    float z1 = (z - page.CenterPoint.z);

                    //Get the color at the grass position
                    uint color = 0;
                    if (layer.ColorMap != null)
                    {
                        color = layer.ColorMap.GetColorAt(x, z);
                    }
                    else
                    {
                        color = 0xFFFFFFFF;
                    }

                    //Calculate size
                    float rnd        = MogreLibMath.Utility.UnitRandom();//The same rnd value is used for width and height to maintain aspect ratio
                    float halfXScale = (layer.mMinWidth + rndWidth * rnd) * 0.5f;
                    float scaleY     = (layer.mMinWidth + rndHeight * rnd);

                    //Randomly mirror grass textures
                    float uvLeft, uvRight;
                    if (MogreLibMath.Utility.UnitRandom() > 0.5f)
                    {
                        uvLeft  = 0;
                        uvRight = 1;
                    }
                    else
                    {
                        uvLeft  = 1;
                        uvRight = 0;
                    }

                    //Add vertices
                    *pReal++ = x1; *pReal++ = y; *pReal++ = z1;                                 //center position
                    *pReal++ = -halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0;      //normal (used to store relative corner positions)
                    *((uint *)pReal++) = color;                                                 //color
                    *pReal++ = uvLeft; *pReal++ = 0;                                            //uv

                    *pReal++ = x1; *pReal++ = y; *pReal++ = z1;                                 //center position
                    *pReal++ = +halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0;      //normal (used to store relative corner positions)
                    *((uint *)pReal++) = color;                                                 //color
                    *pReal++ = uvRight; *pReal++ = 0;                                           //uv

                    *pReal++ = x1; *pReal++ = y; *pReal++ = z1;                                 //center position
                    *pReal++ = -halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0;        //normal (used to store relative corner positions)
                    *((uint *)pReal++) = color;                                                 //color
                    *pReal++ = uvLeft; *pReal++ = 1;                                            //uv

                    *pReal++ = x1; *pReal++ = y; *pReal++ = z1;                                 //center position
                    *pReal++ = +halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0;        //normal (used to store relative corner positions)
                    *((uint *)pReal++) = color;                                                 //color
                    *pReal++ = uvRight; *pReal++ = 1;                                           //uv

                    //Update bounds
                    if (y < minY)
                    {
                        minY = y;
                    }
                    if (y + scaleY > maxY)
                    {
                        maxY = y + scaleY;
                    }
                }

                vbuf.Unlock();
                subMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf);

                //Populate index buffer
                subMesh.indexData.indexStart  = 0;
                subMesh.indexData.indexCount  = 6 * quadCount;
                subMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(
                    IndexType.Size16, subMesh.indexData.indexCount, BufferUsage.DynamicWriteOnly);
                ushort *pI = (ushort *)subMesh.indexData.indexBuffer.Lock(BufferLocking.Discard);
                for (ushort i = 0; i < quadCount; i++)
                {
                    ushort ofset = (ushort)(i * 4);
                    *      pI++  = (ushort)(0 + ofset);
                    *      pI++  = (ushort)(2 + ofset);
                    *      pI++  = (ushort)(1 + ofset);

                    *pI++ = (ushort)(1 + ofset);
                    *pI++ = (ushort)(2 + ofset);
                    *pI++ = (ushort)(3 + ofset);
                }

                subMesh.indexData.indexBuffer.Unlock();
                //Finish up mesh
                AxisAlignedBox bounds = new AxisAlignedBox(
                    new Vector3(page.Bounds.Left - page.CenterPoint.x, minY, page.Bounds.Top - page.CenterPoint.z),
                    new Vector3(page.Bounds.Right - page.CenterPoint.x, maxY, page.Bounds.Bottom - page.CenterPoint.z));

                mesh.BoundingBox = bounds;
                Vector3 tmp = bounds.Maximum - bounds.Minimum;
                mesh.BoundingSphereRadius = tmp.Length * 0.5f;
                mesh.Load();
                //Apply grass material to mesh
                subMesh.MaterialName = layer.Material.Name;

                //Return the mesh
                return(mesh);
            }
        }
Example #26
0
        protected void EnsureObjectsCreated()
        {
            ClearCreatedObjects();
            Texture prototypeTexture = null;

            if (useTextures)
            {
                prototypeMaterial = MaterialManager.Instance.Load("barrel.barrel");
                if (uniqueTextures)
                {
                    prototypeTexture = TextureManager.Instance.Load("blank.dds");
                }
            }
            else
            {
                prototypeMaterial = MaterialManager.Instance.Load("unit_box.unit_box");
            }
            prototypeMaterial.Compile();
            if (objectCount == 0)
            {
                return;
            }
            int materialCount = (animatedObjects ? 0 :
                                 (numObjectsSharingMaterial == 0 ? objectCount :
                                  (numObjectsSharingMaterial >= objectCount ? 1 :
                                   (objectCount + numObjectsSharingMaterial - 1) / numObjectsSharingMaterial)));

            materialCountLabel.Text = "Material Count: " + materialCount;
            if (whichObjects == WhichObjectsEnum.woPlane || whichObjects == WhichObjectsEnum.woRandom)
            {
                Mesh plane = meshes[(int)WhichObjectsEnum.woPlane];
                if (plane != null)
                {
                    plane.Unload();
                }
                // Create the plane
                float planeSide  = 1000f;
                int   planeUnits = Int32.Parse(planeUnitsTextBox.Text);
                plane = MeshManager.Instance.CreatePlane("testerPlane", new Plane(Vector3.UnitZ, Vector3.Zero), planeSide, planeSide, planeUnits, planeUnits, true,
                                                         1, planeSide / planeUnits, planeSide / planeUnits, Vector3.UnitY);
                meshes[(int)WhichObjectsEnum.woPlane] = plane;
            }
            // Create the new materials
            for (int i = 0; i < materialCount; i++)
            {
                Material mat = prototypeMaterial.Clone("mat" + i);
                Pass     p   = mat.GetTechnique(0).GetPass(0);
                if (!animatedObjects && uniqueTextures)
                {
                    Texture t       = prototypeTexture;
                    Texture texture = TextureManager.Instance.CreateManual("texture" + i, t.TextureType, t.Width, t.Height, t.NumMipMaps, t.Format, t.Usage);
                    textureList.Add(texture);
                    p.CreateTextureUnitState(texture.Name);
                }
                // Make the materials lovely shades of blue
                p.Ambient  = new ColorEx(1f, .2f, .2f, (1f / materialCount) * i);
                p.Diffuse  = new ColorEx(p.Ambient);
                p.Specular = new ColorEx(1f, 0f, 0f, 0f);
                materialList.Add(mat);
            }

            // Create the entities and scene nodes
            for (int i = 0; i < objectCount; i++)
            {
                Mesh     mesh = selectMesh();
                Material mat  = null;
                if (materialCount > 0)
                {
                    mat = materialList[i % materialCount];
                }
                Entity entity = scene.CreateEntity("entity" + i, mesh);
                if (animatedObjects)
                {
                    string[] visibleSubs = visibleSubMeshes[(int)whichObjects - (int)WhichObjectsEnum.woZombie];
                    for (int j = 0; j < entity.SubEntityCount; ++j)
                    {
                        SubEntity sub     = entity.GetSubEntity(j);
                        bool      visible = false;
                        foreach (string s in visibleSubs)
                        {
                            if (s == sub.SubMesh.Name)
                            {
                                visible = true;
                                break;
                            }
                        }
                        sub.IsVisible = visible;
                        if (visible)
                        {
                            totalVertexCount += sub.SubMesh.VertexData.vertexCount;
                        }
                    }
                }
                else
                {
                    if (mesh.SharedVertexData != null)
                    {
                        totalVertexCount += mesh.SharedVertexData.vertexCount;
                    }
                    else
                    {
                        for (int j = 0; j < mesh.SubMeshCount; j++)
                        {
                            SubMesh subMesh = mesh.GetSubMesh(j);
                            totalVertexCount += subMesh.VertexData.vertexCount;
                        }
                    }
                }
                if (animatedObjects && animateCheckBox.Checked)
                {
                    AnimationState currentAnimation = entity.GetAnimationState(GetAnimationName());
                    currentAnimation.IsEnabled = true;
                    if (!animationInitialized)
                    {
                        currentAnimationLength = entity.GetAnimationState(GetAnimationName()).Length;
                        animationInitialized   = true;
                    }
                }
                if (mat != null)
                {
                    entity.MaterialName = mat.Name;
                }
                entityList.Add(entity);
                SceneNode node = scene.RootSceneNode.CreateChildSceneNode();
                sceneNodeList.Add(node);
                node.AttachObject(entity);
                node.Position = new Vector3(randomCoord(), randomCoord(), randomCoord());
                if (randomSizes)
                {
                    node.ScaleFactor = Vector3.UnitScale * randomScale();
                }
                else if (randomScales)
                {
                    node.ScaleFactor = new Vector3(randomScale(), randomScale(), randomScale());
                }
                else
                {
                    node.ScaleFactor = Vector3.UnitScale * 1f;
                }
                if (randomOrientations)
                {
                    Vector3 axis = new Vector3((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
                    node.Orientation = Vector3.UnitY.GetRotationTo(axis.ToNormalized());
                }
                else
                {
                    node.Orientation = Quaternion.Identity;
                }
            }
        }
Example #27
0
    static void SaveLWO(bool exportUV)
    {
        // Error check
        if (Selection.activeTransform == null)
        {
            Debug.LogWarning("Please select the model you want to export");
            return;
        }

        // Get stuff
        GameObject parent    = Selection.activeTransform.gameObject;
        string     modelName = parent.name;

        MeshRenderer[] meshRenderers = parent.GetComponentsInChildren <MeshRenderer>();

        // Loop through stuff
        List <Material> surfaces     = new List <Material>();
        List <string>   surfaceNames = new List <string>();
        CustomMesh      mesh         = new CustomMesh();
        int             vertBoost    = 0;

        for (int i = 0; i < meshRenderers.Length; i++)
        {
            // Get MeshFilter
            MeshFilter meshFilter = meshRenderers[i].gameObject.GetComponent <MeshFilter>();
            if (meshFilter.sharedMesh.subMeshCount != meshRenderers[i].sharedMaterials.Length)
            {
                Debug.LogError("SubMesh count and material count don't match on " + meshRenderers[i].gameObject.name);
                return;
            }

            // Fill out surface lists
            foreach (Material material in meshRenderers[i].sharedMaterials)
            {
                // Moar error check
                if (material == null)
                {
                    Debug.LogError("Material slot is null on " + meshRenderers[i].gameObject.name);
                    return;
                }
                if (material.shader.name != "Rock Raiders" && material.shader.name != "Rock Raiders Transparent")
                {
                    Debug.LogError(material.name + " doesn't use a Rock Raiders shader");
                    return;
                }

                // Surface stuff
                if (!surfaceNames.Contains(material.name))
                {
                    surfaces.Add(material);
                    surfaceNames.Add(material.name);
                }
            }

            // Fill out our CustomMesh
            // verts
            foreach (Vector3 vertex in meshFilter.sharedMesh.vertices)
            {
                mesh.vertices.Add(meshFilter.gameObject.transform.TransformPoint(vertex));
            }
            // normals - these won't be exported, but used later for determining which verts to merge in the LWO, so the smoothing the game calculates is correct
            if (meshFilter.sharedMesh.normals.Length == 0)
            {
                // default normals - zero is fine for this, the actual value doesn't really matter, we're only gonna be checking if verts have equal normals to each other
                for (int j = 0; j < meshFilter.sharedMesh.vertices.Length; j++)
                {
                    mesh.normals.Add(Vector3.zero);
                }
            }
            else
            {
                // use normals if present
                foreach (Vector3 normal in meshFilter.sharedMesh.normals)
                {
                    mesh.normals.Add(normal);
                }
            }
            // UV
            if (meshFilter.sharedMesh.uv.Length == 0)
            {
                // default UVs
                for (int j = 0; j < meshFilter.sharedMesh.vertices.Length; j++)
                {
                    // these will be 0, 0 in the final UV file once flipped
                    mesh.uv.Add(new Vector2(0.0f, 1.0f));
                }
            }
            else
            {
                // use UVs if present
                foreach (Vector2 uv in meshFilter.sharedMesh.uv)
                {
                    mesh.uv.Add(uv);
                }
            }
            // tris/submeshes
            for (int j = 0; j < meshFilter.sharedMesh.subMeshCount; j++)
            {
                SubMesh subMesh = new SubMesh();
                subMesh.triangles = meshFilter.sharedMesh.GetTriangles(j);
                // reverse winding order for negative scale
                if (meshFilter.gameObject.transform.localToWorldMatrix.determinant < 0.0f)
                {
                    for (int k = 0; k < subMesh.triangles.Length; k += 3)
                    {
                        int temp = subMesh.triangles[k];
                        subMesh.triangles[k]     = subMesh.triangles[k + 2];
                        subMesh.triangles[k + 2] = temp;
                    }
                }
                // vert boost
                for (int k = 0; k < subMesh.triangles.Length; k++)
                {
                    subMesh.triangles[k] += vertBoost;
                }
                subMesh.material = meshRenderers[i].sharedMaterials[j];
                mesh.subMeshes.Add(subMesh);
            }
            vertBoost += meshFilter.sharedMesh.vertices.Length;
        }

        // make condensed list of verts with only those that have different positions and normals (no UV splits etc) - so only intentionally unwelded verts will be unwelded in the LWO
        List <Vertex> uniqueVerts = new List <Vertex>();

        int[] redirectArray = new int[mesh.vertices.Count];
        for (int i = 0; i < mesh.vertices.Count; i++)
        {
            Vertex vertex;
            vertex.position = mesh.vertices[i];
            vertex.normal   = mesh.normals[i];

            if (!uniqueVerts.Contains(vertex))
            {
                uniqueVerts.Add(vertex);
            }

            int newVertexIndex;
            int findResults = uniqueVerts.IndexOf(vertex);
            if (findResults == -1)
            {
                uniqueVerts.Add(vertex);
                newVertexIndex = uniqueVerts.Count - 1;
            }
            else
            {
                newVertexIndex = findResults;
            }
            redirectArray[i] = newVertexIndex;
        }

        // Get path
        string path = EditorUtility.SaveFilePanel("Save LWO", "", modelName + ".lwo", "lwo");

        if (string.IsNullOrEmpty(path))
        {
            return;
        }

        // Start writing stuff
        FileStream   fileStream   = new FileStream(path, FileMode.Create);
        BinaryWriter binaryWriter = new BinaryWriter2(fileStream);
        long         rememberMe;

        binaryWriter.Write("FORMtempLWOB".ToCharArray());

        // PNTS
        binaryWriter.Write("PNTS".ToCharArray());
        // Temp length
        binaryWriter.Write("temp".ToCharArray());
        rememberMe = fileStream.Position;
        foreach (Vertex vertex in uniqueVerts)
        {
            binaryWriter.Write(-vertex.position.x);
            binaryWriter.Write(vertex.position.y);
            binaryWriter.Write(-vertex.position.z);
        }
        FinishWritingChunk(fileStream, binaryWriter, rememberMe);

        // SRFS
        binaryWriter.Write("SRFS".ToCharArray());
        // Temp length
        binaryWriter.Write("temp".ToCharArray());
        rememberMe = fileStream.Position;
        foreach (string surfaceName in surfaceNames)
        {
            binaryWriter.Write(surfaceName.ToCharArray());
            binaryWriter.Write('\0');
            // padding
            if (surfaceName.Length % 2 == 0)
            {
                binaryWriter.Write('\0');
            }
        }
        FinishWritingChunk(fileStream, binaryWriter, rememberMe);

        // POLS
        binaryWriter.Write("POLS".ToCharArray());
        // Temp length
        binaryWriter.Write("temp".ToCharArray());
        rememberMe = fileStream.Position;
        for (int i = 0; i < mesh.subMeshes.Count; i++)
        {
            int   surfaceIndex = surfaceNames.IndexOf(mesh.subMeshes[i].material.name) + 1;
            int[] tris         = mesh.subMeshes[i].triangles;
            for (int j = 0; j < tris.Length; j += 3)
            {
                binaryWriter.Write((UInt16)3);                 // How many verts
                binaryWriter.Write((UInt16)redirectArray[tris[j]]);
                binaryWriter.Write((UInt16)redirectArray[tris[j + 1]]);
                binaryWriter.Write((UInt16)redirectArray[tris[j + 2]]);
                binaryWriter.Write((UInt16)surfaceIndex);
            }
        }
        FinishWritingChunk(fileStream, binaryWriter, rememberMe);

        // SURFs
        foreach (Material surface in surfaces)
        {
            binaryWriter.Write("SURF".ToCharArray());
            // Temp length
            binaryWriter.Write("temp".ToCharArray());
            rememberMe = fileStream.Position;
            binaryWriter.Write(surface.name.ToCharArray());
            binaryWriter.Write('\0');
            // padding
            if (surface.name.Length % 2 == 0)
            {
                binaryWriter.Write('\0');
            }

            // COLR
            binaryWriter.Write("COLR".ToCharArray());
            binaryWriter.Write((UInt16)4);
            Color32 color = (Color32)surface.GetColor("_Color");
            binaryWriter.Write(color.r);
            binaryWriter.Write(color.g);
            binaryWriter.Write(color.b);
            binaryWriter.Write((byte)0);

            // FLAG
            binaryWriter.Write("FLAG".ToCharArray());
            binaryWriter.Write((UInt16)2);
            int flag = 0;
            if (surface.GetFloat("_Luminosity") != 0.0f)
            {
                flag++;
            }
            flag += 4;             // smoothing
            if (surface.GetFloat("_Additive") != 0.0f)
            {
                flag += 512;
            }
            binaryWriter.Write((UInt16)flag);

            // DIFF
            if (surface.GetFloat("_Diffuse") != 0.0f)
            {
                binaryWriter.Write("DIFF".ToCharArray());
                binaryWriter.Write((UInt16)2);
                binaryWriter.Write((UInt16)(surface.GetFloat("_Diffuse") * 256.0f));
            }

            // TRAN
            if (surface.GetFloat("_Transparency") != 0.0f)
            {
                binaryWriter.Write("TRAN".ToCharArray());
                binaryWriter.Write((UInt16)2);
                binaryWriter.Write((UInt16)(surface.GetFloat("_Transparency") * 256.0f));
            }

            // LUMI
            if (surface.GetFloat("_Luminosity") != 0.0f)
            {
                binaryWriter.Write("LUMI".ToCharArray());
                binaryWriter.Write((UInt16)2);
                binaryWriter.Write((UInt16)(surface.GetFloat("_Luminosity") * 256.0f));
            }

            if (!exportUV && surface.GetTexture("_MainTex") != null)
            {
                // CTEX
                binaryWriter.Write("CTEX".ToCharArray());
                binaryWriter.Write((UInt16)18);
                binaryWriter.Write("Planar Image Map".ToCharArray());
                binaryWriter.Write('\0');
                binaryWriter.Write('\0');

                // TIMG
                binaryWriter.Write("TIMG".ToCharArray());
                // Temp length
                binaryWriter.Write("te".ToCharArray());
                long   rememberMe2 = fileStream.Position;
                string texturePath = null;
                string sequence;
                if (surface.GetFloat("_Sequence") != 0.0f)
                {
                    sequence = " (sequence)";
                }
                else
                {
                    sequence = "";
                }
                if (surface.GetFloat("_SharedTexture") != 0.0f)
                {
                    texturePath = @"\\dummy\" + surface.GetTexture("_MainTex").name + ".bmp" + sequence;
                }
                else
                {
                    texturePath = @"D:\dummy\" + surface.GetTexture("_MainTex").name + ".bmp" + sequence;
                }
                binaryWriter.Write(texturePath.ToCharArray());
                binaryWriter.Write('\0');
                // padding
                if (texturePath.Length % 2 == 0)
                {
                    binaryWriter.Write('\0');
                }
                FinishWritingSurfChunk(fileStream, binaryWriter, rememberMe2);

                // TFLG
                binaryWriter.Write("TFLG".ToCharArray());
                binaryWriter.Write((UInt16)2);
                int textureFlag = 0;
                if (surface.GetFloat("_X") != 0.0f)
                {
                    textureFlag++;
                }
                else if (surface.GetFloat("_Y") != 0.0f)
                {
                    textureFlag += 2;
                }
                else if (surface.GetFloat("_Z") != 0.0f)
                {
                    textureFlag += 4;
                }
                else
                {
                    // default to z like the game seems to do if none are specified
                    textureFlag += 4;
                }
                if (surface.GetFloat("_PixelBlending") != 0.0f)
                {
                    textureFlag += 32;
                }
                binaryWriter.Write((UInt16)textureFlag);

                // TSIZ
                binaryWriter.Write("TSIZ".ToCharArray());
                binaryWriter.Write((UInt16)12);
                binaryWriter.Write(surface.GetFloat("_TextureSizeX"));
                binaryWriter.Write(surface.GetFloat("_TextureSizeY"));
                binaryWriter.Write(surface.GetFloat("_TextureSizeZ"));

                // TCTR
                binaryWriter.Write("TCTR".ToCharArray());
                binaryWriter.Write((UInt16)12);
                binaryWriter.Write(surface.GetFloat("_TextureCenterX"));
                binaryWriter.Write(surface.GetFloat("_TextureCenterY"));
                binaryWriter.Write(surface.GetFloat("_TextureCenterZ"));
            }

            FinishWritingChunk(fileStream, binaryWriter, rememberMe);
        }

        // Final length
        fileStream.Seek(4, SeekOrigin.Begin);
        binaryWriter.Write((UInt32)(fileStream.Length - 8));

        binaryWriter.Close();
        fileStream.Close();

        Debug.Log("Saved file " + path);



        // UV TIME
        if (!exportUV)
        {
            return;
        }

        StringBuilder uvString = new StringBuilder();

        uvString.Append("2\n");
        uvString.Append(surfaces.Count).Append("\n");
        foreach (string surfaceName in surfaceNames)
        {
            uvString.Append(surfaceName).Append("\n");
        }
        foreach (Material surface in surfaces)
        {
            string texturePath;
            string sequence;
            if (surface.GetFloat("_Sequence") != 0.0f)
            {
                sequence = " (sequence)";
            }
            else
            {
                sequence = "";
            }
            if (surface.GetTexture("_MainTex") == null)
            {
                texturePath = "NULL";
            }
            else if (surface.GetFloat("_SharedTexture") != 0.0f)
            {
                texturePath = @"\\dummy\" + surface.GetTexture("_MainTex").name + ".bmp" + sequence;
            }
            else
            {
                texturePath = @"D:\dummy\" + surface.GetTexture("_MainTex").name + ".bmp" + sequence;
            }
            uvString.Append(texturePath).Append("\n");
        }
        int totalIndexCount = 0;

        foreach (SubMesh subMesh in mesh.subMeshes)
        {
            totalIndexCount += subMesh.triangles.Length;
        }
        uvString.Append(totalIndexCount / 3).Append("\n");
        int whatever = 0;

        foreach (SubMesh subMesh in mesh.subMeshes)
        {
            for (int i = 0; i < subMesh.triangles.Length; i += 3)
            {
                uvString.Append(whatever).Append(" 3\n");
                uvString.Append(mesh.uv[subMesh.triangles[i]].x).Append(" ").Append(-mesh.uv[subMesh.triangles[i]].y + 1.0f).Append(" 0\n");
                uvString.Append(mesh.uv[subMesh.triangles[i + 1]].x).Append(" ").Append(-mesh.uv[subMesh.triangles[i + 1]].y + 1.0f).Append(" 0\n");
                uvString.Append(mesh.uv[subMesh.triangles[i + 2]].x).Append(" ").Append(-mesh.uv[subMesh.triangles[i + 2]].y + 1.0f).Append(" 0\n");
                whatever++;
            }
        }
        // dummy data
        for (int i = 0; i < surfaces.Count; i++)
        {
            uvString.Append("4\n0.000000 0.000000 0.000000\n0.000000 0.000000 0.000000\n0.000000 0.000000 0.000000\n1.000000 1.000000 1.000000\n");
        }

        string uvPath = Path.ChangeExtension(path, ".uv");

        File.WriteAllText(uvPath, uvString.ToString());
        Debug.Log("Saved file " + uvPath);
    }
        /// <summary>
        /// Apply all model combines and seal builder.
        /// </summary>
        public void Apply()
        {
            // Do nothing if sealed
            if (isSealed)
            {
                return;
            }

            // Count total vertices and indices
            int totalVertices = 0;
            int totalIndices  = 0;

            foreach (var item in builderDictionary)
            {
                totalVertices += item.Value.Vertices.Count;
                totalIndices  += item.Value.Indices.Count;
            }

            // Create combined data
            combinedModel           = new CombinedModel();
            combinedModel.Vertices  = new Vector3[totalVertices];
            combinedModel.Normals   = new Vector3[totalVertices];
            combinedModel.UVs       = new Vector2[totalVertices];
            combinedModel.Indices   = new int[totalIndices];
            combinedModel.SubMeshes = new SubMesh[builderDictionary.Count];

            // Populate static arrays
            int currentVertex = 0;
            int currentIndex  = 0;
            int subMeshIndex  = 0;

            foreach (var item in builderDictionary)
            {
                // Save current highest vertex and index
                int highestVertex = currentVertex;
                int highestIndex  = currentIndex;

                // Copy vertex data
                for (int i = 0; i < item.Value.Vertices.Count; i++)
                {
                    combinedModel.Vertices[currentVertex] = item.Value.Vertices[i];
                    combinedModel.Normals[currentVertex]  = item.Value.Normals[i];
                    combinedModel.UVs[currentVertex]      = item.Value.UVs[i];
                    currentVertex++;
                }

                // Copy index data
                for (int i = 0; i < item.Value.Indices.Count; i++)
                {
                    combinedModel.Indices[currentIndex++] = highestVertex + i;
                }

                // Add submesh
                int     frame;
                SubMesh sm = new SubMesh();
                sm.StartIndex     = highestIndex;
                sm.PrimitiveCount = item.Value.Indices.Count / 3;
                MaterialReader.ReverseTextureKey(item.Key, out sm.TextureArchive, out sm.TextureRecord, out frame);
                combinedModel.SubMeshes[subMeshIndex++] = sm;
            }

            Seal();
        }
Example #29
0
        public Mesh Import(string filename)
        {
            using (var importer = new AssimpContext())
            {
                //importer.AttachLogStream(new LogStream((msg, userData) =>
                //{
                //	Common.Log.WriteLine(msg);
                //}));

                var mesh = new Mesh();

                importer.SetConfig(new Assimp.Configs.VertexBoneWeightLimitConfig(4));
                //importer.ZAxisRotation = (float)(System.Math.PI / 2.0);

                var model = importer.ImportFile(filename, PostProcessSteps.CalculateTangentSpace | PostProcessSteps.Triangulate
                    | PostProcessSteps.GenerateNormals | PostProcessSteps.LimitBoneWeights | PostProcessSteps.GenerateUVCoords);

                foreach (var meshToImport in model.Meshes)
                {
                    // Validate sub mesh data
                    if (meshToImport.PrimitiveType != PrimitiveType.Triangle)
                    {
                        Common.Log.WriteLine("{0}:{1} invalid primitive type {2} should be Triangle", filename, meshToImport.Name, meshToImport.PrimitiveType);
                        continue;
                    }

                    if (!meshToImport.HasNormals)
                    {
                        Common.Log.WriteLine("{0}:{1} does not have any normals", filename, meshToImport.Name);
                        continue;
                    }

                    if (!meshToImport.HasTangentBasis)
                    {
                        Common.Log.WriteLine("{0}:{1} does not have any tangents", filename, meshToImport.Name);
                        continue;
                    }

                    if (meshToImport.TextureCoordinateChannelCount == 0)
                    {
                        Common.Log.WriteLine("{0}:{1} does not have any texture channels", filename, meshToImport.Name);
                        continue;
                    }

                    var subMesh = new SubMesh();
                    subMesh.BoundingSphereRadius = 0;

                    // Create vertex format
                    if (meshToImport.HasBones)
                    {
                        subMesh.VertexFormat = new Renderer.VertexFormat(new Renderer.VertexFormatElement[]
                        {
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Position, Renderer.VertexPointerType.Float, 3, 0),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Normal, Renderer.VertexPointerType.Float, 3, sizeof(float) * 3),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Tangent, Renderer.VertexPointerType.Float, 3, sizeof(float) * 6),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.TexCoord, Renderer.VertexPointerType.Float, 2, sizeof(float) * 9),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.BoneIndex, Renderer.VertexPointerType.Float, 4, sizeof(float) * 11),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.BoneWeight, Renderer.VertexPointerType.Float, 4, sizeof(float) * 15),
                        });
                    }
                    else
                    {
                        subMesh.VertexFormat = new Renderer.VertexFormat(new Renderer.VertexFormatElement[]
                        {
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Position, Renderer.VertexPointerType.Float, 3, 0),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Normal, Renderer.VertexPointerType.Float, 3, sizeof(float) * 3),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.Tangent, Renderer.VertexPointerType.Float, 3, sizeof(float) * 6),
                            new Renderer.VertexFormatElement(Renderer.VertexFormatSemantic.TexCoord, Renderer.VertexPointerType.Float, 2, sizeof(float) * 9),
                        });
                    }

                    subMesh.TriangleCount = meshToImport.FaceCount;

                    Vertex[] vertices = new Vertex[meshToImport.VertexCount];

                    var positions = meshToImport.Vertices;
                    var normals = meshToImport.Normals;
                    var tangents = meshToImport.Tangents;
                    var texCoords = meshToImport.TextureCoordinateChannels[0];

                    // Setup vertex data
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].Position = new Vector3(positions[i].X, positions[i].Y, positions[i].Z);
                        vertices[i].Normal = new Vector3(normals[i].X, normals[i].Y, normals[i].Z);
                        vertices[i].Tangent = new Vector3(tangents[i].X, tangents[i].Y, tangents[i].Z);
                        vertices[i].TexCoord = new Vector2(texCoords[i].X, texCoords[i].Y);

                        var length = vertices[i].Position.Length;
                        if (subMesh.BoundingSphereRadius < length)
                            subMesh.BoundingSphereRadius = length;
                    }

                    // Map bone weights if they are available
                    if (meshToImport.HasBones)
                    {
                        var bones = meshToImport.Bones;

                        for (var i = 0; i < bones.Count; i++)
                        {
                            var bone = bones[i];

                            if (!bone.HasVertexWeights)
                                continue;

                            foreach (var weight in bone.VertexWeights)
                            {
                                var index = weight.VertexID;

                                var vertex = vertices[index];

                                if (vertex.BoneCount == 0)
                                {
                                    vertex.BoneIndex.X = i;
                                    vertex.BoneWeight.X = weight.Weight;
                                }
                                else if (vertex.BoneCount == 1)
                                {
                                    vertex.BoneIndex.Y = i;
                                    vertex.BoneWeight.Y = weight.Weight;
                                }
                                else if (vertex.BoneCount == 2)
                                {
                                    vertex.BoneIndex.Z = i;
                                    vertex.BoneWeight.Z = weight.Weight;
                                }
                                else if (vertex.BoneCount == 3)
                                {
                                    vertex.BoneIndex.W = i;
                                    vertex.BoneWeight.W = weight.Weight;
                                }

                                vertex.BoneCount++;
                                vertices[index] = vertex;
                            }
                        }
                    }

                    using (var memStream = new MemoryStream(meshToImport.VertexCount * subMesh.VertexFormat.Size))
                    {
                        using (var writer = new BinaryWriter(memStream))
                        {
                            for (int i = 0; i < meshToImport.VertexCount; i++)
                            {
                                writer.Write(vertices[i].Position);
                                writer.Write(vertices[i].Normal);
                                writer.Write(vertices[i].Tangent);
                                writer.Write(vertices[i].TexCoord);

                                if (meshToImport.HasBones)
                                {
                                    writer.Write(vertices[i].BoneIndex);
                                    writer.Write(vertices[i].BoneWeight);
                                }
                            }

                            subMesh.Vertices = memStream.GetBuffer();
                        }
                    }

                    using (var memStream = new MemoryStream(meshToImport.VertexCount * subMesh.VertexFormat.Size))
                    {
                        using (var writer = new BinaryWriter(memStream))
                        {
                            var indices = meshToImport.GetIndices();
                            foreach (var index in indices)
                            {
                                writer.Write(index);
                            }
                            subMesh.Indices = memStream.GetBuffer();
                        }
                    }

                    if (model.HasMaterials)
                    {
                        var material = model.Materials[meshToImport.MaterialIndex].Name;

                        if (!material.StartsWith("/materials/"))
                        {
                            material = "/materials/" + material;
                        }

                        subMesh.Material = material;
                    }
                    else
                    {
                        subMesh.Material = "no_material";
                    }

                    mesh.SubMeshes.Add(subMesh);
                }

                return mesh;
            }
        }
Example #30
0
 void VertexUV(SubMesh data, CardShape shape, Vector3 pos, Vector2 uv)
 {
     data.AddVertex(pos, uv, Color.white);
 }
        private unsafe void UpdateGeometry()
        {
            DestroyGeometry();

            Curve positionCurve = GetPositionCurve();

            Curve radiusCurve = null;

            {
                bool existsSpecialRadius = false;
                foreach (MapCurvePoint point in Points)
                {
                    RenderableCurvePoint point2 = point as RenderableCurvePoint;
                    if (point2 != null && point2.OverrideRadius >= 0)
                    {
                        existsSpecialRadius = true;
                        break;
                    }
                }

                if (existsSpecialRadius)
                {
                    switch (radiusCurveType)
                    {
                    case RadiusCurveTypes.UniformCubicSpline:
                        radiusCurve = new UniformCubicSpline();
                        break;

                    case RadiusCurveTypes.Bezier:
                        radiusCurve = new BezierCurve();
                        break;

                    case RadiusCurveTypes.Line:
                        radiusCurve = new LineCurve();
                        break;
                    }

                    for (int n = 0; n < Points.Count; n++)
                    {
                        MapCurvePoint point = Points[n];

                        if (!point.Editor_IsExcludedFromWorld())
                        {
                            float rad = radius;
                            RenderableCurvePoint renderableCurvePoint = point as RenderableCurvePoint;
                            if (renderableCurvePoint != null && renderableCurvePoint.OverrideRadius >= 0)
                            {
                                rad = renderableCurvePoint.OverrideRadius;
                            }
                            radiusCurve.AddValue(point.Time, new Vec3(rad, 0, 0));
                        }
                    }
                }
            }

            //create mesh
            Vertex[] vertices = null;
            int[]    indices  = null;
            if (positionCurve != null && positionCurve.Values.Count > 1 && Points.Count >= 2)
            {
                Vec3 positionOffset = -Position;

                int steps       = (Points.Count - 1) * pathSteps + 1;
                int vertexCount = steps * (shapeSegments + 1);
                int indexCount  = (steps - 1) * shapeSegments * 2 * 3;

                vertices = new Vertex[vertexCount];
                indices  = new int[indexCount];

                //fill data
                {
                    int   currentVertex   = 0;
                    int   currentIndex    = 0;
                    float currentDistance = 0;
                    Vec3  lastPosition    = Vec3.Zero;
                    Quat  lastRot         = Quat.Identity;

                    for (int nStep = 0; nStep < steps; nStep++)
                    {
                        int startStepVertexIndex = currentVertex;

                        float coefficient = (float)nStep / (float)(steps - 1);
                        Vec3  pos         = CalculateCurvePointByCoefficient(coefficient) + positionOffset;

                        Quat rot;
                        {
                            Vec3 v = CalculateCurvePointByCoefficient(coefficient + .3f / (float)(steps - 1)) -
                                     CalculateCurvePointByCoefficient(coefficient);
                            if (v != Vec3.Zero)
                            {
                                rot = Quat.FromDirectionZAxisUp(v.GetNormalize());
                            }
                            else
                            {
                                rot = lastRot;
                            }
                        }

                        if (nStep != 0)
                        {
                            currentDistance += (pos - lastPosition).Length();
                        }

                        float rad;
                        if (radiusCurve != null)
                        {
                            Range range = new Range(radiusCurve.Times[0], radiusCurve.Times[radiusCurve.Times.Count - 1]);
                            float t     = range.Minimum + (range.Maximum - range.Minimum) * coefficient;
                            rad = radiusCurve.CalculateValueByTime(t).X;
                        }
                        else
                        {
                            rad = radius;
                        }

                        for (int nSegment = 0; nSegment < shapeSegments + 1; nSegment++)
                        {
                            float rotateCoefficient = ((float)nSegment / (float)(shapeSegments));
                            float angle             = rotateCoefficient * MathFunctions.PI * 2;
                            Vec3  p = pos + rot * new Vec3(0, MathFunctions.Cos(angle) * rad, MathFunctions.Sin(angle) * rad);

                            Vertex vertex = new Vertex();
                            vertex.position = p;
                            Vec3 pp = p - pos;
                            if (pp != Vec3.Zero)
                            {
                                vertex.normal = pp.GetNormalize();
                            }
                            else
                            {
                                vertex.normal = Vec3.XAxis;
                            }
                            //vertex.normal = ( p - pos ).GetNormalize();
                            vertex.texCoord           = new Vec2(currentDistance * textureCoordinatesTilesPerMeter, rotateCoefficient + .25f);
                            vertex.tangent            = new Vec4(rot.GetForward(), 1);
                            vertices[currentVertex++] = vertex;
                        }

                        if (nStep < steps - 1)
                        {
                            for (int nSegment = 0; nSegment < shapeSegments; nSegment++)
                            {
                                indices[currentIndex++] = startStepVertexIndex + nSegment;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + 1 + shapeSegments + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment + shapeSegments + 1;
                                indices[currentIndex++] = startStepVertexIndex + nSegment;
                            }
                        }

                        lastPosition = pos;
                        lastRot      = rot;
                    }
                    if (currentVertex != vertexCount)
                    {
                        Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentVertex != vertexCount.");
                    }
                    if (currentIndex != indexCount)
                    {
                        Log.Fatal("RenderableCurve: UpdateRenderingGeometry: currentIndex != indexCount.");
                    }
                }

                if (vertices.Length != 0 && indices.Length != 0)
                {
                    //create mesh
                    string meshName = MeshManager.Instance.GetUniqueName(
                        string.Format("__RenderableCurve_{0}_{1}", Name, uniqueMeshIdentifier));
                    uniqueMeshIdentifier++;
                    //string meshName = MeshManager.Instance.GetUniqueName( string.Format( "__RenderableCurve_{0}", Name ) );
                    mesh = MeshManager.Instance.CreateManual(meshName);
                    SubMesh subMesh = mesh.CreateSubMesh();
                    subMesh.UseSharedVertices = false;

                    //init vertexData
                    VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration;
                    declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position);
                    declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal);
                    declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0);
                    declaration.AddElement(0, 32, VertexElementType.Float4, VertexElementSemantic.Tangent, 0);

                    fixed(Vertex *pVertices = vertices)
                    {
                        subMesh.VertexData = VertexData.CreateFromArray(declaration, (IntPtr)pVertices,
                                                                        vertices.Length * Marshal.SizeOf(typeof(Vertex)));
                    }

                    subMesh.IndexData = IndexData.CreateFromArray(indices, 0, indices.Length, false);

                    //set material
                    subMesh.MaterialName = materialName;

                    //set mesh gabarites
                    Bounds bounds = Bounds.Cleared;
                    foreach (Vertex vertex in vertices)
                    {
                        bounds.Add(vertex.position);
                    }
                    mesh.SetBoundsAndRadius(bounds, bounds.GetRadius());
                }
            }

            //create MeshObject, SceneNode
            if (mesh != null)
            {
                meshObject = SceneManager.Instance.CreateMeshObject(mesh.Name);
                if (meshObject != null)
                {
                    meshObject.SetMaterialNameForAllSubObjects(materialName);
                    meshObject.CastShadows = true;

                    sceneNode = new SceneNode();
                    sceneNode.Attach(meshObject);
                    //apply offset
                    sceneNode.Position = Position;
                    MapObject.AssociateSceneNodeWithMapObject(sceneNode, this);
                }
            }

            //create collision body
            if (mesh != null && collision)
            {
                Vec3[] positions = new Vec3[vertices.Length];
                for (int n = 0; n < vertices.Length; n++)
                {
                    positions[n] = vertices[n].position;
                }
                string meshPhysicsMeshName = PhysicsWorld.Instance.AddCustomMeshGeometry(positions, indices, null,
                                                                                         MeshShape.MeshTypes.TriangleMesh, 0, 0);

                collisionBody                   = PhysicsWorld.Instance.CreateBody();
                collisionBody.Static            = true;
                collisionBody._InternalUserData = this;
                collisionBody.Position          = Position;

                MeshShape shape = collisionBody.CreateMeshShape();
                shape.MeshName     = meshPhysicsMeshName;
                shape.MaterialName = CollisionMaterialName;
                shape.ContactGroup = (int)ContactGroup.Collision;
                //shape.VehicleDrivableSurface = collisionVehicleDrivableSurface;

                collisionBody.PushedToWorld = true;
            }

            needUpdate = false;
        }
Example #32
0
        private static void ToAssimp(Module.Export.Assimp.Context context, Scene scene, Module.Export.Assimp.Mesh mesh_indexes, aiMesh assimp_mesh)
        {
            Mesh mesh = scene.meshes[mesh_indexes.mesh];

            assimp_mesh.mMaterialIndex = (uint)mesh_indexes.material;

            using (aiString assimp_mesh_name = new aiString(mesh.name))
            {
                assimp_mesh.mName = assimp_mesh_name.Unmanaged();
            }

            if (mesh.vertices.Length > 0)
            {
                using (aiVector3DArray vertices = assimp_mesh.Vertices)
                {
                    Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Vector3, mesh.vertices, vertices);
                }
            }
            if (mesh.normals.Length > 0)
            {
                using (aiVector3DArray normals = assimp_mesh.Normals)
                {
                    Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Vector3, mesh.normals, normals);
                }
            }
            if (mesh.tangents.Length > 0)
            {
                using (aiVector3DArray tangents = assimp_mesh.Tangents)
                {
                    Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Tangent, mesh.tangents, tangents);
                }
            }
            if (mesh_indexes.submesh < mesh.submeshes.Length)
            {
                // Support for submeshes: this mesh represent only one submesh of the original mesh
                SubMesh sub_mesh = mesh.submeshes[mesh_indexes.submesh];

                if (sub_mesh != null && sub_mesh.triangles != null && sub_mesh.triangles.Length > 0)
                {
                    using (aiFaceArray faces = assimp_mesh.Faces)
                    {
                        Assimp.Convert.UnityToAssimp.Face(sub_mesh.triangles, sub_mesh.topology, faces);
                    }
                }
            }
            if (mesh.uv1.Length > 0 || mesh.uv2.Length > 0)
            {
                using (aiVector3DMultiArray texture_coords = assimp_mesh.TextureCoords)
                {
                    if (mesh.uv1.Length > 0)
                    {
                        using (aiVector3DArray texture_coords0 = texture_coords.Get(0))
                        {
                            Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.UV, mesh.uv1, texture_coords0);
                        }
                    }

                    if (mesh.uv2.Length > 0)
                    {
                        using (aiVector3DArray texture_coords1 = texture_coords.Get(1))
                        {
                            Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.UV, mesh.uv2, texture_coords1);
                        }
                    }
                }
            }
            if (mesh.colors.Length > 0)
            {
                using (aiColor4DMultiArray colors = assimp_mesh.Colors)
                {
                    using (aiColor4DArray colors0 = colors.Get(0))
                    {
                        Assimp.Convert.UnityToAssimp.Array(Assimp.Convert.UnityToAssimp.Color, mesh.colors, colors0);
                    }
                }
            }

            context.progress.Update(ASSIMP_PROGRESS_FACTOR);
        }
Example #33
0
        public static Shape SaveShape(FSHP fshp)
        {
            Shape Shape = new Shape();

            Shape.VertexSkinCount   = (byte)fshp.VertexSkinCount;
            Shape.Flags             = ShapeFlags.HasVertexBuffer;
            Shape.BoneIndex         = (ushort)fshp.BoneIndex;
            Shape.MaterialIndex     = (ushort)fshp.MaterialIndex;
            Shape.VertexBufferIndex = (ushort)fshp.VertexBufferIndex;
            Shape.KeyShapes         = new List <KeyShape>();
            Shape.KeyShapeDict      = new ResDict();
            Shape.Name = fshp.Text;
            Shape.TargetAttribCount = (byte)fshp.TargetAttribCount;
            Shape.SkinBoneIndices   = fshp.BoneIndices;
            Shape.SubMeshBoundings  = new List <Bounding>();
            Shape.RadiusArray       = new List <float>();
            Shape.RadiusArray       = fshp.boundingRadius;

            Shape.Meshes = new List <Mesh>();

            foreach (FSHP.BoundingBox box in fshp.boundingBoxes)
            {
                Bounding bnd = new Bounding();
                bnd.Center = new Syroot.Maths.Vector3F(box.Center.X, box.Center.Y, box.Center.Z);
                bnd.Extent = new Syroot.Maths.Vector3F(box.Extend.X, box.Extend.Y, box.Extend.Z);
                Shape.SubMeshBoundings.Add(bnd);
            }

            foreach (FSHP.LOD_Mesh mesh in fshp.lodMeshes)
            {
                Mesh msh = new Mesh();
                msh.MemoryPool    = new MemoryPool();
                msh.SubMeshes     = new List <SubMesh>();
                msh.PrimitiveType = (PrimitiveType)mesh.PrimitiveType;
                msh.FirstVertex   = mesh.FirstVertex;

                foreach (FSHP.LOD_Mesh.SubMesh sub in mesh.subMeshes)
                {
                    SubMesh subMesh = new SubMesh();
                    subMesh.Offset = sub.offset;
                    subMesh.Count  = (uint)mesh.faces.Count;
                    msh.SubMeshes.Add(subMesh);
                }

                IList <uint> faceList = new List <uint>();
                foreach (int f in mesh.faces)
                {
                    faceList.Add((uint)f);
                }
                if (faceList.Count > 65000)
                {
                    MessageBox.Show($"Warning! Your poly count for a single mesh {fshp.Text} is pretty high! ({faceList.Count})." +
                                    $" You may want to split this!");
                    msh.SetIndices(faceList, IndexFormat.UInt32);
                }
                else
                {
                    msh.SetIndices(faceList, IndexFormat.UInt16);
                }

                Shape.Meshes.Add(msh);
                break;
            }
            return(Shape);
        }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="parent"></param>
            /// <param name="ent"></param>
            public SubBatch(BatchedGeometry parent, SubEntity ent) {
                mMeshType = ent.SubMesh;
                mParent = parent;
                mBuild = false;
                mRequireVertexColors = false;
                // Material must always exist
                Material origMat = (Material)MaterialManager.Instance.GetByName(ent.MaterialName);
                if (origMat != null) {
                    material = (Material)MaterialManager.Instance.GetByName(GetMaterialClone(origMat).Name);
                }
                else {
                    Tuple<Resource, bool> result = MaterialManager.Instance.CreateOrRetrieve("PagedGeometry_Batched_Material", "General");
                    if (result.First == null)
                        throw new Exception("BatchedGeometry failed to create a material for entity with invalid material.");

                    material = (Material)result.First;
                }

                //Setup vertex/index data structure
                vertexData = mMeshType.vertexData.Clone(false);
                indexData = mMeshType.indexData.Clone(false);

                //Remove blend weights from vertex format
                VertexElement blendIndices = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendIndices);
                VertexElement blendWeights = vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendWeights);

                if (blendIndices != null && blendWeights != null) {
                    Debug.Assert(blendIndices.Source == blendWeights.Source, "Blend indices and weights should be in the same buffer");
                    Debug.Assert(blendIndices.Size + blendWeights.Size == vertexData.vertexBufferBinding.GetBuffer(blendIndices.Source).VertexSize,
                        "Blend indices and blend buffers should have buffer to themselves!");

                    //Remove the blend weights
                    vertexData.vertexBufferBinding.UnsetBinding(blendIndices.Source);
                    vertexData.vertexDeclaration.RemoveElement(VertexElementSemantic.BlendIndices);
                    vertexData.vertexDeclaration.RemoveElement(VertexElementSemantic.BlendWeights);
                }

                //Reset vertex/index count
                vertexData.vertexStart = 0;
                vertexData.vertexCount = 0;
                indexData.indexStart = 0;
                indexData.indexCount = 0;
            }
Example #35
0
    public void Rebuild()
    {
        if (!IsValid())
        {
            Debug.LogError("The card definition is not valid.");
            return;
        }

        Stock.Validate();

        Dictionary <Texture2D, SubMesh> table = new Dictionary <Texture2D, SubMesh>();

        CardMesh  card  = new CardMesh();
        CardShape paper = Definition.Atlas.FindById(Definition.Stock.Paper);

        if (paper == null)
        {
            Debug.LogError("Paper does not exist in atlas = " + Definition.Atlas.name + "::" + Definition.Stock.Paper);
            return;
        }
        SubMesh data = GetMesh(card, table, paper);

        float x = Stock.Size.x / 2;
        float y = Stock.Size.y / 2;

        float   cx = x - Stock.Border.x;
        float   cy = y - Stock.Border.y;
        Vector3 v0 = new Vector2(-cx, +cy);        // middle
        Vector3 v1 = new Vector2(+cx, +cy);
        Vector3 v2 = new Vector2(+cx, -cy);
        Vector3 v3 = new Vector2(-cx, -cy);
        Vector3 v4 = new Vector2(-cx, +y);         // top edge
        Vector3 v5 = new Vector2(+cx, +y);
        Vector3 v6 = new Vector2(+x, +cy);         // right edge
        Vector3 v7 = new Vector2(+x, -cy);
        Vector3 v8 = new Vector2(+cx, -y);         // bot edge
        Vector3 v9 = new Vector2(-cx, -y);
        Vector3 vA = new Vector2(-x, -cy);         // left edge
        Vector3 vB = new Vector2(-x, +cy);
        //   4  5
        // B 0  1 6
        //   C  D
        // A 3  2 7
        //   9  8
        Vector3 vC = new Vector2(-cx, 0);        // mid
        Vector3 vD = new Vector2(+cx, 0);

        if (Stock.Smooth > 0)
        {
            // middle
            Square4(data, paper, v0, v1, v2, v3, Color.white, false, false);
            // top
            Square4(data, paper, v4, v5, v1, v0, Color.white, false, false);
            // right
            Square4(data, paper, v1, v6, v7, v2, Color.white, false, false);
            // bottom
            Square4(data, paper, v3, v2, v8, v9, Color.white, false, false);
            // left
            Square4(data, paper, vB, v0, v3, vA, Color.white, false, false);

            BuildCorner3(data, paper, v0, vB, v4);
            BuildCorner3(data, paper, v1, v5, v6);
            BuildCorner3(data, paper, v2, v7, v8);
            BuildCorner3(data, paper, v3, v9, vA);
        }
        else         // simple rectangle
        {
            Vector3 p1 = new Vector3(-x, +y, 0);
            Vector3 p2 = new Vector3(+x, +y, 0);
            Vector3 p3 = new Vector3(+x, -y, 0);
            Vector3 p4 = new Vector3(-x, -y, 0);
            Square4(data, paper, p1, p2, p3, p4, Color.white, false, false);
        }

        Vector2 textSize = new Vector2(0.175f, 0.175f);
        Vector2 symSize  = new Vector2(0.25f, 0.25f);
        float   symW     = symSize.x * 0.5f;
        float   symH     = symSize.y * 0.5f;
        float   rimX     = Mathf.Max(textSize.x, symW);
        float   rimY     = Mathf.Max(textSize.y, symH);

        CardShape symbol = Atlas.FindById(Definition.Symbol);

        if (symbol == null && !string.IsNullOrEmpty(Definition.Symbol))
        {
            Debug.LogError(string.Format("Symbol shape '{0}' is not defined in atlas.", Definition.Symbol));
        }
        CardShape fullImage = Definition.FullImage ? Atlas.FindById(Definition.Image) : null;
        CardShape halfImage = !Definition.FullImage ? Atlas.FindById(Definition.Image) : null;

        if (fullImage != null)
        {
            SubMesh core = GetMesh(card, table, fullImage);
            Square4(core, fullImage, v0, v1, v2, v3, Color.white, false, false);
        }
        else if (halfImage != null)
        {
            SubMesh core = GetMesh(card, table, halfImage);
            Vector3 lift = new Vector3(0, 0, -0.01f);
            Square4(core, halfImage, v0 + lift, v1 + lift, vD + lift, vC + lift, Color.white, false, false);
            Square4(core, halfImage, vC + lift, vD + lift, v2 + lift, v3 + lift, Color.white, true, true);
        }
        else if (Definition.Pattern != 0 && symbol != null)
        {
            if (Definition.Pattern >= 1 && Definition.Pattern < patternBits.Length)
            {
                SubMesh core  = GetMesh(card, table, symbol);
                Vector2 ssize = symSize;
                int     bits  = patternBits[Definition.Pattern];
                float   x0    = -x + Stock.Border.x;
                float   x1    = +x - Stock.Border.x;
                float   y0    = +y - Stock.Border.y;
                float   y1    = -y + Stock.Border.y;
                for (int b = 0; b < 17; b++)
                {
                    if ((bits & (1 << b)) != 0)
                    {
                        float px    = Mathf.Lerp(x0, x1, patternPos[b].x);
                        float py    = Mathf.Lerp(y0, y1, patternPos[b].y);
                        float scale = (Definition.Pattern == 1) ? 2.5f:1;
                        Square(core, symbol, new Vector3(px, py, -0.01f), scale * ssize, Color.white);
                    }
                }
            }
            else
            {
                Debug.LogError(string.Format("Pattern value '{0}' is not valid.", Definition.Pattern));
            }
        }

        CardShape text = Atlas.FindById(Definition.Text);

        if (text == null && !string.IsNullOrEmpty(Definition.Text))
        {
            Debug.LogError(string.Format("Text shape '{0}' is not defined in atlas.", Definition.Text));
        }
        if (text != null)
        {
            SubMesh sub   = GetMesh(card, table, text);
            float   x0    = -x + (Stock.Border.x + rimX) * 0.5f;
            float   x1    = +x - (Stock.Border.x + rimX) * 0.5f;
            float   y0    = +y - Stock.Border.y;
            float   y1    = -y + Stock.Border.y;
            Color   color = GetSymbolColor(Definition.Symbol);
            Square(sub, text, new Vector3(x0, y0, -0.01f), textSize, color);
            Square(sub, text, new Vector3(x1, y1, -0.01f), textSize, color);
        }
        if (symbol != null)
        {
            SubMesh sub   = GetMesh(card, table, symbol);
            Vector2 ssize = symSize * 0.5f;
            float   gapY  = ssize.y / 3;
            float   x0    = -x + (Stock.Border.x + rimX) * 0.5f;
            float   x1    = +x - (Stock.Border.x + rimX) * 0.5f;
            float   y0    = +y - Stock.Border.y - textSize.y - gapY - ssize.y;
            float   y1    = -y + Stock.Border.y + textSize.y + gapY + ssize.y;
            Color   color = GetSymbolColor(Definition.Symbol);
            Square(sub, symbol, new Vector3(x0, y0, -0.01f), ssize, color);
            Square(sub, symbol, new Vector3(x1, y1, -0.01f), ssize, color);
        }

        if (Stock.TwoSided)
        {
            CardShape back = Atlas.FindById(Stock.Back);
            if (back != null)
            {
                SubMesh core = GetMesh(card, table, back);
                // middle
                Square4(core, back, v1, v0, vC, vD, Color.white, false, false);
                Square4(core, back, vD, vC, v3, v2, Color.white, true, true);
                // top
                Square4(core, paper, v5, v4, v0, v1, Color.white, false, false);
                // back-left
                Square5(core, paper, v2, v7, v6, v1, vD, Color.white, false);
                // bottom
                Square4(core, paper, v2, v3, v9, v8, Color.white, false, false);
                // back-right
                Square5(core, paper, v0, vB, vA, v3, vC, Color.white, false);

                BuildCorner3(core, paper, v1, v6, v5);
                BuildCorner3(core, paper, v2, v8, v7);
                BuildCorner3(core, paper, v3, vA, v9);
                BuildCorner3(core, paper, v0, v4, vB);
            }
        }

        Mesh mesh = SetupMesh();

        mesh.vertices  = card.GetCombinedVertices().ToArray();
        mesh.triangles = data.IndexList.ToArray();
        mesh.uv        = card.GetCombinedTexCoords().ToArray();
        mesh.colors    = card.GetCombinedColors().ToArray();

        if (card.MeshList.Count > 1)
        {
            mesh.subMeshCount = card.MeshList.Count;
            int vbase = 0;
            for (int i = 1; i < card.MeshList.Count; ++i)
            {
                SubMesh sub  = card.MeshList[i];
                int []  tris = sub.IndexList.ToArray();
                vbase += card.MeshList[i - 1].VertexList.Count;
                for (int t = 0; t < tris.Length; ++t)
                {
                    tris[t] += vbase;
                }
                mesh.SetTriangles(tris, i);
            }
        }

        mesh.RecalculateBounds();
        mesh.Optimize();
        mesh.RecalculateNormals();

        this.GetComponent <Renderer>().sharedMaterials = card.Materials.ToArray();
    }
        /// <summary>
        /// Apply all model combines and seal builder.
        /// </summary>
        public void Apply()
        {
            // Do nothing if sealed
            if (isSealed)
                return;

            // Count total vertices and indices
            int totalVertices = 0;
            int totalIndices = 0;
            foreach (var item in builderDictionary)
            {
                totalVertices += item.Value.Vertices.Count;
                totalIndices += item.Value.Indices.Count;
            }

            // Create combined data
            combinedModel = new CombinedModel();
            combinedModel.Vertices = new Vector3[totalVertices];
            combinedModel.Normals = new Vector3[totalVertices];
            combinedModel.UVs = new Vector2[totalVertices];
            combinedModel.Indices = new int[totalIndices];
            combinedModel.SubMeshes = new SubMesh[builderDictionary.Count];

            // Populate static arrays
            int currentVertex = 0;
            int currentIndex = 0;
            int subMeshIndex = 0;
            foreach (var item in builderDictionary)
            {
                // Save current highest vertex and index
                int highestVertex = currentVertex;
                int highestIndex = currentIndex;

                // Copy vertex data
                for (int i = 0; i < item.Value.Vertices.Count; i++)
                {
                    combinedModel.Vertices[currentVertex] = item.Value.Vertices[i];
                    combinedModel.Normals[currentVertex] = item.Value.Normals[i];
                    combinedModel.UVs[currentVertex] = item.Value.UVs[i];
                    currentVertex++;
                }

                // Copy index data
                for (int i = 0; i < item.Value.Indices.Count; i++)
                {
                    combinedModel.Indices[currentIndex++] = highestVertex + i;
                }

                // Add submesh
                int frame;
                SubMesh sm = new SubMesh();
                sm.StartIndex = highestIndex;
                sm.PrimitiveCount = item.Value.Indices.Count / 3;
                MaterialReader.ReverseTextureKey(item.Key, out sm.TextureArchive, out sm.TextureRecord, out frame);
                combinedModel.SubMeshes[subMeshIndex++] = sm;
            }

            Seal();
        }
Example #37
0
 protected void CreateSubMeshList()
 {
     int idx = 0;
     for (int i = 0; i < _model.Meshes.Count; i++)
     {
         ModelMesh modelMesh = _model.Meshes[i];
         for (int index = 0; index < modelMesh.MeshParts.Count; index++)
         {
             ModelMeshPart modelMeshPart = modelMesh.MeshParts[index];
             SubMesh subMesh = new SubMesh(this);
             subMesh._meshPart = modelMeshPart;
             subMesh._modelIndex = idx;
             subMesh.Effect = modelMeshPart.Effect;
             subMesh._metadata = _metadata.SubMeshesMetadata[idx];
             _subMeshes.Add(subMesh);
         }
         idx++;
     }
     UpdateSubMeshes();
 }
        /// <summary>
        /// 
        /// </summary>
        public void Build()
        {
            if (mRenderMethod == BillboardMethod.Accelerated)
            {
                Clear();

                //If there are no billboards to create, exit
                if (mBillboardBuffer.Count == 0)
                    return;

                //Create manual mesh to store billboard quads
                mMesh = MeshManager.Instance.CreateManual(GetUniqueID("SBSMesh"), ResourceGroupManager.DefaultResourceGroupName, null);
                mSubMesh = mMesh.CreateSubMesh();
                mSubMesh.useSharedVertices = false;

                //Setup vertex format information
                mSubMesh.vertexData = new VertexData();
                mSubMesh.vertexData.vertexStart = 0;
                mSubMesh.vertexData.vertexCount = 4 * mBillboardBuffer.Count;

                VertexDeclaration dcl = mSubMesh.vertexData.vertexDeclaration;

                int offset = 0;
                dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
                offset += VertexElement.GetTypeSize(VertexElementType.Float3);
                dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal);
                offset += VertexElement.GetTypeSize(VertexElementType.Float3);
                dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Diffuse);
                offset += VertexElement.GetTypeSize(VertexElementType.Color);
                dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.TexCoords);
                offset += VertexElement.GetTypeSize(VertexElementType.Float2);

                //Populate a new vertex buffer
                HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
                    /*offset*/dcl, mSubMesh.vertexData.vertexCount, BufferUsage.StaticWriteOnly, false);
                unsafe
                {
                    float* pReal = (float*)vbuf.Lock(BufferLocking.Discard);

                    float minX = float.PositiveInfinity;
                    float maxX = float.NegativeInfinity;
                    float minY = float.PositiveInfinity;
                    float maxY = float.NegativeInfinity;
                    float minZ = float.PositiveInfinity;
                    float maxZ = float.NegativeInfinity;

                    foreach (StaticBillboard it in mBillboardBuffer)
                    {
                        StaticBillboard bb = it;
                        float halfXScale = bb.XScale * 0.5f;
                        float halfYScale = bb.YScale * 0.5f;

                        // position
                        *pReal++ = bb.Position.x;
                        *pReal++ = bb.Position.y;
                        *pReal++ = bb.Position.z;

                        // normals (actually used as scale / translate info for vertex shader)
                        *pReal++ = halfXScale;
                        *pReal++ = halfYScale;
                        *pReal++ = 0.0f;
                        // color
                        *((uint*)pReal++) = bb.Color;
                        // uv
                        *pReal++ = (float)(bb.TextCoordIndexU * mUFactor);
                        *pReal++ = (float)(bb.TextCoordIndexV * mVFactor);

                        // position
                        *pReal++ = bb.Position.x;
                        *pReal++ = bb.Position.y;
                        *pReal++ = bb.Position.z;

                        // normals (actually used as scale / translate info for vertex shader)
                        *pReal++ = halfXScale;
                        *pReal++ = halfYScale;
                        *pReal++ = 1.0f;
                        // color
                        *((uint*)pReal++) = bb.Color;
                        // uv
                        *pReal++ = (float)((bb.TextCoordIndexU + 1)* mUFactor);
                        *pReal++ = (float)(bb.TextCoordIndexV * mVFactor);

                        // position
                        *pReal++ = bb.Position.x;
                        *pReal++ = bb.Position.y;
                        *pReal++ = bb.Position.z;

                        // normals (actually used as scale / translate info for vertex shader)
                        *pReal++ = halfXScale;
                        *pReal++ = halfYScale;
                        *pReal++ = 2.0f;
                        // color
                        *((uint*)pReal++) = bb.Color;
                        // uv
                        *pReal++ = (float)(bb.TextCoordIndexU * mUFactor);
                        *pReal++ = (float)((bb.TextCoordIndexV + 1) * mVFactor);

                        // position
                        *pReal++ = bb.Position.x;
                        *pReal++ = bb.Position.y;
                        *pReal++ = bb.Position.z;

                        // normals (actually used as scale / translate info for vertex shader)
                        *pReal++ = halfXScale;
                        *pReal++ = halfYScale;
                        *pReal++ = 3.0f;
                        // color
                        *((uint*)pReal++) = bb.Color;
                        // uv
                        *pReal++ = (float)((bb.TextCoordIndexU + 1) * mUFactor);
                        *pReal++ = (float)((bb.TextCoordIndexV + 1) * mVFactor);

                        //Update bounding box
                        if (bb.Position.x - halfXScale < minX) minX = bb.Position.x - halfXScale;
                        if (bb.Position.x + halfXScale > maxX) maxX = bb.Position.x + halfXScale;
                        if (bb.Position.y - halfYScale < minY) minY = bb.Position.y - halfYScale;
                        if (bb.Position.y + halfYScale > maxY) maxY = bb.Position.y + halfYScale;
                        if (bb.Position.z - halfXScale < minZ) minZ = bb.Position.z - halfXScale;
                        if (bb.Position.z + halfXScale > maxZ) maxZ = bb.Position.z + halfXScale;

                    }

                    AxisAlignedBox bounds = new AxisAlignedBox(
                        new Vector3(minX, minY, minZ),
                        new Vector3(maxX, maxY, maxZ));
                    vbuf.Unlock();
                    mSubMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf);

                    //Populate index buffer
                    mSubMesh.indexData.indexStart = 0;
                    mSubMesh.indexData.indexCount = 6 * mBillboardBuffer.Count;
                    mSubMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(
                        IndexType.Size16, mSubMesh.indexData.indexCount, BufferUsage.StaticWriteOnly);

                    ushort* pI = (ushort*)mSubMesh.indexData.indexBuffer.Lock(BufferLocking.Discard);
                    for (ushort i = 0; i < mBillboardBuffer.Count; i++)
                    {
                        ushort ofset = (ushort)(i * 4);

                        *pI++ = (ushort)(0 + ofset);
                        *pI++ = (ushort)(2 + ofset);
                        *pI++ = (ushort)(1 + ofset);

                        *pI++ = (ushort)(1 + ofset);
                        *pI++ = (ushort)(2 + ofset);
                        *pI++ = (ushort)(3 + ofset);
                    }

                    mSubMesh.indexData.indexBuffer.Unlock();

                    //Finish up mesh
                    mMesh.BoundingBox = bounds;
                    Vector3 tmp = bounds.Maximum - bounds.Minimum;
                    mMesh.BoundingSphereRadius = tmp.Length * 0.5f;

                    LoggingLevel lvl = LogManager.Instance.LogDetail;
                    LogManager.Instance.LogDetail = LoggingLevel.Low;
                    mMesh.Load();
                    LogManager.Instance.LogDetail = lvl;

                    //Empty the billboardBuffer now, because all billboards have been built
                    mBillboardBuffer.Clear();

                    //Create an entity for the mesh
                    mEntity = mSceneMgr.CreateEntity(mEntityName, mMesh.Name);
                    mEntity.CastShadows = false;

                    //Apply texture
                    if (mFadeEnabled)
                    {
                        Debug.Assert(mFadeMaterial != null);
                        mEntity.MaterialName = mFadeMaterial.Name;
                    }
                    else
                    {
                        Debug.Assert(mMaterial != null);
                        mEntity.MaterialName = mMaterial.Name;
                    }

                    //Add to scene
                    mNode.AttachObject(mEntity);
                    mEntity.IsVisible = mVisible;
                }
            }
        }
Example #39
0
    /**************** New Functions Begin ***************/
    /// <summary>
    /// Generate navmesh by entity
    /// </summary>
    /// <param name="ent">Ogre Entity</param>
    /// <returns>Navmesh</returns>

    public static Navmesh LoadNavmesh(Entity ent)
    {
        bool addedSharedVertex = false;

        vertices.Clear();
        faces.Clear();
        MeshPtr mesh = ent.GetMesh();

        Mesh.SubMeshIterator subIterator = mesh.GetSubMeshIterator();

        uint vertexNum    = 0;
        uint vertexOffset = mesh.sharedVertexData.vertexStart;

        MyVector3 <float>[]           verticeArray = new MyVector3 <float> [vertexNum];
        VertexElement                 posElem      = mesh.sharedVertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
        HardwareVertexBufferSharedPtr vertexBuffer = mesh.sharedVertexData.vertexBufferBinding.GetBuffer(posElem.Source);

        while (subIterator.MoveNext())
        {
            SubMesh subMesh = subIterator.Current;

            VertexData vertexData = subMesh.useSharedVertices ? mesh.sharedVertexData : subMesh.vertexData;

            HardwareIndexBufferSharedPtr  indexBuffer = subMesh.indexData.indexBuffer;
            HardwareIndexBuffer.IndexType indexType   = indexBuffer.Type;
            uint indexCount = subMesh.indexData.indexCount;

            uint trisNum = indexCount / 3;

            uint[] indcies     = new uint[indexCount];
            uint   indexOffset = subMesh.indexData.indexStart;

            if (subMesh.useSharedVertices)
            {
                if (!addedSharedVertex)
                {
                    vertexNum        += mesh.sharedVertexData.vertexCount;
                    addedSharedVertex = true;
                }
            }
            else
            {
                vertexNum += subMesh.vertexData.vertexCount;
            }

            unsafe
            {
                uint *  pLong  = (uint *)(indexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY));
                ushort *pShort = (ushort *)pLong;
                for (int i = 0; i < indexCount; i++)
                {
                    if (indexType == HardwareIndexBuffer.IndexType.IT_32BIT)
                    {
                        indcies[indexOffset] = pLong[i] + vertexNum;
                    }
                    else
                    {
                        indcies[indexOffset] = pShort[i] + vertexNum;
                    }
                    indexOffset++;
                }
            }

            int indexLength = indcies.Length / 3;
            for (int i = 0; i < indexLength; i++)
            {
                faces.Add(new MyVector3 <ushort>(
                              (ushort)indcies[i * 3 + 0],
                              (ushort)indcies[i * 3 + 1],
                              (ushort)indcies[i * 3 + 2]
                              ));
            }

            indexBuffer.Unlock();

            if (subMesh.vertexData != null)
            {
                vertexNum    = subMesh.vertexData.vertexCount;
                vertexOffset = subMesh.vertexData.vertexStart;
                verticeArray = new MyVector3 <float> [vertexNum];
                posElem      = subMesh.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
                vertexBuffer = subMesh.vertexData.vertexBufferBinding.GetBuffer(posElem.Source);
                unsafe
                {
                    byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
                    float *pVertexBuffer;
                    for (int i = 0; i < vertexNum; i++)
                    {
                        posElem.BaseVertexPointerToElement(vertexMemory, &pVertexBuffer);
                        verticeArray[vertexOffset] = (new MyVector3 <float>(
                                                          pVertexBuffer[0],
                                                          pVertexBuffer[1],
                                                          pVertexBuffer[2]
                                                          ));
                        vertexMemory += vertexBuffer.VertexSize;
                        vertexOffset++;
                    }
                }
                for (int i = 0; i < verticeArray.Length; i++)
                {
                    vertices.Add(verticeArray[i]);
                }
                vertexBuffer.Unlock();
            }
        }

        vertexNum    = mesh.sharedVertexData.vertexCount;
        vertexOffset = mesh.sharedVertexData.vertexStart;
        verticeArray = new MyVector3 <float> [vertexNum];
        posElem      = mesh.sharedVertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
        vertexBuffer = mesh.sharedVertexData.vertexBufferBinding.GetBuffer(posElem.Source);

        unsafe
        {
            byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
            float *pVertexBuffer;
            for (int i = 0; i < vertexNum; i++)
            {
                posElem.BaseVertexPointerToElement(vertexMemory, &pVertexBuffer);
                verticeArray[vertexOffset] = (new MyVector3 <float>(
                                                  pVertexBuffer[0],
                                                  pVertexBuffer[1],
                                                  pVertexBuffer[2]
                                                  ));
                vertexMemory += vertexBuffer.VertexSize;
                vertexOffset++;
            }
        }
        for (int i = 0; i < verticeArray.Length; i++)
        {
            vertices.Add(verticeArray[i]);
        }
        vertexBuffer.Unlock();

        return(GenerateNavmesh());
    }
Example #40
0
        private void VertexDataToOutline(List <Vector2f[]> outlines, Vector3f[] vertices, ref SubMesh submesh)
        {
            Vector3i[] triangles = new Vector3i[submesh.IndexCount / 3];
            for (int o = submesh.FirstByte, ti = 0; ti < triangles.Length; o += 6, ti++)
            {
                int x = BitConverter.ToInt16(IndexBuffer, o + 0);
                int y = BitConverter.ToInt16(IndexBuffer, o + 2);
                int z = BitConverter.ToInt16(IndexBuffer, o + 4);
                triangles[ti] = new Vector3i(x, y, z);
            }
            MeshOutlineGenerator outlineGenerator = new MeshOutlineGenerator(vertices, triangles);
            List <Vector2f[]>    meshOutlines     = outlineGenerator.GenerateOutlines();

            outlines.AddRange(meshOutlines);
        }
Example #41
0
            public string GetSubmeshName(SubMesh _mesh)
            {
                Mesh.Const_SubMeshNameMap map = mainStick.GetMesh().GetSubMeshNameMap();

                for (uint i = 0; i < map.Count; i++)
                {
                  if(_mesh == mainStick.GetMesh().GetSubMesh((ushort)i))
                  {
                for (Mesh.Const_SubMeshNameMap.ConstIterator start = map.Begin();
                start != map.End(); start++)
                {
                  if (start.Value == i)
                return start.Key;
                }
                  }
                }

                return "";
            }