Exemplo n.º 1
0
        private void _setupGeometry()
        {
            var vertexCount = this._caption.Length * 6;

            if (renderOperation.vertexData != null)
            {
                renderOperation.vertexData = null;
                this._updateColor          = true;
            }

            if (renderOperation.vertexData == null)
            {
                renderOperation.vertexData = new VertexData();
            }

            renderOperation.indexData = null;
            renderOperation.vertexData.vertexStart = 0;
            renderOperation.vertexData.vertexCount = vertexCount;
            renderOperation.operationType          = OperationType.TriangleList;
            renderOperation.useIndices             = false;

            var decl   = renderOperation.vertexData.vertexDeclaration;
            var bind   = renderOperation.vertexData.vertexBufferBinding;
            var offset = 0;

            // create/bind positions/tex.ccord. buffer
            if (decl.FindElementBySemantic(VertexElementSemantic.Position) == null)
            {
                decl.AddElement(POS_TEX_BINDING, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            }
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);

            if (decl.FindElementBySemantic(VertexElementSemantic.TexCoords) == null)
            {
                decl.AddElement(POS_TEX_BINDING, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            }

            var vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(POS_TEX_BINDING),
                                                                         renderOperation.vertexData.vertexCount,
                                                                         BufferUsage.DynamicWriteOnly);

            bind.SetBinding(POS_TEX_BINDING, vbuf);

            // Colors - store these in a separate buffer because they change less often
            if (decl.FindElementBySemantic(VertexElementSemantic.Diffuse) == null)
            {
                decl.AddElement(COLOR_BINDING, 0, VertexElementType.Color, VertexElementSemantic.Diffuse);
            }
            var cbuf = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(COLOR_BINDING),
                                                                         renderOperation.vertexData.vertexCount,
                                                                         BufferUsage.DynamicWriteOnly);

            bind.SetBinding(COLOR_BINDING, cbuf);

            var charlen = this._caption.Length;

            var largestWidth = 0.0f;
            var left         = 0f * 2.0f - 1.0f;
            var top          = -((0f * 2.0f) - 1.0f);

            // Derive space with from a capital A
            if (this._spaceWidth == 0)
            {
                this._spaceWidth = (int)(this._font.GetGlyphAspectRatio('A') * this._characterHeight * 2.0f);
            }

            // for calculation of AABB
            Vector3 min, max, currPos;
            var     maxSquaredRadius = 0.0f;
            var     first            = true;

            min = max = currPos = Vector3.NegativeUnitY;
            // Use iterator
            var newLine = true;
            var len     = 0.0f;

            if (this._verticalAlignment == VerticalAlignment.Above)
            {
                // Raise the first line of the caption
                top += this._characterHeight;
                for (var i = 0; i != charlen; i++)
                {
                    if (this._caption[i] == '\n')
                    {
                        top += this._characterHeight * 2.0f;
                    }
                }
            }

            //Real *pPCBuff = static_cast<Real*>(ptbuf.lock(HardwareBuffer::HBL_DISCARD));
            var ipPos  = vbuf.Lock(BufferLocking.Discard);
            var cntPos = 0;

#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                var pPCBuff = ipPos.ToFloatPointer();

                for (var i = 0; i != charlen; i++)
                {
                    if (newLine)
                    {
                        len = 0.0f;
                        for (var j = i; j != charlen && this._caption[j] != '\n'; j++)
                        {
                            if (this._caption[j] == ' ')
                            {
                                len += this._spaceWidth;
                            }
                            else
                            {
                                len += this._font.GetGlyphAspectRatio(this._caption[j]) * this._characterHeight * 2.0f;
                            }
                        }
                        newLine = false;
                    }

                    if (this._caption[i] == '\n')
                    {
                        left    = 0f * 2.0f - 1.0f;
                        top    -= this._characterHeight * 2.0f;
                        newLine = true;
                        continue;
                    }

                    if (this._caption[i] == ' ')
                    {
                        // Just leave a gap, no tris
                        left += this._spaceWidth;
                        // Also reduce tri count
                        renderOperation.vertexData.vertexCount -= 6;
                        continue;
                    }

                    var  horiz_height = this._font.GetGlyphAspectRatio(this._caption[i]);
                    Real u1, u2, v1, v2;
                    this._font.GetGlyphTexCoords(this._caption[i], out u1, out v1, out u2, out v2);

                    // each vert is (x, y, z, u, v)
                    //-------------------------------------------------------------------------------------
                    // First tri
                    //
                    // Upper left
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        pPCBuff[cntPos++] = left;
                    }
                    else
                    {
                        pPCBuff[cntPos++] = left - (len / 2.0f);
                    }
                    pPCBuff[cntPos++] = top;
                    pPCBuff[cntPos++] = -1.0f;
                    pPCBuff[cntPos++] = u1;
                    pPCBuff[cntPos++] = v1;

                    // Deal with bounds
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        currPos = new Vector3(left, top, -1.0f);
                    }
                    else
                    {
                        currPos = new Vector3(left - (len / 2.0f), top, -1.0f);
                    }

                    if (first)
                    {
                        min = max = currPos;
                        maxSquaredRadius = currPos.LengthSquared;
                        first            = false;
                    }
                    else
                    {
                        min.Floor(currPos);
                        max.Ceil(currPos);
                        maxSquaredRadius = Max(maxSquaredRadius, currPos.LengthSquared);
                    }

                    top -= this._characterHeight * 2.0f;

                    // Bottom left
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        pPCBuff[cntPos++] = left;
                    }
                    else
                    {
                        pPCBuff[cntPos++] = left - (len / 2.0f);
                    }
                    pPCBuff[cntPos++] = top;
                    pPCBuff[cntPos++] = -1.0f;
                    pPCBuff[cntPos++] = u1;
                    pPCBuff[cntPos++] = v2;

                    // Deal with bounds
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        currPos = new Vector3(left, top, -1.0f);
                    }
                    else
                    {
                        currPos = new Vector3(left - (len / 2.0f), top, -1.0f);
                    }

                    min.Floor(currPos);
                    max.Ceil(currPos);
                    maxSquaredRadius = Max(maxSquaredRadius, currPos.LengthSquared);

                    top  += this._characterHeight * 2.0f;
                    left += horiz_height * this._characterHeight * 2.0f;

                    // Top right
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        pPCBuff[cntPos++] = left;
                    }
                    else
                    {
                        pPCBuff[cntPos++] = left - (len / 2.0f);
                    }
                    pPCBuff[cntPos++] = top;
                    pPCBuff[cntPos++] = -1.0f;
                    pPCBuff[cntPos++] = u2;
                    pPCBuff[cntPos++] = v1;
                    //-------------------------------------------------------------------------------------

                    // Deal with bounds
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        currPos = new Vector3(left, top, -1.0f);
                    }
                    else
                    {
                        currPos = new Vector3(left - (len / 2.0f), top, -1.0f);
                    }
                    min.Floor(currPos);
                    max.Ceil(currPos);
                    maxSquaredRadius = Max(maxSquaredRadius, currPos.LengthSquared);

                    //-------------------------------------------------------------------------------------
                    // Second tri
                    //
                    // Top right (again)
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        pPCBuff[cntPos++] = left;
                    }
                    else
                    {
                        pPCBuff[cntPos++] = left - (len / 2.0f);
                    }
                    pPCBuff[cntPos++] = top;
                    pPCBuff[cntPos++] = -1.0f;
                    pPCBuff[cntPos++] = u2;
                    pPCBuff[cntPos++] = v1;

                    currPos = new Vector3(left, top, -1.0f);
                    min.Floor(currPos);
                    max.Ceil(currPos);
                    maxSquaredRadius = Max(maxSquaredRadius, currPos.LengthSquared);

                    top  -= this._characterHeight * 2.0f;
                    left -= horiz_height * this._characterHeight * 2.0f;

                    // Bottom left (again)
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        pPCBuff[cntPos++] = left;
                    }
                    else
                    {
                        pPCBuff[cntPos++] = left - (len / 2.0f);
                    }
                    pPCBuff[cntPos++] = top;
                    pPCBuff[cntPos++] = -1.0f;
                    pPCBuff[cntPos++] = u1;
                    pPCBuff[cntPos++] = v2;

                    currPos = new Vector3(left, top, -1.0f);
                    min.Floor(currPos);
                    max.Ceil(currPos);
                    maxSquaredRadius = Max(maxSquaredRadius, currPos.LengthSquared);

                    left += horiz_height * this._characterHeight * 2.0f;

                    // Bottom right
                    if (this._horizontalAlignment == HorizontalAlignment.Left)
                    {
                        pPCBuff[cntPos++] = left;
                    }
                    else
                    {
                        pPCBuff[cntPos++] = left - (len / 2.0f);
                    }
                    pPCBuff[cntPos++] = top;
                    pPCBuff[cntPos++] = -1.0f;
                    pPCBuff[cntPos++] = u2;
                    pPCBuff[cntPos++] = v2;
                    //-------------------------------------------------------------------------------------

                    currPos = new Vector3(left, top, -1.0f);
                    min.Floor(currPos);
                    max.Ceil(currPos);
                    maxSquaredRadius = Max(maxSquaredRadius, currPos.LengthSquared);

                    // Go back up with top
                    top += this._characterHeight * 2.0f;

                    var currentWidth = (left + 1.0f) / 2.0f - 0.0f;
                    if (currentWidth > largestWidth)
                    {
                        largestWidth = currentWidth;
                    }
                }
            }
            // Unlock vertex buffer
            vbuf.Unlock();

            // update AABB/Sphere radius
            box          = new AxisAlignedBox(min, max);
            this._radius = Sqrt(maxSquaredRadius);

            if (this._updateColor)
            {
                _updateColors();
            }

            this._needUpdate = false;
        }
