Use mesh to estimate real center of prims if avaiable. Let sculpt map textures with alpha channel work. On linux J2DecodeCache folder must be deleted to remove bad entries. Corrently this can't be cached on linux (mono/ cairo/? problem)

avinationmerge
UbitUmarov 2012-02-11 03:25:17 +00:00
parent b617411b97
commit f415256e0b
5 changed files with 129 additions and 33 deletions

View File

@ -65,5 +65,6 @@ namespace OpenSim.Region.Physics.Manager
void releasePinned(); void releasePinned();
void Append(IMesh newMesh); void Append(IMesh newMesh);
void TransformLinear(float[,] matrix, float[] offset); void TransformLinear(float[,] matrix, float[] offset);
Vector3 GetCentroid();
} }
} }

View File

@ -46,11 +46,36 @@ namespace OpenSim.Region.Physics.Meshing
IntPtr m_indicesPtr = IntPtr.Zero; IntPtr m_indicesPtr = IntPtr.Zero;
int m_indexCount = 0; int m_indexCount = 0;
public float[] m_normals; public float[] m_normals;
Vector3 _centroid;
int _centroidDiv;
private class vertexcomp : IEqualityComparer<Vertex>
{
public bool Equals(Vertex v1, Vertex v2)
{
if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
return true;
else
return false;
}
public int GetHashCode(Vertex v)
{
int a = v.X.GetHashCode();
int b = v.Y.GetHashCode();
int c = v.Z.GetHashCode();
return (a << 16) ^ (b << 8) ^ c;
}
}
public Mesh() public Mesh()
{ {
m_vertices = new Dictionary<Vertex, int>(); vertexcomp vcomp = new vertexcomp();
m_vertices = new Dictionary<Vertex, int>(vcomp);
m_triangles = new List<Triangle>(); m_triangles = new List<Triangle>();
_centroid = Vector3.Zero;
_centroidDiv = 0;
} }
public Mesh Clone() public Mesh Clone()
@ -61,7 +86,8 @@ namespace OpenSim.Region.Physics.Meshing
{ {
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
} }
result._centroid = _centroid;
result._centroidDiv = _centroidDiv;
return result; return result;
} }
@ -71,15 +97,57 @@ namespace OpenSim.Region.Physics.Meshing
throw new NotSupportedException("Attempt to Add to a pinned Mesh"); throw new NotSupportedException("Attempt to Add to a pinned Mesh");
// If a vertex of the triangle is not yet in the vertices list, // If a vertex of the triangle is not yet in the vertices list,
// add it and set its index to the current index count // add it and set its index to the current index count
// vertex == seems broken
// skip colapsed triangles
if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
|| (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
|| (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
)
{
return;
}
if (m_vertices.Count == 0)
{
_centroidDiv = 0;
_centroid = Vector3.Zero;
}
if (!m_vertices.ContainsKey(triangle.v1)) if (!m_vertices.ContainsKey(triangle.v1))
{
m_vertices[triangle.v1] = m_vertices.Count; m_vertices[triangle.v1] = m_vertices.Count;
_centroid.X += triangle.v1.X;
_centroid.Y += triangle.v1.Y;
_centroid.Z += triangle.v1.Z;
_centroidDiv++;
}
if (!m_vertices.ContainsKey(triangle.v2)) if (!m_vertices.ContainsKey(triangle.v2))
{
m_vertices[triangle.v2] = m_vertices.Count; m_vertices[triangle.v2] = m_vertices.Count;
_centroid.X += triangle.v2.X;
_centroid.Y += triangle.v2.Y;
_centroid.Z += triangle.v2.Z;
_centroidDiv++;
}
if (!m_vertices.ContainsKey(triangle.v3)) if (!m_vertices.ContainsKey(triangle.v3))
{
m_vertices[triangle.v3] = m_vertices.Count; m_vertices[triangle.v3] = m_vertices.Count;
_centroid.X += triangle.v3.X;
_centroid.Y += triangle.v3.Y;
_centroid.Z += triangle.v3.Z;
_centroidDiv++;
}
m_triangles.Add(triangle); m_triangles.Add(triangle);
} }
public Vector3 GetCentroid()
{
if (_centroidDiv > 0)
return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
else
return Vector3.Zero;
}
public void CalcNormals() public void CalcNormals()
{ {
int iTriangles = m_triangles.Count; int iTriangles = m_triangles.Count;

View File

@ -74,6 +74,8 @@ namespace OpenSim.Region.Physics.Meshing
#endif #endif
private bool cacheSculptMaps = true; private bool cacheSculptMaps = true;
private bool cacheSculptAlphaMaps = true;
private string decodedSculptMapPath = null; private string decodedSculptMapPath = null;
private bool useMeshiesPhysicsMesh = false; private bool useMeshiesPhysicsMesh = false;
@ -87,7 +89,16 @@ namespace OpenSim.Region.Physics.Meshing
IConfig mesh_config = config.Configs["Mesh"]; IConfig mesh_config = config.Configs["Mesh"];
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
cacheSculptAlphaMaps = false;
}
else
cacheSculptAlphaMaps = cacheSculptMaps;
if(mesh_config != null) if(mesh_config != null)
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
@ -268,15 +279,18 @@ namespace OpenSim.Region.Physics.Meshing
{ {
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces)) if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
return null; return null;
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
// don't loose it
// primShape.SculptData = Utils.EmptyBytes;
} }
// primShape.SculptDataLoaded = true;
} }
else else
{ {
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces)) if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
return null; return null;
} }
// keep compatible
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
primShape.SculptData = Utils.EmptyBytes; primShape.SculptData = Utils.EmptyBytes;
int numCoords = coords.Count; int numCoords = coords.Count;
@ -482,7 +496,8 @@ namespace OpenSim.Region.Physics.Meshing
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
if (cacheSculptMaps) if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
// don't cache images with alpha channel in linux since mono can't load them correctly)
{ {
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }

View File

@ -58,28 +58,24 @@ namespace PrimMesher
if (bmW == 0 || bmH == 0) if (bmW == 0 || bmH == 0)
throw new Exception("SculptMap: bitmap has no data"); throw new Exception("SculptMap: bitmap has no data");
int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
bool smallMap = bmW * bmH <= numLodPixels;
bool needsScaling = false; bool needsScaling = false;
bool smallMap = bmW * bmH <= lod * lod;
width = bmW; width = bmW;
height = bmH; height = bmH;
while (width * height > numLodPixels) while (width * height > numLodPixels * 4)
{ {
width >>= 1; width >>= 1;
height >>= 1; height >>= 1;
needsScaling = true; needsScaling = true;
} }
try try
{ {
if (needsScaling) if (needsScaling)
bm = ScaleImage(bm, width, height, bm = ScaleImage(bm, width, height);
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
} }
catch (Exception e) catch (Exception e)
@ -87,7 +83,7 @@ namespace PrimMesher
throw new Exception("Exception in ScaleImage(): e: " + e.ToString()); throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
} }
if (width * height > lod * lod) if (width * height > numLodPixels)
{ {
width >>= 1; width >>= 1;
height >>= 1; height >>= 1;
@ -144,15 +140,17 @@ namespace PrimMesher
int rowNdx, colNdx; int rowNdx, colNdx;
int smNdx = 0; int smNdx = 0;
for (rowNdx = 0; rowNdx < numRows; rowNdx++) for (rowNdx = 0; rowNdx < numRows; rowNdx++)
{ {
List<Coord> row = new List<Coord>(numCols); List<Coord> row = new List<Coord>(numCols);
for (colNdx = 0; colNdx < numCols; colNdx++) for (colNdx = 0; colNdx < numCols; colNdx++)
{ {
if (mirror) if (mirror)
row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f)); row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
else else
row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f)); row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
++smNdx; ++smNdx;
} }
@ -161,23 +159,39 @@ namespace PrimMesher
return rows; return rows;
} }
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight, private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
System.Drawing.Drawing2D.InterpolationMode interpMode)
{ {
Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
scaledImage.SetResolution(96.0f, 96.0f);
Graphics grPhoto = Graphics.FromImage(scaledImage); Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
grPhoto.InterpolationMode = interpMode;
grPhoto.DrawImage(srcImage, Color c;
new Rectangle(0, 0, destWidth, destHeight), float xscale = srcImage.Width / destWidth;
new Rectangle(0, 0, srcImage.Width, srcImage.Height), float yscale = srcImage.Height / destHeight;
GraphicsUnit.Pixel);
grPhoto.Dispose(); float sy = 0.5f;
for (int y = 0; y < destHeight; y++)
{
float sx = 0.5f;
for (int x = 0; x < destWidth; x++)
{
try
{
c = srcImage.GetPixel((int)(sx), (int)(sy));
scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
}
catch (IndexOutOfRangeException)
{
}
sx += xscale;
}
sy += yscale;
}
srcImage.Dispose();
return scaledImage; return scaledImage;
} }
}
} }
}
#endif #endif

View File

@ -1,4 +1,3 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
@ -1056,9 +1055,8 @@ namespace OpenSim.Region.Physics.OdePlugin
return false; return false;
} }
// primOOBoffset = mesh.GetCentroid(); primOOBoffset = mesh.GetCentroid();
// hasOOBoffsetFromMesh = true; hasOOBoffsetFromMesh = true;
hasOOBoffsetFromMesh = false;
_triMeshData = d.GeomTriMeshDataCreate(); _triMeshData = d.GeomTriMeshDataCreate();