diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 161 |
1 files changed, 153 insertions, 8 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 3fe71e1..d9b738b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -39,26 +39,171 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
39 | // unless the difference is significant. | 39 | // unless the difference is significant. |
40 | public abstract class BSPhysObject : PhysicsActor | 40 | public abstract class BSPhysObject : PhysicsActor |
41 | { | 41 | { |
42 | public abstract BSLinkset Linkset { get; set; } | 42 | protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName) |
43 | { | ||
44 | PhysicsScene = parentScene; | ||
45 | LocalID = localID; | ||
46 | PhysObjectName = name; | ||
47 | TypeName = typeName; | ||
43 | 48 | ||
44 | public abstract bool Collide(uint collidingWith, BSPhysObject collidee, | 49 | Linkset = new BSLinkset(PhysicsScene, this); |
45 | OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); | ||
46 | public abstract void SendCollisions(); | ||
47 | 50 | ||
48 | // Return the object mass without calculating it or side effects | 51 | CollisionCollection = new CollisionEventUpdate(); |
52 | SubscribedEventsMs = 0; | ||
53 | CollidingStep = 0; | ||
54 | CollidingGroundStep = 0; | ||
55 | } | ||
56 | |||
57 | public BSScene PhysicsScene { get; protected set; } | ||
58 | // public override uint LocalID { get; set; } // Use the LocalID definition in PhysicsActor | ||
59 | public string PhysObjectName { get; protected set; } | ||
60 | public string TypeName { get; protected set; } | ||
61 | |||
62 | public BSLinkset Linkset { get; set; } | ||
63 | |||
64 | // Return the object mass without calculating it or having side effects | ||
49 | public abstract float MassRaw { get; } | 65 | public abstract float MassRaw { get; } |
50 | 66 | ||
51 | // Reference to the physical body (btCollisionObject) of this object | 67 | // Reference to the physical body (btCollisionObject) of this object |
52 | public abstract BulletBody BSBody { get; set; } | 68 | public BulletBody BSBody; |
53 | // Reference to the physical shape (btCollisionShape) of this object | 69 | // Reference to the physical shape (btCollisionShape) of this object |
54 | public abstract BulletShape BSShape { get; set; } | 70 | public BulletShape BSShape; |
55 | 71 | ||
72 | // Stop all physical motion. | ||
56 | public abstract void ZeroMotion(); | 73 | public abstract void ZeroMotion(); |
57 | 74 | ||
75 | // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured. | ||
58 | public virtual void StepVehicle(float timeStep) { } | 76 | public virtual void StepVehicle(float timeStep) { } |
59 | 77 | ||
78 | // Update the physical location and motion of the object. Called with data from Bullet. | ||
60 | public abstract void UpdateProperties(EntityProperties entprop); | 79 | public abstract void UpdateProperties(EntityProperties entprop); |
61 | 80 | ||
81 | // Tell the object to clean up. | ||
62 | public abstract void Destroy(); | 82 | public abstract void Destroy(); |
83 | |||
84 | #region Collisions | ||
85 | |||
86 | // Requested number of milliseconds between collision events. Zero means disabled. | ||
87 | protected int SubscribedEventsMs { get; set; } | ||
88 | // Given subscription, the time that a collision may be passed up | ||
89 | protected int NextCollisionOkTime { get; set; } | ||
90 | // The simulation step that last had a collision | ||
91 | protected long CollidingStep { get; set; } | ||
92 | // The simulation step that last had a collision with the ground | ||
93 | protected long CollidingGroundStep { get; set; } | ||
94 | // The collision flags we think are set in Bullet | ||
95 | protected CollisionFlags CurrentCollisionFlags { get; set; } | ||
96 | |||
97 | // The collisions that have been collected this tick | ||
98 | protected CollisionEventUpdate CollisionCollection; | ||
99 | |||
100 | // The simulation step is telling this object about a collision. | ||
101 | // Return 'true' if a collision was processed and should be sent up. | ||
102 | // Called at taint time from within the Step() function | ||
103 | public virtual bool Collide(uint collidingWith, BSPhysObject collidee, | ||
104 | OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) | ||
105 | { | ||
106 | bool ret = false; | ||
107 | |||
108 | // The following lines make IsColliding() and IsCollidingGround() work | ||
109 | CollidingStep = PhysicsScene.SimulationStep; | ||
110 | if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID) | ||
111 | { | ||
112 | CollidingGroundStep = PhysicsScene.SimulationStep; | ||
113 | } | ||
114 | |||
115 | // prims in the same linkset cannot collide with each other | ||
116 | if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID)) | ||
117 | { | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | // if someone has subscribed for collision events.... | ||
122 | if (SubscribedEvents()) { | ||
123 | CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); | ||
124 | // DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", | ||
125 | // LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); | ||
126 | |||
127 | ret = true; | ||
128 | } | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | // Routine to send the collected collisions into the simulator. | ||
133 | // Also handles removal of this from the collection of objects with collisions if | ||
134 | // there are no collisions from this object. Mechanism is create one last | ||
135 | // collision event to make collision_end work. | ||
136 | // Called at taint time from within the Step() function thus no locking problems | ||
137 | // with CollisionCollection and ObjectsWithNoMoreCollisions. | ||
138 | // Return 'true' if there were some actual collisions passed up | ||
139 | public virtual bool SendCollisions() | ||
140 | { | ||
141 | bool ret = true; | ||
142 | |||
143 | // throttle the collisions to the number of milliseconds specified in the subscription | ||
144 | int nowTime = PhysicsScene.SimulationNowTime; | ||
145 | if (nowTime >= NextCollisionOkTime) | ||
146 | { | ||
147 | NextCollisionOkTime = nowTime + SubscribedEventsMs; | ||
148 | |||
149 | // We are called if we previously had collisions. If there are no collisions | ||
150 | // this time, send up one last empty event so OpenSim can sense collision end. | ||
151 | if (CollisionCollection.Count == 0) | ||
152 | { | ||
153 | // If I have no collisions this time, remove me from the list of objects with collisions. | ||
154 | ret = false; | ||
155 | } | ||
156 | |||
157 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); | ||
158 | base.SendCollisionUpdate(CollisionCollection); | ||
159 | |||
160 | // The collisionCollection structure is passed around in the simulator. | ||
161 | // Make sure we don't have a handle to that one and that a new one is used for next time. | ||
162 | CollisionCollection = new CollisionEventUpdate(); | ||
163 | } | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | // Subscribe for collision events. | ||
168 | // Parameter is the millisecond rate the caller wishes collision events to occur. | ||
169 | public override void SubscribeEvents(int ms) { | ||
170 | // DetailLog("{0},{1}.SubscribeEvents,subscribing,ms={2}", LocalID, TypeName, ms); | ||
171 | SubscribedEventsMs = ms; | ||
172 | if (ms > 0) | ||
173 | { | ||
174 | // make sure first collision happens | ||
175 | NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs); | ||
176 | |||
177 | PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() | ||
178 | { | ||
179 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
180 | }); | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | // Subscribing for zero or less is the same as unsubscribing | ||
185 | UnSubscribeEvents(); | ||
186 | } | ||
187 | } | ||
188 | public override void UnSubscribeEvents() { | ||
189 | // DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName); | ||
190 | SubscribedEventsMs = 0; | ||
191 | PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() | ||
192 | { | ||
193 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
194 | }); | ||
195 | } | ||
196 | // Return 'true' if the simulator wants collision events | ||
197 | public override bool SubscribedEvents() { | ||
198 | return (SubscribedEventsMs > 0); | ||
199 | } | ||
200 | |||
201 | #endregion // Collisions | ||
202 | |||
203 | // High performance detailed logging routine used by the physical objects. | ||
204 | protected void DetailLog(string msg, params Object[] args) | ||
205 | { | ||
206 | PhysicsScene.PhysicsLogging.Write(msg, args); | ||
207 | } | ||
63 | } | 208 | } |
64 | } | 209 | } |