Пример #1
0
        public string GetOrCreateMaterial(WarpRenderer renderer, Color4 faceColor, UUID textureID, bool useAverageTextureColor, SceneObjectPart sop)
        {
            int    color        = ConvertColor(faceColor);
            string idstr        = textureID.ToString() + color.ToString();
            string materialName = "MAPMAT" + idstr;

            if (renderer.Scene.material(materialName) != null)
            {
                return(materialName);
            }

            warp_Material mat     = new warp_Material();
            warp_Texture  texture = GetTexture(textureID, sop);

            if (texture != null)
            {
                if (useAverageTextureColor)
                {
                    color = warp_Color.multiply(color, texture.averageColor);
                }
                else
                {
                    mat.setTexture(texture);
                }
            }
            else
            {
                color = warp_Color.multiply(color, warp_Color.Grey);
            }

            mat.setColor(color);
            renderer.Scene.addMaterial(materialName, mat);

            return(materialName);
        }
Пример #2
0
        // Add a water plane to the renderer.
        private void CreateWater(WarpRenderer renderer)
        {
            float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;

            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f, false);
            renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX * 0.5f,
                                                       waterHeight,
                                                       m_scene.RegionInfo.RegionSizeY * 0.5f);

            warp_Material waterMaterial = new warp_Material(ConvertColor(WATER_COLOR));

            renderer.Scene.addMaterial("WaterMat", waterMaterial);
            renderer.SetObjectMaterial("Water", "WaterMat");
        }
Пример #3
0
        private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color)
        {
            string name = color.ToString();

            warp_Material material = renderer.Scene.material(name);

            if (material != null)
            {
                return(name);
            }

            renderer.AddMaterial(name, ConvertColor(color));
            return(name);
        }
        private void CreateWater(WarpRenderer renderer)
        {
            float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;

            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f);
            renderer.Scene.sceneobject("Water").setPos((m_scene.RegionInfo.RegionSizeX / 2) - 0.5f, waterHeight,
                                                       (m_scene.RegionInfo.RegionSizeY / 2) - 0.5f);

            RegionLightShareData rls = m_scene.RequestModuleInterface <IWindLightSettingsModule>().FindRegionWindLight();

            warp_Material waterColormaterial;

            if (rls != null)
            {
                waterColormaterial =
                    new warp_Material(
                        ConvertColor(new Color4(rls.waterColor.X / 256, rls.waterColor.Y / 256, rls.waterColor.Z / 256,
                                                WATER_COLOR.A)));
            }
            else
            {
                waterColormaterial = new warp_Material(ConvertColor(WATER_COLOR));
            }

            waterColormaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f) * 2);
            waterColormaterial.setReflectivity(50);
            renderer.Scene.addMaterial("WaterColor", waterColormaterial);
            renderer.SetObjectMaterial("Water", "WaterColor");

            /*
             * AssetBase textureAsset = m_scene.AssetService.Get(rls.normalMapTexture.ToString());
             * if (textureAsset != null)
             * {
             *  IJ2KDecoder decoder = m_scene.RequestModuleInterface<IJ2KDecoder> ();
             *  Bitmap bitmap = (Bitmap)decoder.DecodeToImage (textureAsset.Data);
             *  if (bitmap != null)
             *  {
             *      textureAsset = null;
             *      warp_Texture texture = new warp_Texture (bitmap);
             *      warp_Material waterTextmaterial = new warp_Material (texture);
             *      waterTextmaterial.setTransparency ((byte)((1f - WATER_COLOR.A) * 255f) * 4);
             *      waterTextmaterial.setReflectivity (0);
             *      renderer.AddPlane ("Water2", m_scene.RegionInfo.RegionSizeX * 0.5f);
             *      renderer.Scene.sceneobject ("Water2").setPos ((m_scene.RegionInfo.RegionSizeX / 2) - 0.5f, waterHeight, (m_scene.RegionInfo.RegionSizeY / 2) - 0.5f);
             *      renderer.Scene.addMaterial ("WaterColor2", waterTextmaterial);
             *      renderer.SetObjectMaterial ("Water2", "WaterColor2");
             *  }
             * }*/
        }
Пример #5
0
        private void CreateWater(WarpRenderer renderer)
        {
            float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;

            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f);
            renderer.Scene.sceneobject("Water").setPos((m_scene.RegionInfo.RegionSizeX / 2) - 0.5f, waterHeight,
                                                       (m_scene.RegionInfo.RegionSizeY / 2) - 0.5f);

            warp_Material waterColormaterial = new warp_Material(ConvertColor(WATER_COLOR));

            waterColormaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f) * 2);
            waterColormaterial.setReflectivity(50);
            renderer.Scene.addMaterial("WaterColor", waterColormaterial);
            renderer.SetObjectMaterial("Water", "WaterColor");
        }