Exemplo n.º 2
0
        private static void _createCube(Mesh mesh)
        {
            var sub = mesh.CreateSubMesh();

            const int NUM_VERTICES           = 4 * 6; // 4 vertices per side * 6 sides
            const int NUM_ENTRIES_PER_VERTEX = 8;
            const int NUM_VERTEX_ENTRIES     = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX;
            const int NUM_INDICES            = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides

            const float CUBE_SIZE      = 100.0f;
            const float CUBE_HALF_SIZE = CUBE_SIZE / 2.0f;

            // Create 4 vertices per side instead of 6 that are shared for the whole cube.
            // The reason for this is with only 6 vertices the normals will look bad
            // since each vertex can "point" in a different direction depending on the face it is included in.
            var vertices = new float[NUM_VERTEX_ENTRIES]
            {
                // front side
                -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos
                0, 0, 1,                                          // normal
                0, 1,                                             // texcoord
                CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0, 0, 1, 1, 1, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
                CUBE_HALF_SIZE, 0, 0, 1, 1, 0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0, 0, 1, 0, 0,
                // back side
                CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0, 0, -1, 0, 1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
                -CUBE_HALF_SIZE, 0, 0, -1, 1, 1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0, 0, -1, 1, 0,
                CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0, 0, -1, 0, 0,                         // left side
                -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1, 0, 0, 0, 1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
                CUBE_HALF_SIZE, -1, 0, 0, 1, 1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1, 0, 0, 1, 0,
                -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1, 0, 0, 0, 0,                         // right side
                CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1, 0, 0, 0, 1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
                -CUBE_HALF_SIZE, 1, 0, 0, 1, 1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1, 0, 0, 1, 0,
                CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1, 0, 0, 0, 0,                         // up side
                -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0, 1, 0, 0, 1, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
                CUBE_HALF_SIZE, 0, 1, 0, 1, 1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0, 1, 0, 1, 0,
                -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0, 1, 0, 0, 0,                         // down side
                -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0, -1, 0, 0, 1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
                -CUBE_HALF_SIZE, 0, -1, 0, 1, 1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0, -1, 0, 1, 0,
                -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0, -1, 0, 0, 0
            };

            mesh.SharedVertexData             = new VertexData();
            mesh.SharedVertexData.vertexCount = NUM_VERTICES;
            var decl = mesh.SharedVertexData.vertexDeclaration;
            var bind = mesh.SharedVertexData.vertexBufferBinding;

            var offset = 0;

            decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);

            var vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(decl, NUM_VERTICES, BufferUsage.StaticWriteOnly);

            bind.SetBinding(0, vbuf);

            vbuf.WriteData(0, vbuf.Size, vertices, true);

            sub.useSharedVertices = true;
            var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, NUM_INDICES,
                                                                        BufferUsage.StaticWriteOnly);

            var faces = new short[NUM_INDICES]
            {
                // front
                0, 1, 2, 0, 2, 3,                         // back
                4, 5, 6, 4, 6, 7,                         // left
                8, 9, 10, 8, 10, 11,                      // right
                12, 13, 14, 12, 14, 15,                   // up
                16, 17, 18, 16, 18, 19,                   // down
                20, 21, 22, 20, 22, 23
            };

            sub.IndexData.indexBuffer = ibuf;
            sub.IndexData.indexCount  = NUM_INDICES;
            sub.IndexData.indexStart  = 0;
            ibuf.WriteData(0, ibuf.Size, faces, true);

            mesh.BoundingBox = new AxisAlignedBox(new Vector3(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE),
                                                  new Vector3(CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE));

            mesh.BoundingSphereRadius = CUBE_HALF_SIZE;
        }
Exemplo n.º 3
0
        public void Init(TerrainOptions options)
        {
            this.options = options;

            this.numMipMaps = options.maxMipmap;
            this.size       = options.size;

            this.terrain             = new VertexData();
            this.terrain.vertexStart = 0;

            this.terrain.vertexCount = options.size * options.size;

            VertexDeclaration   decl    = this.terrain.vertexDeclaration;
            VertexBufferBinding binding = this.terrain.vertexBufferBinding;

            int offset = 0;

            // Position/Normal
            decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position);
            decl.AddElement(NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal);

            // TexCoords
            decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            // TODO: Color

            HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(POSITION),
                                                                                            this.terrain.vertexCount,
                                                                                            BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(POSITION, buffer);

            buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(NORMAL), this.terrain.vertexCount,
                                                                       BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(NORMAL, buffer);

            buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(TEXCOORD), this.terrain.vertexCount,
                                                                       BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(TEXCOORD, buffer);

            this.minLevelDistSqr = new float[this.numMipMaps];

            int endx = options.startx + options.size;
            int endz = options.startz + options.size;

            // TODO: name buffers different so we can unlock
            HardwareVertexBuffer posBuffer = binding.GetBuffer(POSITION);
            var pos = posBuffer.Lock(BufferLocking.Discard);

            HardwareVertexBuffer texBuffer = binding.GetBuffer(TEXCOORD);
            var tex = texBuffer.Lock(BufferLocking.Discard);

            float min = 99999999, max = 0;

#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                var posPtr = pos.ToFloatPointer();
                var texPtr = tex.ToFloatPointer();

                int posCount = 0;
                int texCount = 0;

                for (int j = options.startz; j < endz; j++)
                {
                    for (int i = options.startx; i < endx; i++)
                    {
                        float height = options.GetWorldHeight(i, j) * options.scaley;

                        posPtr[posCount++] = i * options.scalex;
                        posPtr[posCount++] = height;
                        posPtr[posCount++] = j * options.scalez;

                        texPtr[texCount++] = (float)i / options.worldSize;
                        texPtr[texCount++] = (float)j / options.worldSize;

                        texPtr[texCount++] = ((float)i / options.size) * options.detailTile;
                        texPtr[texCount++] = ((float)j / options.size) * options.detailTile;

                        if (height < min)
                        {
                            min = height;
                        }

                        if (height > max)
                        {
                            max = height;
                        }
                    }     // for i
                }         // for j
            }             // unsafe

            // unlock the buffers
            posBuffer.Unlock();
            texBuffer.Unlock();

            this.box.SetExtents(new Vector3(options.startx * options.scalex, min, options.startz * options.scalez),
                                new Vector3((endx - 1) * options.scalex, max, (endz - 1) * options.scalez));

            this.center = new Vector3((options.startx * options.scalex + endx - 1) / 2, (min + max) / 2,
                                      (options.startz * options.scalez + endz - 1) / 2);

            float C = CalculateCFactor();

            CalculateMinLevelDist2(C);
        }
