diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs new file mode 100755 index 0000000..d9b738b --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
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 copyrightD | ||
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 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Text; | ||
30 | |||
31 | using OMV = OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Physics.Manager; | ||
34 | |||
35 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
36 | { | ||
37 | // Class to wrap all objects. | ||
38 | // The rest of BulletSim doesn't need to keep checking for avatars or prims | ||
39 | // unless the difference is significant. | ||
40 | public abstract class BSPhysObject : PhysicsActor | ||
41 | { | ||
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; | ||
48 | |||
49 | Linkset = new BSLinkset(PhysicsScene, this); | ||
50 | |||
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 | ||
65 | public abstract float MassRaw { get; } | ||
66 | |||
67 | // Reference to the physical body (btCollisionObject) of this object | ||
68 | public BulletBody BSBody; | ||
69 | // Reference to the physical shape (btCollisionShape) of this object | ||
70 | public BulletShape BSShape; | ||
71 | |||
72 | // Stop all physical motion. | ||
73 | public abstract void ZeroMotion(); | ||
74 | |||
75 | // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured. | ||
76 | public virtual void StepVehicle(float timeStep) { } | ||
77 | |||
78 | // Update the physical location and motion of the object. Called with data from Bullet. | ||
79 | public abstract void UpdateProperties(EntityProperties entprop); | ||
80 | |||
81 | // Tell the object to clean up. | ||
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 | } | ||
208 | } | ||
209 | } | ||