aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs131
1 files changed, 87 insertions, 44 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 3e3a0f0..72dce6d 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -40,6 +40,7 @@ using log4net;
40using Nini.Config; 40using Nini.Config;
41using System.Reflection; 41using System.Reflection;
42using System.IO; 42using System.IO;
43using ComponentAce.Compression.Libs.zlib;
43 44
44namespace OpenSim.Region.Physics.Meshing 45namespace OpenSim.Region.Physics.Meshing
45{ 46{
@@ -74,6 +75,7 @@ namespace OpenSim.Region.Physics.Meshing
74 75
75 private bool cacheSculptMaps = true; 76 private bool cacheSculptMaps = true;
76 private string decodedSculptMapPath = null; 77 private string decodedSculptMapPath = null;
78 private bool useMeshiesPhysicsMesh = false;
77 79
78 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
79 81
@@ -85,6 +87,7 @@ namespace OpenSim.Region.Physics.Meshing
85 87
86 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); 88 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
87 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); 89 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
90 useMeshiesPhysicsMesh = start_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
88 91
89 try 92 try
90 { 93 {
@@ -268,73 +271,113 @@ namespace OpenSim.Region.Physics.Meshing
268 { 271 {
269 if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) 272 if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh)
270 { 273 {
271 // add code for mesh physics proxy generation here 274 if (!useMeshiesPhysicsMesh)
272 m_log.Debug("[MESH]: mesh proxy generation not implemented yet "); 275 return null;
273
274 OSD meshOsd;
275 276
276 if (primShape.SculptData.Length > 0) 277 m_log.Debug("[MESH]: experimental mesh proxy generation");
277 {
278
279
280 m_log.Debug("[MESH]: asset data length: " + primShape.SculptData.Length.ToString());
281 byte[] header = Util.StringToBytes256("<? LLSD/Binary ?>");
282 278
283 ////dump to debugging file 279 OSD meshOsd;
284 //string filename = System.IO.Path.Combine(decodedSculptMapPath, "mesh_" + primShape.SculptTexture.ToString());
285 //BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create));
286 //writer.Write(primShape.SculptData);
287 //writer.Close();
288 280
289 } 281 if (primShape.SculptData.Length <= 0)
290 else
291 { 282 {
292 m_log.Error("[MESH]: asset data is zero length"); 283 m_log.Error("[MESH]: asset data is zero length");
293 return null; 284 return null;
294 } 285 }
295 286
296 try 287 long start = 0;
288 using (MemoryStream data = new MemoryStream(primShape.SculptData))
297 { 289 {
298 meshOsd = OSDParser.DeserializeLLSDBinary(primShape.SculptData, true); 290 meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data, true);
299 } 291 start = data.Position;
300 catch (Exception e)
301 {
302 m_log.Error("[MESH]: exception decoding mesh asset: " + e.ToString());
303 return null;
304 } 292 }
305 293
306 if (meshOsd is OSDMap) 294 if (meshOsd is OSDMap)
307 { 295 {
308 OSDMap map = (OSDMap)meshOsd; 296 OSDMap map = (OSDMap)meshOsd;
309 //foreach (string name in map.Keys)
310 // m_log.Debug("[MESH]: key:" + name + " value:" + map[name].AsString());
311 OSDMap physicsParms = (OSDMap)map["physics_shape"]; 297 OSDMap physicsParms = (OSDMap)map["physics_shape"];
312 int physOffset = physicsParms["offset"].AsInteger(); 298 int physOffset = physicsParms["offset"].AsInteger() + (int)start;
313 int physSize = physicsParms["size"].AsInteger(); 299 int physSize = physicsParms["size"].AsInteger();
314 300
315 if (physOffset < 0 || physSize == 0) 301 if (physOffset < 0 || physSize == 0)
316 return null; // no mesh data in asset 302 return null; // no mesh data in asset
317 303
318 m_log.Debug("[MESH]: physOffset:" + physOffset.ToString() + " physSize:" + physSize.ToString()); 304 OSD decodedMeshOsd = new OSD();
319 //MemoryStream ms = new MemoryStream(primShape.SculptData, physOffset, physSize); 305 byte[] meshBytes = new byte[physSize];
320 //GZipStream gzStream = new GZipStream(ms, CompressionMode.Decompress); 306 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
321 307 byte[] decompressed = new byte[physSize * 5];
322 //int maxSize = physSize * 5; // arbitrary guess 308 try
323 //byte[] readBuffer = new byte[maxSize]; 309 {
324 310 using (MemoryStream inMs = new MemoryStream(meshBytes))
325 //int bytesRead = gzStream.Read(readBuffer, 0, maxSize); 311 {
326 312 using (MemoryStream outMs = new MemoryStream())
327 //OSD physMeshOsd = OSDParser.DeserializeLLSDBinary(readBuffer); 313 {
328 314 using (ZOutputStream zOut = new ZOutputStream(outMs))
329 315 {
330 316 byte[] readBuffer = new byte[2048];
317 int readLen = 0;
318 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
319 {
320 zOut.Write(readBuffer, 0, readLen);
321 }
322 zOut.Flush();
323 outMs.Seek(0, SeekOrigin.Begin);
324
325 byte[] decompressedBuf = outMs.GetBuffer();
326
327 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf, true);
328 }
329 }
330 }
331 }
332 catch (Exception e)
333 {
334 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
335 return null;
336 }
331 337
338 OSDArray decodedMeshOsdArray = null;
332 339
340 // physics_shape is an array of OSDMaps, one for each submesh
341 if (decodedMeshOsd is OSDArray)
342 {
343 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
344 foreach (OSD subMeshOsd in decodedMeshOsdArray)
345 {
346 if (subMeshOsd is OSDMap)
347 {
348 OSDMap subMeshMap = (OSDMap)subMeshOsd;
349
350 OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
351 OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
352
353 byte[] posBytes = subMeshMap["Position"].AsBinary();
354 for (int i = 0; i < posBytes.Length; i += 6)
355 {
356 ushort uX = Utils.BytesToUInt16(posBytes, i);
357 ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
358 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
359
360 Coord c = new Coord(
361 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
362 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
363 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);
364
365 coords.Add(c);
366 }
367
368 byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
369 for (int i = 0; i < triangleBytes.Length; i += 6)
370 {
371 ushort v1 = Utils.BytesToUInt16(triangleBytes, i);
372 ushort v2 = Utils.BytesToUInt16(triangleBytes, i + 2);
373 ushort v3 = Utils.BytesToUInt16(triangleBytes, i + 4);
374 Face f = new Face(v1, v2, v3);
375 faces.Add(f);
376 }
377 }
378 }
379 }
333 } 380 }
334
335 //just bail out for now until mesh code is finished
336 return null;
337
338 } 381 }
339 else 382 else
340 { 383 {