예제 #1
0
        public override void LoadPage(PageInfo page)
        {
            //Calculate x/z indexes for the grid array
            page.XIndex -= (int)System.Math.Floor(mGridBounds.Left / mPageSize);
            page.ZIndex -= (int)System.Math.Floor(mGridBounds.Top / mPageSize);

            //Check if the requested page is in bounds
            if (page.XIndex < 0 || page.ZIndex < 0 || page.XIndex >= mPageGridX || page.ZIndex >= mPageGridZ)
            {
                return;
            }

            //For each tree type...
            foreach (KeyValuePair <Entity, List <List <TreeDef> > > it in mPageGridList)
            {
                //Get the appropriate tree list for the specified page
                List <List <TreeDef> > pageGrid = it.Value;
                List <TreeDef>         treeList = GetGridPage(pageGrid, page.XIndex, page.ZIndex);
                Entity entity = it.Key;

                //Load the listed trees into the page
                foreach (TreeDef o in treeList)
                {
                    //Get position
                    Vector3 pos = Vector3.Zero;
                    pos.x = page.Bounds.Left + ((float)o.XPos / 65535) * mPageSize;
                    pos.z = page.Bounds.Top + ((float)o.ZPos / 65535) * mPageSize;

                    //Calculate terrain height at pos.x / pos.z to get pos.y
                    if (mHeightFunction != null)
                    {
                        pos.y = mHeightFunction.GetHeightAt(pos.x, pos.z, mHeightFunctionUserData);
                    }
                    else
                    {
                        pos.y = 0.0f;
                    }

                    //Get rotation
                    Degree     angle = new Degree((Real)o.Rotation * (360.0f / 255));
                    Quaternion rot   = Quaternion.FromAngleAxis((float)angle.InRadians, Vector3.UnitY);

                    //Get scale
                    Vector3 scale = Vector3.Zero;
                    scale.y = (float)(o.Scale * (mMaximumScale / 255) + mMinimumScale);
                    scale.x = scale.y;
                    scale.z = scale.y;

                    //Get color
                    ColorEx col = ColorEx.White;
                    if (mColorMap != null)
                    {
                        col = mColorMap.GetColorAtUnpacked(pos.x, pos.z);
                    }

                    AddEntity(entity, pos, rot, scale, col);
                }
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="page"></param>
        /// <param name="layer"></param>
        /// <param name="grassPostions"></param>
        /// <param name="grassCount"></param>
        /// <returns></returns>
        private Mesh GenerateGrassQuad(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.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 halfScaleX = (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) * halfScaleX;
                    float zTrans = MogreLibMath.Utility.Sin(angle) * halfScaleX;

                    //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;
                    }
                }

                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);
            }
        }