Exemplo n.º 4
0
            public GeometryBucket(MaterialBucket parent,
                                  String formatString, VertexData vData,
                                  IndexData iData)
                : base()
            {
                mParent       = parent;
                mFormatString = formatString;
                mVertexData   = null;
                mIndexData    = null;
                mBatch        = mParent.Parent.Parent.Parent;
                if (mBatch.BaseSkeleton != null)
                {
                    SetCustomParameter(0, new Vector4(mBatch.BaseSkeleton.BoneCount, 0, 0, 0));
                }

                mVertexData = vData.Clone(false);

                renderOperation.useIndices = true;
                renderOperation.indexData  = new IndexData();

                renderOperation.indexData.indexCount   = 0;
                renderOperation.indexData.indexStart   = 0;
                renderOperation.vertexData             = new VertexData();
                renderOperation.vertexData.vertexCount = 0;

                renderOperation.vertexData.vertexDeclaration = (VertexDeclaration)vData.vertexDeclaration.Clone();
                mIndexType = iData.indexBuffer.Type;
                // Derive the max vertices
                if (mIndexType == IndexType.Size32)
                {
                    mMaxVertexIndex = 0xFFFFFFFF;
                }
                else
                {
                    mMaxVertexIndex = 0xFFFF;
                }

                int   offset = 0, tcOffset = 0;
                short texCoordOffset = 0;
                short texCoordSource = 0;

                for (int i = 0; i < renderOperation.vertexData.vertexDeclaration.ElementCount; i++)
                {
                    if (renderOperation.vertexData.vertexDeclaration.GetElement(i).Semantic == VertexElementSemantic.TexCoords)
                    {
                        texCoordOffset++;
                        texCoordSource = renderOperation.vertexData.vertexDeclaration.GetElement(i).Source;
                        tcOffset       = renderOperation.vertexData.vertexDeclaration.GetElement(i).Offset + VertexElement.GetTypeSize(
                            renderOperation.vertexData.vertexDeclaration.GetElement(i).Type);
                    }
                    offset += VertexElement.GetTypeSize(renderOperation.vertexData.vertexDeclaration.GetElement(i).Type);
                }

                renderOperation.vertexData.vertexDeclaration.AddElement(texCoordSource, tcOffset, VertexElementType.Float1,
                                                                        VertexElementSemantic.TexCoords, texCoordOffset);

                mTexCoordIndex = texCoordOffset;
            }
        /// <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;
                }
            }
        }
Exemplo n.º 6
0
        private XmlVertexData GetXmlVertexData(VertexData vertexData)
        {
            XmlVertexData xmlVertexData = new XmlVertexData(vertexData.vertexCount);

            xmlVertexData.positionData = null;
            xmlVertexData.normalData   = null;
            xmlVertexData.diffuseData  = null;
            xmlVertexData.specularData = null;

            // Normals are transformed by the transpose of the inverse of the spatial transform.
            // Exclude the scale though, since I don't want to mess that up.
            float   scale        = GetScale(exportTransform);
            Matrix4 tmpTransform = ScaleMatrix(exportTransform, 1 / scale);
            Matrix4 invTrans     = tmpTransform.Inverse().Transpose();
            // I'm going to write all the texture buffers to one vertex
            // buffer, so I can leave textureOffset at zero.
            int textureOffset = 0;

            for (short bindIdx = 0; bindIdx < vertexData.vertexDeclaration.ElementCount; ++bindIdx)
            {
                VertexElement        element = vertexData.vertexDeclaration.GetElement(bindIdx);
                HardwareVertexBuffer vBuffer = vertexData.vertexBufferBinding.GetBuffer(element.Source);
                int vertexOffset             = element.Offset;
                int vertexStride             = vBuffer.VertexSize;
                switch (element.Semantic)
                {
                case VertexElementSemantic.Position:
                    xmlVertexData.positionData = new float[xmlVertexData.vertexCount, 3];
                    ReadBuffer(vBuffer, vertexOffset, vertexStride, xmlVertexData.vertexCount, element.Size, xmlVertexData.positionData, exportTransform);
                    break;

                case VertexElementSemantic.Normal:
                    xmlVertexData.normalData = new float[xmlVertexData.vertexCount, 3];
                    ReadBuffer(vBuffer, vertexOffset, vertexStride, xmlVertexData.vertexCount, element.Size, xmlVertexData.normalData, invTrans);
                    break;

                case VertexElementSemantic.Diffuse:
                    xmlVertexData.diffuseData = new uint[xmlVertexData.vertexCount];
                    ReadBuffer(vBuffer, vertexOffset, vertexStride, xmlVertexData.vertexCount, element.Size, xmlVertexData.diffuseData);
                    break;

                case VertexElementSemantic.Specular:
                    xmlVertexData.specularData = new uint[xmlVertexData.vertexCount];
                    ReadBuffer(vBuffer, vertexOffset, vertexStride, xmlVertexData.vertexCount, element.Size, xmlVertexData.specularData);
                    break;

                case VertexElementSemantic.TexCoords: {
                    int dim = VertexElement.GetTypeSize(element.Type) /
                              VertexElement.GetTypeSize(VertexElementType.Float1);
                    float[,] data = new float[xmlVertexData.vertexCount, dim];
                    ReadBuffer(vBuffer, vertexOffset, vertexStride, xmlVertexData.vertexCount, element.Size, data);
                    // pad out the list
                    while (textureOffset + element.Index >= xmlVertexData.multiTexData.Count)
                    {
                        xmlVertexData.multiTexData.Add(null);
                    }
                    // set this element
                    xmlVertexData.multiTexData[textureOffset + element.Index] = data;
                    textureOffset++;
                }
                break;

                case VertexElementSemantic.Tangent:
                case VertexElementSemantic.Binormal: {
                    int dim = VertexElement.GetTypeSize(element.Type) /
                              VertexElement.GetTypeSize(VertexElementType.Float1);
                    float[,] data = new float[xmlVertexData.vertexCount, dim];
                    ReadBuffer(vBuffer, vertexOffset, vertexStride, xmlVertexData.vertexCount, element.Size, data);
                    // pad out the list
                    while (textureOffset + element.Index >= xmlVertexData.multiTexData.Count)
                    {
                        xmlVertexData.multiTexData.Add(null);
                    }
                    // set this element
                    xmlVertexData.multiTexData[textureOffset + element.Index] = data;
                    textureOffset++;
                }
                break;

                default:
                    log.WarnFormat("Unknown vertex buffer semantic: {0}", element.Semantic);
                    break;
                }
            }
            return(xmlVertexData);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="name"></param>
        /// <param name="plane"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="curvature"></param>
        /// <param name="xSegments"></param>
        /// <param name="ySegments"></param>
        /// <param name="normals"></param>
        /// <param name="numberOfTexCoordSets"></param>
        /// <param name="uTiles"></param>
        /// <param name="vTiles"></param>
        /// <param name="upVector"></param>
        /// <param name="orientation"></param>
        /// <param name="vertexBufferUsage"></param>
        /// <param name="indexBufferUsage"></param>
        /// <param name="vertexShadowBuffer"></param>
        /// <param name="indexShadowBuffer"></param>
        /// <returns></returns>
        public Mesh CreateCurvedIllusionPlane(string name, Plane plane, float width, float height, float curvature, int xSegments, int ySegments, bool normals, int numberOfTexCoordSets, float uTiles, float vTiles, Vector3 upVector, Quaternion orientation, BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer)
        {
            Mesh    mesh    = CreateManual(name);
            SubMesh subMesh = mesh.CreateSubMesh(name + "SubMesh");

            // set up vertex data, use a single shared buffer
            mesh.SharedVertexData = new VertexData();
            VertexData vertexData = mesh.SharedVertexData;

            // set up vertex declaration
            VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration;
            int currentOffset = 0;

            // always need positions
            vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            // optional normals
            if (normals)
            {
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
            }

            for (ushort i = 0; i < numberOfTexCoordSets; i++)
            {
                // assumes 2d texture coordinates
                vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i);
                currentOffset += VertexElement.GetTypeSize(VertexElementType.Float2);
            }

            vertexData.vertexCount = (xSegments + 1) * (ySegments + 1);

            // allocate vertex buffer
            HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, vertexBufferUsage, vertexShadowBuffer);

            // set up the binding, one source only
            VertexBufferBinding binding = vertexData.vertexBufferBinding;

            binding.SetBinding(0, vertexBuffer);

            // work out the transform required, default orientation of plane is normal along +z, distance 0
            Matrix4 xlate, xform, rot;
            Matrix3 rot3 = Matrix3.Identity;

            xlate = rot = Matrix4.Identity;

            // determine axes
            Vector3 zAxis, yAxis, xAxis;

            zAxis = plane.Normal;
            zAxis.Normalize();
            yAxis = upVector;
            yAxis.Normalize();
            xAxis = yAxis.Cross(zAxis);
            if (xAxis.Length == 0)
            {
                throw new AxiomException("The up vector for a plane cannot be parallel to the planes normal.");
            }

            rot3.FromAxes(xAxis, yAxis, zAxis);
            rot = rot3;

            // set up standard xform from origin
            xlate.Translation = plane.Normal * -plane.D;

            // concatenate
            xform = xlate * rot;

            // generate vertex data, imagine a large sphere with the camera located near the top,
            // the lower the curvature, the larger the sphere.  use the angle from the viewer to the
            // points on the plane
            float cameraPosition;      // camera position relative to the sphere center

            // derive sphere radius (unused)
            //float sphereDistance;      // distance from the camera to the sphere along box vertex vector
            float sphereRadius;

            // actual values irrelevant, it's the relation between the sphere's radius and the camera's position which is important
            float SPHERE_RADIUS   = 100;
            float CAMERA_DISTANCE = 5;

            sphereRadius   = SPHERE_RADIUS - curvature;
            cameraPosition = sphereRadius - CAMERA_DISTANCE;

            // lock the whole buffer
            float   xSpace           = width / xSegments;
            float   ySpace           = height / ySegments;
            float   halfWidth        = width / 2;
            float   halfHeight       = height / 2;
            Vector3 vec              = Vector3.Zero;
            Vector3 norm             = Vector3.Zero;
            Vector3 min              = Vector3.Zero;
            Vector3 max              = Vector3.Zero;
            float   maxSquaredLength = 0;
            bool    firstTime        = true;

            // generate vertex data
            GenerateCurvedIllusionPlaneVertexData(vertexBuffer, ySegments, xSegments, xSpace, halfWidth, ySpace, halfHeight, xform, firstTime, normals, orientation, cameraPosition, sphereRadius, uTiles, vTiles, numberOfTexCoordSets, ref min, ref max, ref maxSquaredLength);

            // generate face list
            subMesh.useSharedVertices = true;
            Tesselate2DMesh(subMesh, xSegments + 1, ySegments + 1, false, indexBufferUsage, indexShadowBuffer);

            // generate bounds for the mesh
            mesh.BoundingBox          = new AxisAlignedBox(min, max);
            mesh.BoundingSphereRadius = MathUtil.Sqrt(maxSquaredLength);

            mesh.Load();
            mesh.Touch();

            return(mesh);
        }