Пример #6
0
        private void CreateWater(WarpRenderer renderer, bool threeD)
        {
            float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;

            warp_Material waterColormaterial;

            if (!threeD)
            {
                if (m_scene.RegionInfo.RegionSizeX >= m_scene.RegionInfo.RegionSizeY)
                {
                    renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX / 2);
                }
                else
                {
                    renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeY / 2);
                }

                renderer.Scene.sceneobject("Water").setPos((m_scene.RegionInfo.RegionSizeX / 2) - 0.5f, waterHeight,
                                                           (m_scene.RegionInfo.RegionSizeY / 2) - 0.5f);
                waterColormaterial = new warp_Material(ConvertColor(WATER_COLOR));
                waterColormaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f) * 2);
            }
            else
            {
                if (m_scene.RegionInfo.RegionSizeX >= m_scene.RegionInfo.RegionSizeY)
                {
                    renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX / 2);
                }
                else
                {
                    renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeY / 2);
                }

                renderer.Scene.sceneobject("Water").setPos(
                    (m_scene.RegionInfo.RegionSizeX / 2) - 0.5f,
                    -0.5f,
                    waterHeight + 5.1f
                    );

                waterColormaterial = new warp_Material(ConvertColor(OPAQUE_WATER_COLOR));
                waterColormaterial.setTransparency(48);
                //waterColormaterial.opaque = true;
            }

            waterColormaterial.setReflectivity(0);
            renderer.Scene.addMaterial("WaterColor", waterColormaterial);
            renderer.SetObjectMaterial("Water", "WaterColor");
        }
Пример #7
0
        // Add a water plane to the renderer.
        private void CreateWater(WarpRenderer renderer)
        {
            float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;

            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f);
            renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX * 0.5f - 0.5f,
                                                       waterHeight,
                                                       m_scene.RegionInfo.RegionSizeY * 0.5f - 0.5f);

            warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR));

            waterColorMaterial.setReflectivity(0);  // match water color with standard map module thanks lkalif
            waterColorMaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
            renderer.Scene.addMaterial("WaterColor", waterColorMaterial);
            renderer.SetObjectMaterial("Water", "WaterColor");
        }
Пример #8
0
        private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color)
        {
            string name = color.ToString();

            warp_Material material = renderer.Scene.material(name);

            if (material != null)
            {
                return(name);
            }

            renderer.AddMaterial(name, ConvertColor(color));
            if (color.A < 1f)
            {
                renderer.Scene.material(name).setTransparency((byte)((1f - color.A) * 255f));
            }
            return(name);
        }
Пример #9
0
        // Add a terrain to the renderer.
        // Note that we create a 'low resolution' 256x256 vertex terrain rather than trying for
        //    full resolution. This saves a lot of memory especially for very large regions.
        private void CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.Heightmap;

            // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding
            float diff = (float)m_scene.RegionInfo.RegionSizeX / 256f;

            warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2);

            // Create all the vertices for the terrain
            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                {
                    warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]);
                    obj.addVertex(new warp_Vertex(pos,
                                                  x / (float)m_scene.RegionInfo.RegionSizeX,
                                                  (((float)m_scene.RegionInfo.RegionSizeY) - y) / m_scene.RegionInfo.RegionSizeY));
                }
            }

            // Now that we have all the vertices, make another pass and create
            //     the normals for each of the surface triangles and
            //     create the list of triangle indices.
            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                {
                    float newX = x / diff;
                    float newY = y / diff;
                    if (newX < 255 && newY < 255)
                    {
                        int v = (int)newY * 256 + (int)newX;

                        // Normal for a triangle made up of three adjacent vertices
                        Vector3     v1   = new Vector3(newX, newY, (float)terrain[(int)x, (int)y]);
                        Vector3     v2   = new Vector3(newX + 1, newY, (float)terrain[(int)(x + 1), (int)y]);
                        Vector3     v3   = new Vector3(newX, newY + 1, (float)terrain[(int)x, ((int)(y + 1))]);
                        warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                        norm            = norm.reverse();
                        obj.vertex(v).n = norm;

                        // Make two triangles for each of the squares in the grid of vertices
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + 256);

                        obj.addTriangle(
                            v + 256 + 1,
                            v + 256,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            OpenSim.Framework.RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float)regionInfo.Elevation1SW;
            startHeights[1] = (float)regionInfo.Elevation1NW;
            startHeights[2] = (float)regionInfo.Elevation1SE;
            startHeights[3] = (float)regionInfo.Elevation1NE;

            heightRanges[0] = (float)regionInfo.Elevation2SW;
            heightRanges[1] = (float)regionInfo.Elevation2NW;
            heightRanges[2] = (float)regionInfo.Elevation2SE;
            heightRanges[3] = (float)regionInfo.Elevation2NE;

            uint globalX, globalY;

            Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            warp_Texture texture;

            using (
                Bitmap image
                    = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges,
                                         new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain))
            {
                texture = new warp_Texture(image);
            }

            warp_Material material = new warp_Material(texture);

            material.setReflectivity(50);
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.Scene.material("TerrainColor").setReflectivity(0);             // reduces tile seams a bit thanks lkalif
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
        }
