aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs137
1 files changed, 94 insertions, 43 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 3e3a0f0..89ee5af 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,121 @@ 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;
297 { 288 using (MemoryStream data = new MemoryStream(primShape.SculptData))
298 meshOsd = OSDParser.DeserializeLLSDBinary(primShape.SculptData, true);
299 }
300 catch (Exception e)
301 { 289 {
302 m_log.Error("[MESH]: exception decoding mesh asset: " + e.ToString()); 290 meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data, true);
303 return null; 291 start = data.Position;
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 {
325 //int bytesRead = gzStream.Read(readBuffer, 0, maxSize); 311 string filename = System.IO.Path.Combine(decodedSculptMapPath, "meshInput_" + primShape.SculptTexture.ToString());
326 312 using (FileStream fs = new FileStream(filename, FileMode.Create))
327 //OSD physMeshOsd = OSDParser.DeserializeLLSDBinary(readBuffer); 313 {
328 314 fs.Write(meshBytes, 0, meshBytes.Length);
329 315 }
316 }
330 317
318 using (MemoryStream inMs = new MemoryStream(meshBytes))
319 {
320 using (MemoryStream outMs = new MemoryStream())
321 {
322 using (ZOutputStream zOut = new ZOutputStream(outMs))
323 {
324 byte[] readBuffer = new byte[2048];
325 int readLen = 0;
326 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
327 {
328 zOut.Write(readBuffer, 0, readLen);
329 }
330 zOut.Flush();
331 outMs.Seek(0, SeekOrigin.Begin);
332
333 byte[] decompressedBuf = outMs.GetBuffer();
334
335 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf, true);
336 }
337 }
338 }
339 }
340 catch (Exception e)
341 {
342 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
343 return null;
344 }
331 345
346 OSDArray decodedMeshOsdArray = null;
332 347
348 // physics_shape is an array of OSDMaps, one for each submesh
349 if (decodedMeshOsd is OSDArray)
350 {
351 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
352 foreach (OSD subMeshOsd in decodedMeshOsdArray)
353 {
354 if (subMeshOsd is OSDMap)
355 {
356 OSDMap subMeshMap = (OSDMap)subMeshOsd;
357
358 OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
359 OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
360
361 byte[] posBytes = subMeshMap["Position"].AsBinary();
362 for (int i = 0; i < posBytes.Length; i += 6)
363 {
364 ushort uX = Utils.BytesToUInt16(posBytes, i);
365 ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
366 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
367
368 Coord c = new Coord(
369 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
370 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
371 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);
372
373 coords.Add(c);
374 }
375
376 byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
377 for (int i = 0; i < triangleBytes.Length; i += 6)
378 {
379 ushort v1 = Utils.BytesToUInt16(triangleBytes, i);
380 ushort v2 = Utils.BytesToUInt16(triangleBytes, i + 2);
381 ushort v3 = Utils.BytesToUInt16(triangleBytes, i + 4);
382 Face f = new Face(v1, v2, v3);
383 faces.Add(f);
384 }
385 }
386 }
387 }
333 } 388 }
334
335 //just bail out for now until mesh code is finished
336 return null;
337
338 } 389 }
339 else 390 else
340 { 391 {