Exemplo n.º 8
0
        /// <summary>
        ///
        /// </summary>
        private unsafe void CreateGeometry()
        {
            // Vertex buffers
            _subMesh.vertexData             = new VertexData();
            _subMesh.vertexData.vertexStart = 0;
            _subMesh.vertexData.vertexCount = (uint)_vertexCount;

            VertexDeclaration   vdecl = _subMesh.vertexData.vertexDeclaration;
            VertexBufferBinding vbind = _subMesh.vertexData.vertexBufferBinding;

            uint offset = 0;

            // Position
            vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
            // 3D coords
            vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
            // Noise coords
            vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 1);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2);
            // Opacity
            vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT1, VertexElementSemantic.VES_TEXTURE_COORDINATES, 2);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT1);

            _vertexBuffer = HardwareBufferManager.Singleton.CreateVertexBuffer(
                offset, (uint)_vertexCount,
                HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY);

            vbind.SetBinding(0, _vertexBuffer);

            int[] indexbuffer = new int[_numberOfTriangles * 3];

            int IndexOffset  = 0;
            int VertexOffset = 0;

            // C
            for (int k = 0; k < _nc; k++)
            {
                // First triangle
                indexbuffer[IndexOffset]     = VertexOffset;
                indexbuffer[IndexOffset + 1] = VertexOffset + 1;
                indexbuffer[IndexOffset + 2] = VertexOffset + 3;

                // Second triangle
                indexbuffer[IndexOffset + 3] = VertexOffset;
                indexbuffer[IndexOffset + 4] = VertexOffset + 3;
                indexbuffer[IndexOffset + 5] = VertexOffset + 2;

                IndexOffset  += 6;
                VertexOffset += 4;
            }
            // B
            for (int k = 0; k < _nb; k++)
            {
                // First triangle
                indexbuffer[IndexOffset]     = VertexOffset;
                indexbuffer[IndexOffset + 1] = VertexOffset + 1;
                indexbuffer[IndexOffset + 2] = VertexOffset + 3;

                // Second triangle
                indexbuffer[IndexOffset + 3] = VertexOffset;
                indexbuffer[IndexOffset + 4] = VertexOffset + 3;
                indexbuffer[IndexOffset + 5] = VertexOffset + 2;

                // Third triangle
                indexbuffer[IndexOffset + 6] = VertexOffset + 2;
                indexbuffer[IndexOffset + 7] = VertexOffset + 3;
                indexbuffer[IndexOffset + 8] = VertexOffset + 5;

                // Fourth triangle
                indexbuffer[IndexOffset + 9]  = VertexOffset + 2;
                indexbuffer[IndexOffset + 10] = VertexOffset + 5;
                indexbuffer[IndexOffset + 11] = VertexOffset + 4;

                IndexOffset  += 12;
                VertexOffset += 6;
            }

            // A
            for (int k = 0; k < _na; k++)
            {
                // First triangle
                indexbuffer[IndexOffset]     = VertexOffset;
                indexbuffer[IndexOffset + 1] = VertexOffset + 1;
                indexbuffer[IndexOffset + 2] = VertexOffset + 3;

                // Second triangle
                indexbuffer[IndexOffset + 3] = VertexOffset;
                indexbuffer[IndexOffset + 4] = VertexOffset + 3;
                indexbuffer[IndexOffset + 5] = VertexOffset + 2;

                // Third triangle
                indexbuffer[IndexOffset + 6] = VertexOffset + 2;
                indexbuffer[IndexOffset + 7] = VertexOffset + 3;
                indexbuffer[IndexOffset + 8] = VertexOffset + 5;

                // Fourth triangle
                indexbuffer[IndexOffset + 9]  = VertexOffset + 2;
                indexbuffer[IndexOffset + 10] = VertexOffset + 5;
                indexbuffer[IndexOffset + 11] = VertexOffset + 4;

                // Fifth triangle
                indexbuffer[IndexOffset + 12] = VertexOffset + 4;
                indexbuffer[IndexOffset + 13] = VertexOffset + 5;
                indexbuffer[IndexOffset + 14] = VertexOffset + 6;

                IndexOffset  += 15;
                VertexOffset += 7;
            }
            // Prepare buffer for indices
            _indexBuffer =
                HardwareBufferManager.Singleton.CreateIndexBuffer(Mogre.HardwareIndexBuffer.IndexType.IT_32BIT,
                                                                  (uint)_numberOfTriangles * 3, HardwareBuffer.Usage.HBU_STATIC, true);
            fixed(int *addr = &indexbuffer[0])
            {
                _indexBuffer.WriteData(
                    0, _indexBuffer.SizeInBytes, addr, true);
            }

            //indexbufferArr = null;

            // Set index buffer for this submesh
            _subMesh.indexData.indexBuffer = _indexBuffer;
            _subMesh.indexData.indexStart  = 0;
            _subMesh.indexData.indexCount  = (uint)_numberOfTriangles * 3;

            // Create our internal buffer for manipulations
            _vertices = new Vertex[_vertexCount];
            // Update geometry
            UpdateGeometry();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="name">Name of the plane mesh.</param>
        /// <param name="plane">Plane to use for distance and orientation of the mesh.</param>
        /// <param name="width">Width in world coordinates.</param>
        /// <param name="height">Height in world coordinates.</param>
        /// <param name="xSegments">Number of x segments for tesselation.</param>
        /// <param name="ySegments">Number of y segments for tesselation.</param>
        /// <param name="normals">If true, plane normals are created.</param>
        /// <param name="numTexCoordSets">Number of 2d texture coord sets to use.</param>
        /// <param name="uTile">Number of times the texture should be repeated in the u direction.</param>
        /// <param name="vTile">Number of times the texture should be repeated in the v direction.</param>
        /// <param name="upVec">The up direction of the plane.</param>
        /// <returns></returns>
        public Mesh CreatePlane(string name, Plane plane, float width, float height, int xSegments, int ySegments, bool normals, int numTexCoordSets, float uTile, float vTile, Vector3 upVec,
                                BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer)
        {
            Mesh    mesh    = CreateManual(name);
            SubMesh subMesh = mesh.CreateSubMesh(name + "SubMesh");

            mesh.SharedVertexData = new VertexData();
            VertexData vertexData = mesh.SharedVertexData;

            VertexDeclaration decl = vertexData.vertexDeclaration;
            int currOffset         = 0;

            // add position data
            decl.AddElement(0, currOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            currOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            // normals are optional
            if (normals)
            {
                decl.AddElement(0, currOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
                currOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
            }

            // add texture coords
            for (ushort i = 0; i < numTexCoordSets; i++)
            {
                decl.AddElement(0, currOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i);
                currOffset += VertexElement.GetTypeSize(VertexElementType.Float2);
            }

            vertexData.vertexCount = (xSegments + 1) * (ySegments + 1);

            // create a new vertex buffer (based on current API)
            HardwareVertexBuffer vbuf =
                HardwareBufferManager.Instance.CreateVertexBuffer(decl.GetVertexSize(0), vertexData.vertexCount, vertexBufferUsage, vertexShadowBuffer);

            // get a reference to the vertex buffer binding
            VertexBufferBinding binding = vertexData.vertexBufferBinding;

            // bind the first vertex buffer
            binding.SetBinding(0, vbuf);

            // transform the plane based on its plane def
            Matrix4 translate = Matrix4.Identity;
            Matrix4 transform = Matrix4.Zero;
            Matrix4 rotation  = Matrix4.Identity;
            Matrix3 rot3x3    = Matrix3.Zero;

            Vector3 xAxis, yAxis, zAxis;

            zAxis = plane.Normal;
            zAxis.Normalize();
            yAxis = upVec;
            yAxis.Normalize();
            xAxis = yAxis.Cross(zAxis);

            if (xAxis.Length == 0)
            {
                throw new AxiomException("The up vector for a plane cannot be parallel to the planes normal.");
            }

            rot3x3.FromAxes(xAxis, yAxis, zAxis);
            rotation = rot3x3;

            // set up transform from origin
            translate.Translation = plane.Normal * -plane.D;

            transform = translate * rotation;

            float   xSpace           = width / xSegments;
            float   ySpace           = height / ySegments;
            float   halfWidth        = width / 2;
            float   halfHeight       = height / 2;
            float   xTexCoord        = (1.0f * uTile) / xSegments;
            float   yTexCoord        = (1.0f * vTile) / ySegments;
            Vector3 vec              = Vector3.Zero;
            Vector3 min              = Vector3.Zero;
            Vector3 max              = Vector3.Zero;
            float   maxSquaredLength = 0;
            bool    firstTime        = true;

            // generate vertex data
            GeneratePlaneVertexData(vbuf, ySegments, xSegments, xSpace, halfWidth, ySpace, halfHeight, transform, firstTime, normals, rotation, numTexCoordSets, xTexCoord, yTexCoord, subMesh, ref min, ref max, ref maxSquaredLength);

            // generate face list
            Tesselate2DMesh(subMesh, xSegments + 1, ySegments + 1, false, indexBufferUsage, indexShadowBuffer);

            // generate bounds for the mesh
            mesh.BoundingBox          = new AxisAlignedBox(min, max);
            mesh.BoundingSphereRadius = MathUtil.Sqrt(maxSquaredLength);

            mesh.Load();
            mesh.Touch();

            return(mesh);
        }
        public Mesh CreateBoneMesh(string name)
        {
            Mesh mesh = CreateManual(name);

            mesh.SkeletonName = name + ".skeleton";
            SubMesh subMesh = mesh.CreateSubMesh("BoneSubMesh");

            subMesh.useSharedVertices = true;
            subMesh.MaterialName      = "BaseWhite";

            // short[] faces = { 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 2, 1, 2, 5, 1, 5, 4, 1, 4, 3, 1, 3, 2 };
            // short[] faces = { 0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 2, 5, 1, 5, 2, 1, 4, 5, 1, 3, 4, 1, 2, 3 };
            short[] faces = { 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 2, 1, 2, 5, 1, 5, 4, 1, 4, 3, 1, 3, 2,
                              0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 2, 5, 1, 5, 2, 1, 4, 5, 1, 3, 4, 1, 2, 3 };
            int     faceCount   = faces.Length / 3; // faces per bone
            int     vertexCount = 6;                // vertices per bone

            // set up vertex data, use a single shared buffer
            mesh.SharedVertexData = new VertexData();
            VertexData vertexData = mesh.SharedVertexData;

            // set up vertex declaration
            VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration;
            int currentOffset = 0;

            // always need positions
            vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
            vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            int boneCount = mesh.Skeleton.BoneCount;

            // I want 6 vertices per bone - exclude the root bone
            vertexData.vertexCount = boneCount * vertexCount;

            // allocate vertex buffer
            HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, BufferUsage.StaticWriteOnly);

            // set up the binding, one source only
            VertexBufferBinding binding = vertexData.vertexBufferBinding;

            binding.SetBinding(0, vertexBuffer);

            Vector3[] vertices = new Vector3[vertexData.vertexCount];
            GetVertices(ref vertices, mesh.Skeleton.RootBone);

            // Generate vertex data
            unsafe {
                // lock the vertex buffer
                IntPtr data = vertexBuffer.Lock(BufferLocking.Discard);

                float *pData = (float *)data.ToPointer();

                foreach (Vector3 vec in vertices)
                {
                    // assign to geometry
                    *pData++ = vec.x;
                    *pData++ = vec.y;
                    *pData++ = vec.z;
                    // fake normals
                    *pData++ = 0;
                    *pData++ = 1;
                    *pData++ = 0;
                }

                // unlock the buffer
                vertexBuffer.Unlock();
            } // unsafe


            // Generate index data
            HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, faces.Length * boneCount, BufferUsage.StaticWriteOnly);

            subMesh.indexData.indexBuffer = indexBuffer;
            subMesh.indexData.indexCount  = faces.Length * boneCount;
            subMesh.indexData.indexStart  = 0;
            for (ushort boneIndex = 0; boneIndex < mesh.Skeleton.BoneCount; ++boneIndex)
            {
                Axiom.Animating.Bone bone = mesh.Skeleton.GetBone(boneIndex);
                short[] tmpFaces          = new short[faces.Length];
                for (int tmp = 0; tmp < faces.Length; ++tmp)
                {
                    tmpFaces[tmp] = (short)(faces[tmp] + vertexCount * bone.Handle);
                }
                indexBuffer.WriteData(faces.Length * bone.Handle * sizeof(short), tmpFaces.Length * sizeof(short), tmpFaces, true);
            }

            for (ushort boneIndex = 0; boneIndex < mesh.Skeleton.BoneCount; ++boneIndex)
            {
                Axiom.Animating.Bone bone       = mesh.Skeleton.GetBone(boneIndex);
                Axiom.Animating.Bone parentBone = bone;
                if (bone.Parent != null)
                {
                    parentBone = (Axiom.Animating.Bone)bone.Parent;
                }
                for (int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
                {
                    Axiom.Animating.VertexBoneAssignment vba = new Axiom.Animating.VertexBoneAssignment();
                    // associate the base of the joint display with the bone's parent,
                    // and the rest of the points with the bone.
                    vba.boneIndex   = parentBone.Handle;
                    vba.weight      = 1.0f;
                    vba.vertexIndex = vertexCount * bone.Handle + vertexIndex;
                    mesh.AddBoneAssignment(vba);
                }
            }

            mesh.Load();
            mesh.Touch();

            return(mesh);
        }
Exemplo n.º 11
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();
        }