Пример #10
0
        private void CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.Heightmap;

            float[] heightmap = terrain.GetFloatsSerialised();

            warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2);

            for (int y = 0; y < 256; y++)
            {
                for (int x = 0; x < 256; x++)
                {
                    int   v      = y * 256 + x;
                    float height = heightmap[v];

                    warp_Vector pos = ConvertVector(new Vector3(x, y, height));
                    obj.addVertex(new warp_Vertex(pos, (float)x / 255f, (float)(255 - y) / 255f));
                }
            }

            for (int y = 0; y < 256; y++)
            {
                for (int x = 0; x < 256; x++)
                {
                    if (x < 255 && y < 255)
                    {
                        int v = y * 256 + x;

                        // Normal
                        Vector3     v1   = new Vector3(x, y, heightmap[y * 256 + x]);
                        Vector3     v2   = new Vector3(x + 1, y, heightmap[y * 256 + x + 1]);
                        Vector3     v3   = new Vector3(x, y + 1, heightmap[(y + 1) * 256 + x]);
                        warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                        norm            = norm.reverse();
                        obj.vertex(v).n = norm;

                        // Triangle 1
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + 256);

                        // Triangle 2
                        obj.addTriangle(
                            v + 256 + 1,
                            v + 256,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float)regionInfo.Elevation1SW;
            startHeights[1] = (float)regionInfo.Elevation1NW;
            startHeights[2] = (float)regionInfo.Elevation1SE;
            startHeights[3] = (float)regionInfo.Elevation1NE;

            heightRanges[0] = (float)regionInfo.Elevation2SW;
            heightRanges[1] = (float)regionInfo.Elevation2NW;
            heightRanges[2] = (float)regionInfo.Elevation2SE;
            heightRanges[3] = (float)regionInfo.Elevation2NE;

            uint globalX, globalY;

            Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            warp_Texture texture;

            using (
                Bitmap image
                    = TerrainSplat.Splat(
                          heightmap, textureIDs, startHeights, heightRanges,
                          new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain))
            {
                texture = new warp_Texture(image);
            }

            warp_Material material = new warp_Material(texture);

            material.setReflectivity(50);
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.Scene.material("TerrainColor").setReflectivity(0);             // reduces tile seams a bit thanks lkalif
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
        }
Пример #11
0
        // Add a terrain to the renderer.
        // Note that we create a 'low resolution' 257x257 vertex terrain rather than trying for
        //    full resolution. This saves a lot of memory especially for very large regions.
        private void CreateTerrain(WarpRenderer renderer)
        {
            ITerrainChannel terrain = m_scene.Heightmap;

            float regionsx = m_scene.RegionInfo.RegionSizeX;
            float regionsy = m_scene.RegionInfo.RegionSizeY;

            // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding

            int bitWidth;
            int bitHeight;

            const double log2inv = 1.4426950408889634073599246810019;

            bitWidth  = (int)Math.Ceiling((Math.Log(terrain.Width) * log2inv));
            bitHeight = (int)Math.Ceiling((Math.Log(terrain.Height) * log2inv));

            if (bitWidth > 8) // more than 256 is very heavy :(
            {
                bitWidth = 8;
            }
            if (bitHeight > 8)
            {
                bitHeight = 8;
            }

            int twidth  = (int)Math.Pow(2, bitWidth);
            int theight = (int)Math.Pow(2, bitHeight);

            float diff = regionsx / twidth;

            int npointsx = (int)(regionsx / diff);
            int npointsy = (int)(regionsy / diff);

            float invsx = 1.0f / (npointsx * diff);
            float invsy = 1.0f / (npointsy * diff);

            npointsx++;
            npointsy++;

            // Create all the vertices for the terrain
            warp_Object obj = new warp_Object();
            warp_Vector pos;
            float       x, y;
            float       tv;

            for (y = 0; y < regionsy; y += diff)
            {
                tv = y * invsy;
                for (x = 0; x < regionsx; x += diff)
                {
                    pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]);
                    obj.addVertex(new warp_Vertex(pos, x * invsx, tv));
                }
                pos = ConvertVector(x, y, (float)terrain[(int)(x - diff), (int)y]);
                obj.addVertex(new warp_Vertex(pos, 1.0f, tv));
            }

            int lastY = (int)(y - diff);

            for (x = 0; x < regionsx; x += diff)
            {
                pos = ConvertVector(x, y, (float)terrain[(int)x, lastY]);
                obj.addVertex(new warp_Vertex(pos, x * invsx, 1.0f));
            }
            pos = ConvertVector(x, y, (float)terrain[(int)(x - diff), lastY]);
            obj.addVertex(new warp_Vertex(pos, 1.0f, 1.0f));

            // create triangles.
            int limx = npointsx - 1;
            int limy = npointsy - 1;

            for (int j = 0; j < limy; j++)
            {
                for (int i = 0; i < limx; i++)
                {
                    int v = j * npointsx + i;

                    // Make two triangles for each of the squares in the grid of vertices
                    obj.addTriangle(
                        v,
                        v + 1,
                        v + npointsx);

                    obj.addTriangle(
                        v + npointsx + 1,
                        v + npointsx,
                        v + 1);
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            OpenSim.Framework.RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float)regionInfo.Elevation1SW;
            startHeights[1] = (float)regionInfo.Elevation1NW;
            startHeights[2] = (float)regionInfo.Elevation1SE;
            startHeights[3] = (float)regionInfo.Elevation1NE;

            heightRanges[0] = (float)regionInfo.Elevation2SW;
            heightRanges[1] = (float)regionInfo.Elevation2NW;
            heightRanges[2] = (float)regionInfo.Elevation2SE;
            heightRanges[3] = (float)regionInfo.Elevation2NE;

            warp_Texture texture;

            using (Bitmap image = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges,
                                                     m_scene.RegionInfo.WorldLocX, m_scene.RegionInfo.WorldLocY,
                                                     m_scene.AssetService, m_imgDecoder, m_textureTerrain, m_textureAverageTerrain,
                                                     twidth, twidth))
                texture = new warp_Texture(image);

            warp_Material material = new warp_Material(texture);

            renderer.Scene.addMaterial("TerrainMat", material);
            renderer.SetObjectMaterial("Terrain", "TerrainMat");
        }
