diff options
author | Teravus Ovares | 2008-02-29 05:46:24 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-02-29 05:46:24 +0000 |
commit | e333eaf4b604453da9a8952356086d4a5a1fc4a8 (patch) | |
tree | a94c05af8b965298523249c708973937860d2161 /OpenSim/Region/Physics | |
parent | From: Alan M Webb <awebb@vnet.ibm.com> (diff) | |
download | opensim-SC-e333eaf4b604453da9a8952356086d4a5a1fc4a8.zip opensim-SC-e333eaf4b604453da9a8952356086d4a5a1fc4a8.tar.gz opensim-SC-e333eaf4b604453da9a8952356086d4a5a1fc4a8.tar.bz2 opensim-SC-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')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 208 |
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 | } |