Exemplo n.º 12
0
        public void Stitch(HeightField south1, HeightField south2, HeightField east1,
                           HeightField east2, HeightField southEast, bool stitchMiddleSouth, bool stitchMiddleEast)
        {
            Debug.Assert((south2 == null || south2.metersPerSample == south1.metersPerSample), "south neighbors have different LOD");
            Debug.Assert((east2 == null || east2.metersPerSample == east1.metersPerSample), "east neighbors have different LOD");

            //
            // Determine the stitch types for south and east direction
            //
            StitchType southStitchType;
            StitchType eastStitchType;

            int southMetersPerSample = 0;

            if (south1 == null)
            {
                southStitchType = StitchType.None;
            }
            else
            {
                southMetersPerSample = south1.metersPerSample;

                if (south1.metersPerSample == metersPerSample)
                {
                    southStitchType = StitchType.ToSame;
                }
                else if (south1.metersPerSample > metersPerSample)
                {
                    Debug.Assert(south1.metersPerSample == (2 * metersPerSample), "stitching:south LOD not half");
                    southStitchType = StitchType.ToLower;
                }
                else
                {
                    Debug.Assert((south1.metersPerSample * 2) == metersPerSample, "stitching: south LOD not double");
                    southStitchType = StitchType.ToHigher;
                }
            }

            int eastMetersPerSample = 0;

            if (east1 == null)
            {
                eastStitchType = StitchType.None;
            }
            else
            {
                eastMetersPerSample = east1.metersPerSample;

                if (east1.metersPerSample == metersPerSample)
                {
                    eastStitchType = StitchType.ToSame;
                }
                else if (east1.metersPerSample > metersPerSample)
                {
                    Debug.Assert(east1.metersPerSample == (2 * metersPerSample), "stitching:east LOD not half");
                    eastStitchType = StitchType.ToLower;
                }
                else
                {
                    Debug.Assert((east1.metersPerSample * 2) == metersPerSample, "stitching:east LOD not double");
                    eastStitchType = StitchType.ToHigher;
                }
            }

            if (stitchRenderable != null)
            {
                if (stitchRenderable.IsValid(numSamples, southMetersPerSample, eastMetersPerSample))
                {                 // existing stitchRenderable is still ok, so just use it
                    return;
                }
                else
                {
                    stitchRenderable.Dispose();
                    stitchRenderable = null;
                }
            }

            //
            // The following combinations are acceptable:
            //  1) both same
            //  2) one same and one lower
            //  3) one same and one higher
            //  4) both lower
            //
            Debug.Assert(((southStitchType == StitchType.ToSame) || (eastStitchType == StitchType.ToSame)) ||
                         ((southStitchType == StitchType.ToLower) && (eastStitchType == StitchType.ToLower)) ||
                         ((southStitchType == StitchType.None) && (eastStitchType == StitchType.None)),
                         "stitching:invalid stitchType combination");

            bool bothSame  = false;
            bool bothLower = false;
            int  vertexCount;

            if (southStitchType == eastStitchType)
            {
                if (southStitchType == StitchType.ToSame)
                {
                    bothSame    = true;
                    vertexCount = numSamples * 4;
                }
                else if (southStitchType == StitchType.ToLower)
                {
                    bothLower   = true;
                    vertexCount = numSamples * 3;
                }
                else
                {
                    // both are StitchType.None, which means we are at the NE corner, so we dont need stitching
                    return;
                }
            }
            else
            {
                if ((southStitchType == StitchType.ToLower) || (eastStitchType == StitchType.ToLower))
                {
                    // one same and one lower
                    vertexCount = numSamples * 3 + (numSamples / 2);
                }
                else if ((southStitchType == StitchType.ToHigher) || (eastStitchType == StitchType.ToHigher))
                {
                    // one same and one higher
                    vertexCount = numSamples * 5;
                }
                else
                {
                    // one same and one none
                    vertexCount = numSamples * 2;
                }
            }

            VertexData vertexData = new VertexData();

            vertexData.vertexCount = vertexCount;
            vertexData.vertexStart = 0;

            // set up the vertex declaration
            int vDecOffset = 0;

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // create the hardware vertex buffer and set up the buffer binding
            HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

            // lock the vertex buffer
            IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

            int bufferOff = 0;

            int southSamples = 0;
            int eastSamples  = 0;
            int vertOff      = 0;

            unsafe
            {
                float *buffer = (float *)ipBuf.ToPointer();

                if (southStitchType != StitchType.None)
                {
                    //
                    // First the south edge of this tile
                    //
                    fillVerts(this, buffer, vertOff, numSamples, 0, numSamples - 1, 1, 0, 0, 0, tile.Page.Location);
                    vertOff += numSamples;
                }

                if (eastStitchType != StitchType.None)
                {
                    int adjust = 0;
                    if (southStitchType == StitchType.None)
                    {
                        // include the inner corner because it wasnt done with the south edge
                        adjust = 1;
                    }
                    //
                    // Now the east edge of the tile
                    //
                    fillVerts(this, buffer, vertOff, numSamples - 1 + adjust, numSamples - 1, numSamples - 2 + adjust, 0, -1, 0, 0, tile.Page.Location);
                    vertOff += (numSamples - 1 + adjust);
                }

                if (southStitchType != StitchType.None)
                {
                    //
                    // fill the verts from the south neighbor
                    //
                    southSamples = neighborSamples(southStitchType);

                    if (south2 == null)
                    {                     // only one southern neighbor
                        int xStart   = 0;
                        int xSampOff = 0;
                        if (stitchMiddleSouth)
                        {
                            // go from bottom to middle of east tile, rather than middle to top
                            xStart   = southSamples;
                            xSampOff = -tile.Size;
                        }

                        fillVerts(south1, buffer, vertOff, southSamples, xStart, 0, 1, 0, xSampOff, tile.Size, tile.Page.Location);
                        vertOff += southSamples;
                    }
                    else
                    {                     // two southern neighbors
                        int halfSamples = southSamples / 2;
                        fillVerts(south1, buffer, vertOff, halfSamples, 0, 0, 1, 0, 0, tile.Size, tile.Page.Location);
                        vertOff += halfSamples;

                        fillVerts(south2, buffer, vertOff, halfSamples, 0, 0, 1, 0, south1.tile.Size, tile.Size, tile.Page.Location);
                        vertOff += halfSamples;
                    }
                }

                if ((southStitchType != StitchType.None) && (eastStitchType != StitchType.None))
                {
                    //
                    // fill the single sample from the SE neighbor
                    //
                    if (southEast == east1)
                    {
                        fillVerts(southEast, buffer, vertOff, 1, 0, neighborSamples(eastStitchType), 0, 0, tile.Size, 0, tile.Page.Location);
                    }
                    else if (southEast == south1)
                    {
                        fillVerts(southEast, buffer, vertOff, 1, neighborSamples(southStitchType), 0, 0, 0, 0, tile.Size, tile.Page.Location);
                    }
                    else
                    {
                        fillVerts(southEast, buffer, vertOff, 1, 0, 0, 0, 0, tile.Size, tile.Size, tile.Page.Location);
                    }
                    vertOff++;
                }

                if (eastStitchType != StitchType.None)
                {
                    //
                    // fill the verts from the east neighbor
                    //
                    eastSamples = neighborSamples(eastStitchType);

                    if (east2 == null)
                    {                     // only one eastern neighbor
                        int zStart   = eastSamples - 1;
                        int zSampOff = 0;
                        if (stitchMiddleEast)
                        {
                            // go from bottom to middle of east tile, rather than middle to top
                            zStart   = (eastSamples * 2) - 1;
                            zSampOff = -tile.Size;
                        }

                        fillVerts(east1, buffer, vertOff, eastSamples, 0, zStart, 0, -1, tile.Size, zSampOff, tile.Page.Location);
                        vertOff += eastSamples;
                    }
                    else
                    {                     // two eastern neighbors
                        int halfSamples = eastSamples / 2;

                        fillVerts(east2, buffer, vertOff, halfSamples, 0, halfSamples - 1, 0, -1, tile.Size, east1.tile.Size, tile.Page.Location);
                        vertOff += halfSamples;

                        fillVerts(east1, buffer, vertOff, halfSamples, 0, halfSamples - 1, 0, -1, tile.Size, 0, tile.Page.Location);
                        vertOff += halfSamples;
                    }
                }

                Debug.Assert(vertexCount == vertOff, "stitching: generated incorrect number of vertices");
            }
            hvBuffer.Unlock();

            IndexData indexData = IndexBufferManager.Instance.GetStitchIndexBuffer(numSamples, southSamples, eastSamples);

            stitchRenderable = new StitchRenderable(this, vertexData, indexData, numSamples, southMetersPerSample, eastMetersPerSample);
        }