Пример #12
0
        private void CreateTerrain(IScene scene, WarpRenderer renderer, ITerrain terrain, RegionInfo regionInfo)
        {
            float[] heightmap = (terrain != null) ? terrain.GetHeightmap() : new float[256 * 256];

            warp_Object obj = new warp_Object(256 * 256, 255 * 255 * 2);

            for (int y = 0; y < 256; y++)
            {
                for (int x = 0; x < 256; x++)
                {
                    int   v      = y * 256 + x;
                    float height = heightmap[v];

                    warp_Vector pos = ConvertVector(new Vector3(x, y, height));
                    obj.addVertex(new warp_Vertex(pos, (float)x / 255f, (float)(255 - y) / 255f));
                }
            }

            for (int y = 0; y < 256; y++)
            {
                for (int x = 0; x < 256; x++)
                {
                    if (x < 255 && y < 255)
                    {
                        int v = y * 256 + x;

                        // Normal
                        Vector3     v1   = new Vector3(x, y, heightmap[y * 256 + x]);
                        Vector3     v2   = new Vector3(x + 1, y, heightmap[y * 256 + x + 1]);
                        Vector3     v3   = new Vector3(x, y + 1, heightmap[(y + 1) * 256 + x]);
                        warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                        norm            = norm.reverse();
                        obj.vertex(v).n = norm;

                        // Triangle 1
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + 256);

                        // Triangle 2
                        obj.addTriangle(
                            v + 256 + 1,
                            v + 256,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];
            if (regionInfo != null)
            {
                textureIDs[0] = regionInfo.TerrainDetail0;
                textureIDs[1] = regionInfo.TerrainDetail1;
                textureIDs[2] = regionInfo.TerrainDetail2;
                textureIDs[3] = regionInfo.TerrainDetail3;

                startHeights[0] = regionInfo.TerrainStartHeight00;
                startHeights[1] = regionInfo.TerrainStartHeight01;
                startHeights[2] = regionInfo.TerrainStartHeight10;
                startHeights[3] = regionInfo.TerrainStartHeight11;

                heightRanges[0] = regionInfo.TerrainHeightRange00;
                heightRanges[1] = regionInfo.TerrainHeightRange01;
                heightRanges[2] = regionInfo.TerrainHeightRange10;
                heightRanges[3] = regionInfo.TerrainHeightRange11;
            }

            Bitmap        image    = TerrainSplat.Splat(heightmap, textureIDs, startHeights, heightRanges, scene.MinPosition, m_assetClient);
            warp_Texture  texture  = new warp_Texture(image);
            warp_Material material = new warp_Material(texture);

            material.setReflectivity(50);
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
        }
Пример #13
0
        private void CreateWater(WarpRenderer renderer)
        {
            float waterHeight = (float) m_scene.RegionInfo.RegionSettings.WaterHeight;

            renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX*0.5f);
            renderer.Scene.sceneobject("Water").setPos((m_scene.RegionInfo.RegionSizeX/2) - 0.5f, waterHeight,
                                                       (m_scene.RegionInfo.RegionSizeY/2) - 0.5f);

            warp_Material waterColormaterial = new warp_Material(ConvertColor(WATER_COLOR));
            waterColormaterial.setTransparency((byte) ((1f - WATER_COLOR.A)*255f)*2);
            waterColormaterial.setReflectivity(50);
            renderer.Scene.addMaterial("WaterColor", waterColormaterial);
            renderer.SetObjectMaterial("Water", "WaterColor");
        }
Пример #14
0
        private void CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.RequestModuleInterface <ITerrainChannel>();

            warp_Object obj = new warp_Object(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY, (m_scene.RegionInfo.RegionSizeX - 1) * (m_scene.RegionInfo.RegionSizeY - 1) * 2);

            for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y++)
            {
                for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x++)
                {
                    float height = terrain[x, y];

                    warp_Vector pos = ConvertVector(new Vector3(x, y, height));
                    obj.addVertex(new warp_Vertex(pos, (float)x / (m_scene.RegionInfo.RegionSizeX - 1), (float)((m_scene.RegionInfo.RegionSizeX - 1) - y) / (m_scene.RegionInfo.RegionSizeX - 1)));
                }
            }

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += 1)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += 1)
                {
                    if (x < m_scene.RegionInfo.RegionSizeX - 1 && y < m_scene.RegionInfo.RegionSizeY - 1)
                    {
                        float v = y * m_scene.RegionInfo.RegionSizeX + x;

                        // Normal
                        warp_Vector norm = new warp_Vector(x, y, terrain.GetNormalizedGroundHeight((int)x, (int)y));
                        norm = norm.reverse();
                        obj.vertex((int)v).n = norm;

                        // Triangle 1
                        obj.addTriangle(
                            (int)v,
                            (int)v + 1,
                            (int)v + m_scene.RegionInfo.RegionSizeX);

                        // Triangle 2
                        obj.addTriangle(
                            (int)v + m_scene.RegionInfo.RegionSizeX + 1,
                            (int)v + m_scene.RegionInfo.RegionSizeX,
                            (int)v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float)regionInfo.Elevation1SW;
            startHeights[1] = (float)regionInfo.Elevation1NW;
            startHeights[2] = (float)regionInfo.Elevation1SE;
            startHeights[3] = (float)regionInfo.Elevation1NE;

            heightRanges[0] = (float)regionInfo.Elevation2SW;
            heightRanges[1] = (float)regionInfo.Elevation2NW;
            heightRanges[2] = (float)regionInfo.Elevation2SE;
            heightRanges[3] = (float)regionInfo.Elevation2NE;

            uint globalX, globalY;

            Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            Bitmap        image    = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges, new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain);
            warp_Texture  texture  = new warp_Texture(image);
            warp_Material material = new warp_Material(texture);

            material.setReflectivity(50);
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
        }
