aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin
diff options
context:
space:
mode:
authorTeravus Ovares2008-02-29 05:46:24 +0000
committerTeravus Ovares2008-02-29 05:46:24 +0000
commite333eaf4b604453da9a8952356086d4a5a1fc4a8 (patch)
treea94c05af8b965298523249c708973937860d2161 /OpenSim/Region/Physics/OdePlugin
parentFrom: Alan M Webb <awebb@vnet.ibm.com> (diff)
downloadopensim-SC_OLD-e333eaf4b604453da9a8952356086d4a5a1fc4a8.zip
opensim-SC_OLD-e333eaf4b604453da9a8952356086d4a5a1fc4a8.tar.gz
opensim-SC_OLD-e333eaf4b604453da9a8952356086d4a5a1fc4a8.tar.bz2
opensim-SC_OLD-e333eaf4b604453da9a8952356086d4a5a1fc4a8.tar.xz
* ODEPlugin
** Added more realistic calculations of mass for the rest of the supported prim shapes+holes+cuts+tapers. Previously they were the generic height * width * length. Spheres roll (Angular velocity) more realistically, etc.
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs208
1 files changed, 207 insertions, 1 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 05dcd7a..62b6a7f 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -353,6 +353,176 @@ namespace OpenSim.Region.Physics.OdePlugin
353 } 353 }
354 354
355 break; 355 break;
356 case ProfileShape.Circle:
357 if (_pbs.PathCurve == (byte)Extrusion.Straight)
358 {
359 // Cylinder
360 float volume1 = (float)(Math.PI * Math.Pow(_size.X, 2) * _size.Z);
361 float volume2 = (float)(Math.PI * Math.Pow(_size.Y, 2) * _size.Z);
362
363 // Approximating the cylinder's irregularity.
364 if (volume1 > volume2)
365 {
366 volume = (float)volume1 - (volume1 - volume2);
367 }
368 else if (volume2 > volume1)
369 {
370 volume = (float)volume2 - (volume2 - volume1);
371 }
372 else
373 {
374 // Regular cylinder
375 volume = volume1;
376 }
377 }
378 else
379 {
380 // We don't know what the shape is yet, so use default
381 volume = _size.X * _size.Y * _size.Z;
382 }
383 // If the user has 'hollowed out'
384 // ProfileHollow is one of those 0 to 50000 values :P
385 // we like percentages better.. so turning into a percentage
386
387 if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
388 {
389 float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
390
391 // calculate the hollow volume by it's shape compared to the prim shape
392 float hollowVolume = 0;
393 switch (_pbs.HollowShape)
394 {
395
396 case HollowShape.Same:
397 case HollowShape.Circle:
398 // Hollow shape is a perfect cyllinder in respect to the cube's scale
399 // Cyllinder hollow volume calculation
400 float hRadius = _size.X / 2;
401 float hLength = _size.Z;
402
403 // pi * r2 * h
404 hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
405 break;
406
407 case HollowShape.Square:
408 // Cube Hollow volume calculation
409 float hollowsizex = _size.X * hollowAmount;
410 float hollowsizey = _size.Y * hollowAmount;
411 float hollowsizez = _size.Z * hollowAmount;
412 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
413 break;
414
415
416
417 case HollowShape.Triangle:
418 // Equilateral Triangular Prism volume hollow calculation
419 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
420
421 float aLength = _size.Y;
422 // 1/2 abh
423 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
424 break;
425
426 default:
427 hollowVolume = 0;
428 break;
429 }
430 volume = volume - hollowVolume;
431 }
432 break;
433
434 case ProfileShape.HalfCircle:
435 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
436 {
437 if (_size.X == _size.Z && _size.Z == _size.X)
438 {
439 // regular sphere
440 // v = 4/3 * pi * r^3
441 float sradius3 = (float)Math.Pow((_size.X / 2), 3);
442 volume = (float)((4 / 3) * Math.PI * sradius3);
443 }
444 else
445 {
446 // we treat this as a box currently
447 volume = _size.X * _size.Y * _size.Z;
448 }
449
450 }
451 else
452 {
453 // We don't know what the shape is yet, so use default
454 volume = _size.X * _size.Y * _size.Z;
455 }
456 break;
457 case ProfileShape.EquilateralTriangle:
458 /*
459 v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
460
461 // seed mesh
462 Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
463 Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
464 Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
465 */
466 float xA = -0.25f * _size.X;
467 float yA = -0.45f * _size.Y;
468
469 float xB = 0.5f * _size.X;
470 float yB = 0;
471
472 float xC = -0.25f * _size.X;
473 float yC = 0.45f * _size.Y;
474
475 volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z);
476
477 // If the user has 'hollowed out'
478 // ProfileHollow is one of those 0 to 50000 values :P
479 // we like percentages better.. so turning into a percentage
480 float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
481 if (((float)fhollowFactor / 50000f) > 0.0)
482 {
483 float hollowAmount = (float)fhollowFactor / 50000f;
484
485 // calculate the hollow volume by it's shape compared to the prim shape
486 float hollowVolume = 0;
487 switch (_pbs.HollowShape)
488 {
489
490 case HollowShape.Same:
491 case HollowShape.Triangle:
492 // Equilateral Triangular Prism volume hollow calculation
493 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
494
495 float aLength = _size.Y;
496 // 1/2 abh
497 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
498 break;
499
500 case HollowShape.Square:
501 // Cube Hollow volume calculation
502 float hollowsizex = _size.X * hollowAmount;
503 float hollowsizey = _size.Y * hollowAmount;
504 float hollowsizez = _size.Z * hollowAmount;
505 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
506 break;
507
508 case HollowShape.Circle:
509 // Hollow shape is a perfect cyllinder in respect to the cube's scale
510 // Cyllinder hollow volume calculation
511 float hRadius = _size.X / 2;
512 float hLength = _size.Z;
513
514 // pi * r2 * h
515 hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount);
516 break;
517
518
519 default:
520 hollowVolume = 0;
521 break;
522 }
523 volume = volume - hollowVolume;
524 }
525 break;
356 526
357 default: 527 default:
358 // we don't have all of the volume formulas yet so 528 // we don't have all of the volume formulas yet so
@@ -383,9 +553,41 @@ namespace OpenSim.Region.Physics.OdePlugin
383 553
384 volume = volume - (volume*pathCutAmount); 554 volume = volume - (volume*pathCutAmount);
385 } 555 }
556 UInt16 taperX = _pbs.PathScaleX;
557 UInt16 taperY = _pbs.PathScaleY;
558 float taperFactorX = 0;
559 float taperFactorY = 0;
386 560
387 // Mass = density * volume 561 // Mass = density * volume
562 if (taperX != 100)
563 {
564 if (taperX > 100)
565 {
566 taperFactorX = 1.0f - ((float)taperX / 200);
567 //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
568 }
569 else
570 {
571 taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
572 //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
573 }
574 volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
575 }
388 576
577 if (taperY != 100)
578 {
579 if (taperY > 100)
580 {
581 taperFactorY = 1.0f - ((float)taperY / 200);
582 //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
583 }
584 else
585 {
586 taperFactorY = 1.0f - ((100 - (float)taperY) / 100);
587 //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
588 }
589 volume = (float)volume * ((taperFactorY / 3f) + 0.001f);
590 }
389 returnMass = m_density*volume; 591 returnMass = m_density*volume;
390 592
391 return returnMass; 593 return returnMass;
@@ -395,7 +597,11 @@ namespace OpenSim.Region.Physics.OdePlugin
395 { 597 {
396 if (Body != (IntPtr) 0) 598 if (Body != (IntPtr) 0)
397 { 599 {
398 d.MassSetBoxTotal(out pMass, CalculateMass(), _size.X, _size.Y, _size.Z); 600 float newmass = CalculateMass();
601 m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString());
602
603 if (newmass <= 0) newmass = 0.0001f;
604 d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z);
399 d.BodySetMass(Body, ref pMass); 605 d.BodySetMass(Body, ref pMass);
400 } 606 }
401 } 607 }