diff options
author | UbitUmarov | 2012-03-20 19:24:45 +0000 |
---|---|---|
committer | UbitUmarov | 2012-03-20 19:24:45 +0000 |
commit | 8c1550b58e70b98bacd5fe9ecf710b59a4c43198 (patch) | |
tree | 0c8ee36c3deed767ac0820d539b11f8a2089c3cf | |
parent | add some more notifications about changes on physical parameters ( still inc... (diff) | |
download | opensim-SC-8c1550b58e70b98bacd5fe9ecf710b59a4c43198.zip opensim-SC-8c1550b58e70b98bacd5fe9ecf710b59a4c43198.tar.gz opensim-SC-8c1550b58e70b98bacd5fe9ecf710b59a4c43198.tar.bz2 opensim-SC-8c1550b58e70b98bacd5fe9ecf710b59a4c43198.tar.xz |
WORK in progress!! Now it reads the simple hull shape to use if convex shape is selected for a prim. Due to ODE limitations on convex hulls colisions, it creates a mesh. Being work in progress it is hardcoded to only read that simple convex hull for now. It writes a file named "lixo_lixo.raw" that can be imported into blender for examination of the created mesh (the last one loaded and also hardcoded). To play with put in opensim.ini "meshing = UbitMeshmerizer"
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs | 108 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 180 |
2 files changed, 164 insertions, 124 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..a04df81 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -41,6 +41,7 @@ using Nini.Config; | |||
41 | using System.Reflection; | 41 | using System.Reflection; |
42 | using System.IO; | 42 | using System.IO; |
43 | using ComponentAce.Compression.Libs.zlib; | 43 | using ComponentAce.Compression.Libs.zlib; |
44 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | ||
44 | 45 | ||
45 | namespace OpenSim.Region.Physics.Meshing | 46 | namespace OpenSim.Region.Physics.Meshing |
46 | { | 47 | { |
@@ -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 | ||
@@ -329,6 +328,10 @@ namespace OpenSim.Region.Physics.Meshing | |||
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 | |||
332 | bool convex = true; // this will be a input | ||
333 | bool usemesh = false; | ||
334 | |||
332 | coords = new List<Coord>(); | 335 | coords = new List<Coord>(); |
333 | faces = new List<Face>(); | 336 | faces = new List<Face>(); |
334 | OSD meshOsd = null; | 337 | OSD meshOsd = null; |
@@ -365,14 +368,25 @@ namespace OpenSim.Region.Physics.Meshing | |||
365 | { | 368 | { |
366 | OSDMap physicsParms = null; | 369 | OSDMap physicsParms = null; |
367 | OSDMap map = (OSDMap)meshOsd; | 370 | OSDMap map = (OSDMap)meshOsd; |
368 | if (map.ContainsKey("physics_shape")) | 371 | |
369 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format | 372 | if (!convex) |
370 | else if (map.ContainsKey("physics_mesh")) | 373 | { |
371 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format | 374 | if (map.ContainsKey("physics_shape")) |
375 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format | ||
376 | else if (map.ContainsKey("physics_mesh")) | ||
377 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format | ||
378 | |||
379 | if (physicsParms != null) | ||
380 | usemesh = true; | ||
381 | } | ||
382 | |||
383 | if(!usemesh && (map.ContainsKey("physics_convex"))) | ||
384 | physicsParms = (OSDMap)map["physics_convex"]; | ||
385 | |||
372 | 386 | ||
373 | if (physicsParms == null) | 387 | if (physicsParms == null) |
374 | { | 388 | { |
375 | m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); | 389 | m_log.Warn("[MESH]: unknown mesh type"); |
376 | return false; | 390 | return false; |
377 | } | 391 | } |
378 | 392 | ||
@@ -416,20 +430,142 @@ namespace OpenSim.Region.Physics.Meshing | |||
416 | return false; | 430 | return false; |
417 | } | 431 | } |
418 | 432 | ||
419 | OSDArray decodedMeshOsdArray = null; | ||
420 | 433 | ||
421 | // physics_shape is an array of OSDMaps, one for each submesh | 434 | if (usemesh) |
422 | if (decodedMeshOsd is OSDArray) | ||
423 | { | 435 | { |
424 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | 436 | OSDArray decodedMeshOsdArray = null; |
425 | 437 | ||
426 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | 438 | // physics_shape is an array of OSDMaps, one for each submesh |
427 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | 439 | if (decodedMeshOsd is OSDArray) |
428 | { | 440 | { |
429 | if (subMeshOsd is OSDMap) | 441 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); |
430 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); | 442 | |
443 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | ||
444 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | ||
445 | { | ||
446 | if (subMeshOsd is OSDMap) | ||
447 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); | ||
448 | } | ||
431 | } | 449 | } |
432 | } | 450 | } |
451 | else | ||
452 | { | ||
453 | OSDMap cmap = (OSDMap)decodedMeshOsd; | ||
454 | if (cmap == null) | ||
455 | return false; | ||
456 | |||
457 | byte[] data; | ||
458 | const float invMaxU16 = 1.0f / 65535f; | ||
459 | int t1; | ||
460 | int t2; | ||
461 | int t3; | ||
462 | int i; | ||
463 | |||
464 | List<float3> vs = new List<float3>(); | ||
465 | |||
466 | float3 f3; | ||
467 | PHullResult hullr = new PHullResult(); | ||
468 | Mesh m = new Mesh(); | ||
469 | |||
470 | Vector3 range; | ||
471 | Vector3 min; | ||
472 | |||
473 | if (cmap.ContainsKey("Max")) | ||
474 | range = cmap["Max"].AsVector3(); | ||
475 | else | ||
476 | range = new Vector3(0.5f, 0.5f, 0.5f); | ||
477 | |||
478 | if (cmap.ContainsKey("Min")) | ||
479 | min = cmap["Min"].AsVector3(); | ||
480 | else | ||
481 | min = new Vector3(-0.5f, -0.5f, -0.5f); | ||
482 | |||
483 | range = range - min; | ||
484 | range *= invMaxU16; | ||
485 | /* | ||
486 | // if (!convex && cmap.ContainsKey("HullList")) | ||
487 | if (cmap.ContainsKey("HullList")) | ||
488 | { | ||
489 | List<int> hsizes = new List<int>(); | ||
490 | |||
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 | hsizes.Add(t1); | ||
498 | } | ||
499 | |||
500 | bla bla | ||
501 | |||
502 | |||
503 | |||
504 | } | ||
505 | */ | ||
506 | |||
507 | if (cmap.ContainsKey("BoundingVerts")) | ||
508 | { | ||
509 | data = cmap["BoundingVerts"].AsBinary(); | ||
510 | |||
511 | for (i = 0; i < data.Length; ) | ||
512 | { | ||
513 | t1 = data[i++]; | ||
514 | t1 += data[i++] << 8; | ||
515 | t2 = data[i++]; | ||
516 | t2 += data[i++] << 8; | ||
517 | t3 = data[i++]; | ||
518 | t3 += data[i++] << 8; | ||
519 | |||
520 | f3 = new float3((t1 * range.X + min.X) * size.X, | ||
521 | (t2 * range.Y + min.Y) * size.Y, | ||
522 | (t3 * range.Z + min.Z) * size.Z); | ||
523 | vs.Add(f3); | ||
524 | } | ||
525 | |||
526 | |||
527 | if (!HullUtils.ComputeHull(vs, ref hullr, 300, 0.0f)) | ||
528 | return false; | ||
529 | |||
530 | int nverts = hullr.Vertices.Count; | ||
531 | int nindexs = hullr.Indices.Count; | ||
532 | |||
533 | if (nindexs % 3 != 0) | ||
534 | return false; | ||
535 | |||
536 | Coord c; | ||
537 | for (i = 0; i < nverts; i++) | ||
538 | { | ||
539 | c.X = hullr.Vertices[i].x; | ||
540 | c.Y = hullr.Vertices[i].y; | ||
541 | c.Z = hullr.Vertices[i].z; | ||
542 | coords.Add(c); | ||
543 | } | ||
544 | |||
545 | Face f; | ||
546 | |||
547 | for (i = 0; i < nindexs; i += 3) | ||
548 | { | ||
549 | t1 = hullr.Indices[i]; | ||
550 | if (t1 > nverts) | ||
551 | break; | ||
552 | t2 = hullr.Indices[i + 1]; | ||
553 | if (t2 > nverts) | ||
554 | break; | ||
555 | t3 = hullr.Indices[i + 2]; | ||
556 | if (t3 > nverts) | ||
557 | break; | ||
558 | f = new Face(t1, t2, t3); | ||
559 | faces.Add(f); | ||
560 | } | ||
561 | |||
562 | if (coords.Count > 0 && faces.Count > 0) | ||
563 | return true; | ||
564 | } | ||
565 | else | ||
566 | return false; | ||
567 | |||
568 | } | ||
433 | } | 569 | } |
434 | 570 | ||
435 | return true; | 571 | return true; |