Пример #15
0
        // Add a terrain to the renderer.
        // Note that we create a 'low resolution' 256x256 vertex terrain rather than trying for
        //    full resolution. This saves a lot of memory especially for very large regions.
        private void CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.Heightmap;

            float regionsx = m_scene.RegionInfo.RegionSizeX;
            float regionsy = m_scene.RegionInfo.RegionSizeY;

            // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding
            float diff = regionsx / 256f;

            int npointsx = (int)(regionsx / diff);
            int npointsy = (int)(regionsy / diff);

            float invsx = 1.0f / regionsx;
            float invsy = 1.0f / (float)m_scene.RegionInfo.RegionSizeY;

            // Create all the vertices for the terrain
            warp_Object obj = new warp_Object();

            for (float y = 0; y < regionsy; y += diff)
            {
                for (float x = 0; x < regionsx; x += diff)
                {
                    warp_Vector pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]);
                    obj.addVertex(new warp_Vertex(pos, x * invsx, 1.0f - y * invsy));
                }
            }

            // Now that we have all the vertices, make another pass and
            // create the list of triangle indices.
            float invdiff = 1.0f / diff;
            int   limx    = npointsx - 1;
            int   limy    = npointsy - 1;

            for (float y = 0; y < regionsy; y += diff)
            {
                for (float x = 0; x < regionsx; x += diff)
                {
                    float newX = x * invdiff;
                    float newY = y * invdiff;
                    if (newX < limx && newY < limy)
                    {
                        int v = (int)newY * npointsx + (int)newX;

                        // Make two triangles for each of the squares in the grid of vertices
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + npointsx);

                        obj.addTriangle(
                            v + npointsx + 1,
                            v + npointsx,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            OpenSim.Framework.RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float)regionInfo.Elevation1SW;
            startHeights[1] = (float)regionInfo.Elevation1NW;
            startHeights[2] = (float)regionInfo.Elevation1SE;
            startHeights[3] = (float)regionInfo.Elevation1NE;

            heightRanges[0] = (float)regionInfo.Elevation2SW;
            heightRanges[1] = (float)regionInfo.Elevation2NW;
            heightRanges[2] = (float)regionInfo.Elevation2SE;
            heightRanges[3] = (float)regionInfo.Elevation2NE;

            uint globalX, globalY;

            Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            warp_Texture texture;

            using (Bitmap image = TerrainSplat.Splat(
                       terrain, textureIDs, startHeights, heightRanges,
                       new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain))
                texture = new warp_Texture(image);

            warp_Material material = new warp_Material(texture);

            material.setReflectivity(50);
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
        }
Пример #16
0
        private warp_Object CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.RequestModuleInterface<ITerrainChannel>();

            float diff = (float) m_scene.RegionInfo.RegionSizeY/(float) Constants.RegionSize;
            warp_Object obj =
                new warp_Object(Constants.RegionSize*Constants.RegionSize,
                                ((Constants.RegionSize - 1)*(Constants.RegionSize - 1)*2));

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                {
                    warp_Vector pos = ConvertVector(x, y, terrain[(int) x, (int) y]);
                    obj.addVertex(new warp_Vertex(pos, x/(float) (m_scene.RegionInfo.RegionSizeX),
                                                  (((float) m_scene.RegionInfo.RegionSizeX) - y)/
                                                  (m_scene.RegionInfo.RegionSizeX)));
                }
            }

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                {
                    float newX = x/diff;
                    float newY = y/diff;
                    if (newX < Constants.RegionSize - 1 && newY < Constants.RegionSize - 1)
                    {
                        int v = (int) (newY*Constants.RegionSize + newX);

                        // Normal
                        Vector3 v1 = new Vector3(newX, newY, (terrain[(int) x, (int) y])/Constants.TerrainCompression);
                        Vector3 v2 = new Vector3(newX + 1, newY,
                                                 (terrain[(int) x + 1, (int) y])/Constants.TerrainCompression);
                        Vector3 v3 = new Vector3(newX, newY + 1,
                                                 (terrain[(int) x, (int) (y + 1)])/Constants.TerrainCompression);
                        warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                        norm = norm.reverse();
                        obj.vertex(v).n = norm;

                        // Triangle 1
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + Constants.RegionSize);

                        // Triangle 2
                        obj.addTriangle(
                            v + Constants.RegionSize + 1,
                            v + Constants.RegionSize,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[] textureIDs = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float) regionInfo.Elevation1SW;
            startHeights[1] = (float) regionInfo.Elevation1NW;
            startHeights[2] = (float) regionInfo.Elevation1SE;
            startHeights[3] = (float) regionInfo.Elevation1NE;

            heightRanges[0] = (float) regionInfo.Elevation2SW;
            heightRanges[1] = (float) regionInfo.Elevation2NW;
            heightRanges[2] = (float) regionInfo.Elevation2SE;
            heightRanges[3] = (float) regionInfo.Elevation2NE;

            uint globalX, globalY;
            Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            Bitmap image = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges,
                                              new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain);
            warp_Texture texture = new warp_Texture(image);
            warp_Material material = new warp_Material(texture);
            material.setReflectivity(0); // reduces tile seams a bit thanks lkalif
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
            return obj;
        }
        public Bitmap TerrainToBitmap(Bitmap mapbmp)
        {
            List <string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());

            if (renderers.Count > 0)
            {
                m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
                MainConsole.Instance.Debug("[MAPTILE]: Loaded prim mesher " + m_primMesher);
            }
            else
            {
                MainConsole.Instance.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
            }

            bool drawPrimVolume = true;
            bool textureTerrain = true;

            try
            {
                IConfig startupConfig = m_config.Configs["Startup"];
                drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", drawPrimVolume);
                textureTerrain = startupConfig.GetBoolean("TextureOnMapTile", textureTerrain);
            }
            catch
            {
                MainConsole.Instance.Warn("[MAPTILE]: Failed to load StartupConfig");
            }

            m_texturePrims = m_config.Configs["MapModule"].GetBoolean("WarpTexturePrims", false);
            m_colors.Clear();

            int     scaledRemovalFactor = m_scene.RegionInfo.RegionSizeX / (Constants.RegionSize / 2);
            Vector3 camPos = new Vector3(m_scene.RegionInfo.RegionSizeX / 2 - 0.5f,
                                         m_scene.RegionInfo.RegionSizeY / 2 - 0.5f, 221.7025033688163f);
            Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f,
                                             m_scene.RegionInfo.RegionSizeX - scaledRemovalFactor,
                                             m_scene.RegionInfo.RegionSizeY - scaledRemovalFactor,
                                             m_scene.RegionInfo.RegionSizeX - scaledRemovalFactor,
                                             m_scene.RegionInfo.RegionSizeY - scaledRemovalFactor);

            int width  = viewport.Width;
            int height = viewport.Height;

            if (m_useAntiAliasing)
            {
                width  *= 2;
                height *= 2;
            }

            WarpRenderer renderer   = new WarpRenderer();
            warp_Object  terrainObj = null;

            renderer.CreateScene(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeX);
            renderer.Scene.autoCalcNormals = false;

            #region Camera

            warp_Vector pos = ConvertVector(viewport.Position);
            pos.z -= 0.001f; // Works around an issue with the Warp3D camera
            warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection));

            renderer.Scene.defaultCamera.setPos(pos);
            renderer.Scene.defaultCamera.lookAt(lookat);

            if (viewport.Orthographic)
            {
                renderer.Scene.defaultCamera.isOrthographic  = true;
                renderer.Scene.defaultCamera.orthoViewWidth  = viewport.OrthoWindowWidth;
                renderer.Scene.defaultCamera.orthoViewHeight = viewport.OrthoWindowHeight;
            }
            else
            {
                viewport.Orthographic = false;
                float fov = 256;
                //fov *= 1.75f; // FIXME: ???
                renderer.Scene.defaultCamera.setFov(fov);
            }

            #endregion Camera

            renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40));
            renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40));

            try
            {
                CreateWater(renderer);
                terrainObj = CreateTerrain(renderer, textureTerrain);
                if (drawPrimVolume && m_primMesher != null)
                {
#if (!ISWIN)
                    foreach (ISceneEntity ent in m_scene.Entities.GetEntities())
                    {
                        foreach (ISceneChildEntity part in ent.ChildrenEntities())
                        {
                            CreatePrim(renderer, part);
                        }
                    }
#else
                    foreach (ISceneChildEntity part in m_scene.Entities.GetEntities().SelectMany(ent => ent.ChildrenEntities()))
                    {
                        CreatePrim(renderer, part);
                    }
#endif
                }
            }
            catch (Exception ex)
            {
                MainConsole.Instance.Warn("[Warp3D]: Exception in the map generation, " + ex);
            }

            renderer.Render();
            Bitmap bitmap = renderer.Scene.getImage();
            //bitmap = ImageUtils.ResizeImage(bitmap, Constants.RegionSize, Constants.RegionSize);
            foreach (var o in renderer.Scene.objectData.Values)
            {
                warp_Object obj = (warp_Object)o;
                obj.vertexData   = null;
                obj.triangleData = null;
            }
            foreach (var t in renderer.Scene.materialData.Values)
            {
                warp_Material mat = (warp_Material)t;
                if (mat.texture != null)
                {
                    mat.texture.pixel = null;
                    mat.texture       = null;
                }
            }
            renderer.Scene.removeAllObjects();
            renderer                = null;
            viewport                = null;
            m_primMesher            = null;
            terrainObj.fastvertex   = null;
            terrainObj.fasttriangle = null;
            terrainObj              = null;
            m_colors.Clear();

            //Force GC to try to clean this mess up
            GC.GetTotalMemory(true);

            return(bitmap);
        }
        warp_Object CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.RequestModuleInterface <ITerrainChannel> ();

            float diffX  = 1.0f; //(float) m_scene.RegionInfo.RegionSizeX/(float) Constants.RegionSize;
            float diffY  = 1.0f; //(float) m_scene.RegionInfo.RegionSizeY/(float) Constants.RegionSize;
            int   newRsX = m_scene.RegionInfo.RegionSizeX / (int)diffX;
            int   newRsY = m_scene.RegionInfo.RegionSizeY / (int)diffY;

            warp_Object obj = new warp_Object(newRsX * newRsY, ((newRsX - 1) * (newRsY - 1) * 2));

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diffY)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diffX)
                {
                    float t_height    = terrain [(int)x, (int)y];
                    float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;

                    //clamp to eliminate artifacts
                    t_height = Utils.Clamp(t_height, waterHeight - 0.5f, waterHeight + 0.5f);
                    if (t_height < 0.0f)
                    {
                        t_height = 0.0f;
                    }

                    warp_Vector pos = ConvertVector(x / diffX, y / diffY, t_height);
                    obj.addVertex(
                        new warp_Vertex(pos,
                                        x / m_scene.RegionInfo.RegionSizeX,
                                        (m_scene.RegionInfo.RegionSizeY - y) / (m_scene.RegionInfo.RegionSizeY)));
                }
            }

            const float normal_map_reduction = 2.0f; //2.0f-2.5f is the sweet spot

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diffY)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diffX)
                {
                    float newX = x / diffX;
                    float newY = y / diffY;

                    if (newX < newRsX - 1 && newY < newRsY - 1)
                    {
                        int v = (int)(newY * newRsX + newX);

                        // Normal
                        Vector3 v1 = new Vector3(newX, newY, (terrain [(int)x, (int)y]) / normal_map_reduction);
                        Vector3 v2 = new Vector3(newX + 1, newY,
                                                 (terrain [(int)x + 1, (int)y]) / normal_map_reduction);
                        Vector3 v3 = new Vector3(newX, newY + 1,
                                                 (terrain [(int)x, (int)(y + 1)]) / normal_map_reduction);
                        warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                        norm            = norm.reverse();
                        obj.vertex(v).n = norm;

                        // Triangle 1
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + newRsX);

                        // Triangle 2
                        obj.addTriangle(
                            v + newRsX + 1,
                            v + newRsX,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);
            renderer.Scene.sceneobject("Terrain").setPos(0.0f, 0.0f, 0.0f);

            UUID []  textureIDs   = new UUID [4];
            float [] startHeights = new float [4];
            float [] heightRanges = new float [4];

            RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs [0] = regionInfo.TerrainTexture1;
            textureIDs [1] = regionInfo.TerrainTexture2;
            textureIDs [2] = regionInfo.TerrainTexture3;
            textureIDs [3] = regionInfo.TerrainTexture4;

            startHeights [0] = (float)regionInfo.Elevation1SW;
            startHeights [1] = (float)regionInfo.Elevation1NW;
            startHeights [2] = (float)regionInfo.Elevation1SE;
            startHeights [3] = (float)regionInfo.Elevation1NE;

            heightRanges [0] = (float)regionInfo.Elevation2SW;
            heightRanges [1] = (float)regionInfo.Elevation2NW;
            heightRanges [2] = (float)regionInfo.Elevation2SE;
            heightRanges [3] = (float)regionInfo.Elevation2NE;

            uint globalX, globalY;

            Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            Bitmap image = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges,
                                              new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain);
            warp_Texture  texture  = new warp_Texture(image);
            warp_Material material = new warp_Material(texture);

            material.setReflectivity(0);  // reduces tile seams a bit thanks lkalif
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.SetObjectMaterial("Terrain", "TerrainColor");

            image.Dispose();

            return(obj);
        }
        void CreateWater(WarpRenderer renderer, bool threeD)
        {
            float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;
            int   maxSize     = m_scene.RegionInfo.RegionSizeX;

            if (m_scene.RegionInfo.RegionSizeY >= maxSize)
            {
                maxSize = m_scene.RegionInfo.RegionSizeY;
            }

            warp_Material waterColormaterial;

            if (!threeD)
            {
                // 20160210 -greythane-
                // it appears that the default plan object is rotated 45 degrees
                // work-a-round until verified or otherwise in the Warp3D library
                renderer.AddPlane("Water", maxSize);
                renderer.Scene.sceneobject("Water").setPos(0, waterHeight, 0);

                /* reference    if(m_scene.RegionInfo.RegionSizeX >= m_scene.RegionInfo.RegionSizeY)
                 *                  renderer.AddPlane ("Water", m_scene.RegionInfo.RegionSizeX/2);
                 *              else
                 *                  renderer.AddPlane ("Water", m_scene.RegionInfo.RegionSizeY/2);
                 *
                 *              renderer.Scene.sceneobject ("Water").setPos (
                 *                  (m_scene.RegionInfo.RegionSizeX / 2) - 0.5f,
                 *                  waterHeight,
                 *                  (m_scene.RegionInfo.RegionSizeY / 2) - 0.5f);
                 *
                 *
                 */
                waterColormaterial = new warp_Material(ConvertColor(WATER_COLOR));
                //  waterColormaterial.setTransparency ((byte)((1f - WATER_COLOR.A) * 255f) * 2);
                waterColormaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
            }
            else
            {
                renderer.AddPlane("Water", maxSize / 2);

                /* for reference
                 *              if(m_scene.RegionInfo.RegionSizeX >= m_scene.RegionInfo.RegionSizeY)
                 *                  renderer.AddPlane ("Water", m_scene.RegionInfo.RegionSizeX/2);
                 *              else
                 *                  renderer.AddPlane ("Water", m_scene.RegionInfo.RegionSizeY/2);
                 */
                renderer.Scene.sceneobject("Water").setPos(
                    (m_scene.RegionInfo.RegionSizeX / 2f) - 0.5f,
                    -0.5f,
                    waterHeight + 5.1f
                    );

                waterColormaterial = new warp_Material(ConvertColor(OPAQUE_WATER_COLOR));
                waterColormaterial.setTransparency(48);
                //waterColormaterial.opaque = true;
            }

            waterColormaterial.setReflectivity(0);
            renderer.Scene.addMaterial("WaterColor", waterColormaterial);
            renderer.SetObjectMaterial("Water", "WaterColor");
        }
