aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2010-10-02 00:19:30 +0200
committerMelanie2010-10-02 00:19:30 +0200
commitb40c91777cf272b485da0cdfba2ffec868cfc7cf (patch)
tree16bd545ba26474fd76fe736eb691222b1b740a30 /OpenSim/Region
parentReplace CalculateMass with a better, contributed version (diff)
downloadopensim-SC-b40c91777cf272b485da0cdfba2ffec868cfc7cf.zip
opensim-SC-b40c91777cf272b485da0cdfba2ffec868cfc7cf.tar.gz
opensim-SC-b40c91777cf272b485da0cdfba2ffec868cfc7cf.tar.bz2
opensim-SC-b40c91777cf272b485da0cdfba2ffec868cfc7cf.tar.xz
Replace CalculateMass with a more accurate version, contributed by Ubit.
Thank you.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs453
1 files changed, 219 insertions, 234 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index daf7fb0..319a951 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -403,300 +403,285 @@ namespace OpenSim.Region.Physics.OdePlugin
403 403
404 private float CalculateMass() 404 private float CalculateMass()
405 { 405 {
406 float volume = 0; 406 float volume = _size.X * _size.Y * _size.Z; // default
407 407 float tmp;
408 // No material is passed to the physics engines yet.. soo..
409 // we're using the m_density constant in the class definition
410 408
411 float returnMass = 0; 409 float returnMass = 0;
412 410 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
411 float hollowVolume = hollowAmount * hollowAmount;
412
413 switch (_pbs.ProfileShape) 413 switch (_pbs.ProfileShape)
414 { 414 {
415 case ProfileShape.Square: 415 case ProfileShape.Square:
416 // Profile Volume 416 // default box
417 417
418 volume = _size.X*_size.Y*_size.Z; 418 if (_pbs.PathCurve == (byte)Extrusion.Straight)
419 {
420 if (hollowAmount > 0.0)
421 {
422 switch (_pbs.HollowShape)
423 {
424 case HollowShape.Square:
425 case HollowShape.Same:
426 break;
419 427
420 // If the user has 'hollowed out' 428 case HollowShape.Circle:
421 // ProfileHollow is one of those 0 to 50000 values :P
422 // we like percentages better.. so turning into a percentage
423 429
424 if (((float) _pbs.ProfileHollow/50000f) > 0.0) 430 hollowVolume *= 0.78539816339f;
425 { 431 break;
426 float hollowAmount = (float) _pbs.ProfileHollow/50000f;
427 432
428 // calculate the hollow volume by it's shape compared to the prim shape 433 case HollowShape.Triangle:
429 float hollowVolume = 0;
430 switch (_pbs.HollowShape)
431 {
432 case HollowShape.Square:
433 case HollowShape.Same:
434 // Cube Hollow volume calculation
435 float hollowsizex = _size.X*hollowAmount;
436 float hollowsizey = _size.Y*hollowAmount;
437 float hollowsizez = _size.Z*hollowAmount;
438 hollowVolume = hollowsizex*hollowsizey*hollowsizez;
439 break;
440 434
441 case HollowShape.Circle: 435 hollowVolume *= (0.5f * .5f);
442 // Hollow shape is a perfect cyllinder in respect to the cube's scale 436 break;
443 // Cyllinder hollow volume calculation
444 float hRadius = _size.X/2;
445 float hLength = _size.Z;
446
447 // pi * r2 * h
448 hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount);
449 break;
450 437
451 case HollowShape.Triangle: 438 default:
452 // Equilateral Triangular Prism volume hollow calculation 439 hollowVolume = 0;
453 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y 440 break;
441 }
442 volume *= (1.0f - hollowVolume);
443 }
444 }
454 445
455 float aLength = _size.Y; 446 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
456 // 1/2 abh 447 {
457 hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); 448 //a tube
458 break;
459 449
460 default: 450 volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX);
461 hollowVolume = 0; 451 tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY);
462 break; 452 volume -= volume*tmp*tmp;
453
454 if (hollowAmount > 0.0)
455 {
456 hollowVolume *= hollowAmount;
457
458 switch (_pbs.HollowShape)
459 {
460 case HollowShape.Square:
461 case HollowShape.Same:
462 break;
463
464 case HollowShape.Circle:
465 hollowVolume *= 0.78539816339f;;
466 break;
467
468 case HollowShape.Triangle:
469 hollowVolume *= 0.5f * 0.5f;
470 break;
471 default:
472 hollowVolume = 0;
473 break;
474 }
475 volume *= (1.0f - hollowVolume);
476 }
463 } 477 }
464 volume = volume - hollowVolume;
465 }
466 478
467 break; 479 break;
480
468 case ProfileShape.Circle: 481 case ProfileShape.Circle:
469 if (_pbs.PathCurve == (byte)Extrusion.Straight)
470 {
471 // Cylinder
472 float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z);
473 float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z);
474 482
475 // Approximating the cylinder's irregularity. 483 if (_pbs.PathCurve == (byte)Extrusion.Straight)
476 if (volume1 > volume2)
477 {
478 volume = (float)volume1 - (volume1 - volume2);
479 }
480 else if (volume2 > volume1)
481 {
482 volume = (float)volume2 - (volume2 - volume1);
483 }
484 else
485 { 484 {
486 // Regular cylinder 485 volume *= 0.78539816339f; // elipse base
487 volume = volume1;
488 }
489 }
490 else
491 {
492 // We don't know what the shape is yet, so use default
493 volume = _size.X * _size.Y * _size.Z;
494 }
495 // If the user has 'hollowed out'
496 // ProfileHollow is one of those 0 to 50000 values :P
497 // we like percentages better.. so turning into a percentage
498 486
499 if (((float)_pbs.ProfileHollow / 50000f) > 0.0) 487 if (hollowAmount > 0.0)
500 { 488 {
501 float hollowAmount = (float)_pbs.ProfileHollow / 50000f; 489 switch (_pbs.HollowShape)
490 {
491 case HollowShape.Same:
492 case HollowShape.Circle:
493 break;
502 494
503 // calculate the hollow volume by it's shape compared to the prim shape 495 case HollowShape.Square:
504 float hollowVolume = 0; 496 hollowVolume *= 0.5f * 2.5984480504799f;
505 switch (_pbs.HollowShape) 497 break;
498
499 case HollowShape.Triangle:
500 hollowVolume *= .5f * 1.27323954473516f;
501 break;
502
503 default:
504 hollowVolume = 0;
505 break;
506 }
507 volume *= (1.0f - hollowVolume);
508 }
509 }
510
511 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
506 { 512 {
507 case HollowShape.Same: 513 volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX);
508 case HollowShape.Circle: 514 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
509 // Hollow shape is a perfect cyllinder in respect to the cube's scale 515 volume *= (1.0f - tmp * tmp);
510 // Cyllinder hollow volume calculation 516
511 float hRadius = _size.X / 2; 517 if (hollowAmount > 0.0)
512 float hLength = _size.Z; 518 {
513
514 // pi * r2 * h
515 hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
516 break;
517 519
518 case HollowShape.Square: 520 // calculate the hollow volume by it's shape compared to the prim shape
519 // Cube Hollow volume calculation 521 hollowVolume *= hollowAmount;
520 float hollowsizex = _size.X * hollowAmount;
521 float hollowsizey = _size.Y * hollowAmount;
522 float hollowsizez = _size.Z * hollowAmount;
523 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
524 break;
525 522
526 case HollowShape.Triangle: 523 switch (_pbs.HollowShape)
527 // Equilateral Triangular Prism volume hollow calculation 524 {
528 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y 525 case HollowShape.Same:
526 case HollowShape.Circle:
527 break;
529 528
530 float aLength = _size.Y; 529 case HollowShape.Square:
531 // 1/2 abh 530 hollowVolume *= 0.5f * 2.5984480504799f;
532 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); 531 break;
533 break;
534 532
535 default: 533 case HollowShape.Triangle:
536 hollowVolume = 0; 534 hollowVolume *= .5f * 1.27323954473516f;
537 break; 535 break;
536
537 default:
538 hollowVolume = 0;
539 break;
540 }
541 volume *= (1.0f - hollowVolume);
542 }
538 } 543 }
539 volume = volume - hollowVolume;
540 }
541 break; 544 break;
542 545
543 case ProfileShape.HalfCircle: 546 case ProfileShape.HalfCircle:
544 if (_pbs.PathCurve == (byte)Extrusion.Curve1) 547 if (_pbs.PathCurve == (byte)Extrusion.Curve1)
545 { 548 {
546 if (_size.X == _size.Y && _size.Y == _size.Z) 549 volume *= 0.52359877559829887307710723054658f;
547 {
548 // regular sphere
549 // v = 4/3 * pi * r^3
550 float sradius3 = (float)Math.Pow((_size.X / 2), 3);
551 volume = (float)((4f / 3f) * Math.PI * sradius3);
552 }
553 else
554 {
555 // we treat this as a box currently
556 volume = _size.X * _size.Y * _size.Z;
557 }
558 }
559 else
560 {
561 // We don't know what the shape is yet, so use default
562 volume = _size.X * _size.Y * _size.Z;
563 } 550 }
564 break; 551 break;
565 552
566 case ProfileShape.EquilateralTriangle: 553 case ProfileShape.EquilateralTriangle:
567 /*
568 v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
569 554
570 // seed mesh 555 if (_pbs.PathCurve == (byte)Extrusion.Straight)
571 Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); 556 {
572 Vertex PM = new Vertex(+0.5f, 0f, 0.0f); 557 volume *= 0.32475953f;
573 Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
574 */
575 float xA = -0.25f * _size.X;
576 float yA = -0.45f * _size.Y;
577 558
578 float xB = 0.5f * _size.X; 559 if (hollowAmount > 0.0)
579 float yB = 0; 560 {
580 561
581 float xC = -0.25f * _size.X; 562 // calculate the hollow volume by it's shape compared to the prim shape
582 float yC = 0.45f * _size.Y; 563 switch (_pbs.HollowShape)
564 {
565 case HollowShape.Same:
566 case HollowShape.Triangle:
567 hollowVolume *= .25f;
568 break;
583 569
584 volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); 570 case HollowShape.Square:
571 hollowVolume *= 0.499849f * 3.07920140172638f;
572 break;
585 573
586 // If the user has 'hollowed out' 574 case HollowShape.Circle:
587 // ProfileHollow is one of those 0 to 50000 values :P 575 // Hollow shape is a perfect cyllinder in respect to the cube's scale
588 // we like percentages better.. so turning into a percentage 576 // Cyllinder hollow volume calculation
589 float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
590 if (((float)fhollowFactor / 50000f) > 0.0)
591 {
592 float hollowAmount = (float)fhollowFactor / 50000f;
593 577
594 // calculate the hollow volume by it's shape compared to the prim shape 578 hollowVolume *= 0.1963495f * 3.07920140172638f;
595 float hollowVolume = 0; 579 break;
596 switch (_pbs.HollowShape) 580
581 default:
582 hollowVolume = 0;
583 break;
584 }
585 volume *= (1.0f - hollowVolume);
586 }
587 }
588 else if (_pbs.PathCurve == (byte)Extrusion.Curve1)
597 { 589 {
598 case HollowShape.Same: 590 volume *= 0.32475953f;
599 case HollowShape.Triangle: 591 volume *= 0.01f * (float)(200 - _pbs.PathScaleX);
600 // Equilateral Triangular Prism volume hollow calculation 592 tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY);
601 // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y 593 volume *= (1.0f - tmp * tmp);
602
603 float aLength = _size.Y;
604 // 1/2 abh
605 hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
606 break;
607 594
608 case HollowShape.Square: 595 if (hollowAmount > 0.0)
609 // Cube Hollow volume calculation 596 {
610 float hollowsizex = _size.X * hollowAmount;
611 float hollowsizey = _size.Y * hollowAmount;
612 float hollowsizez = _size.Z * hollowAmount;
613 hollowVolume = hollowsizex * hollowsizey * hollowsizez;
614 break;
615 597
616 case HollowShape.Circle: 598 hollowVolume *= hollowAmount;
617 // Hollow shape is a perfect cyllinder in respect to the cube's scale
618 // Cyllinder hollow volume calculation
619 float hRadius = _size.X / 2;
620 float hLength = _size.Z;
621 599
622 // pi * r2 * h 600 switch (_pbs.HollowShape)
623 hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); 601 {
624 break; 602 case HollowShape.Same:
603 case HollowShape.Triangle:
604 hollowVolume *= .25f;
605 break;
625 606
626 default: 607 case HollowShape.Square:
627 hollowVolume = 0; 608 hollowVolume *= 0.499849f * 3.07920140172638f;
628 break; 609 break;
629 }
630 volume = volume - hollowVolume;
631 }
632 break;
633 610
634 default: 611 case HollowShape.Circle:
635 // we don't have all of the volume formulas yet so
636 // use the common volume formula for all
637 volume = _size.X*_size.Y*_size.Z;
638 break;
639 }
640 612
641 // Calculate Path cut effect on volume 613 hollowVolume *= 0.1963495f * 3.07920140172638f;
642 // Not exact, in the triangle hollow example 614 break;
643 // They should never be zero or less then zero..
644 // we'll ignore it if it's less then zero
645 615
646 // ProfileEnd and ProfileBegin are values 616 default:
647 // from 0 to 50000 617 hollowVolume = 0;
618 break;
619 }
620 volume *= (1.0f - hollowVolume);
621 }
622 }
623 break;
648 624
649 // Turning them back into percentages so that I can cut that percentage off the volume 625 default:
626 break;
627 }
650 628
651 float PathCutEndAmount = _pbs.ProfileEnd;
652 float PathCutStartAmount = _pbs.ProfileBegin;
653 if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f)
654 {
655 float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f);
656 629
657 // Check the return amount for sanity
658 if (pathCutAmount >= 0.99f)
659 pathCutAmount = 0.99f;
660 630
661 volume = volume - (volume*pathCutAmount); 631 float taperX1;
662 } 632 float taperY1;
663 UInt16 taperX = _pbs.PathScaleX; 633 float taperX;
664 UInt16 taperY = _pbs.PathScaleY; 634 float taperY;
665 float taperFactorX = 0; 635 float pathBegin;
666 float taperFactorY = 0; 636 float pathEnd;
637 float profileBegin;
638 float profileEnd;
667 639
668 // Mass = density * volume 640 if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible)
669 if (taperX != 100)
670 {
671 if (taperX > 100)
672 { 641 {
673 taperFactorX = 1.0f - ((float)taperX / 200); 642 taperX1 = _pbs.PathScaleX * 0.01f;
674 //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString()); 643 if (taperX1 > 1.0f)
675 } 644 taperX1 = 2.0f - taperX1;
676 else 645 taperX = 1.0f - taperX1;
677 {
678 taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
679 //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
680 }
681 volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
682 }
683 646
684 if (taperY != 100) 647 taperY1 = _pbs.PathScaleY * 0.01f;
685 { 648 if (taperY1 > 1.0f)
686 if (taperY > 100) 649 taperY1 = 2.0f - taperY1;
687 { 650 taperY = 1.0f - taperY1;
688 taperFactorY = 1.0f - ((float)taperY / 200);
689 //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
690 } 651 }
691 else 652 else
692 { 653 {
693 taperFactorY = 1.0f - ((100 - (float)taperY) / 100); 654 taperX = _pbs.PathTaperX * 0.01f;
694 //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString()); 655 if (taperX < 0.0f)
656 taperX = -taperX;
657 taperX1 = 1.0f - taperX;
658
659 taperY = _pbs.PathTaperY * 0.01f;
660 if (taperY < 0.0f)
661 taperY = -taperY;
662 taperY1 = 1.0f - taperY;
663
695 } 664 }
696 volume = (float)volume * ((taperFactorY / 3f) + 0.001f); 665
697 } 666
698 returnMass = m_density*volume; 667 volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY);
699 if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. 668
669 pathBegin = (float)_pbs.PathBegin * 2.0e-5f;
670 pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f;
671 volume *= (pathEnd - pathBegin);
672
673// this is crude aproximation
674 profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f;
675 profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f;
676 volume *= (profileEnd - profileBegin);
677
678 returnMass = m_density * volume;
679
680 if (returnMass <= 0)
681 returnMass = 0.0001f;//ckrinke: Mass must be greater then zero.
682// else if (returnMass > _parent_scene.maximumMassObject)
683// returnMass = _parent_scene.maximumMassObject;
684
700 685
701 686
702 687