diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 622b16c910..95fa567d4c 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public static Bitmap Splat(ITerrainChannel terrain, UUID[] textureIDs, float[] startHeights, float[] heightRanges, uint regionPositionX,uint regionPositionY, - IAssetService assetService, bool textureTerrain, bool averagetextureTerrain) + IAssetService assetService, bool textureTerrain, bool averagetextureTerrain, bool FlipedY) { Debug.Assert(textureIDs.Length == 4); Debug.Assert(startHeights.Length == 4); @@ -294,38 +294,79 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap // pixel data directly if(usecolors) { - unsafe + if(FlipedY) { - for(int y = 0; y < 256; ++y) + unsafe { - int ty = (int)((255 - y) * yFactor); - byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride; - - for(int x = 0; x < 256; ++x) + for(int y = 0; y < 256; ++y) { - int tx = (int)(x * xFactor); - float height = (float)terrain[tx, ty]; - float layer = getLayerTex(height, x, (255 - y), - (uint)tx + regionPositionX, (uint)ty + regionPositionY, - startHeights, heightRanges); + int ty = (int)(y * yFactor); + byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride; - // Select two textures - int l0 = (int)layer; - int l1 = Math.Min(l0 + 1, 3); + for(int x = 0; x < 256; ++x) + { + int tx = (int)(x * xFactor); + float height = (float)terrain[tx, ty]; + float layer = getLayerTex(height, x, y, + (uint)tx + regionPositionX, (uint)ty + regionPositionY, + startHeights, heightRanges); - float layerDiff = layer - l0; + // Select two textures + int l0 = (int)layer; + int l1 = Math.Min(l0 + 1, 3); - float a = mapColorsRed[l0]; - float b = mapColorsRed[l1]; - *(ptrO++) = (byte)(a + layerDiff * (b - a)); + float layerDiff = layer - l0; - a = mapColorsGreen[l0]; - b = mapColorsGreen[l1]; - *(ptrO++) = (byte)(a + layerDiff * (b - a)); + float a = mapColorsRed[l0]; + float b = mapColorsRed[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); - a = mapColorsBlue[l0]; - b = mapColorsBlue[l1]; - *(ptrO++) = (byte)(a + layerDiff * (b - a)); + a = mapColorsGreen[l0]; + b = mapColorsGreen[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); + + a = mapColorsBlue[l0]; + b = mapColorsBlue[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); + } + } + } + } + else + { + unsafe + { + for(int y = 0; y < 256; ++y) + { + int ty = (int)((255 - y) * yFactor); + byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride; + + for(int x = 0; x < 256; ++x) + { + int tx = (int)(x * xFactor); + float height = (float)terrain[tx, ty]; + float layer = getLayerTex(height, x, (255 - y), + (uint)tx + regionPositionX, (uint)ty + regionPositionY, + startHeights, heightRanges); + + // Select two textures + int l0 = (int)layer; + int l1 = Math.Min(l0 + 1, 3); + + float layerDiff = layer - l0; + + float a = mapColorsRed[l0]; + float b = mapColorsRed[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); + + a = mapColorsGreen[l0]; + b = mapColorsGreen[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); + + a = mapColorsBlue[l0]; + b = mapColorsBlue[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); + } } } } @@ -343,42 +384,86 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap detailTexture[3].LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) }; - for(int y = 0; y < 256; y++) + if(FlipedY) { - int ty = (int)((255 - y) * yFactor); - int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride; - - for(int x = 0; x < 256; x++) + for(int y = 0; y < 256; y++) { - int tx = (int)(x * xFactor); - float height = (float)terrain[tx, ty]; - float layer = getLayerTex(height, x, (255 - y), - (uint)tx + regionPositionX, (uint)ty + regionPositionY, - startHeights, heightRanges); + int ty = (int)(y * yFactor); + int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride; - // Select two textures - int l0 = (int)layer; - int l1 = Math.Min(l0 + 1, 3); + for(int x = 0; x < 256; x++) + { + int tx = (int)(x * xFactor); + float height = (float)terrain[tx, ty]; + float layer = getLayerTex(height, x, y, + (uint)tx + regionPositionX, (uint)ty + regionPositionY, + startHeights, heightRanges); - int patchOffset = (tx & 0x0f) * 3 + ypatch; - byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset; - byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset; - byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; + // Select two textures + int l0 = (int)layer; + int l1 = Math.Min(l0 + 1, 3); - float aB = *(ptrA + 0); - float aG = *(ptrA + 1); - float aR = *(ptrA + 2); + int patchOffset = (tx & 0x0f) * 3 + ypatch; + byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset; + byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset; + byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; - float bB = *(ptrB + 0); - float bG = *(ptrB + 1); - float bR = *(ptrB + 2); + float aB = *(ptrA + 0); + float aG = *(ptrA + 1); + float aR = *(ptrA + 2); - float layerDiff = layer - l0; + float bB = *(ptrB + 0); + float bG = *(ptrB + 1); + float bR = *(ptrB + 2); - // Interpolate between the two selected textures - *(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB)); - *(ptrO + 1) = (byte)(aG + layerDiff * (bG - aG)); - *(ptrO + 2) = (byte)(aR + layerDiff * (bR - aR)); + float layerDiff = layer - l0; + + // Interpolate between the two selected textures + *(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB)); + *(ptrO + 1) = (byte)(aG + layerDiff * (bG - aG)); + *(ptrO + 2) = (byte)(aR + layerDiff * (bR - aR)); + } + } + } + else + { + for(int y = 0; y < 256; y++) + { + int ty = (int)((255 - y) * yFactor); + int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride; + + for(int x = 0; x < 256; x++) + { + int tx = (int)(x * xFactor); + float height = (float)terrain[tx, ty]; + float layer = getLayerTex(height, x, (255 - y), + (uint)tx + regionPositionX, (uint)ty + regionPositionY, + startHeights, heightRanges); + + // Select two textures + int l0 = (int)layer; + int l1 = Math.Min(l0 + 1, 3); + + int patchOffset = (tx & 0x0f) * 3 + ypatch; + byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset; + byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset; + byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; + + float aB = *(ptrA + 0); + float aG = *(ptrA + 1); + float aR = *(ptrA + 2); + + float bB = *(ptrB + 0); + float bG = *(ptrB + 1); + float bR = *(ptrB + 2); + + float layerDiff = layer - l0; + + // Interpolate between the two selected textures + *(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB)); + *(ptrO + 1) = (byte)(aG + layerDiff * (bG - aG)); + *(ptrO + 2) = (byte)(aR + layerDiff * (bR - aR)); + } } } @@ -420,6 +505,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap heightRanges[1], heightRanges[3], pctX, pctY); heightRange = Utils.Clamp(heightRange, 0f, 255f); + if(heightRange == 0f) + return 0; // Generate two frequencies of perlin noise based on our global position // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting @@ -435,8 +522,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap // Combine the current height, generated noise, start height, and height range parameters, then scale all of it float layer = ((height + noise - startHeight) / heightRange) * 4f; - if(Single.IsNaN(layer)) - return 0; return Utils.Clamp(layer, 0f, 3f); } } diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Viewport.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Viewport.cs deleted file mode 100644 index 5ea4d29c32..0000000000 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Viewport.cs +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Drawing; -using OpenMetaverse; - -namespace OpenSim.Region.CoreModules.World.Warp3DMap -{ - public class Viewport - { - private const float DEG_TO_RAD = (float)Math.PI / 180f; - private static readonly Vector3 UP_DIRECTION = Vector3.UnitZ; - - public Vector3 Position; - public Vector3 LookDirection; - public float FieldOfView; - public float NearPlaneDistance; - public float FarPlaneDistance; - public int Width; - public int Height; - public bool Orthographic; - public float OrthoWindowWidth; - public float OrthoWindowHeight; - - public Viewport(Vector3 position, Vector3 lookDirection, float fieldOfView, float farPlaneDist, float nearPlaneDist, int width, int height) - { - // Perspective projection mode - Position = position; - LookDirection = lookDirection; - FieldOfView = fieldOfView; - FarPlaneDistance = farPlaneDist; - NearPlaneDistance = nearPlaneDist; - Width = width; - Height = height; - Orthographic = false; - } - - public Viewport(Vector3 position, Vector3 lookDirection, float farPlaneDist, float nearPlaneDist, int width, int height, float orthoWindowWidth, float orthoWindowHeight) - { - // Orthographic projection mode - Position = position; - LookDirection = lookDirection; - FarPlaneDistance = farPlaneDist; - NearPlaneDistance = nearPlaneDist; - Width = width; - Height = height; - OrthoWindowWidth = orthoWindowWidth; - OrthoWindowHeight = orthoWindowHeight; - Orthographic = true; - } - - public Point VectorToScreen(Vector3 v) - { - Matrix4 m = GetWorldToViewportMatrix(); - Vector3 screenPoint = v * m; - return new Point((int)screenPoint.X, (int)screenPoint.Y); - } - - public Matrix4 GetWorldToViewportMatrix() - { - Matrix4 result = GetViewMatrix(); - result *= GetPerspectiveProjectionMatrix(); - result *= GetViewportMatrix(); - - return result; - } - - public Matrix4 GetViewMatrix() - { - Vector3 zAxis = -LookDirection; - zAxis.Normalize(); - - Vector3 xAxis = Vector3.Cross(UP_DIRECTION, zAxis); - xAxis.Normalize(); - - Vector3 yAxis = Vector3.Cross(zAxis, xAxis); - - Vector3 position = Position; - float offsetX = -Vector3.Dot(xAxis, position); - float offsetY = -Vector3.Dot(yAxis, position); - float offsetZ = -Vector3.Dot(zAxis, position); - - return new Matrix4( - xAxis.X, yAxis.X, zAxis.X, 0f, - xAxis.Y, yAxis.Y, zAxis.Y, 0f, - xAxis.Z, yAxis.Z, zAxis.Z, 0f, - offsetX, offsetY, offsetZ, 1f); - } - - public Matrix4 GetPerspectiveProjectionMatrix() - { - float aspectRatio = (float)Width / (float)Height; - - float hFoV = FieldOfView * DEG_TO_RAD; - float zn = NearPlaneDistance; - float zf = FarPlaneDistance; - - float xScale = 1f / (float)Math.Tan(hFoV / 2f); - float yScale = aspectRatio * xScale; - float m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf)); - float m43 = zn * m33; - - return new Matrix4( - xScale, 0f, 0f, 0f, - 0f, yScale, 0f, 0f, - 0f, 0f, m33, -1f, - 0f, 0f, m43, 0f); - } - - public Matrix4 GetOrthographicProjectionMatrix(float aspectRatio) - { - float w = Width; - float h = Height; - float zn = NearPlaneDistance; - float zf = FarPlaneDistance; - - float m33 = 1 / (zn - zf); - float m43 = zn * m33; - - return new Matrix4( - 2f / w, 0f, 0f, 0f, - 0f, 2f / h, 0f, 0f, - 0f, 0f, m33, 0f, - 0f, 0f, m43, 1f); - } - - public Matrix4 GetViewportMatrix() - { - float scaleX = (float)Width * 0.5f; - float scaleY = (float)Height * 0.5f; - float offsetX = 0f + scaleX; - float offsetY = 0f + scaleY; - - return new Matrix4( - scaleX, 0f, 0f, 0f, - 0f, -scaleY, 0f, 0f, - 0f, 0f, 1f, 0f, - offsetX, offsetY, 0f, 1f); - } - } -} diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index b41a27c81f..b4659cc937 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs @@ -156,65 +156,74 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap #region IMapImageGenerator Members + private Vector3 cameraPos; + private Vector3 cameraDir; + private int viewWitdh = 256; + private int viewHeigth = 256; + private float fov; + private bool orto; + public Bitmap CreateMapTile() { - /* this must be on all map, not just its image - if ((DateTime.Now - lastImageTime).TotalSeconds < 3600) - { - return (Bitmap)lastImage.Clone(); - } - */ - List renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); if (renderers.Count > 0) { m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); } - Vector3 camPos = new Vector3( + cameraPos = new Vector3( (m_scene.RegionInfo.RegionSizeX) * 0.5f, (m_scene.RegionInfo.RegionSizeY) * 0.5f, 250f); - // Viewport viewing down onto the region - Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, - (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY, - (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY); - Bitmap tile = CreateMapTile(viewport); + cameraDir = -Vector3.UnitZ; + viewWitdh = (int)m_scene.RegionInfo.RegionSizeX; + viewHeigth = (int)m_scene.RegionInfo.RegionSizeY; + orto = true; + + Bitmap tile = GenMapTile(); m_primMesher = null; return tile; -/* - lastImage = tile; - lastImageTime = DateTime.Now; - return (Bitmap)lastImage.Clone(); - */ } - public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) + public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float pfov, int width, int height, bool useTextures) { - Viewport viewport = new Viewport(camPos, camDir, fov, Constants.RegionSize, 0.1f, width, height); - return CreateMapTile(viewport); + List renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); + if (renderers.Count > 0) + { + m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); + } + + cameraPos = camPos; + cameraDir = camDir; + viewWitdh = width; + viewHeigth = height; + fov = pfov; + orto = false; + + Bitmap tile = GenMapTile(); + m_primMesher = null; + return tile; } - public Bitmap CreateMapTile(Viewport viewport) + private Bitmap GenMapTile() { m_colors.Clear(); - int width = viewport.Width; - int height = viewport.Height; - WarpRenderer renderer = new WarpRenderer(); - if(!renderer.CreateScene(width, height)) - return new Bitmap(width,height); + if(!renderer.CreateScene(viewWitdh, viewHeigth)) + return new Bitmap(viewWitdh, viewHeigth); #region Camera - warp_Vector pos = ConvertVector(viewport.Position); - warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection)); + warp_Vector pos = ConvertVector(cameraPos); + warp_Vector lookat = warp_Vector.add(pos, ConvertVector(cameraDir)); - - renderer.Scene.defaultCamera.setOrthographic(true, viewport.OrthoWindowWidth, viewport.OrthoWindowHeight); + if(orto) + renderer.Scene.defaultCamera.setOrthographic(true, viewWitdh, viewHeigth); + else + renderer.Scene.defaultCamera.setFov(fov); renderer.Scene.defaultCamera.setPos(pos); renderer.Scene.defaultCamera.lookAt(lookat); @@ -234,7 +243,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap renderer.Scene.destroy(); renderer.Reset(); renderer = null; - viewport = null; m_colors.Clear(); GC.Collect(); @@ -303,28 +311,31 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap npointsy++; // Create all the vertices for the terrain + // for texture fliped on Y 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, 1.0f - y * invsy)); + 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, 1.0f - y * invsy)); + 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, 0f)); + 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, 0f)); + obj.addVertex(new warp_Vertex(pos, 1.0f, 1.0f)); // Now that we have all the vertices, make another pass and // create the list of triangle indices. @@ -376,10 +387,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); warp_Texture texture; + // get texture fliped on Y using (Bitmap image = TerrainSplat.Splat( terrain, textureIDs, startHeights, heightRanges, m_scene.RegionInfo.WorldLocX, m_scene.RegionInfo.WorldLocY, - m_scene.AssetService, m_textureTerrain, m_textureAvegareTerrain)) + m_scene.AssetService, m_textureTerrain, m_textureAvegareTerrain, true)) texture = new warp_Texture(image); warp_Material material = new warp_Material(texture); diff --git a/bin/Warp3D.dll b/bin/Warp3D.dll index 21662e2abe..2f9a13b44c 100755 Binary files a/bin/Warp3D.dll and b/bin/Warp3D.dll differ