Пример #20
0
        private warp_Object CreateTerrain(WarpRenderer renderer, bool textureTerrain)
        {
            ITerrainChannel terrain = m_scene.RequestModuleInterface <ITerrainChannel>();

            float       diff = (float)m_scene.RegionInfo.RegionSizeY / (float)Constants.RegionSize;
            warp_Object obj  =
                new warp_Object(Constants.RegionSize * Constants.RegionSize,
                                ((Constants.RegionSize - 1) * (Constants.RegionSize - 1) * 2));

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                {
                    warp_Vector pos = ConvertVector(x, y, terrain[(int)x, (int)y]);
                    obj.addVertex(new warp_Vertex(pos, x / (float)(m_scene.RegionInfo.RegionSizeX),
                                                  (((float)m_scene.RegionInfo.RegionSizeX) - y) /
                                                  (m_scene.RegionInfo.RegionSizeX)));
                }
            }

            for (float y = 0; y < m_scene.RegionInfo.RegionSizeY; y += diff)
            {
                for (float x = 0; x < m_scene.RegionInfo.RegionSizeX; x += diff)
                {
                    float newX = x / diff;
                    float newY = y / diff;
                    if (newX < Constants.RegionSize - 1 && newY < Constants.RegionSize - 1)
                    {
                        int v = (int)(newY * Constants.RegionSize + newX);

                        // Normal
                        Vector3 v1 = new Vector3(newX, newY, (terrain[(int)x, (int)y]) / Constants.TerrainCompression);
                        Vector3 v2 = new Vector3(newX + 1, newY,
                                                 (terrain[(int)x + 1, (int)y]) / Constants.TerrainCompression);
                        Vector3 v3 = new Vector3(newX, newY + 1,
                                                 (terrain[(int)x, (int)(y + 1)]) / Constants.TerrainCompression);
                        warp_Vector norm = ConvertVector(SurfaceNormal(v1, v2, v3));
                        norm            = norm.reverse();
                        obj.vertex(v).n = norm;

                        // Triangle 1
                        obj.addTriangle(
                            v,
                            v + 1,
                            v + Constants.RegionSize);

                        // Triangle 2
                        obj.addTriangle(
                            v + Constants.RegionSize + 1,
                            v + Constants.RegionSize,
                            v + 1);
                    }
                }
            }

            renderer.Scene.addObject("Terrain", obj);

            UUID[]  textureIDs   = new UUID[4];
            float[] startHeights = new float[4];
            float[] heightRanges = new float[4];

            RegionSettings regionInfo = m_scene.RegionInfo.RegionSettings;

            textureIDs[0] = regionInfo.TerrainTexture1;
            textureIDs[1] = regionInfo.TerrainTexture2;
            textureIDs[2] = regionInfo.TerrainTexture3;
            textureIDs[3] = regionInfo.TerrainTexture4;

            startHeights[0] = (float)regionInfo.Elevation1SW;
            startHeights[1] = (float)regionInfo.Elevation1NW;
            startHeights[2] = (float)regionInfo.Elevation1SE;
            startHeights[3] = (float)regionInfo.Elevation1NE;

            heightRanges[0] = (float)regionInfo.Elevation2SW;
            heightRanges[1] = (float)regionInfo.Elevation2NW;
            heightRanges[2] = (float)regionInfo.Elevation2SE;
            heightRanges[3] = (float)regionInfo.Elevation2NE;

            uint globalX, globalY;

            Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);

            Bitmap image = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges,
                                              new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain);
            warp_Texture  texture  = new warp_Texture(image);
            warp_Material material = new warp_Material(texture);

            material.setReflectivity(0); // reduces tile seams a bit thanks lkalif
            renderer.Scene.addMaterial("TerrainColor", material);
            renderer.SetObjectMaterial("Terrain", "TerrainColor");
            return(obj);
        }