aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs33
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs102
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs99
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs132
-rw-r--r--OpenSim/Region/Physics/Meshing/SculptMap.cs176
-rw-r--r--OpenSim/Region/Physics/Meshing/SculptMesh.cs146
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs4
7 files changed, 557 insertions, 135 deletions
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
index 198962b..f13c323 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
@@ -108,12 +108,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
108 private bool[] m_colliderarr = new bool[11]; 108 private bool[] m_colliderarr = new bool[11];
109 private bool[] m_colliderGroundarr = new bool[11]; 109 private bool[] m_colliderGroundarr = new bool[11];
110 110
111
112
113 private BulletDotNETScene m_parent_scene; 111 private BulletDotNETScene m_parent_scene;
114 112
115 public int m_eventsubscription = 0; 113 public int m_eventsubscription = 0;
116 // private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); 114 private CollisionEventUpdate CollisionEventsThisFrame = null;
115 private int m_requestedUpdateFrequency = 0;
117 116
118 public BulletDotNETCharacter(string avName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) 117 public BulletDotNETCharacter(string avName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor)
119 { 118 {
@@ -212,7 +211,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
212 m_mass = Mass; 211 m_mass = Mass;
213 212
214 Body = new btRigidBody(m_mass, m_bodyMotionState, Shell); 213 Body = new btRigidBody(m_mass, m_bodyMotionState, Shell);
215 Body.setUserPointer(new IntPtr((int)Body.Handle)); 214 // this is used for self identification. User localID instead of body handle
215 Body.setUserPointer(new IntPtr((int)m_localID));
216 216
217 if (ClosestCastResult != null) 217 if (ClosestCastResult != null)
218 ClosestCastResult.Dispose(); 218 ClosestCastResult.Dispose();
@@ -716,6 +716,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
716 public override void SubscribeEvents(int ms) 716 public override void SubscribeEvents(int ms)
717 { 717 {
718 m_eventsubscription = ms; 718 m_eventsubscription = ms;
719 m_requestedUpdateFrequency = ms;
719 m_parent_scene.addCollisionEventReporting(this); 720 m_parent_scene.addCollisionEventReporting(this);
720 } 721 }
721 722
@@ -723,6 +724,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
723 { 724 {
724 m_parent_scene.remCollisionEventReporting(this); 725 m_parent_scene.remCollisionEventReporting(this);
725 m_eventsubscription = 0; 726 m_eventsubscription = 0;
727 m_requestedUpdateFrequency = 0;
726 } 728 }
727 729
728 public override bool SubscribedEvents() 730 public override bool SubscribedEvents()
@@ -732,6 +734,29 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
732 return false; 734 return false;
733 } 735 }
734 736
737 public void AddCollision(uint collideWith, ContactPoint contact)
738 {
739 if (CollisionEventsThisFrame == null)
740 {
741 CollisionEventsThisFrame = new CollisionEventUpdate();
742 }
743 CollisionEventsThisFrame.addCollider(collideWith, contact);
744 }
745
746 public void SendCollisions()
747 {
748 if (m_eventsubscription >= m_requestedUpdateFrequency)
749 {
750 if (CollisionEventsThisFrame != null)
751 {
752 base.SendCollisionUpdate(CollisionEventsThisFrame);
753 }
754 CollisionEventsThisFrame = new CollisionEventUpdate();
755 m_eventsubscription = 0;
756 }
757 return;
758 }
759
735 internal void Dispose() 760 internal void Dispose()
736 { 761 {
737 if (Body.isInWorld()) 762 if (Body.isInWorld())
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
index 920ed96..dc3229a 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
@@ -154,7 +154,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
154 private Vector3 _target_velocity; 154 private Vector3 _target_velocity;
155 155
156 public int m_eventsubscription; 156 public int m_eventsubscription;
157 // private CollisionEventUpdate CollisionEventsThisFrame = null; 157 private int m_requestedUpdateFrequency = 0;
158 private CollisionEventUpdate CollisionEventsThisFrame = null;
158 159
159 public volatile bool childPrim; 160 public volatile bool childPrim;
160 161
@@ -595,6 +596,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
595 public override void SubscribeEvents(int ms) 596 public override void SubscribeEvents(int ms)
596 { 597 {
597 m_eventsubscription = ms; 598 m_eventsubscription = ms;
599 m_requestedUpdateFrequency = ms;
598 _parent_scene.addCollisionEventReporting(this); 600 _parent_scene.addCollisionEventReporting(this);
599 } 601 }
600 602
@@ -602,6 +604,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
602 { 604 {
603 _parent_scene.remCollisionEventReporting(this); 605 _parent_scene.remCollisionEventReporting(this);
604 m_eventsubscription = 0; 606 m_eventsubscription = 0;
607 m_requestedUpdateFrequency = 0;
605 } 608 }
606 609
607 public override bool SubscribedEvents() 610 public override bool SubscribedEvents()
@@ -611,7 +614,28 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
611 614
612 #endregion 615 #endregion
613 616
617 public void AddCollision(uint collideWith, ContactPoint contact)
618 {
619 if (CollisionEventsThisFrame == null)
620 {
621 CollisionEventsThisFrame = new CollisionEventUpdate();
622 }
623 CollisionEventsThisFrame.addCollider(collideWith, contact);
624 }
614 625
626 public void SendCollisions()
627 {
628 if (m_eventsubscription >= m_requestedUpdateFrequency)
629 {
630 if (CollisionEventsThisFrame != null)
631 {
632 base.SendCollisionUpdate(CollisionEventsThisFrame);
633 }
634 CollisionEventsThisFrame = null;
635 // m_eventsubscription = 0;
636 }
637 return;
638 }
615 639
616 internal void Dispose() 640 internal void Dispose()
617 { 641 {
@@ -759,7 +783,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
759 { 783 {
760 if (m_taintadd) 784 if (m_taintadd)
761 { 785 {
762 m_log.Debug("[PHYSICS]: TaintAdd"); 786 // m_log.Debug("[PHYSICS]: TaintAdd");
763 changeadd(timestep); 787 changeadd(timestep);
764 } 788 }
765 789
@@ -771,7 +795,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
771 SetBody(Mass); 795 SetBody(Mass);
772 else 796 else
773 SetBody(0); 797 SetBody(0);
774 m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); 798 // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
775 } 799 }
776 800
777 if (prim_geom.Handle == IntPtr.Zero) 801 if (prim_geom.Handle == IntPtr.Zero)
@@ -782,31 +806,31 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
782 SetBody(Mass); 806 SetBody(Mass);
783 else 807 else
784 SetBody(0); 808 SetBody(0);
785 m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); 809 // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
786 810
787 } 811 }
788 812
789 if (!_position.ApproxEquals(m_taintposition, 0f)) 813 if (!_position.ApproxEquals(m_taintposition, 0f))
790 { 814 {
791 m_log.Debug("[PHYSICS]: TaintMove"); 815 // m_log.Debug("[PHYSICS]: TaintMove");
792 changemove(timestep); 816 changemove(timestep);
793 } 817 }
794 if (m_taintrot != _orientation) 818 if (m_taintrot != _orientation)
795 { 819 {
796 m_log.Debug("[PHYSICS]: TaintRotate"); 820 // m_log.Debug("[PHYSICS]: TaintRotate");
797 rotate(timestep); 821 rotate(timestep);
798 } // 822 } //
799 823
800 if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) 824 if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent))
801 { 825 {
802 m_log.Debug("[PHYSICS]: TaintPhysics"); 826 // m_log.Debug("[PHYSICS]: TaintPhysics");
803 changePhysicsStatus(timestep); 827 changePhysicsStatus(timestep);
804 } 828 }
805 // 829 //
806 830
807 if (!_size.ApproxEquals(m_taintsize, 0f)) 831 if (!_size.ApproxEquals(m_taintsize, 0f))
808 { 832 {
809 m_log.Debug("[PHYSICS]: TaintSize"); 833 // m_log.Debug("[PHYSICS]: TaintSize");
810 changesize(timestep); 834 changesize(timestep);
811 } 835 }
812 836
@@ -814,43 +838,43 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
814 838
815 if (m_taintshape) 839 if (m_taintshape)
816 { 840 {
817 m_log.Debug("[PHYSICS]: TaintShape"); 841 // m_log.Debug("[PHYSICS]: TaintShape");
818 changeshape(timestep); 842 changeshape(timestep);
819 } // 843 } //
820 844
821 if (m_taintforce) 845 if (m_taintforce)
822 { 846 {
823 m_log.Debug("[PHYSICS]: TaintForce"); 847 // m_log.Debug("[PHYSICS]: TaintForce");
824 changeAddForce(timestep); 848 changeAddForce(timestep);
825 } 849 }
826 if (m_taintaddangularforce) 850 if (m_taintaddangularforce)
827 { 851 {
828 m_log.Debug("[PHYSICS]: TaintAngularForce"); 852 // m_log.Debug("[PHYSICS]: TaintAngularForce");
829 changeAddAngularForce(timestep); 853 changeAddAngularForce(timestep);
830 } 854 }
831 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) 855 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
832 { 856 {
833 m_log.Debug("[PHYSICS]: TaintTorque"); 857 // m_log.Debug("[PHYSICS]: TaintTorque");
834 changeSetTorque(timestep); 858 changeSetTorque(timestep);
835 } 859 }
836 if (m_taintdisable) 860 if (m_taintdisable)
837 { 861 {
838 m_log.Debug("[PHYSICS]: TaintDisable"); 862 // m_log.Debug("[PHYSICS]: TaintDisable");
839 changedisable(timestep); 863 changedisable(timestep);
840 } 864 }
841 if (m_taintselected != m_isSelected) 865 if (m_taintselected != m_isSelected)
842 { 866 {
843 m_log.Debug("[PHYSICS]: TaintSelected"); 867 // m_log.Debug("[PHYSICS]: TaintSelected");
844 changeSelectedStatus(timestep); 868 changeSelectedStatus(timestep);
845 } 869 }
846 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) 870 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
847 { 871 {
848 m_log.Debug("[PHYSICS]: TaintVelocity"); 872 // m_log.Debug("[PHYSICS]: TaintVelocity");
849 changevelocity(timestep); 873 changevelocity(timestep);
850 } 874 }
851 if (m_taintparent != _parent) 875 if (m_taintparent != _parent)
852 { 876 {
853 m_log.Debug("[PHYSICS]: TaintLink"); 877 // m_log.Debug("[PHYSICS]: TaintLink");
854 changelink(timestep); 878 changelink(timestep);
855 } 879 }
856 if (m_taintCollidesWater != m_collidesWater) 880 if (m_taintCollidesWater != m_collidesWater)
@@ -859,7 +883,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
859 } 883 }
860 if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0)) 884 if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0))
861 { 885 {
862 m_log.Debug("[PHYSICS]: TaintAngularLock"); 886 // m_log.Debug("[PHYSICS]: TaintAngularLock");
863 changeAngularLock(timestep); 887 changeAngularLock(timestep);
864 } 888 }
865 if (m_taintremove) 889 if (m_taintremove)
@@ -917,7 +941,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
917 private void changemove(float timestep) 941 private void changemove(float timestep)
918 { 942 {
919 943
920 m_log.Debug("[PHYSICS]: _________ChangeMove"); 944 // m_log.Debug("[PHYSICS]: _________ChangeMove");
921 if (!m_isphysical) 945 if (!m_isphysical)
922 { 946 {
923 tempTransform2 = Body.getWorldTransform(); 947 tempTransform2 = Body.getWorldTransform();
@@ -977,7 +1001,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
977 1001
978 private void rotate(float timestep) 1002 private void rotate(float timestep)
979 { 1003 {
980 m_log.Debug("[PHYSICS]: _________ChangeRotate"); 1004 // m_log.Debug("[PHYSICS]: _________ChangeRotate");
981 tempTransform2 = Body.getWorldTransform(); 1005 tempTransform2 = Body.getWorldTransform();
982 tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W); 1006 tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
983 tempTransform2.setRotation(tempOrientation2); 1007 tempTransform2.setRotation(tempOrientation2);
@@ -1000,7 +1024,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1000 //Body = null; 1024 //Body = null;
1001 // TODO: dispose parts that make up body 1025 // TODO: dispose parts that make up body
1002 } 1026 }
1003 m_log.Debug("[PHYSICS]: _________ChangePhysics"); 1027 // m_log.Debug("[PHYSICS]: _________ChangePhysics");
1004 1028
1005 ProcessGeomCreation(); 1029 ProcessGeomCreation();
1006 1030
@@ -1092,7 +1116,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1092 // TODO: dispose parts that make up body 1116 // TODO: dispose parts that make up body
1093 } 1117 }
1094 1118
1095 m_log.Debug("[PHYSICS]: _________ChangeSize"); 1119 // m_log.Debug("[PHYSICS]: _________ChangeSize");
1096 SetCollisionShape(null); 1120 SetCollisionShape(null);
1097 // Construction of new prim 1121 // Construction of new prim
1098 ProcessGeomCreation(); 1122 ProcessGeomCreation();
@@ -1297,13 +1321,13 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1297 // TODO: throw new NotImplementedException(); 1321 // TODO: throw new NotImplementedException();
1298 if (m_taintselected) 1322 if (m_taintselected)
1299 { 1323 {
1300 Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE); 1324 // Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE);
1301 disableBodySoft(); 1325 disableBodySoft();
1302 1326
1303 } 1327 }
1304 else 1328 else
1305 { 1329 {
1306 Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK); 1330 // Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
1307 enableBodySoft(); 1331 enableBodySoft();
1308 } 1332 }
1309 m_isSelected = m_taintselected; 1333 m_isSelected = m_taintselected;
@@ -1605,6 +1629,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1605 enableBodySoft(); 1629 enableBodySoft();
1606 } 1630 }
1607 */ 1631 */
1632 if (!Body.isActive())
1633 {
1634 Body.clearForces();
1635 enableBodySoft();
1636 }
1608 // 35x10 = 350n times the mass per second applied maximum. 1637 // 35x10 = 350n times the mass per second applied maximum.
1609 1638
1610 float nmax = 35f * m_mass; 1639 float nmax = 35f * m_mass;
@@ -1632,6 +1661,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1632 Body.applyCentralImpulse(tempAddForce); 1661 Body.applyCentralImpulse(tempAddForce);
1633 } 1662 }
1634 } 1663 }
1664 else
1665 {
1666 // if no forces on the prim, make sure everything is zero
1667 Body.clearForces();
1668 enableBodySoft();
1669 }
1635 } 1670 }
1636 else 1671 else
1637 { 1672 {
@@ -1985,7 +2020,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
1985 2020
1986 public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh) 2021 public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh)
1987 { 2022 {
1988 m_log.Debug("[PHYSICS]: _________CreateGeom"); 2023 // m_log.Debug("[PHYSICS]: _________CreateGeom");
1989 if (p_mesh != null) 2024 if (p_mesh != null)
1990 { 2025 {
1991 //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); 2026 //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
@@ -2042,7 +2077,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2042 // TODO: Set Collision Body Mesh 2077 // TODO: Set Collision Body Mesh
2043 // This sleeper is there to moderate how long it takes between 2078 // This sleeper is there to moderate how long it takes between
2044 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object 2079 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
2045 m_log.Debug("_________SetMesh"); 2080 // m_log.Debug("_________SetMesh");
2046 Thread.Sleep(10); 2081 Thread.Sleep(10);
2047 2082
2048 //Kill Body so that mesh can re-make the geom 2083 //Kill Body so that mesh can re-make the geom
@@ -2159,7 +2194,14 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2159 2194
2160 // Body = new btRigidBody(mass, tempMotionState1, prim_geom); 2195 // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
2161 //else 2196 //else
2162 Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); 2197 // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2198 if (Body == null)
2199 {
2200 Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2201 // add localID so we can later map bullet object back to OpenSim object
2202 Body.setUserPointer(new IntPtr((int)m_localID));
2203 }
2204
2163 2205
2164 if (prim_geom is btGImpactMeshShape) 2206 if (prim_geom is btGImpactMeshShape)
2165 { 2207 {
@@ -2250,7 +2292,13 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
2250 2292
2251 // Body = new btRigidBody(mass, tempMotionState1, prim_geom); 2293 // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
2252 //else 2294 //else
2253 Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); 2295 // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2296 if (Body == null)
2297 {
2298 Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
2299 // each body has the localID stored into it so we can identify collision objects
2300 Body.setUserPointer(new IntPtr((int)m_localID));
2301 }
2254 2302
2255 if (prim_geom is btGImpactMeshShape) 2303 if (prim_geom is btGImpactMeshShape)
2256 { 2304 {
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
index 9e048ab..85e34c1 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
@@ -47,7 +47,9 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
47 // private string m_sceneIdentifier = string.Empty; 47 // private string m_sceneIdentifier = string.Empty;
48 48
49 private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>(); 49 private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>();
50 private Dictionary<uint, BulletDotNETCharacter> m_charactersLocalID = new Dictionary<uint, BulletDotNETCharacter>();
50 private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>(); 51 private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>();
52 private Dictionary<uint, BulletDotNETPrim> m_primsLocalID = new Dictionary<uint, BulletDotNETPrim>();
51 private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>(); 53 private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>();
52 private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>(); 54 private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>();
53 private btDiscreteDynamicsWorld m_world; 55 private btDiscreteDynamicsWorld m_world;
@@ -134,7 +136,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
134 m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); 136 m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
135 m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); 137 m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
136 m_world.setGravity(m_gravity); 138 m_world.setGravity(m_gravity);
137 //EnableCollisionInterface(); 139 EnableCollisionInterface();
138 140
139 141
140 } 142 }
@@ -145,7 +147,16 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
145 avCapRadius, avStandupTensor, avDensity, 147 avCapRadius, avStandupTensor, avDensity,
146 avHeightFudgeFactor, avMovementDivisorWalk, 148 avHeightFudgeFactor, avMovementDivisorWalk,
147 avMovementDivisorRun); 149 avMovementDivisorRun);
148 m_characters.Add(chr); 150 try
151 {
152 m_characters.Add(chr);
153 m_charactersLocalID.Add(chr.m_localID, chr);
154 }
155 catch
156 {
157 // noop if it's already there
158 m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate avatar localID");
159 }
149 AddPhysicsActorTaint(chr); 160 AddPhysicsActorTaint(chr);
150 return chr; 161 return chr;
151 } 162 }
@@ -154,6 +165,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
154 { 165 {
155 BulletDotNETCharacter chr = (BulletDotNETCharacter) actor; 166 BulletDotNETCharacter chr = (BulletDotNETCharacter) actor;
156 167
168 m_charactersLocalID.Remove(chr.m_localID);
157 m_characters.Remove(chr); 169 m_characters.Remove(chr);
158 m_world.removeRigidBody(chr.Body); 170 m_world.removeRigidBody(chr.Body);
159 m_world.removeCollisionObject(chr.Body); 171 m_world.removeCollisionObject(chr.Body);
@@ -279,7 +291,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
279 prim.Move(timeStep); 291 prim.Move(timeStep);
280 } 292 }
281 } 293 }
282 float steps = m_world.stepSimulation(timeStep * 1000, 10, WorldTimeComp); 294 float steps = m_world.stepSimulation(timeStep, 10, WorldTimeComp);
283 295
284 foreach (BulletDotNETCharacter chr in m_characters) 296 foreach (BulletDotNETCharacter chr in m_characters)
285 { 297 {
@@ -296,20 +308,67 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
296 } 308 }
297 if (m_CollisionInterface != null) 309 if (m_CollisionInterface != null)
298 { 310 {
299 List<int> collisions = m_CollisionInterface.GetContactList(); 311 List<BulletDotNETPrim> primsWithCollisions = new List<BulletDotNETPrim>();
300 lock (collisions) 312 List<BulletDotNETCharacter> charactersWithCollisions = new List<BulletDotNETCharacter>();
313
314 // get the collisions that happened this tick
315 List<BulletDotNET.ContactAddedCallbackHandler.ContactInfo> collisions = m_CollisionInterface.GetContactList();
316 // passed back the localID of the prim so we can associate the prim
317 foreach (BulletDotNET.ContactAddedCallbackHandler.ContactInfo ci in collisions)
301 { 318 {
302 foreach (int pvalue in collisions) 319 // ContactPoint = { contactPoint, contactNormal, penetrationDepth }
303 { 320 ContactPoint contact = new ContactPoint(new Vector3(ci.pX, ci.pY, ci.pZ),
304 System.Console.Write(string.Format("{0} ", pvalue)); 321 new Vector3(ci.nX, ci.nY, ci.nZ), ci.depth);
305 } 322
323 ProcessContact(ci.contact, ci.contactWith, contact, ref primsWithCollisions, ref charactersWithCollisions);
324 ProcessContact(ci.contactWith, ci.contact, contact, ref primsWithCollisions, ref charactersWithCollisions);
325
306 } 326 }
307 m_CollisionInterface.Clear(); 327 m_CollisionInterface.Clear();
308 328 // for those prims and characters that had collisions cause collision events
329 foreach (BulletDotNETPrim bdnp in primsWithCollisions)
330 {
331 bdnp.SendCollisions();
332 }
333 foreach (BulletDotNETCharacter bdnc in charactersWithCollisions)
334 {
335 bdnc.SendCollisions();
336 }
309 } 337 }
310 return steps; 338 return steps;
311 } 339 }
312 340
341 private void ProcessContact(uint cont, uint contWith, ContactPoint contact,
342 ref List<BulletDotNETPrim> primsWithCollisions,
343 ref List<BulletDotNETCharacter> charactersWithCollisions)
344 {
345 BulletDotNETPrim bdnp;
346 // collisions with a normal prim?
347 if (m_primsLocalID.TryGetValue(cont, out bdnp))
348 {
349 // Added collision event to the prim. This creates a pile of events
350 // that will be sent to any subscribed listeners.
351 bdnp.AddCollision(contWith, contact);
352 if (!primsWithCollisions.Contains(bdnp))
353 {
354 primsWithCollisions.Add(bdnp);
355 }
356 }
357 else
358 {
359 BulletDotNETCharacter bdnc;
360 // if not a prim, maybe it's one of the characters
361 if (m_charactersLocalID.TryGetValue(cont, out bdnc))
362 {
363 bdnc.AddCollision(contWith, contact);
364 if (!charactersWithCollisions.Contains(bdnc))
365 {
366 charactersWithCollisions.Add(bdnc);
367 }
368 }
369 }
370 }
371
313 public override void GetResults() 372 public override void GetResults()
314 { 373 {
315 374
@@ -387,6 +446,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
387 m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); 446 m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition);
388 m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); 447 m_terrainMotionState = new btDefaultMotionState(m_terrainTransform);
389 TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape); 448 TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape);
449 TerrainBody.setUserPointer((IntPtr)0);
390 m_world.addRigidBody(TerrainBody); 450 m_world.addRigidBody(TerrainBody);
391 451
392 452
@@ -459,6 +519,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
459 { 519 {
460 lock (m_prims) 520 lock (m_prims)
461 { 521 {
522 m_primsLocalID.Clear();
462 foreach (BulletDotNETPrim prim in m_prims) 523 foreach (BulletDotNETPrim prim in m_prims)
463 { 524 {
464 if (prim.Body != null) 525 if (prim.Body != null)
@@ -513,6 +574,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
513 m_world.removeRigidBody(body); 574 m_world.removeRigidBody(body);
514 } 575 }
515 remActivePrim(prm); 576 remActivePrim(prm);
577 m_primsLocalID.Remove(prm.m_localID);
516 m_prims.Remove(prm); 578 m_prims.Remove(prm);
517 } 579 }
518 580
@@ -686,9 +748,18 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
686 { 748 {
687 if (!m_prims.Contains(pPrim)) 749 if (!m_prims.Contains(pPrim))
688 { 750 {
689 m_prims.Add(pPrim); 751 try
752 {
753 m_prims.Add(pPrim);
754 m_primsLocalID.Add(pPrim.m_localID, pPrim);
755 }
756 catch
757 {
758 // noop if it's already there
759 m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate prim localID");
760 }
690 m_world.addRigidBody(pPrim.Body); 761 m_world.addRigidBody(pPrim.Body);
691 m_log.Debug("ADDED"); 762 // m_log.Debug("[PHYSICS] added prim to scene");
692 } 763 }
693 } 764 }
694 } 765 }
@@ -696,8 +767,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
696 { 767 {
697 if (m_CollisionInterface == null) 768 if (m_CollisionInterface == null)
698 { 769 {
699 m_CollisionInterface = new ContactAddedCallbackHandler(); 770 m_CollisionInterface = new ContactAddedCallbackHandler(m_world);
700 m_world.SetCollisionAddedCallback(m_CollisionInterface); 771 // m_world.SetCollisionAddedCallback(m_CollisionInterface);
701 } 772 }
702 } 773 }
703 774
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 2a213c3..53022ad 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -257,7 +257,6 @@ namespace PrimMesher
257 public int uv2; 257 public int uv2;
258 public int uv3; 258 public int uv3;
259 259
260
261 public Face(int v1, int v2, int v3) 260 public Face(int v1, int v2, int v3)
262 { 261 {
263 primFace = 0; 262 primFace = 0;
@@ -630,6 +629,9 @@ namespace PrimMesher
630 internal int numOuterVerts = 0; 629 internal int numOuterVerts = 0;
631 internal int numHollowVerts = 0; 630 internal int numHollowVerts = 0;
632 631
632 internal int outerFaceNumber = -1;
633 internal int hollowFaceNumber = -1;
634
633 internal bool calcVertexNormals = false; 635 internal bool calcVertexNormals = false;
634 internal int bottomFaceNumber = 0; 636 internal int bottomFaceNumber = 0;
635 internal int numPrimFaces = 0; 637 internal int numPrimFaces = 0;
@@ -827,15 +829,16 @@ namespace PrimMesher
827 829
828 if (createFaces) 830 if (createFaces)
829 { 831 {
830 int numOuterVerts = this.coords.Count; 832 //int numOuterVerts = this.coords.Count;
831 int numHollowVerts = hollowCoords.Count; 833 //numOuterVerts = this.coords.Count;
832 int numTotalVerts = numOuterVerts + numHollowVerts; 834 //int numHollowVerts = hollowCoords.Count;
835 int numTotalVerts = this.numOuterVerts + this.numHollowVerts;
833 836
834 if (numOuterVerts == numHollowVerts) 837 if (this.numOuterVerts == this.numHollowVerts)
835 { 838 {
836 Face newFace = new Face(); 839 Face newFace = new Face();
837 840
838 for (int coordIndex = 0; coordIndex < numOuterVerts - 1; coordIndex++) 841 for (int coordIndex = 0; coordIndex < this.numOuterVerts - 1; coordIndex++)
839 { 842 {
840 newFace.v1 = coordIndex; 843 newFace.v1 = coordIndex;
841 newFace.v2 = coordIndex + 1; 844 newFace.v2 = coordIndex + 1;
@@ -850,12 +853,12 @@ namespace PrimMesher
850 } 853 }
851 else 854 else
852 { 855 {
853 if (numOuterVerts < numHollowVerts) 856 if (this.numOuterVerts < this.numHollowVerts)
854 { 857 {
855 Face newFace = new Face(); 858 Face newFace = new Face();
856 int j = 0; // j is the index for outer vertices 859 int j = 0; // j is the index for outer vertices
857 int maxJ = numOuterVerts - 1; 860 int maxJ = this.numOuterVerts - 1;
858 for (int i = 0; i < numHollowVerts; i++) // i is the index for inner vertices 861 for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices
859 { 862 {
860 if (j < maxJ) 863 if (j < maxJ)
861 if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) 864 if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f)
@@ -879,8 +882,8 @@ namespace PrimMesher
879 { 882 {
880 Face newFace = new Face(); 883 Face newFace = new Face();
881 int j = 0; // j is the index for inner vertices 884 int j = 0; // j is the index for inner vertices
882 int maxJ = numHollowVerts - 1; 885 int maxJ = this.numHollowVerts - 1;
883 for (int i = 0; i < numOuterVerts; i++) 886 for (int i = 0; i < this.numOuterVerts; i++)
884 { 887 {
885 if (j < maxJ) 888 if (j < maxJ)
886 if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) 889 if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f)
@@ -935,10 +938,10 @@ namespace PrimMesher
935 938
936 if (calcVertexNormals && hasProfileCut) 939 if (calcVertexNormals && hasProfileCut)
937 { 940 {
941 int lastOuterVertIndex = this.numOuterVerts - 1;
942
938 if (hasHollow) 943 if (hasHollow)
939 { 944 {
940 int lastOuterVertIndex = this.numOuterVerts - 1;
941
942 this.cut1CoordIndices.Add(0); 945 this.cut1CoordIndices.Add(0);
943 this.cut1CoordIndices.Add(this.coords.Count - 1); 946 this.cut1CoordIndices.Add(this.coords.Count - 1);
944 947
@@ -954,6 +957,12 @@ namespace PrimMesher
954 957
955 else 958 else
956 { 959 {
960 this.cut1CoordIndices.Add(0);
961 this.cut1CoordIndices.Add(1);
962
963 this.cut2CoordIndices.Add(lastOuterVertIndex);
964 this.cut2CoordIndices.Add(0);
965
957 this.cutNormal1.X = this.vertexNormals[1].Y; 966 this.cutNormal1.X = this.vertexNormals[1].Y;
958 this.cutNormal1.Y = -this.vertexNormals[1].X; 967 this.cutNormal1.Y = -this.vertexNormals[1].X;
959 968
@@ -978,11 +987,14 @@ namespace PrimMesher
978 // I know it's ugly but so is the whole concept of prim face numbers 987 // I know it's ugly but so is the whole concept of prim face numbers
979 988
980 int faceNum = 1; // start with outer faces 989 int faceNum = 1; // start with outer faces
990 this.outerFaceNumber = faceNum;
991
981 int startVert = hasProfileCut && !hasHollow ? 1 : 0; 992 int startVert = hasProfileCut && !hasHollow ? 1 : 0;
982 if (startVert > 0) 993 if (startVert > 0)
983 this.faceNumbers.Add(-1); 994 this.faceNumbers.Add(-1);
984 for (int i = 0; i < numOuterVerts - 1; i++) 995 for (int i = 0; i < this.numOuterVerts - 1; i++)
985 this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum); 996 //this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum);
997 this.faceNumbers.Add(sides < 5 && i < sides ? faceNum++ : faceNum);
986 998
987 //if (!hasHollow && !hasProfileCut) 999 //if (!hasHollow && !hasProfileCut)
988 // this.bottomFaceNumber = faceNum++; 1000 // this.bottomFaceNumber = faceNum++;
@@ -992,12 +1004,15 @@ namespace PrimMesher
992 if (sides > 4 && (hasHollow || hasProfileCut)) 1004 if (sides > 4 && (hasHollow || hasProfileCut))
993 faceNum++; 1005 faceNum++;
994 1006
1007 if (sides < 5 && (hasHollow || hasProfileCut) && this.numOuterVerts < sides)
1008 faceNum++;
1009
995 if (hasHollow) 1010 if (hasHollow)
996 { 1011 {
997 for (int i = 0; i < numHollowVerts; i++) 1012 for (int i = 0; i < this.numHollowVerts; i++)
998 this.faceNumbers.Add(faceNum); 1013 this.faceNumbers.Add(faceNum);
999 1014
1000 faceNum++; 1015 this.hollowFaceNumber = faceNum++;
1001 } 1016 }
1002 //if (hasProfileCut || hasHollow) 1017 //if (hasProfileCut || hasHollow)
1003 // this.bottomFaceNumber = faceNum++; 1018 // this.bottomFaceNumber = faceNum++;
@@ -1005,11 +1020,11 @@ namespace PrimMesher
1005 1020
1006 if (hasHollow && hasProfileCut) 1021 if (hasHollow && hasProfileCut)
1007 this.faceNumbers.Add(faceNum++); 1022 this.faceNumbers.Add(faceNum++);
1023
1008 for (int i = 0; i < this.faceNumbers.Count; i++) 1024 for (int i = 0; i < this.faceNumbers.Count; i++)
1009 if (this.faceNumbers[i] == -1) 1025 if (this.faceNumbers[i] == -1)
1010 this.faceNumbers[i] = faceNum++; 1026 this.faceNumbers[i] = faceNum++;
1011 1027
1012
1013 this.numPrimFaces = faceNum; 1028 this.numPrimFaces = faceNum;
1014 } 1029 }
1015 1030
@@ -1019,7 +1034,7 @@ namespace PrimMesher
1019 { 1034 {
1020 this.faceUVs = new List<UVCoord>(); 1035 this.faceUVs = new List<UVCoord>();
1021 foreach (Coord c in this.coords) 1036 foreach (Coord c in this.coords)
1022 this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); 1037 this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y));
1023 } 1038 }
1024 1039
1025 internal Profile Copy() 1040 internal Profile Copy()
@@ -1348,7 +1363,6 @@ namespace PrimMesher
1348 float stepSize = twoPi / this.stepsPerRevolution; 1363 float stepSize = twoPi / this.stepsPerRevolution;
1349 1364
1350 int step = (int)(startAngle / stepSize); 1365 int step = (int)(startAngle / stepSize);
1351// int firstStep = step;
1352 float angle = startAngle; 1366 float angle = startAngle;
1353 1367
1354 bool done = false; 1368 bool done = false;
@@ -1455,11 +1469,15 @@ namespace PrimMesher
1455 public float revolutions = 1.0f; 1469 public float revolutions = 1.0f;
1456 public int stepsPerRevolution = 24; 1470 public int stepsPerRevolution = 24;
1457 1471
1472 private int profileOuterFaceNumber = -1;
1473 private int profileHollowFaceNumber = -1;
1474
1458 private bool hasProfileCut = false; 1475 private bool hasProfileCut = false;
1459 private bool hasHollow = false; 1476 private bool hasHollow = false;
1460 public bool calcVertexNormals = false; 1477 public bool calcVertexNormals = false;
1461 private bool normalsProcessed = false; 1478 private bool normalsProcessed = false;
1462 public bool viewerMode = false; 1479 public bool viewerMode = false;
1480 public bool sphereMode = false;
1463 1481
1464 public int numPrimFaces = 0; 1482 public int numPrimFaces = 0;
1465 1483
@@ -1491,10 +1509,35 @@ namespace PrimMesher
1491 s += "\nradius...............: " + this.radius.ToString(); 1509 s += "\nradius...............: " + this.radius.ToString();
1492 s += "\nrevolutions..........: " + this.revolutions.ToString(); 1510 s += "\nrevolutions..........: " + this.revolutions.ToString();
1493 s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); 1511 s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString();
1512 s += "\nsphereMode...........: " + this.sphereMode.ToString();
1513 s += "\nhasProfileCut........: " + this.hasProfileCut.ToString();
1514 s += "\nhasHollow............: " + this.hasHollow.ToString();
1515 s += "\nviewerMode...........: " + this.viewerMode.ToString();
1494 1516
1495 return s; 1517 return s;
1496 } 1518 }
1497 1519
1520 public int ProfileOuterFaceNumber
1521 {
1522 get { return profileOuterFaceNumber; }
1523 }
1524
1525 public int ProfileHollowFaceNumber
1526 {
1527 get { return profileHollowFaceNumber; }
1528 }
1529
1530 public bool HasProfileCut
1531 {
1532 get { return hasProfileCut; }
1533 }
1534
1535 public bool HasHollow
1536 {
1537 get { return hasHollow; }
1538 }
1539
1540
1498 /// <summary> 1541 /// <summary>
1499 /// Constructs a PrimMesh object and creates the profile for extrusion. 1542 /// Constructs a PrimMesh object and creates the profile for extrusion.
1500 /// </summary> 1543 /// </summary>
@@ -1531,8 +1574,12 @@ namespace PrimMesher
1531 if (hollow < 0.0f) 1574 if (hollow < 0.0f)
1532 this.hollow = 0.0f; 1575 this.hollow = 0.0f;
1533 1576
1534 this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f); 1577 //if (sphereMode)
1535 this.hasHollow = (this.hollow > 0.001f); 1578 // this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f;
1579 //else
1580 // //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f);
1581 // this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f;
1582 //this.hasHollow = (this.hollow > 0.001f);
1536 } 1583 }
1537 1584
1538 /// <summary> 1585 /// <summary>
@@ -1540,6 +1587,8 @@ namespace PrimMesher
1540 /// </summary> 1587 /// </summary>
1541 public void Extrude(PathType pathType) 1588 public void Extrude(PathType pathType)
1542 { 1589 {
1590 bool needEndFaces = false;
1591
1543 this.coords = new List<Coord>(); 1592 this.coords = new List<Coord>();
1544 this.faces = new List<Face>(); 1593 this.faces = new List<Face>();
1545 1594
@@ -1565,6 +1614,12 @@ namespace PrimMesher
1565 steps = (int)(steps * 4.5 * length); 1614 steps = (int)(steps * 4.5 * length);
1566 } 1615 }
1567 1616
1617 if (sphereMode)
1618 this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f;
1619 else
1620 //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f);
1621 this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f;
1622 this.hasHollow = (this.hollow > 0.001f);
1568 1623
1569 float twistBegin = this.twistBegin / 360.0f * twoPi; 1624 float twistBegin = this.twistBegin / 360.0f * twoPi;
1570 float twistEnd = this.twistEnd / 360.0f * twoPi; 1625 float twistEnd = this.twistEnd / 360.0f * twoPi;
@@ -1634,6 +1689,32 @@ namespace PrimMesher
1634 1689
1635 this.numPrimFaces = profile.numPrimFaces; 1690 this.numPrimFaces = profile.numPrimFaces;
1636 1691
1692 //profileOuterFaceNumber = profile.faceNumbers[0];
1693 //if (!needEndFaces)
1694 // profileOuterFaceNumber--;
1695 //profileOuterFaceNumber = needEndFaces ? 1 : 0;
1696
1697
1698 //if (hasHollow)
1699 //{
1700 // if (needEndFaces)
1701 // profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts + 1];
1702 // else
1703 // profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts] - 1;
1704 //}
1705
1706
1707 profileOuterFaceNumber = profile.outerFaceNumber;
1708 if (!needEndFaces)
1709 profileOuterFaceNumber--;
1710
1711 if (hasHollow)
1712 {
1713 profileHollowFaceNumber = profile.hollowFaceNumber;
1714 if (!needEndFaces)
1715 profileHollowFaceNumber--;
1716 }
1717
1637 int cut1Vert = -1; 1718 int cut1Vert = -1;
1638 int cut2Vert = -1; 1719 int cut2Vert = -1;
1639 if (hasProfileCut) 1720 if (hasProfileCut)
@@ -1673,7 +1754,7 @@ namespace PrimMesher
1673 1754
1674 path.Create(pathType, steps); 1755 path.Create(pathType, steps);
1675 1756
1676 bool needEndFaces = false; 1757
1677 if (pathType == PathType.Circular) 1758 if (pathType == PathType.Circular)
1678 { 1759 {
1679 needEndFaces = false; 1760 needEndFaces = false;
@@ -1738,7 +1819,6 @@ namespace PrimMesher
1738 // append this layer 1819 // append this layer
1739 1820
1740 int coordsLen = this.coords.Count; 1821 int coordsLen = this.coords.Count;
1741// int lastCoordsLen = coordsLen;
1742 newLayer.AddValue2FaceVertexIndices(coordsLen); 1822 newLayer.AddValue2FaceVertexIndices(coordsLen);
1743 1823
1744 this.coords.AddRange(newLayer.coords); 1824 this.coords.AddRange(newLayer.coords);
@@ -1762,7 +1842,7 @@ namespace PrimMesher
1762 int startVert = coordsLen + 1; 1842 int startVert = coordsLen + 1;
1763 int endVert = this.coords.Count; 1843 int endVert = this.coords.Count;
1764 1844
1765 if (sides < 5 || this.hasProfileCut || hollow > 0.0f) 1845 if (sides < 5 || this.hasProfileCut || this.hasHollow)
1766 startVert--; 1846 startVert--;
1767 1847
1768 for (int i = startVert; i < endVert; i++) 1848 for (int i = startVert; i < endVert; i++)
@@ -1814,11 +1894,13 @@ namespace PrimMesher
1814 u1 -= (int)u1; 1894 u1 -= (int)u1;
1815 if (u2 < 0.1f) 1895 if (u2 < 0.1f)
1816 u2 = 1.0f; 1896 u2 = 1.0f;
1897 //this.profileOuterFaceNumber = primFaceNum;
1817 } 1898 }
1818 else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1) 1899 else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1)
1819 { 1900 {
1820 u1 *= 2.0f; 1901 u1 *= 2.0f;
1821 u2 *= 2.0f; 1902 u2 *= 2.0f;
1903 //this.profileHollowFaceNumber = primFaceNum;
1822 } 1904 }
1823 } 1905 }
1824 1906
diff --git a/OpenSim/Region/Physics/Meshing/SculptMap.cs b/OpenSim/Region/Physics/Meshing/SculptMap.cs
new file mode 100644
index 0000000..d2d71de
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/SculptMap.cs
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) Contributors
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28// to build without references to System.Drawing, comment this out
29#define SYSTEM_DRAWING
30
31using System;
32using System.Collections.Generic;
33using System.Text;
34
35#if SYSTEM_DRAWING
36using System.Drawing;
37using System.Drawing.Imaging;
38
39namespace PrimMesher
40{
41 public class SculptMap
42 {
43 public int width;
44 public int height;
45 public byte[] redBytes;
46 public byte[] greenBytes;
47 public byte[] blueBytes;
48
49 public SculptMap()
50 {
51 }
52
53 public SculptMap(Bitmap bm, int lod)
54 {
55 int bmW = bm.Width;
56 int bmH = bm.Height;
57
58 if (bmW == 0 || bmH == 0)
59 throw new Exception("SculptMap: bitmap has no data");
60
61 int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
62
63 bool needsScaling = false;
64
65 width = bmW;
66 height = bmH;
67 while (width * height > numLodPixels)
68 {
69 width >>= 1;
70 height >>= 1;
71 needsScaling = true;
72 }
73
74
75
76 try
77 {
78 if (needsScaling)
79 bm = ScaleImage(bm, width, height,
80 System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
81 }
82
83 catch (Exception e)
84 {
85 throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
86 }
87
88 if (width * height > lod * lod)
89 {
90 width >>= 1;
91 height >>= 1;
92 }
93
94 int numBytes = (width + 1) * (height + 1);
95 redBytes = new byte[numBytes];
96 greenBytes = new byte[numBytes];
97 blueBytes = new byte[numBytes];
98
99 int byteNdx = 0;
100
101 try
102 {
103 for (int y = 0; y <= height; y++)
104 {
105 for (int x = 0; x <= width; x++)
106 {
107 int bmY = y < height ? y * 2 : y * 2 - 1;
108 int bmX = x < width ? x * 2 : x * 2 - 1;
109 Color c = bm.GetPixel(bmX, bmY);
110
111 redBytes[byteNdx] = c.R;
112 greenBytes[byteNdx] = c.G;
113 blueBytes[byteNdx] = c.B;
114
115 ++byteNdx;
116 }
117 }
118 }
119 catch (Exception e)
120 {
121 throw new Exception("Caught exception processing byte arrays in SculptMap(): e: " + e.ToString());
122 }
123
124 width++;
125 height++;
126 }
127
128 public List<List<Coord>> ToRows(bool mirror)
129 {
130 int numRows = height;
131 int numCols = width;
132
133 List<List<Coord>> rows = new List<List<Coord>>(numRows);
134
135 float pixScale = 1.0f / 255;
136
137 int rowNdx, colNdx;
138 int smNdx = 0;
139
140 for (rowNdx = 0; rowNdx < numRows; rowNdx++)
141 {
142 List<Coord> row = new List<Coord>(numCols);
143 for (colNdx = 0; colNdx < numCols; colNdx++)
144 {
145 if (mirror)
146 row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f));
147 else
148 row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f));
149
150 ++smNdx;
151 }
152 rows.Add(row);
153 }
154 return rows;
155 }
156
157 private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
158 System.Drawing.Drawing2D.InterpolationMode interpMode)
159 {
160 Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
161 scaledImage.SetResolution(96.0f, 96.0f);
162
163 Graphics grPhoto = Graphics.FromImage(scaledImage);
164 grPhoto.InterpolationMode = interpMode;
165
166 grPhoto.DrawImage(srcImage,
167 new Rectangle(0, 0, destWidth, destHeight),
168 new Rectangle(0, 0, srcImage.Width, srcImage.Height),
169 GraphicsUnit.Pixel);
170
171 grPhoto.Dispose();
172 return scaledImage;
173 }
174 }
175}
176#endif
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs
index 4dc6e2e..6aa8fe4 100644
--- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs
+++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs
@@ -53,43 +53,6 @@ namespace PrimMesher
53 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; 53 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 };
54 54
55#if SYSTEM_DRAWING 55#if SYSTEM_DRAWING
56 // private Bitmap ScaleImage(Bitmap srcImage, float scale)
57 // {
58 // int sourceWidth = srcImage.Width;
59 // int sourceHeight = srcImage.Height;
60 // int sourceX = 0;
61 // int sourceY = 0;
62
63 // int destX = 0;
64 // int destY = 0;
65 // int destWidth = (int)(srcImage.Width * scale);
66 // int destHeight = (int)(srcImage.Height * scale);
67
68 // if (srcImage.PixelFormat == PixelFormat.Format32bppArgb)
69 // for (int y = 0; y < srcImage.Height; y++)
70 // for (int x = 0; x < srcImage.Width; x++)
71 // {
72 // Color c = srcImage.GetPixel(x, y);
73 // srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B));
74 // }
75
76 // Bitmap scaledImage = new Bitmap(destWidth, destHeight,
77 // PixelFormat.Format24bppRgb);
78
79 // scaledImage.SetResolution(96.0f, 96.0f);
80
81 // Graphics grPhoto = Graphics.FromImage(scaledImage);
82 // grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
83
84 // grPhoto.DrawImage(srcImage,
85 // new Rectangle(destX, destY, destWidth, destHeight),
86 // new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
87 // GraphicsUnit.Pixel);
88
89 // grPhoto.Dispose();
90 // return scaledImage;
91 // }
92
93 56
94 public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) 57 public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
95 { 58 {
@@ -99,6 +62,7 @@ namespace PrimMesher
99 return sculptMesh; 62 return sculptMesh;
100 } 63 }
101 64
65
102 public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert) 66 public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert)
103 { 67 {
104 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); 68 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
@@ -268,6 +232,11 @@ namespace PrimMesher
268 for (imageY = imageYStart; imageY < imageYEnd; imageY++) 232 for (imageY = imageYStart; imageY < imageYEnd; imageY++)
269 { 233 {
270 Color c = bitmap.GetPixel(imageX, imageY); 234 Color c = bitmap.GetPixel(imageX, imageY);
235 if (c.A != 255)
236 {
237 bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
238 c = bitmap.GetPixel(imageX, imageY);
239 }
271 rSum += c.R; 240 rSum += c.R;
272 gSum += c.G; 241 gSum += c.G;
273 bSum += c.B; 242 bSum += c.B;
@@ -284,30 +253,53 @@ namespace PrimMesher
284 return rows; 253 return rows;
285 } 254 }
286 255
287 256 private List<List<Coord>> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror)
288 void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
289 { 257 {
290 coords = new List<Coord>(); 258 int numRows = bitmap.Height / scale;
291 faces = new List<Face>(); 259 int numCols = bitmap.Width / scale;
292 normals = new List<Coord>(); 260 List<List<Coord>> rows = new List<List<Coord>>(numRows);
293 uvs = new List<UVCoord>();
294 261
295 sculptType = (SculptType)(((int)sculptType) & 0x07); 262 float pixScale = 1.0f / 256.0f;
296 263
297 if (mirror) 264 int imageX, imageY = 0;
298 if (sculptType == SculptType.plane) 265
299 invert = !invert; 266 int rowNdx, colNdx;
267
268 for (rowNdx = 0; rowNdx <= numRows; rowNdx++)
269 {
270 List<Coord> row = new List<Coord>(numCols);
271 imageY = rowNdx * scale;
272 if (rowNdx == numRows) imageY--;
273 for (colNdx = 0; colNdx <= numCols; colNdx++)
274 {
275 imageX = colNdx * scale;
276 if (colNdx == numCols) imageX--;
300 277
301 float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); 278 Color c = bitmap.GetPixel(imageX, imageY);
279 if (c.A != 255)
280 {
281 bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
282 c = bitmap.GetPixel(imageX, imageY);
283 }
302 284
303 int scale = (int)(1.0f / sourceScaleFactor); 285 if (mirror)
304 if (scale < 1) scale = 1; 286 row.Add(new Coord(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f));
287 else
288 row.Add(new Coord(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f));
305 289
306 _SculptMesh(bitmap2Coords(sculptBitmap, scale, mirror), sculptType, viewerMode, mirror, invert); 290 }
291 rows.Add(row);
292 }
293 return rows;
307 } 294 }
308#endif
309 295
310 296
297 void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
298 {
299 _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert);
300 }
301#endif
302
311 void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) 303 void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
312 { 304 {
313 coords = new List<Coord>(); 305 coords = new List<Coord>();
@@ -331,8 +323,18 @@ namespace PrimMesher
331 323
332 if (sculptType != SculptType.plane) 324 if (sculptType != SculptType.plane)
333 { 325 {
334 for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++) 326 if (rows.Count % 2 == 0)
335 rows[rowNdx].Add(rows[rowNdx][0]); 327 {
328 for (int rowNdx = 0; rowNdx < rows.Count; rowNdx++)
329 rows[rowNdx].Add(rows[rowNdx][0]);
330 }
331 else
332 {
333 int lastIndex = rows[0].Count - 1;
334
335 for (int i = 0; i < rows.Count; i++)
336 rows[i][0] = rows[i][lastIndex];
337 }
336 } 338 }
337 339
338 Coord topPole = rows[0][width / 2]; 340 Coord topPole = rows[0][width / 2];
@@ -340,23 +342,41 @@ namespace PrimMesher
340 342
341 if (sculptType == SculptType.sphere) 343 if (sculptType == SculptType.sphere)
342 { 344 {
343 int count = rows[0].Count; 345 if (rows.Count % 2 == 0)
344 List<Coord> topPoleRow = new List<Coord>(count); 346 {
345 List<Coord> bottomPoleRow = new List<Coord>(count); 347 int count = rows[0].Count;
348 List<Coord> topPoleRow = new List<Coord>(count);
349 List<Coord> bottomPoleRow = new List<Coord>(count);
346 350
347 for (int i = 0; i < count; i++) 351 for (int i = 0; i < count; i++)
352 {
353 topPoleRow.Add(topPole);
354 bottomPoleRow.Add(bottomPole);
355 }
356 rows.Insert(0, topPoleRow);
357 rows.Add(bottomPoleRow);
358 }
359 else
348 { 360 {
349 topPoleRow.Add(topPole); 361 int count = rows[0].Count;
350 bottomPoleRow.Add(bottomPole); 362
363 List<Coord> topPoleRow = rows[0];
364 List<Coord> bottomPoleRow = rows[rows.Count - 1];
365
366 for (int i = 0; i < count; i++)
367 {
368 topPoleRow[i] = topPole;
369 bottomPoleRow[i] = bottomPole;
370 }
351 } 371 }
352 rows.Insert(0, topPoleRow);
353 rows.Add(bottomPoleRow);
354 } 372 }
355 else if (sculptType == SculptType.torus) 373
374 if (sculptType == SculptType.torus)
356 rows.Add(rows[0]); 375 rows.Add(rows[0]);
357 376
358 int coordsDown = rows.Count; 377 int coordsDown = rows.Count;
359 int coordsAcross = rows[0].Count; 378 int coordsAcross = rows[0].Count;
379 int lastColumn = coordsAcross - 1;
360 380
361 float widthUnit = 1.0f / (coordsAcross - 1); 381 float widthUnit = 1.0f / (coordsAcross - 1);
362 float heightUnit = 1.0f / (coordsDown - 1); 382 float heightUnit = 1.0f / (coordsDown - 1);
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 2ab00a3..be7c348 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -1575,11 +1575,11 @@ Console.WriteLine(" JointCreateFixed");
1575 { 1575 {
1576//Console.WriteLine("Move " + m_primName); 1576//Console.WriteLine("Move " + m_primName);
1577 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 1577 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
1578 /*
1579 // NON-'VEHICLES' are dealt with here 1578 // NON-'VEHICLES' are dealt with here
1580 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) 1579 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
1581 { 1580 {
1582 d.Vector3 avel2 = d.BodyGetAngularVel(Body); 1581 d.Vector3 avel2 = d.BodyGetAngularVel(Body);
1582 /*
1583 if (m_angularlock.X == 1) 1583 if (m_angularlock.X == 1)
1584 avel2.X = 0; 1584 avel2.X = 0;
1585 if (m_angularlock.Y == 1) 1585 if (m_angularlock.Y == 1)
@@ -1587,8 +1587,8 @@ Console.WriteLine(" JointCreateFixed");
1587 if (m_angularlock.Z == 1) 1587 if (m_angularlock.Z == 1)
1588 avel2.Z = 0; 1588 avel2.Z = 0;
1589 d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); 1589 d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z);
1590 */
1590 } 1591 }
1591 */
1592 //float PID_P = 900.0f; 1592 //float PID_P = 900.0f;
1593 1593
1594 float m_mass = CalculateMass(); 1594 float m_mass = CalculateMass();