Exemplo n.º 13
0
        private VertexData buildVertexData()
        {
            VertexData vertexData = new VertexData();

            vertexData.vertexCount = numSamples * numSamples;
            vertexData.vertexStart = 0;

            // set up the vertex declaration
            int vDecOffset = 0;

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // create the hardware vertex buffer and set up the buffer binding
            HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

            // lock the vertex buffer
            IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

            int bufferOff = 0;

            unsafe
            {
                float *buffer          = (float *)ipBuf.ToPointer();
                int    heightMapOffset = 0;

                for (int zIndex = 0; zIndex < numSamples; zIndex++)
                {
                    float z = (zIndex * metersPerSample * WorldManager.oneMeter);

                    for (int xIndex = 0; xIndex < numSamples; xIndex++)
                    {
                        float height = heightMap[heightMapOffset++];

                        // Position
                        float x = (xIndex * metersPerSample * WorldManager.oneMeter);
                        buffer[bufferOff++] = x;
                        buffer[bufferOff++] = height;
                        buffer[bufferOff++] = z;

                        // normals
                        // XXX - this can be optimized quite a bit
                        Vector3 norm = tile.GetNormalAt(new Vector3(x + tile.Location.x, height, z + tile.Location.z));

                        buffer[bufferOff++] = norm.x;
                        buffer[bufferOff++] = norm.y;
                        buffer[bufferOff++] = norm.z;

                        // Texture
                        // XXX - assumes one unit of texture space is one page.
                        //   how does the vertex shader deal with texture coords?
                        buffer[bufferOff++] = (x + location.x - tile.Page.Location.x) /
                                              (WorldManager.Instance.PageSize * WorldManager.oneMeter);
                        buffer[bufferOff++] = (z + location.z - tile.Page.Location.z) /
                                              (WorldManager.Instance.PageSize * WorldManager.oneMeter);
                    }
                }
            }
            hvBuffer.Unlock();

            return(vertexData);
        }
