aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitMeshing
diff options
context:
space:
mode:
authorMelanie2012-03-21 00:01:11 +0000
committerMelanie2012-03-21 00:01:11 +0000
commit117a86276904d8f75e4cea7e9528dd267ca3ea9f (patch)
tree467a85e00ef65c0a4bb8dad020e19055f2d39026 /OpenSim/Region/Physics/UbitMeshing
parentMove the health monitoring stuff where it will do some good (diff)
parentUpdate prebuild (diff)
downloadopensim-SC-117a86276904d8f75e4cea7e9528dd267ca3ea9f.zip
opensim-SC-117a86276904d8f75e4cea7e9528dd267ca3ea9f.tar.gz
opensim-SC-117a86276904d8f75e4cea7e9528dd267ca3ea9f.tar.bz2
opensim-SC-117a86276904d8f75e4cea7e9528dd267ca3ea9f.tar.xz
Merge branch 'master' of ssh://melanie@3dhosting.de/var/git/careminster into careminster
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing')
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs108
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs321
2 files changed, 300 insertions, 129 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs
index 8cd8dcf..2938257 100644
--- a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs
@@ -270,116 +270,20 @@ public class Triangle
270 public Vertex v2; 270 public Vertex v2;
271 public Vertex v3; 271 public Vertex v3;
272 272
273 private float radius_square;
274 private float cx;
275 private float cy;
276
277 public Triangle(Vertex _v1, Vertex _v2, Vertex _v3) 273 public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
278 { 274 {
279 v1 = _v1; 275 v1 = _v1;
280 v2 = _v2; 276 v2 = _v2;
281 v3 = _v3; 277 v3 = _v3;
282
283 CalcCircle();
284 }
285
286 public bool isInCircle(float x, float y)
287 {
288 float dx, dy;
289 float dd;
290
291 dx = x - cx;
292 dy = y - cy;
293
294 dd = dx*dx + dy*dy;
295 if (dd < radius_square)
296 return true;
297 else
298 return false;
299 } 278 }
300 279
301 public bool isDegraded() 280 public Triangle(float _v1x,float _v1y,float _v1z,
281 float _v2x,float _v2y,float _v2z,
282 float _v3x,float _v3y,float _v3z)
302 { 283 {
303 // This means, the vertices of this triangle are somewhat strange. 284 v1 = new Vertex(_v1x, _v1y, _v1z);
304 // They either line up or at least two of them are identical 285 v2 = new Vertex(_v2x, _v2y, _v2z);
305 return (radius_square == 0.0); 286 v3 = new Vertex(_v3x, _v3y, _v3z);
306 }
307
308 private void CalcCircle()
309 {
310 // Calculate the center and the radius of a circle given by three points p1, p2, p3
311 // It is assumed, that the triangles vertices are already set correctly
312 double p1x, p2x, p1y, p2y, p3x, p3y;
313
314 // Deviation of this routine:
315 // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
316 // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
317 // putting respectively two equations together gives two equations
318 // f(p1)=f(p2) and f(p1)=f(p3)
319 // bringing all constant terms to one side brings them to the form
320 // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
321 // and c1, c2 are scalars (Naming conventions like the variables below)
322 // Now using the equations that are formed by the components of the vectors
323 // and isolate Mx lets you make one equation that only holds My
324 // The rest is straight forward and eaasy :-)
325 //
326
327 /* helping variables for temporary results */
328 double c1, c2;
329 double v1x, v1y, v2x, v2y;
330
331 double z, n;
332
333 double rx, ry;
334
335 // Readout the three points, the triangle consists of
336 p1x = v1.X;
337 p1y = v1.Y;
338
339 p2x = v2.X;
340 p2y = v2.Y;
341
342 p3x = v3.X;
343 p3y = v3.Y;
344
345 /* calc helping values first */
346 c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
347 c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
348
349 v1x = p1x - p2x;
350 v1y = p1y - p2y;
351
352 v2x = p1x - p3x;
353 v2y = p1y - p3y;
354
355 z = (c1*v2x - c2*v1x);
356 n = (v1y*v2x - v2y*v1x);
357
358 if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
359 {
360 radius_square = 0.0f;
361 return;
362 }
363
364 cy = (float) (z/n);
365
366 if (v2x != 0.0)
367 {
368 cx = (float) ((c2 - v2y*cy)/v2x);
369 }
370 else if (v1x != 0.0)
371 {
372 cx = (float) ((c1 - v1y*cy)/v1x);
373 }
374 else
375 {
376 Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
377 }
378
379 rx = (p1x - cx);
380 ry = (p1y - cy);
381
382 radius_square = (float) (rx*rx + ry*ry);
383 } 287 }
384 288
385 public override String ToString() 289 public override String ToString()
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index c9c52c0..7667e91 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -41,6 +41,7 @@ using Nini.Config;
41using System.Reflection; 41using System.Reflection;
42using System.IO; 42using System.IO;
43using ComponentAce.Compression.Libs.zlib; 43using ComponentAce.Compression.Libs.zlib;
44using OpenSim.Region.Physics.ConvexDecompositionDotNet;
44 45
45namespace OpenSim.Region.Physics.Meshing 46namespace OpenSim.Region.Physics.Meshing
46{ 47{
@@ -256,7 +257,7 @@ namespace OpenSim.Region.Physics.Meshing
256 /// <param name="size"></param> 257 /// <param name="size"></param>
257 /// <param name="lod"></param> 258 /// <param name="lod"></param>
258 /// <returns></returns> 259 /// <returns></returns>
259 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 260 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool convex)
260 { 261 {
261// m_log.DebugFormat( 262// m_log.DebugFormat(
262// "[MESH]: Creating physics proxy for {0}, shape {1}", 263// "[MESH]: Creating physics proxy for {0}, shape {1}",
@@ -272,7 +273,7 @@ namespace OpenSim.Region.Physics.Meshing
272 if (!useMeshiesPhysicsMesh) 273 if (!useMeshiesPhysicsMesh)
273 return null; 274 return null;
274 275
275 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces)) 276 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces, convex))
276 return null; 277 return null;
277 } 278 }
278 else 279 else
@@ -296,22 +297,20 @@ namespace OpenSim.Region.Physics.Meshing
296 int numCoords = coords.Count; 297 int numCoords = coords.Count;
297 int numFaces = faces.Count; 298 int numFaces = faces.Count;
298 299
299 // Create the list of vertices
300 List<Vertex> vertices = new List<Vertex>();
301 for (int i = 0; i < numCoords; i++)
302 {
303 Coord c = coords[i];
304 vertices.Add(new Vertex(c.X, c.Y, c.Z));
305 }
306
307 Mesh mesh = new Mesh(); 300 Mesh mesh = new Mesh();
308 // Add the corresponding triangles to the mesh 301 // Add the corresponding triangles to the mesh
309 for (int i = 0; i < numFaces; i++) 302 for (int i = 0; i < numFaces; i++)
310 { 303 {
311 Face f = faces[i]; 304 Face f = faces[i];
312 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3])); 305 mesh.Add(new Triangle(coords[f.v1].X, coords[f.v1].Y, coords[f.v1].Z,
306 coords[f.v2].X, coords[f.v2].Y, coords[f.v2].Z,
307 coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z));
313 } 308 }
314 309
310
311// mesh.DumpRaw("c:\\lixo", "lixo", "lixo");
312 mesh.DumpRaw(".", "lixo", "lixo");
313
315 return mesh; 314 return mesh;
316 } 315 }
317 316
@@ -325,10 +324,12 @@ namespace OpenSim.Region.Physics.Meshing
325 /// <param name="faces">Faces are added to this list by the method.</param> 324 /// <param name="faces">Faces are added to this list by the method.</param>
326 /// <returns>true if coords and faces were successfully generated, false if not</returns> 325 /// <returns>true if coords and faces were successfully generated, false if not</returns>
327 private bool GenerateCoordsAndFacesFromPrimMeshData( 326 private bool GenerateCoordsAndFacesFromPrimMeshData(
328 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces) 327 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces, bool convex)
329 { 328 {
330// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); 329// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
331 330
331 bool usemesh = false;
332
332 coords = new List<Coord>(); 333 coords = new List<Coord>();
333 faces = new List<Face>(); 334 faces = new List<Face>();
334 OSD meshOsd = null; 335 OSD meshOsd = null;
@@ -365,14 +366,25 @@ namespace OpenSim.Region.Physics.Meshing
365 { 366 {
366 OSDMap physicsParms = null; 367 OSDMap physicsParms = null;
367 OSDMap map = (OSDMap)meshOsd; 368 OSDMap map = (OSDMap)meshOsd;
368 if (map.ContainsKey("physics_shape")) 369
369 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 370 if (!convex)
370 else if (map.ContainsKey("physics_mesh")) 371 {
371 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 372 if (map.ContainsKey("physics_shape"))
373 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
374 else if (map.ContainsKey("physics_mesh"))
375 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
376
377 if (physicsParms != null)
378 usemesh = true;
379 }
380
381 if(!usemesh && (map.ContainsKey("physics_convex")))
382 physicsParms = (OSDMap)map["physics_convex"];
383
372 384
373 if (physicsParms == null) 385 if (physicsParms == null)
374 { 386 {
375 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); 387 m_log.Warn("[MESH]: unknown mesh type");
376 return false; 388 return false;
377 } 389 }
378 390
@@ -416,19 +428,269 @@ namespace OpenSim.Region.Physics.Meshing
416 return false; 428 return false;
417 } 429 }
418 430
419 OSDArray decodedMeshOsdArray = null; 431 if (usemesh)
432 {
433 OSDArray decodedMeshOsdArray = null;
420 434
421 // physics_shape is an array of OSDMaps, one for each submesh 435 // physics_shape is an array of OSDMaps, one for each submesh
422 if (decodedMeshOsd is OSDArray) 436 if (decodedMeshOsd is OSDArray)
437 {
438 // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
439
440 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
441 foreach (OSD subMeshOsd in decodedMeshOsdArray)
442 {
443 if (subMeshOsd is OSDMap)
444 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
445 }
446 }
447 }
448 else
423 { 449 {
424// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 450 OSDMap cmap = (OSDMap)decodedMeshOsd;
451 if (cmap == null)
452 return false;
453
454 byte[] data;
455 const float invMaxU16 = 1.0f / 65535f;
456 int t1;
457 int t2;
458 int t3;
459 int i;
460
461 List<float3> vs = new List<float3>();
462
463 float3 f3;
464 PHullResult hullr = new PHullResult();
465
466 Coord c;
467 Face f;
468
469 Vector3 range;
470 Vector3 min;
471 int nverts;
472 int nindexs;
473
474 if (cmap.ContainsKey("Max"))
475 range = cmap["Max"].AsVector3();
476 else
477 range = new Vector3(0.5f, 0.5f, 0.5f);
478
479 if (cmap.ContainsKey("Min"))
480 min = cmap["Min"].AsVector3();
481 else
482 min = new Vector3(-0.5f, -0.5f, -0.5f);
483
484 range = range - min;
485 range *= invMaxU16;
486
487 if (!convex && cmap.ContainsKey("HullList") && cmap.ContainsKey("Positions"))
488 {
489 List<int> hsizes = new List<int>();
490 int totalpoints = 0;
491 data = cmap["HullList"].AsBinary();
492 for (i = 0; i < data.Length; i++)
493 {
494 t1 = data[i];
495 if (t1 == 0)
496 t1 = 256;
497 totalpoints += t1;
498 hsizes.Add(t1);
499 }
500
501 data = cmap["Positions"].AsBinary();
502 int ptr = 0;
503 int vertsoffset = 0;
504
505 if (totalpoints == data.Length / 6) // 2 bytes per coord, 3 coords per point
506 {
507 foreach (int hullsize in hsizes)
508 {
509 for (i = 0; i < hullsize; i++ )
510 {
511 t1 = data[ptr++];
512 t1 += data[ptr++] << 8;
513 t2 = data[ptr++];
514 t2 += data[ptr++] << 8;
515 t3 = data[ptr++];
516 t3 += data[ptr++] << 8;
517
518 f3 = new float3((t1 * range.X + min.X) * size.X,
519 (t2 * range.Y + min.Y) * size.Y,
520 (t3 * range.Z + min.Z) * size.Z);
521 vs.Add(f3);
522 }
523
524 if(hullsize <3)
525 {
526 vs.Clear();
527 continue;
528 }
529
530 if (hullsize <5)
531 {
532 foreach (float3 point in vs)
533 {
534 c.X = point.x;
535 c.Y = point.y;
536 c.Z = point.z;
537 coords.Add(c);
538 }
539 f = new Face(vertsoffset, vertsoffset + 1, vertsoffset + 2);
540 faces.Add(f);
541
542 if (hullsize == 4)
543 {
544 // not sure about orientation..
545 f = new Face(vertsoffset, vertsoffset + 2, vertsoffset + 3);
546 faces.Add(f);
547 f = new Face(vertsoffset, vertsoffset + 3, vertsoffset + 1);
548 faces.Add(f);
549 f = new Face(vertsoffset + 3, vertsoffset + 2, vertsoffset + 1);
550 faces.Add(f);
551 }
552 vertsoffset += vs.Count;
553 vs.Clear();
554 continue;
555 }
425 556
426 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 557 if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
427 foreach (OSD subMeshOsd in decodedMeshOsdArray) 558 {
559 vs.Clear();
560 continue;
561 }
562
563 nverts = hullr.Vertices.Count;
564 nindexs = hullr.Indices.Count;
565
566 if (nindexs % 3 != 0)
567 {
568 vs.Clear();
569 continue;
570 }
571
572 for (i = 0; i < nverts; i++)
573 {
574 c.X = hullr.Vertices[i].x;
575 c.Y = hullr.Vertices[i].y;
576 c.Z = hullr.Vertices[i].z;
577 coords.Add(c);
578 }
579
580
581 for (i = 0; i < nindexs; i += 3)
582 {
583 t1 = hullr.Indices[i];
584 if (t1 > nverts)
585 break;
586 t2 = hullr.Indices[i + 1];
587 if (t2 > nverts)
588 break;
589 t3 = hullr.Indices[i + 2];
590 if (t3 > nverts)
591 break;
592 f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3);
593 faces.Add(f);
594 }
595 vertsoffset += nverts;
596 vs.Clear();
597 }
598 }
599 if (coords.Count > 0 && faces.Count > 0)
600 return true;
601
602 }
603
604 vs.Clear();
605
606 if (cmap.ContainsKey("BoundingVerts"))
428 { 607 {
429 if (subMeshOsd is OSDMap) 608 data = cmap["BoundingVerts"].AsBinary();
430 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 609
610 for (i = 0; i < data.Length; )
611 {
612 t1 = data[i++];
613 t1 += data[i++] << 8;
614 t2 = data[i++];
615 t2 += data[i++] << 8;
616 t3 = data[i++];
617 t3 += data[i++] << 8;
618
619 f3 = new float3((t1 * range.X + min.X) * size.X,
620 (t2 * range.Y + min.Y) * size.Y,
621 (t3 * range.Z + min.Z) * size.Z);
622 vs.Add(f3);
623 }
624
625 if (vs.Count < 3)
626 {
627 vs.Clear();
628 return false;
629 }
630
631 if (vs.Count < 5)
632 {
633 foreach (float3 point in vs)
634 {
635 c.X = point.x;
636 c.Y = point.y;
637 c.Z = point.z;
638 coords.Add(c);
639 }
640 f = new Face(0, 1, 2);
641 faces.Add(f);
642
643 if (vs.Count == 4)
644 {
645 // not sure about orientation..
646 f = new Face(0, 2, 3);
647 faces.Add(f);
648 f = new Face(0, 3, 1);
649 faces.Add(f);
650 f = new Face( 3, 2, 1);
651 faces.Add(f);
652 }
653 vs.Clear();
654 return true;
655 }
656
657 if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
658 return false;
659
660 nverts = hullr.Vertices.Count;
661 nindexs = hullr.Indices.Count;
662
663 if (nindexs % 3 != 0)
664 return false;
665
666 for (i = 0; i < nverts; i++)
667 {
668 c.X = hullr.Vertices[i].x;
669 c.Y = hullr.Vertices[i].y;
670 c.Z = hullr.Vertices[i].z;
671 coords.Add(c);
672 }
673 for (i = 0; i < nindexs; i += 3)
674 {
675 t1 = hullr.Indices[i];
676 if (t1 > nverts)
677 break;
678 t2 = hullr.Indices[i + 1];
679 if (t2 > nverts)
680 break;
681 t3 = hullr.Indices[i + 2];
682 if (t3 > nverts)
683 break;
684 f = new Face(t1, t2, t3);
685 faces.Add(f);
686 }
687
688 if (coords.Count > 0 && faces.Count > 0)
689 return true;
431 } 690 }
691 else
692 return false;
693
432 } 694 }
433 } 695 }
434 696
@@ -714,11 +976,16 @@ namespace OpenSim.Region.Physics.Meshing
714 976
715 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 977 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
716 { 978 {
717 return CreateMesh(primName, primShape, size, lod, false); 979 return CreateMesh(primName, primShape, size, lod, false,false);
718 } 980 }
719 981
720 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) 982 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
721 { 983 {
984 return CreateMesh(primName, primShape, size, lod, false,false);
985 }
986
987 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
988 {
722#if SPAM 989#if SPAM
723 m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); 990 m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName);
724#endif 991#endif
@@ -736,7 +1003,7 @@ namespace OpenSim.Region.Physics.Meshing
736 if (size.Y < 0.01f) size.Y = 0.01f; 1003 if (size.Y < 0.01f) size.Y = 0.01f;
737 if (size.Z < 0.01f) size.Z = 0.01f; 1004 if (size.Z < 0.01f) size.Z = 0.01f;
738 1005
739 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod); 1006 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex);
740 1007
741 if (mesh != null) 1008 if (mesh != null)
742 { 1009 {