breaking map a bit more...
parent
f87219975d
commit
06d6c4abda
|
@ -80,10 +80,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
/// Note we create a 256x256 dimension texture even if the actual terrain is larger.
|
/// Note we create a 256x256 dimension texture even if the actual terrain is larger.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
|
||||||
public static Bitmap Splat(ITerrainChannel terrain,
|
public static Bitmap Splat(ITerrainChannel terrain, UUID[] textureIDs,
|
||||||
UUID[] textureIDs, float[] startHeights, float[] heightRanges,
|
float[] startHeights, float[] heightRanges,
|
||||||
uint regionPositionX,uint regionPositionY,
|
uint regionPositionX,uint regionPositionY,
|
||||||
IAssetService assetService, bool textureTerrain, bool averagetextureTerrain, bool FlipedY)
|
IAssetService assetService, IJ2KDecoder decoder,
|
||||||
|
bool textureTerrain, bool averagetextureTerrain, bool FlipedY,
|
||||||
|
int twidth, int theight)
|
||||||
{
|
{
|
||||||
Debug.Assert(textureIDs.Length == 4);
|
Debug.Assert(textureIDs.Length == 4);
|
||||||
Debug.Assert(startHeights.Length == 4);
|
Debug.Assert(startHeights.Length == 4);
|
||||||
|
@ -113,27 +115,29 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
for(int i = 0; i < 4; i++)
|
for(int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
AssetBase asset = null;
|
AssetBase asset = null;
|
||||||
UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]);
|
|
||||||
|
// asset cache indexes are strings
|
||||||
|
string cacheName ="MAP-Patch" + textureIDs[i].ToString();
|
||||||
|
|
||||||
// Try to fetch a cached copy of the decoded/resized version of this texture
|
// Try to fetch a cached copy of the decoded/resized version of this texture
|
||||||
// asset = assetService.GetCached(cacheID.ToString());
|
asset = assetService.GetCached(cacheName);
|
||||||
if(asset != null)
|
if(asset != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using(System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data))
|
using(System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data))
|
||||||
detailTexture[i] = (Bitmap)Image.FromStream(stream);
|
detailTexture[i] = (Bitmap)Image.FromStream(stream);
|
||||||
|
|
||||||
|
if(detailTexture[i].PixelFormat != PixelFormat.Format24bppRgb ||
|
||||||
|
detailTexture[i].Width != 16 || detailTexture[i].Height != 16)
|
||||||
|
{
|
||||||
|
detailTexture[i].Dispose();
|
||||||
|
detailTexture[i] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
m_log.Warn("Failed to decode cached terrain texture " + cacheID +
|
m_log.Warn("Failed to decode cached terrain patch texture" + textureIDs[i] + "): " + ex.Message);
|
||||||
" (textureID: " + textureIDs[i] + "): " + ex.Message);
|
|
||||||
}
|
|
||||||
if(detailTexture[i].PixelFormat != PixelFormat.Format24bppRgb ||
|
|
||||||
detailTexture[i].Width != 16 || detailTexture[i].Height != 16)
|
|
||||||
{
|
|
||||||
detailTexture[i].Dispose();
|
|
||||||
detailTexture[i] = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,12 +147,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
asset = assetService.Get(textureIDs[i].ToString());
|
asset = assetService.Get(textureIDs[i].ToString());
|
||||||
if(asset != null)
|
if(asset != null)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data);
|
detailTexture[i] = (Bitmap)decoder.DecodeToImage(asset.Data);
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -177,8 +178,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
Data = data,
|
Data = data,
|
||||||
Description = "PNG",
|
Description = "PNG",
|
||||||
Flags = AssetFlags.Collectable,
|
Flags = AssetFlags.Collectable,
|
||||||
FullID = cacheID,
|
FullID = UUID.Zero,
|
||||||
ID = cacheID.ToString(),
|
ID = cacheName,
|
||||||
Local = true,
|
Local = true,
|
||||||
Name = String.Empty,
|
Name = String.Empty,
|
||||||
Temporary = true,
|
Temporary = true,
|
||||||
|
@ -279,46 +280,61 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
#region Layer Map
|
#region Layer Map
|
||||||
|
|
||||||
// Scale difference between actual region size and the 256 texture being created
|
float xFactor = terrain.Width / twidth;
|
||||||
float xFactor = terrain.Width / 256f;
|
float yFactor = terrain.Height / theight;
|
||||||
float yFactor = terrain.Height / 256f;
|
|
||||||
|
|
||||||
#endregion Layer Map
|
#endregion Layer Map
|
||||||
|
|
||||||
#region Texture Compositing
|
#region Texture Compositing
|
||||||
|
|
||||||
Bitmap output = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
|
Bitmap output = new Bitmap(twidth, theight, PixelFormat.Format24bppRgb);
|
||||||
BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
|
BitmapData outputData = output.LockBits(new Rectangle(0, 0, twidth, theight), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
|
||||||
|
|
||||||
// Unsafe work as we lock down the source textures for quicker access and access the
|
// Unsafe work as we lock down the source textures for quicker access and access the
|
||||||
// pixel data directly
|
// pixel data directly
|
||||||
|
float invtwitdthMinus1 = 1.0f / (twidth - 1);
|
||||||
|
float invtheightMinus1 = 1.0f / (theight - 1);
|
||||||
|
int ty;
|
||||||
|
int tx;
|
||||||
|
float pctx;
|
||||||
|
float pcty;
|
||||||
|
float height;
|
||||||
|
float layer;
|
||||||
|
float layerDiff;
|
||||||
|
int l0;
|
||||||
|
int l1;
|
||||||
|
|
||||||
if(usecolors)
|
if(usecolors)
|
||||||
{
|
{
|
||||||
|
float a;
|
||||||
|
float b;
|
||||||
if(FlipedY)
|
if(FlipedY)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
for(int y = 0; y < 256; ++y)
|
for(int y = 0; y < theight; ++y)
|
||||||
{
|
{
|
||||||
int ty = (int)(y * yFactor);
|
ty = (int)(y * yFactor);
|
||||||
|
pcty = y * invtheightMinus1;
|
||||||
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride;
|
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride;
|
||||||
|
|
||||||
for(int x = 0; x < 256; ++x)
|
for(int x = 0; x < twidth; ++x)
|
||||||
{
|
{
|
||||||
int tx = (int)(x * xFactor);
|
tx = (int)(x * xFactor);
|
||||||
float height = (float)terrain[tx, ty];
|
pctx = x * invtwitdthMinus1;
|
||||||
float layer = getLayerTex(height, x, y,
|
height = (float)terrain[tx, ty];
|
||||||
|
layer = getLayerTex(height, pctx, pcty,
|
||||||
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
||||||
startHeights, heightRanges);
|
startHeights, heightRanges);
|
||||||
|
|
||||||
// Select two textures
|
// Select two textures
|
||||||
int l0 = (int)layer;
|
l0 = (int)layer;
|
||||||
int l1 = Math.Min(l0 + 1, 3);
|
l1 = Math.Min(l0 + 1, 3);
|
||||||
|
|
||||||
float layerDiff = layer - l0;
|
layerDiff = layer - l0;
|
||||||
|
|
||||||
float a = mapColorsRed[l0];
|
a = mapColorsRed[l0];
|
||||||
float b = mapColorsRed[l1];
|
b = mapColorsRed[l1];
|
||||||
*(ptrO++) = (byte)(a + layerDiff * (b - a));
|
*(ptrO++) = (byte)(a + layerDiff * (b - a));
|
||||||
|
|
||||||
a = mapColorsGreen[l0];
|
a = mapColorsGreen[l0];
|
||||||
|
@ -336,27 +352,28 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
for(int y = 0; y < 256; ++y)
|
for(int y = 0; y < theight; ++y)
|
||||||
{
|
{
|
||||||
int ty = (int)((255 - y) * yFactor);
|
ty = (int)((theight - y -1) * yFactor);
|
||||||
|
pcty = 1.0f - y * invtheightMinus1;
|
||||||
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride;
|
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride;
|
||||||
|
|
||||||
for(int x = 0; x < 256; ++x)
|
for(int x = 0; x < twidth; ++x)
|
||||||
{
|
{
|
||||||
int tx = (int)(x * xFactor);
|
tx = (int)(x * xFactor);
|
||||||
float height = (float)terrain[tx, ty];
|
pctx = x * invtwitdthMinus1;
|
||||||
float layer = getLayerTex(height, x, (255 - y),
|
height = (float)terrain[tx, ty];
|
||||||
|
layer = getLayerTex(height, pctx , pcty,
|
||||||
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
||||||
startHeights, heightRanges);
|
startHeights, heightRanges);
|
||||||
|
|
||||||
// Select two textures
|
// Select two textures
|
||||||
int l0 = (int)layer;
|
l0 = (int)layer;
|
||||||
int l1 = Math.Min(l0 + 1, 3);
|
l1 = Math.Min(l0 + 1, 3);
|
||||||
|
|
||||||
float layerDiff = layer - l0;
|
layerDiff = layer - l0;
|
||||||
|
a = mapColorsRed[l0];
|
||||||
float a = mapColorsRed[l0];
|
b = mapColorsRed[l1];
|
||||||
float b = mapColorsRed[l1];
|
|
||||||
*(ptrO++) = (byte)(a + layerDiff * (b - a));
|
*(ptrO++) = (byte)(a + layerDiff * (b - a));
|
||||||
|
|
||||||
a = mapColorsGreen[l0];
|
a = mapColorsGreen[l0];
|
||||||
|
@ -373,6 +390,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
float aB;
|
||||||
|
float aG;
|
||||||
|
float aR;
|
||||||
|
float bB;
|
||||||
|
float bG;
|
||||||
|
float bR;
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
// Get handles to all of the texture data arrays
|
// Get handles to all of the texture data arrays
|
||||||
|
@ -386,37 +409,38 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
if(FlipedY)
|
if(FlipedY)
|
||||||
{
|
{
|
||||||
for(int y = 0; y < 256; y++)
|
for(int y = 0; y < theight; y++)
|
||||||
{
|
{
|
||||||
int ty = (int)(y * yFactor);
|
ty = (int)(y * yFactor);
|
||||||
|
pcty = y * invtheightMinus1;
|
||||||
int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride;
|
int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride;
|
||||||
|
for(int x = 0; x < twidth; x++)
|
||||||
for(int x = 0; x < 256; x++)
|
|
||||||
{
|
{
|
||||||
int tx = (int)(x * xFactor);
|
tx = (int)(x * xFactor);
|
||||||
float height = (float)terrain[tx, ty];
|
pctx = x * invtwitdthMinus1;
|
||||||
float layer = getLayerTex(height, x, y,
|
height = (float)terrain[tx, ty];
|
||||||
|
layer = getLayerTex(height, pctx, pcty,
|
||||||
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
||||||
startHeights, heightRanges);
|
startHeights, heightRanges);
|
||||||
|
|
||||||
// Select two textures
|
// Select two textures
|
||||||
int l0 = (int)layer;
|
l0 = (int)layer;
|
||||||
int l1 = Math.Min(l0 + 1, 3);
|
l1 = Math.Min(l0 + 1, 3);
|
||||||
|
|
||||||
int patchOffset = (tx & 0x0f) * 3 + ypatch;
|
int patchOffset = (tx & 0x0f) * 3 + ypatch;
|
||||||
byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset;
|
byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset;
|
||||||
byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset;
|
byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset;
|
||||||
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3;
|
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3;
|
||||||
|
|
||||||
float aB = *(ptrA + 0);
|
aB = *(ptrA + 0);
|
||||||
float aG = *(ptrA + 1);
|
aG = *(ptrA + 1);
|
||||||
float aR = *(ptrA + 2);
|
aR = *(ptrA + 2);
|
||||||
|
|
||||||
float bB = *(ptrB + 0);
|
bB = *(ptrB + 0);
|
||||||
float bG = *(ptrB + 1);
|
bG = *(ptrB + 1);
|
||||||
float bR = *(ptrB + 2);
|
bR = *(ptrB + 2);
|
||||||
|
|
||||||
float layerDiff = layer - l0;
|
layerDiff = layer - l0;
|
||||||
|
|
||||||
// Interpolate between the two selected textures
|
// Interpolate between the two selected textures
|
||||||
*(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB));
|
*(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB));
|
||||||
|
@ -427,37 +451,39 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int y = 0; y < 256; y++)
|
for(int y = 0; y < theight; y++)
|
||||||
{
|
{
|
||||||
int ty = (int)((255 - y) * yFactor);
|
ty = (int)((theight - y - 1) * yFactor);
|
||||||
|
pcty = 1.0f - y * invtheightMinus1;
|
||||||
int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride;
|
int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride;
|
||||||
|
|
||||||
for(int x = 0; x < 256; x++)
|
for(int x = 0; x < twidth; x++)
|
||||||
{
|
{
|
||||||
int tx = (int)(x * xFactor);
|
tx = (int)(x * xFactor);
|
||||||
float height = (float)terrain[tx, ty];
|
pctx = x * invtwitdthMinus1;
|
||||||
float layer = getLayerTex(height, x, (255 - y),
|
height = (float)terrain[tx, ty];
|
||||||
|
layer = getLayerTex(height, pctx, pcty,
|
||||||
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
(uint)tx + regionPositionX, (uint)ty + regionPositionY,
|
||||||
startHeights, heightRanges);
|
startHeights, heightRanges);
|
||||||
|
|
||||||
// Select two textures
|
// Select two textures
|
||||||
int l0 = (int)layer;
|
l0 = (int)layer;
|
||||||
int l1 = Math.Min(l0 + 1, 3);
|
l1 = Math.Min(l0 + 1, 3);
|
||||||
|
|
||||||
int patchOffset = (tx & 0x0f) * 3 + ypatch;
|
int patchOffset = (tx & 0x0f) * 3 + ypatch;
|
||||||
byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset;
|
byte* ptrA = (byte*)datas[l0].Scan0 + patchOffset;
|
||||||
byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset;
|
byte* ptrB = (byte*)datas[l1].Scan0 + patchOffset;
|
||||||
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3;
|
byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3;
|
||||||
|
|
||||||
float aB = *(ptrA + 0);
|
aB = *(ptrA + 0);
|
||||||
float aG = *(ptrA + 1);
|
aG = *(ptrA + 1);
|
||||||
float aR = *(ptrA + 2);
|
aR = *(ptrA + 2);
|
||||||
|
|
||||||
float bB = *(ptrB + 0);
|
bB = *(ptrB + 0);
|
||||||
float bG = *(ptrB + 1);
|
bG = *(ptrB + 1);
|
||||||
float bR = *(ptrB + 2);
|
bR = *(ptrB + 2);
|
||||||
|
|
||||||
float layerDiff = layer - l0;
|
layerDiff = layer - l0;
|
||||||
|
|
||||||
// Interpolate between the two selected textures
|
// Interpolate between the two selected textures
|
||||||
*(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB));
|
*(ptrO + 0) = (byte)(aB + layerDiff * (bB - aB));
|
||||||
|
@ -486,12 +512,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||||
private static float getLayerTex(float height, int x, int y, uint sourceX, uint sourceY,
|
private static float getLayerTex(float height, float pctX, float pctY, uint sourceX, uint sourceY,
|
||||||
float[] startHeights, float[] heightRanges)
|
float[] startHeights, float[] heightRanges)
|
||||||
{
|
{
|
||||||
float pctX = (float)x / 255f;
|
|
||||||
float pctY = (float)y / 255f;
|
|
||||||
|
|
||||||
// Use bilinear interpolation between the four corners of start height and
|
// Use bilinear interpolation between the four corners of start height and
|
||||||
// height range to select the current values at this position
|
// height range to select the current values at this position
|
||||||
float startHeight = ImageUtils.Bilinear(
|
float startHeight = ImageUtils.Bilinear(
|
||||||
|
|
|
@ -50,15 +50,15 @@ using OpenMetaverse.Imaging;
|
||||||
using OpenMetaverse.Rendering;
|
using OpenMetaverse.Rendering;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
using WarpRenderer = global::Warp3D.Warp3D;
|
using WarpRenderer = Warp3D.Warp3D;
|
||||||
|
|
||||||
namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
{
|
{
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "Warp3DImageModule")]
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "Warp3DImageModule")]
|
||||||
public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
|
public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
|
||||||
{
|
{
|
||||||
private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
|
|
||||||
private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216);
|
private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216);
|
||||||
|
// private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 128);
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
@ -66,9 +66,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
private static string LogHeader = "[WARP 3D IMAGE MODULE]";
|
private static string LogHeader = "[WARP 3D IMAGE MODULE]";
|
||||||
#pragma warning restore 414
|
#pragma warning restore 414
|
||||||
|
|
||||||
private Scene m_scene;
|
internal Scene m_scene;
|
||||||
private IRendering m_primMesher;
|
private IRendering m_primMesher;
|
||||||
private Dictionary<UUID, Color4> m_colors = new Dictionary<UUID, Color4>();
|
internal IJ2KDecoder m_imgDecoder;
|
||||||
|
|
||||||
|
// caches per rendering
|
||||||
|
private Dictionary<string, warp_Texture> m_warpTextures = new Dictionary<string, warp_Texture>();
|
||||||
|
private Dictionary<UUID, int> m_colors = new Dictionary<UUID, int>();
|
||||||
|
|
||||||
private IConfigSource m_config;
|
private IConfigSource m_config;
|
||||||
private bool m_drawPrimVolume = true; // true if should render the prims on the tile
|
private bool m_drawPrimVolume = true; // true if should render the prims on the tile
|
||||||
|
@ -132,6 +136,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
{
|
{
|
||||||
|
m_imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -181,10 +186,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
viewHeigth = (int)m_scene.RegionInfo.RegionSizeY;
|
viewHeigth = (int)m_scene.RegionInfo.RegionSizeY;
|
||||||
orto = true;
|
orto = true;
|
||||||
|
|
||||||
// fov = warp_Math.rad2deg(2f * (float)Math.Atan2(viewWitdh,4096f));
|
// fov = warp_Math.rad2deg(2f * (float)Math.Atan2(viewWitdh, 4096f));
|
||||||
// orto = false;
|
// orto = false;
|
||||||
|
|
||||||
Bitmap tile = GenMapTile();
|
Bitmap tile = GenImage();
|
||||||
|
// image may be reloaded elsewhere, so no compression format
|
||||||
|
string filename = "MAP-" + m_scene.RegionInfo.RegionID.ToString() + ".png";
|
||||||
|
tile.Save(filename, ImageFormat.Png);
|
||||||
m_primMesher = null;
|
m_primMesher = null;
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
@ -204,14 +212,15 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
fov = pfov;
|
fov = pfov;
|
||||||
orto = false;
|
orto = false;
|
||||||
|
|
||||||
Bitmap tile = GenMapTile();
|
Bitmap tile = GenImage();
|
||||||
m_primMesher = null;
|
m_primMesher = null;
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap GenMapTile()
|
private Bitmap GenImage()
|
||||||
{
|
{
|
||||||
m_colors.Clear();
|
m_colors.Clear();
|
||||||
|
m_warpTextures.Clear();
|
||||||
|
|
||||||
WarpRenderer renderer = new WarpRenderer();
|
WarpRenderer renderer = new WarpRenderer();
|
||||||
|
|
||||||
|
@ -233,7 +242,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
#endregion Camera
|
#endregion Camera
|
||||||
|
|
||||||
renderer.Scene.setAmbient(warp_Color.getColor(192,191,173));
|
renderer.Scene.setAmbient(warp_Color.getColor(192,191,173));
|
||||||
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0f, 1f, 8f), 0xffffff, 0, 320, 40));
|
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0f, 1f, 8f), warp_Color.White, 0, 320, 40));
|
||||||
|
|
||||||
CreateWater(renderer);
|
CreateWater(renderer);
|
||||||
CreateTerrain(renderer);
|
CreateTerrain(renderer);
|
||||||
|
@ -248,6 +257,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
renderer = null;
|
renderer = null;
|
||||||
|
|
||||||
m_colors.Clear();
|
m_colors.Clear();
|
||||||
|
m_warpTextures.Clear();
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
// m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
|
// m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
|
||||||
|
|
||||||
|
@ -285,8 +295,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
m_scene.RegionInfo.RegionSizeY * 0.5f);
|
m_scene.RegionInfo.RegionSizeY * 0.5f);
|
||||||
|
|
||||||
warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR));
|
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.Scene.addMaterial("WaterColor", waterColorMaterial);
|
||||||
renderer.SetObjectMaterial("Water", "WaterColor");
|
renderer.SetObjectMaterial("Water", "WaterColor");
|
||||||
}
|
}
|
||||||
|
@ -302,7 +310,23 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
float regionsy = m_scene.RegionInfo.RegionSizeY;
|
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
|
// 'diff' is the difference in scale between the real region size and the size of terrain we're buiding
|
||||||
float diff = regionsx / 256f;
|
|
||||||
|
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 npointsx = (int)(regionsx / diff);
|
||||||
int npointsy = (int)(regionsy / diff);
|
int npointsy = (int)(regionsy / diff);
|
||||||
|
@ -391,14 +415,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
warp_Texture texture;
|
warp_Texture texture;
|
||||||
// get texture fliped on Y
|
// get texture fliped on Y
|
||||||
using (Bitmap image = TerrainSplat.Splat(
|
using (Bitmap image = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges,
|
||||||
terrain, textureIDs, startHeights, heightRanges,
|
|
||||||
m_scene.RegionInfo.WorldLocX, m_scene.RegionInfo.WorldLocY,
|
m_scene.RegionInfo.WorldLocX, m_scene.RegionInfo.WorldLocY,
|
||||||
m_scene.AssetService, m_textureTerrain, m_textureAvegareTerrain, true))
|
m_scene.AssetService, m_imgDecoder, m_textureTerrain, m_textureAvegareTerrain, true,
|
||||||
|
twidth, twidth))
|
||||||
texture = new warp_Texture(image);
|
texture = new warp_Texture(image);
|
||||||
|
|
||||||
warp_Material material = new warp_Material(texture);
|
warp_Material material = new warp_Material(texture);
|
||||||
material.setColor(warp_Color.getColor(255,255,255));
|
|
||||||
renderer.Scene.addMaterial("TerrainColor", material);
|
renderer.Scene.addMaterial("TerrainColor", material);
|
||||||
renderer.SetObjectMaterial("Terrain", "TerrainColor");
|
renderer.SetObjectMaterial("Terrain", "TerrainColor");
|
||||||
}
|
}
|
||||||
|
@ -416,18 +439,31 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim)
|
private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim)
|
||||||
{
|
{
|
||||||
const float MIN_SIZE_SQUARE = 4f;
|
|
||||||
|
|
||||||
if ((PCode)prim.Shape.PCode != PCode.Prim)
|
if ((PCode)prim.Shape.PCode != PCode.Prim)
|
||||||
return;
|
return;
|
||||||
float primScaleLenSquared = prim.Scale.LengthSquared();
|
|
||||||
|
|
||||||
if (primScaleLenSquared < MIN_SIZE_SQUARE)
|
warp_Vector primPos = ConvertVector(prim.GetWorldPosition());
|
||||||
|
warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation());
|
||||||
|
warp_Matrix m = warp_Matrix.quaternionMatrix(primRot);
|
||||||
|
|
||||||
|
float screenFactor = renderer.Scene.EstimateBoxProjectedArea(primPos, ConvertVector(prim.Scale), m);
|
||||||
|
if(screenFactor < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int p2 = (int)( -(float)Math.Log(screenFactor) * 1.442695f * 0.5 - 1);
|
||||||
|
|
||||||
|
if(p2 < 0)
|
||||||
|
p2 = 0;
|
||||||
|
else if(p2>3)
|
||||||
|
p2 = 3;
|
||||||
|
|
||||||
|
DetailLevel lod = (DetailLevel)(3 - p2);
|
||||||
|
|
||||||
|
// DetailLevel lod = DetailLevel.High;
|
||||||
|
|
||||||
FacetedMesh renderMesh = null;
|
FacetedMesh renderMesh = null;
|
||||||
Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);
|
Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);
|
||||||
|
|
||||||
|
@ -443,18 +479,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
if (omvPrim.Sculpt.Type == SculptType.Mesh)
|
if (omvPrim.Sculpt.Type == SculptType.Mesh)
|
||||||
{
|
{
|
||||||
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
|
AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
|
||||||
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh);
|
FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, lod, out renderMesh);
|
||||||
meshAsset = null;
|
meshAsset = null;
|
||||||
}
|
}
|
||||||
else // It's sculptie
|
else // It's sculptie
|
||||||
{
|
{
|
||||||
IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
|
if(m_imgDecoder != null)
|
||||||
if(imgDecoder != null)
|
|
||||||
{
|
{
|
||||||
Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
|
Image sculpt = m_imgDecoder.DecodeToImage(sculptAsset);
|
||||||
if(sculpt != null)
|
if(sculpt != null)
|
||||||
{
|
{
|
||||||
renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim,(Bitmap)sculpt, DetailLevel.High);
|
renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim,(Bitmap)sculpt, lod);
|
||||||
sculpt.Dispose();
|
sculpt.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,7 +501,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
// If not a mesh or sculptie, try the regular mesher
|
// If not a mesh or sculptie, try the regular mesher
|
||||||
if (renderMesh == null)
|
if (renderMesh == null)
|
||||||
{
|
{
|
||||||
renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.High);
|
renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, lod);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderMesh == null)
|
if (renderMesh == null)
|
||||||
|
@ -474,10 +509,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
string primID = prim.UUID.ToString();
|
string primID = prim.UUID.ToString();
|
||||||
|
|
||||||
warp_Vector primPos = ConvertVector(prim.GetWorldPosition());
|
|
||||||
warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation());
|
|
||||||
warp_Matrix m = warp_Matrix.quaternionMatrix(primRot);
|
|
||||||
|
|
||||||
// Create the prim faces
|
// Create the prim faces
|
||||||
// TODO: Implement the useTextures flag behavior
|
// TODO: Implement the useTextures flag behavior
|
||||||
for (int i = 0; i < renderMesh.Faces.Count; i++)
|
for (int i = 0; i < renderMesh.Faces.Count; i++)
|
||||||
|
@ -493,20 +524,34 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
|
Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
|
||||||
Color4 faceColor = teFace.RGBA;
|
Color4 faceColor = teFace.RGBA;
|
||||||
|
if(faceColor.A == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
string materialName = String.Empty;
|
string materialName = String.Empty;
|
||||||
if (m_texturePrims && primScaleLenSquared > m_texturePrimSize*m_texturePrimSize)
|
if (m_texturePrims)
|
||||||
materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID);
|
{
|
||||||
|
// if(lod > DetailLevel.Low)
|
||||||
|
{
|
||||||
|
// materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, lod == DetailLevel.Low);
|
||||||
|
materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, false);
|
||||||
|
if(String.IsNullOrEmpty(materialName))
|
||||||
|
continue;
|
||||||
|
int c = renderer.Scene.material(materialName).getColor();
|
||||||
|
if((c & warp_Color.MASKALPHA) == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
materialName = GetOrCreateMaterial(renderer, GetFaceColor(teFace));
|
materialName = GetOrCreateMaterial(renderer, faceColor);
|
||||||
|
|
||||||
if(renderer.Scene.material(materialName).getTexture() == null)
|
if(renderer.Scene.material(materialName).getTexture() == null)
|
||||||
{
|
{
|
||||||
|
// uv map details dont not matter for color;
|
||||||
for (int j = 0; j < face.Vertices.Count; j++)
|
for (int j = 0; j < face.Vertices.Count; j++)
|
||||||
{
|
{
|
||||||
Vertex v = face.Vertices[j];
|
Vertex v = face.Vertices[j];
|
||||||
warp_Vector pos = ConvertVector(v.Position);
|
warp_Vector pos = ConvertVector(v.Position);
|
||||||
warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, 1.0f - v.TexCoord.Y);
|
warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y);
|
||||||
faceObj.addVertex(vert);
|
faceObj.addVertex(vert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,20 +620,21 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color4 GetFaceColor(Primitive.TextureEntryFace face)
|
private int GetFaceColor(Primitive.TextureEntryFace face)
|
||||||
{
|
{
|
||||||
Color4 color;
|
int color;
|
||||||
|
Color4 ctmp = Color4.White;
|
||||||
|
|
||||||
if (face.TextureID == UUID.Zero)
|
if (face.TextureID == UUID.Zero)
|
||||||
return face.RGBA;
|
return warp_Color.White;
|
||||||
|
|
||||||
if (!m_colors.TryGetValue(face.TextureID, out color))
|
if (!m_colors.TryGetValue(face.TextureID, out color))
|
||||||
{
|
{
|
||||||
bool fetched = false;
|
bool fetched = false;
|
||||||
|
|
||||||
// Attempt to fetch the texture metadata
|
// Attempt to fetch the texture metadata
|
||||||
UUID metadataID = UUID.Combine(face.TextureID, TEXTURE_METADATA_MAGIC);
|
string cacheName = "MAPCLR"+face.TextureID.ToString();
|
||||||
AssetBase metadata = m_scene.AssetService.GetCached(metadataID.ToString());
|
AssetBase metadata = m_scene.AssetService.GetCached(cacheName);
|
||||||
if (metadata != null)
|
if (metadata != null)
|
||||||
{
|
{
|
||||||
OSDMap map = null;
|
OSDMap map = null;
|
||||||
|
@ -596,7 +642,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
color = map["X-JPEG2000-RGBA"].AsColor4();
|
ctmp = map["X-RGBA"].AsColor4();
|
||||||
fetched = true;
|
fetched = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,16 +655,16 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
if (textureAsset != null)
|
if (textureAsset != null)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
color = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height);
|
ctmp = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height);
|
||||||
|
|
||||||
OSDMap data = new OSDMap { { "X-JPEG2000-RGBA", OSD.FromColor4(color) } };
|
OSDMap data = new OSDMap { { "X-RGBA", OSD.FromColor4(ctmp) } };
|
||||||
metadata = new AssetBase
|
metadata = new AssetBase
|
||||||
{
|
{
|
||||||
Data = System.Text.Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)),
|
Data = System.Text.Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)),
|
||||||
Description = "Metadata for JPEG2000 texture " + face.TextureID.ToString(),
|
Description = "Metadata for texture color" + face.TextureID.ToString(),
|
||||||
Flags = AssetFlags.Collectable,
|
Flags = AssetFlags.Collectable,
|
||||||
FullID = metadataID,
|
FullID = UUID.Zero,
|
||||||
ID = metadataID.ToString(),
|
ID = cacheName,
|
||||||
Local = true,
|
Local = true,
|
||||||
Temporary = true,
|
Temporary = true,
|
||||||
Name = String.Empty,
|
Name = String.Empty,
|
||||||
|
@ -628,14 +674,14 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
color = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
|
ctmp = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
color = ConvertColor(ctmp);
|
||||||
m_colors[face.TextureID] = color;
|
m_colors[face.TextureID] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
return color * face.RGBA;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color)
|
private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color)
|
||||||
|
@ -647,26 +693,32 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
return name;
|
return name;
|
||||||
|
|
||||||
renderer.AddMaterial(name, ConvertColor(color));
|
renderer.AddMaterial(name, ConvertColor(color));
|
||||||
if (color.A < 1f)
|
|
||||||
renderer.Scene.material(name).setTransparency((byte)((1f - color.A) * 255f));
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetOrCreateMaterial(WarpRenderer renderer, Color4 faceColor, UUID textureID)
|
public string GetOrCreateMaterial(WarpRenderer renderer, Color4 faceColor, UUID textureID, bool useAverageTextureColor)
|
||||||
{
|
{
|
||||||
string materialName = "Color-" + faceColor.ToString() + "-Texture-" + textureID.ToString();
|
int color = ConvertColor(faceColor);
|
||||||
|
string idstr = textureID.ToString() + color.ToString();
|
||||||
|
string materialName = "MAPMAT" + idstr;
|
||||||
|
|
||||||
if (renderer.Scene.material(materialName) == null)
|
if (renderer.Scene.material(materialName) != null)
|
||||||
|
return materialName;
|
||||||
|
|
||||||
|
warp_Material mat = new warp_Material();
|
||||||
|
warp_Texture texture = GetTexture(textureID);
|
||||||
|
if (texture != null)
|
||||||
{
|
{
|
||||||
renderer.AddMaterial(materialName, ConvertColor(faceColor));
|
if(useAverageTextureColor)
|
||||||
if (faceColor.A < 1f)
|
color = warp_Color.multiply(color, texture.averageColor);
|
||||||
{
|
else
|
||||||
renderer.Scene.material(materialName).setTransparency((byte) ((1f - faceColor.A)*255f));
|
mat.setTexture(texture);
|
||||||
}
|
|
||||||
warp_Texture texture = GetTexture(textureID);
|
|
||||||
if (texture != null)
|
|
||||||
renderer.Scene.material(materialName).setTexture(texture);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
color = warp_Color.multiply(color, warp_Color.Grey);
|
||||||
|
|
||||||
|
mat.setColor(color);
|
||||||
|
renderer.Scene.addMaterial(materialName, mat);
|
||||||
|
|
||||||
return materialName;
|
return materialName;
|
||||||
}
|
}
|
||||||
|
@ -674,13 +726,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
private warp_Texture GetTexture(UUID id)
|
private warp_Texture GetTexture(UUID id)
|
||||||
{
|
{
|
||||||
warp_Texture ret = null;
|
warp_Texture ret = null;
|
||||||
|
if(id == UUID.Zero)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if(m_warpTextures.TryGetValue(id.ToString(), out ret))
|
||||||
|
return ret;
|
||||||
|
|
||||||
byte[] asset = m_scene.AssetService.GetData(id.ToString());
|
byte[] asset = m_scene.AssetService.GetData(id.ToString());
|
||||||
|
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
{
|
{
|
||||||
IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
|
IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (Bitmap img = (Bitmap)imgDecoder.DecodeToImage(asset))
|
using (Bitmap img = (Bitmap)imgDecoder.DecodeToImage(asset))
|
||||||
|
@ -691,7 +747,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e);
|
m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_warpTextures[id.ToString()] = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,10 +772,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
|
|
||||||
private static int ConvertColor(Color4 color)
|
private static int ConvertColor(Color4 color)
|
||||||
{
|
{
|
||||||
int c = warp_Color.getColor((byte)(color.R * 255f), (byte)(color.G * 255f), (byte)(color.B * 255f));
|
int c = warp_Color.getColor((byte)(color.R * 255f), (byte)(color.G * 255f), (byte)(color.B * 255f), (byte)(color.A * 255f));
|
||||||
if (color.A < 1f)
|
|
||||||
c |= (byte)(color.A * 255f) << 24;
|
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,86 +787,83 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
return normal;
|
return normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color4 GetAverageColor(UUID textureID, byte[] j2kData, out int width, out int height)
|
public Color4 GetAverageColor(UUID textureID, byte[] j2kData, out int width, out int height)
|
||||||
{
|
{
|
||||||
ulong r = 0;
|
ulong r = 0;
|
||||||
ulong g = 0;
|
ulong g = 0;
|
||||||
ulong b = 0;
|
ulong b = 0;
|
||||||
ulong a = 0;
|
ulong a = 0;
|
||||||
|
int pixelBytes;
|
||||||
|
|
||||||
using (MemoryStream stream = new MemoryStream(j2kData))
|
try
|
||||||
{
|
{
|
||||||
try
|
using(MemoryStream stream = new MemoryStream(j2kData))
|
||||||
|
using(Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream))
|
||||||
{
|
{
|
||||||
int pixelBytes;
|
width = bitmap.Width;
|
||||||
|
height = bitmap.Height;
|
||||||
|
|
||||||
using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream))
|
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||||
|
pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
|
||||||
|
|
||||||
|
// Sum up the individual channels
|
||||||
|
unsafe
|
||||||
{
|
{
|
||||||
width = bitmap.Width;
|
if(pixelBytes == 4)
|
||||||
height = bitmap.Height;
|
|
||||||
|
|
||||||
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
|
||||||
pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
|
|
||||||
|
|
||||||
// Sum up the individual channels
|
|
||||||
unsafe
|
|
||||||
{
|
{
|
||||||
if (pixelBytes == 4)
|
for(int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y++)
|
byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride);
|
||||||
{
|
|
||||||
byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride);
|
|
||||||
|
|
||||||
for (int x = 0; x < width; x++)
|
for(int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
b += row[x * pixelBytes + 0];
|
b += row[x * pixelBytes + 0];
|
||||||
g += row[x * pixelBytes + 1];
|
g += row[x * pixelBytes + 1];
|
||||||
r += row[x * pixelBytes + 2];
|
r += row[x * pixelBytes + 2];
|
||||||
a += row[x * pixelBytes + 3];
|
a += row[x * pixelBytes + 3];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y++)
|
byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride);
|
||||||
{
|
|
||||||
byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride);
|
|
||||||
|
|
||||||
for (int x = 0; x < width; x++)
|
for(int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
b += row[x * pixelBytes + 0];
|
b += row[x * pixelBytes + 0];
|
||||||
g += row[x * pixelBytes + 1];
|
g += row[x * pixelBytes + 1];
|
||||||
r += row[x * pixelBytes + 2];
|
r += row[x * pixelBytes + 2];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the averages for each channel
|
|
||||||
const decimal OO_255 = 1m / 255m;
|
|
||||||
decimal totalPixels = (decimal)(width * height);
|
|
||||||
|
|
||||||
decimal rm = ((decimal)r / totalPixels) * OO_255;
|
|
||||||
decimal gm = ((decimal)g / totalPixels) * OO_255;
|
|
||||||
decimal bm = ((decimal)b / totalPixels) * OO_255;
|
|
||||||
decimal am = ((decimal)a / totalPixels) * OO_255;
|
|
||||||
|
|
||||||
if (pixelBytes == 3)
|
|
||||||
am = 1m;
|
|
||||||
|
|
||||||
return new Color4((float)rm, (float)gm, (float)bm, (float)am);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
// Get the averages for each channel
|
||||||
{
|
const decimal OO_255 = 1m / 255m;
|
||||||
m_log.WarnFormat(
|
decimal totalPixels = (decimal)(width * height);
|
||||||
"[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}",
|
|
||||||
textureID, j2kData.Length, ex.Message);
|
|
||||||
|
|
||||||
width = 0;
|
decimal rm = ((decimal)r / totalPixels) * OO_255;
|
||||||
height = 0;
|
decimal gm = ((decimal)g / totalPixels) * OO_255;
|
||||||
return new Color4(0.5f, 0.5f, 0.5f, 1.0f);
|
decimal bm = ((decimal)b / totalPixels) * OO_255;
|
||||||
}
|
decimal am = ((decimal)a / totalPixels) * OO_255;
|
||||||
|
|
||||||
|
if(pixelBytes == 3)
|
||||||
|
am = 1m;
|
||||||
|
|
||||||
|
return new Color4((float)rm, (float)gm, (float)bm, (float)am);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}",
|
||||||
|
textureID, j2kData.Length, ex.Message);
|
||||||
|
|
||||||
|
width = 0;
|
||||||
|
height = 0;
|
||||||
|
return new Color4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1409,6 +1409,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
|
|
||||||
// assumed this is 1m less than next grid line
|
// assumed this is 1m less than next grid line
|
||||||
int regionsView = (int)m_scene.MaxRegionViewDistance;
|
int regionsView = (int)m_scene.MaxRegionViewDistance;
|
||||||
|
|
||||||
|
string regionName = m_scene.RegionInfo.RegionName;
|
||||||
|
ulong regionHandle = m_scene.RegionInfo.RegionHandle;
|
||||||
|
|
||||||
int regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;
|
int regionSizeX = (int)m_scene.RegionInfo.RegionSizeX;
|
||||||
int regionSizeY = (int)m_scene.RegionInfo.RegionSizeY;
|
int regionSizeY = (int)m_scene.RegionInfo.RegionSizeY;
|
||||||
|
@ -1439,25 +1442,52 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
g.FillRectangle(sea, 0, 0, spanX, spanY);
|
g.FillRectangle(sea, 0, 0, spanX, spanY);
|
||||||
sea.Dispose();
|
sea.Dispose();
|
||||||
|
|
||||||
|
Font drawFont = new Font("Arial", 32);
|
||||||
|
SolidBrush drawBrush = new SolidBrush(Color.White);
|
||||||
|
|
||||||
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
|
||||||
startX, startY, endX, endY);
|
startX, startY, endX, endY);
|
||||||
|
|
||||||
|
startX--;
|
||||||
|
startY--;
|
||||||
|
|
||||||
|
bool doneLocal = false;
|
||||||
|
string filename = "MAP-" + m_scene.RegionInfo.RegionID.ToString() + ".png";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using(Image localMap = Bitmap.FromFile(filename))
|
||||||
|
{
|
||||||
|
int x = regionX - startX;
|
||||||
|
int y = regionY - startY;
|
||||||
|
int sx = regionSizeX;
|
||||||
|
int sy = regionSizeY;
|
||||||
|
// y origin is top
|
||||||
|
g.DrawImage(localMap,new Rectangle(x, spanY - y - sy, sx, sy),
|
||||||
|
0, 0, localMap.Width, localMap.Height, GraphicsUnit.Pixel, gatrib);
|
||||||
|
|
||||||
|
if(m_exportPrintRegionName)
|
||||||
|
{
|
||||||
|
SizeF stringSize = g.MeasureString(regionName, drawFont);
|
||||||
|
g.DrawString(regionName, drawFont, drawBrush, x + 30, spanY - y - 30 - stringSize.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doneLocal = true;
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
|
||||||
if(regions.Count > 0)
|
if(regions.Count > 0)
|
||||||
{
|
{
|
||||||
Font drawFont = new Font("Arial", 32);
|
|
||||||
SolidBrush drawBrush = new SolidBrush(Color.White);
|
|
||||||
|
|
||||||
ManagedImage managedImage = null;
|
ManagedImage managedImage = null;
|
||||||
Image image = null;
|
Image image = null;
|
||||||
|
|
||||||
startX--;
|
|
||||||
startY--;
|
|
||||||
|
|
||||||
foreach(GridRegion r in regions)
|
foreach(GridRegion r in regions)
|
||||||
{
|
{
|
||||||
if(r.TerrainImage == UUID.Zero)
|
if(r.TerrainImage == UUID.Zero)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(doneLocal && r.RegionHandle == regionHandle)
|
||||||
|
continue;
|
||||||
|
|
||||||
AssetBase texAsset = m_scene.AssetService.Get(r.TerrainImage.ToString());
|
AssetBase texAsset = m_scene.AssetService.Get(r.TerrainImage.ToString());
|
||||||
if(texAsset == null)
|
if(texAsset == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1472,7 +1502,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
g.DrawImage(image,new Rectangle(x, spanY - y - sy, sx, sy),
|
g.DrawImage(image,new Rectangle(x, spanY - y - sy, sx, sy),
|
||||||
0, 0, image.Width, image.Height, GraphicsUnit.Pixel, gatrib);
|
0, 0, image.Width, image.Height, GraphicsUnit.Pixel, gatrib);
|
||||||
|
|
||||||
if(m_exportPrintRegionName && r.RegionHandle == m_scene.RegionInfo.RegionHandle)
|
if(m_exportPrintRegionName && r.RegionHandle == regionHandle)
|
||||||
{
|
{
|
||||||
SizeF stringSize = g.MeasureString(r.RegionName, drawFont);
|
SizeF stringSize = g.MeasureString(r.RegionName, drawFont);
|
||||||
g.DrawString(r.RegionName, drawFont, drawBrush, x + 30, spanY - y - 30 - stringSize.Height);
|
g.DrawString(r.RegionName, drawFont, drawBrush, x + 30, spanY - y - 30 - stringSize.Height);
|
||||||
|
@ -1483,16 +1513,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
if(image != null)
|
if(image != null)
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
|
|
||||||
if(m_exportPrintScale)
|
|
||||||
{
|
|
||||||
String drawString = string.Format("{0}m x {1}m", spanX, spanY);
|
|
||||||
g.DrawString(drawString, drawFont, drawBrush, 30, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawBrush.Dispose();
|
|
||||||
drawFont.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_exportPrintScale)
|
||||||
|
{
|
||||||
|
String drawString = string.Format("{0}m x {1}m", spanX, spanY);
|
||||||
|
g.DrawString(drawString, drawFont, drawBrush, 30, 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawBrush.Dispose();
|
||||||
|
drawFont.Dispose();
|
||||||
gatrib.Dispose();
|
gatrib.Dispose();
|
||||||
g.Dispose();
|
g.Dispose();
|
||||||
|
|
||||||
|
@ -1689,13 +1719,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
{
|
{
|
||||||
float scale = (float)Constants.RegionSize/(float)mb;
|
float scale = (float)Constants.RegionSize/(float)mb;
|
||||||
using(Bitmap scaledbmp = Util.ResizeImageSolid(mapbmp, (int)(bx * scale), (int)(by * scale)))
|
using(Bitmap scaledbmp = Util.ResizeImageSolid(mapbmp, (int)(bx * scale), (int)(by * scale)))
|
||||||
data = OpenJPEG.EncodeFromImage(scaledbmp, false);
|
data = OpenJPEG.EncodeFromImage(scaledbmp, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
data = OpenJPEG.EncodeFromImage(mapbmp, false);
|
data = OpenJPEG.EncodeFromImage(mapbmp, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
data = OpenJPEG.EncodeFromImage(mapbmp, false);
|
data = OpenJPEG.EncodeFromImage(mapbmp, true);
|
||||||
|
|
||||||
if (data != null && data.Length > 0)
|
if (data != null && data.Length > 0)
|
||||||
{
|
{
|
||||||
|
|
BIN
bin/Warp3D.dll
BIN
bin/Warp3D.dll
Binary file not shown.
Loading…
Reference in New Issue