Exemplo n.º 14
0
        private static void _createSphere(Mesh mesh)
        {
            // sphere creation code taken from the DeferredShading sample, originally from the [Ogre] wiki
            var pSphereVertex = mesh.CreateSubMesh();

            const int   NUM_SEGMENTS  = 16;
            const int   NUM_RINGS     = 16;
            const float SPHERE_RADIUS = 50.0f;

            mesh.SharedVertexData = new VertexData();
            var vertexData = mesh.SharedVertexData;

            // define the vertex format
            var vertexDecl = vertexData.vertexDeclaration;
            var offset     = 0;

            // positions
            vertexDecl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            // normals
            vertexDecl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            // two dimensional texture coordinates
            vertexDecl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // allocate the vertex buffer
            vertexData.vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS + 1);

            var vBuf = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDecl.Clone(0), vertexData.vertexCount,
                                                                         BufferUsage.StaticWriteOnly, false);

            var binding = vertexData.vertexBufferBinding;

            binding.SetBinding(0, vBuf);

            // allocate index buffer
            pSphereVertex.IndexData.indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1);

            pSphereVertex.IndexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16,
                                                                                                   pSphereVertex.IndexData.
                                                                                                   indexCount,
                                                                                                   BufferUsage.StaticWriteOnly,
                                                                                                   false);
            var iBuf = pSphereVertex.IndexData.indexBuffer;

#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                var iVertex  = 0;
                var pVertex  = vBuf.Lock(BufferLocking.Discard).ToFloatPointer();
                var iIndices = 0;
                var pIndices = iBuf.Lock(BufferLocking.Discard).ToUShortPointer();

                float  fDeltaRingAngle = (Utility.PI / NUM_RINGS);
                float  fDeltaSegAngle  = (2 * Utility.PI / NUM_SEGMENTS);
                ushort wVerticeIndex   = 0;

                // Generate the group of rings for the sphere
                for (var ring = 0; ring <= NUM_RINGS; ring++)
                {
                    float r0 = SPHERE_RADIUS * Utility.Sin(ring * fDeltaRingAngle);
                    float y0 = SPHERE_RADIUS * Utility.Cos(ring * fDeltaRingAngle);

                    // Generate the group of segments for the current ring
                    for (var seg = 0; seg <= NUM_SEGMENTS; seg++)
                    {
                        float x0 = r0 * Utility.Sin(seg * fDeltaSegAngle);
                        float z0 = r0 * Utility.Cos(seg * fDeltaSegAngle);

                        // Add one vertex to the strip which makes up the sphere
                        pVertex[iVertex++] = x0;
                        pVertex[iVertex++] = y0;
                        pVertex[iVertex++] = z0;

                        var vNormal = new Vector3(x0, y0, z0).ToNormalized();
                        pVertex[iVertex++] = vNormal.x;
                        pVertex[iVertex++] = vNormal.y;
                        pVertex[iVertex++] = vNormal.z;

                        pVertex[iVertex++] = (float)seg / (float)NUM_SEGMENTS;
                        pVertex[iVertex++] = (float)ring / (float)NUM_RINGS;

                        if (ring != NUM_RINGS)
                        {
                            // each vertex (except the last) has six indicies pointing to it
                            pIndices[iIndices++] = (ushort)(wVerticeIndex + NUM_SEGMENTS + 1);
                            pIndices[iIndices++] = (ushort)(wVerticeIndex);
                            pIndices[iIndices++] = (ushort)(wVerticeIndex + NUM_SEGMENTS);
                            pIndices[iIndices++] = (ushort)(wVerticeIndex + NUM_SEGMENTS + 1);
                            pIndices[iIndices++] = (ushort)(wVerticeIndex + 1);
                            pIndices[iIndices++] = (ushort)(wVerticeIndex);
                            wVerticeIndex++;
                        }
                    }
                    ;             // end for seg
                }                 // end for ring
            }

            // Unlock
            vBuf.Unlock();
            iBuf.Unlock();

            // Generate face list
            pSphereVertex.useSharedVertices = true;

            // the original code was missing this line:
            mesh.BoundingBox = new AxisAlignedBox(new Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS),
                                                  new Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS));

            mesh.BoundingSphereRadius = SPHERE_RADIUS;
        }
Exemplo n.º 15
0
        /**	Initializes the LandScapeRenderable with the given options and the starting coordinates of this block.
         */
        public Renderable() : base()
        {
            info             = null;
            materialLODIndex = 0;

            neighbors = new Renderable[4];
            for (long i = 0; i < 4; i++)
            {
                neighbors[i] = null;
            }

            inUse    = false;
            isLoaded = false;
            // Setup render op
            renderOp                        = new RenderOperation();
            renderOp.vertexData             = new VertexData();
            renderOp.vertexData.vertexStart = 0;
            long tileSize = Options.Instance.TileSize;

            renderOp.vertexData.vertexCount = (int)((tileSize + 1) * (tileSize + 1));

            box = new AxisAlignedBox();

            // Vertex declaration
            VertexDeclaration   decl = renderOp.vertexData.vertexDeclaration;
            VertexBufferBinding bind = renderOp.vertexData.vertexBufferBinding;

            HardwareVertexBuffer vbuf;
            // Vertex buffer #1, position
            // positions
            int offset = 0;

            decl.AddElement(POSITION, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            if (Options.Instance.Lit)
            {
                decl.AddElement(POSITION, offset, VertexElementType.Float3, VertexElementSemantic.Normal);
                offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            }
            decl.AddElement(POSITION, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            vbuf    = HardwareBufferManager.Instance.CreateVertexBuffer(
                decl.GetVertexSize(POSITION),
                renderOp.vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            bind.SetBinding(POSITION, vbuf);

//			if (Options.Instance.Lit)
//			{
//				offset = 0;
//				decl.AddElement(NORMAL, offset, VertexElementType.Float3, VertexElementSemantic.Normal);
//				offset += VertexElement.GetTypeSize(VertexElementType.Float3);
//				vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
//					decl.GetVertexSize(NORMAL),
//					renderOp.vertexData.vertexCount,
//					BufferUsage.StaticWriteOnly);
//
//				bind.SetBinding(NORMAL, vbuf);
//			}
//
//			offset = 0;
//			decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
//			offset += VertexElement.GetTypeSize(VertexElementType.Float2);
//			vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
//				decl.GetVertexSize(TEXCOORD),
//				renderOp.vertexData.vertexCount,
//				BufferUsage.StaticWriteOnly);
//
//			bind.SetBinding(TEXCOORD, vbuf);
//
//
//			if (Options.Instance.Colored  ||
//				Options.Instance.Coverage_Vertex_Color ||
//				Options.Instance.Base_Vertex_Color)
//			{
//				offset = 0;
//				decl.AddElement(COLORS, offset,  VertexElementType.Float3, VertexElementSemantic.Diffuse);
//				offset += VertexElement.GetTypeSize(VertexElementType.Color);
//				vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
//					decl.GetVertexSize(COLORS),
//					renderOp.vertexData.vertexCount,
//					BufferUsage.StaticWriteOnly);
//
//				bind.SetBinding(COLORS, vbuf);
//			}

            //No need to set the indexData since it is shared from IndexBuffer class
            renderOp.operationType = OperationType.TriangleList;
            renderOp.useIndices    = true;

            renderOp.indexData = null;

            RenderLevel = Options.Instance.MaxRenderLevel / 2;
        }
Exemplo n.º 16
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();
        }
Exemplo n.º 17
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);
            }
        }
Exemplo n.º 18
0
        private void LoadLevelVertices(Quake3Level q3lvl)
        {
            //-----------------------------------------------------------------------
            // Vertices
            //-----------------------------------------------------------------------
            // Allocate memory for vertices & copy
            vertexData = new VertexData();

            // Create vertex declaration
            VertexDeclaration decl = vertexData.vertexDeclaration;
            int offset             = 0;
            int lightTexOffset     = 0;

            decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal);
            offset += VertexElement.GetTypeSize(VertexElementType.Float3);
            decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1);

            // Build initial patches - we need to know how big the vertex buffer needs to be
            // to accommodate the subdivision
            // we don't want to include the elements for texture lighting, so we clone it
            InitQuake3Patches(q3lvl, (VertexDeclaration)decl.Clone());

            // this is for texture lighting color and alpha
            decl.AddElement(1, lightTexOffset, VertexElementType.Color, VertexElementSemantic.Diffuse);
            lightTexOffset += VertexElement.GetTypeSize(VertexElementType.Color);
            // this is for texture lighting coords
            decl.AddElement(1, lightTexOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 2);


            // Create the vertex buffer, allow space for patches
            HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(
                Marshal.SizeOf(typeof(BspVertex)),
                q3lvl.NumVertices + patchVertexCount,
                BufferUsage.StaticWriteOnly,
                // the vertices will be read often for texture lighting, use shadow buffer
                true
                );

            // Create the vertex buffer for texture lighting, allow space for patches
            HardwareVertexBuffer texLightBuf = HardwareBufferManager.Instance.CreateVertexBuffer(
                Marshal.SizeOf(typeof(TextureLightMap)),
                q3lvl.NumVertices + patchVertexCount,
                BufferUsage.DynamicWriteOnly,
                false
                );

            // COPY static vertex data - Note that we can't just block-copy the vertex data because we have to reorder
            // our vertex elements; this is to ensure compatibility with older cards when using
            // hardware vertex buffers - Direct3D requires that the buffer format maps onto a
            // FVF in those older drivers.
            // Lock just the non-patch area for now.

            unsafe
            {
                BspVertex       vert        = new BspVertex();
                TextureLightMap texLightMap = new TextureLightMap();

                // Keep another base pointer for use later in patch building
                for (int v = 0; v < q3lvl.NumVertices; v++)
                {
                    QuakeVertexToBspVertex(q3lvl.Vertices[v], out vert, out texLightMap);

                    BspVertex *      bvptr = &vert;
                    TextureLightMap *tlptr = &texLightMap;

                    vbuf.WriteData(
                        v * sizeof(BspVertex),
                        sizeof(BspVertex),
                        (IntPtr)bvptr
                        );

                    texLightBuf.WriteData(
                        v * sizeof(TextureLightMap),
                        sizeof(TextureLightMap),
                        (IntPtr)tlptr
                        );
                }
            }

            // Setup binding
            vertexData.vertexBufferBinding.SetBinding(0, vbuf);

            // Setup texture lighting binding
            vertexData.vertexBufferBinding.SetBinding(1, texLightBuf);

            // Set other data
            vertexData.vertexStart = 0;
            vertexData.vertexCount = q3lvl.NumVertices + patchVertexCount;
        }
Exemplo n.º 19
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);
            }
        }
Exemplo n.º 20
0
        public unsafe void createMesh()
        {
            /// Create the mesh via the MeshManager
            MeshPtr msh = MeshManager.Singleton.CreateManual("ColourCube", "General");

            /// Create one submesh
            SubMesh sub = msh.CreateSubMesh();

            /// Define the vertices (8 vertices, each consisting of 2 groups of 3 floats
            //const int nVertices = 8;
            //int row = recordno;
            // int col = demcol;
            int  row  = recordno;
            int  col  = 1100;
            int  step = 10;
            int  vbufCount;
            uint nVertices = (uint)(col * row);

            float[] vertices = CreateVertices(row, col, step, out vbufCount);


            /// Define 12 triangles (two triangles per cube face)
            /// The values in this table refer to vertices in the above table
            uint ibufCount;

            ushort[] faces = CreateFaces(row, col, out ibufCount);

            /// Create vertex data structure for 8 vertices shared between submeshes
            msh.sharedVertexData             = new VertexData();
            msh.sharedVertexData.vertexCount = nVertices;

            /// Create declaration (memory format) of vertex data
            VertexDeclaration decl = msh.sharedVertexData.vertexDeclaration;
            uint offset            = 0;

            // 1st buffer
            decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3);
            decl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES);
            offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2);
            /// Allocate vertex buffer of the requested number of vertices (vertexCount)
            /// and bytes per vertex (offset)
            HardwareVertexBufferSharedPtr vbuf =
                HardwareBufferManager.Singleton.CreateVertexBuffer(offset, msh.sharedVertexData.vertexCount,
                                                                   HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);


            /// Upload the vertex data to the card
            fixed(void *p = vertices)
            {
                vbuf.WriteData(0, vbuf.SizeInBytes, p, true);// writeData(0, vbuf->getSizeInBytes(), vertices, true);
            }

            /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
            VertexBufferBinding bind = msh.sharedVertexData.vertexBufferBinding;//  msh->sharedVertexData->vertexBufferBinding;

            bind.SetBinding(0, vbuf);

            /// Allocate index buffer of the requested number of vertices (ibufCount)
            HardwareIndexBufferSharedPtr ibuf =
                HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT,
                                                                  ibufCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY);

            /// Upload the index data to the card
            fixed(void *p = faces)
            {
                ibuf.WriteData(0, ibuf.SizeInBytes, p, true);
            }

            /// Set parameters of the submesh
            sub.useSharedVertices     = true;
            sub.indexData.indexBuffer = ibuf;
            sub.indexData.indexCount  = ibufCount;
            sub.indexData.indexStart  = 0;

            /// Set bounding information (for culling)
            msh._setBounds(new AxisAlignedBox(min, max));
            // msh._setBoundingSphereRadius(Mogre.Math.Sqrt(3 * 100 * 100));

            /// Notify Mesh object that it has been loaded
            msh.Load();
        }
Exemplo n.º 21
0
            protected int CopyVertices(HardwareVertexBuffer srcBuf, BufferBase pDst, List <VertexElement> elems,
                                       QueuedGeometry geom, Vector3 regionCenter)
            {
#if !AXIOM_SAFE_ONLY
                unsafe
#endif
                {
                    // lock source
                    var src    = srcBuf.Lock(BufferLocking.ReadOnly);
                    var bufInc = srcBuf.VertexSize;

                    var temp = Vector3.Zero;

                    // Calculate elem sizes outside the loop
                    var elemSizes = new int[elems.Count];
                    for (var i = 0; i < elems.Count; i++)
                    {
                        elemSizes[i] = VertexElement.GetTypeSize(elems[i].Type);
                    }

                    // Move the position offset calculation outside the loop
                    var positionDelta = geom.position - regionCenter;

                    for (var v = 0; v < geom.geometry.vertexData.vertexCount; ++v)
                    {
                        // iterate over vertex elements
                        for (var i = 0; i < elems.Count; i++)
                        {
                            var elem     = elems[i];
                            var pSrcReal = (src + elem.Offset).ToFloatPointer();
                            var pDstReal = (pDst + elem.Offset).ToFloatPointer();

                            switch (elem.Semantic)
                            {
                            case VertexElementSemantic.Position:
                                temp.x = pSrcReal[0];
                                temp.y = pSrcReal[1];
                                temp.z = pSrcReal[2];
                                // transform
                                temp        = (geom.orientation * (temp * geom.scale));
                                pDstReal[0] = temp.x + positionDelta.x;
                                pDstReal[1] = temp.y + positionDelta.y;
                                pDstReal[2] = temp.z + positionDelta.z;
                                break;

                            case VertexElementSemantic.Normal:
                            case VertexElementSemantic.Tangent:
                            case VertexElementSemantic.Binormal:
                                temp.x = pSrcReal[0];
                                temp.y = pSrcReal[1];
                                temp.z = pSrcReal[2];
                                // rotation only
                                temp        = geom.orientation * temp;
                                pDstReal[0] = temp.x;
                                pDstReal[1] = temp.y;
                                pDstReal[2] = temp.z;
                                break;

                            default:
                                // just raw copy
                                var size = elemSizes[i];
                                // Optimize the loop for the case that
                                // these things are in units of 4
                                if ((size & 0x3) == 0x3)
                                {
                                    var cnt = size / 4;
                                    while (cnt-- > 0)
                                    {
                                        pDstReal[cnt] = pSrcReal[cnt];
                                    }
                                }
                                else
                                {
                                    // Fall back to the byte-by-byte copy
                                    var pbSrc = (src + elem.Offset).ToBytePointer();
                                    var pbDst = (pDst + elem.Offset).ToBytePointer();
                                    while (size-- > 0)
                                    {
                                        pbDst[size] = pbSrc[size];
                                    }
                                }
                                break;
                            }
                        }

                        // Increment both pointers
                        pDst.Ptr += bufInc;
                        src.Ptr  += bufInc;
                    }

                    srcBuf.Unlock();
                    return(pDst.Ptr);
                }
            }