aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs434
1 files changed, 434 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
new file mode 100644
index 0000000..9f9ebcc
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -0,0 +1,434 @@
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 */
27using System;
28using System.Collections.Generic;
29using System.Reflection;
30using log4net;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37public class BSCharacter : PhysicsActor
38{
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]";
41
42 private BSScene _scene;
43 private String _avName;
44 private bool _stopped;
45 private Vector3 _size;
46 private Vector3 _scale;
47 private PrimitiveBaseShape _pbs;
48 private uint _localID = 0;
49 private bool _grabbed;
50 private bool _selected;
51 private Vector3 _position;
52 private float _mass = 80f;
53 public float _density = 60f;
54 private Vector3 _force;
55 private Vector3 _velocity;
56 private Vector3 _torque;
57 private float _collisionScore;
58 private Vector3 _acceleration;
59 private Quaternion _orientation;
60 private int _physicsActorType;
61 private bool _isPhysical;
62 private bool _flying;
63 private bool _setAlwaysRun;
64 private bool _throttleUpdates;
65 private bool _isColliding;
66 private long _collidingStep;
67 private bool _collidingGround;
68 private long _collidingGroundStep;
69 private bool _collidingObj;
70 private bool _floatOnWater;
71 private Vector3 _rotationalVelocity;
72 private bool _kinematic;
73 private float _buoyancy;
74
75 private int _subscribedEventsMs = 0;
76 private int _lastCollisionTime = 0;
77
78 private Vector3 _PIDTarget;
79 private bool _usePID;
80 private float _PIDTau;
81 private bool _useHoverPID;
82 private float _PIDHoverHeight;
83 private PIDHoverType _PIDHoverType;
84 private float _PIDHoverTao;
85
86 public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying)
87 {
88 _localID = localID;
89 _avName = avName;
90 _scene = parent_scene;
91 _position = pos;
92 _size = size;
93 _orientation = Quaternion.Identity;
94 _velocity = Vector3.Zero;
95 _buoyancy = 0f; // characters return a buoyancy of zero
96 _scale = new Vector3(1f, 1f, 1f);
97 float AVvolume = (float) (Math.PI*Math.Pow(_scene.Params.avatarCapsuleRadius, 2)*_scene.Params.avatarCapsuleHeight);
98 _density = _scene.Params.avatarDensity;
99 _mass = _density*AVvolume;
100
101 ShapeData shapeData = new ShapeData();
102 shapeData.ID = _localID;
103 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
104 shapeData.Position = _position;
105 shapeData.Rotation = _orientation;
106 shapeData.Velocity = _velocity;
107 shapeData.Scale = _scale;
108 shapeData.Mass = _mass;
109 shapeData.Buoyancy = isFlying ? 1f : 0f;
110 shapeData.Static = ShapeData.numericFalse;
111 shapeData.Friction = _scene.Params.avatarFriction;
112 shapeData.Restitution = _scene.Params.defaultRestitution;
113
114 // do actual create at taint time
115 _scene.TaintedObject(delegate()
116 {
117 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
118 });
119
120 return;
121 }
122
123 // called when this character is being destroyed and the resources should be released
124 public void Destroy()
125 {
126 _scene.TaintedObject(delegate()
127 {
128 BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
129 });
130 }
131
132 public override void RequestPhysicsterseUpdate()
133 {
134 base.RequestPhysicsterseUpdate();
135 }
136
137 public override bool Stopped {
138 get { return _stopped; }
139 }
140 public override Vector3 Size {
141 get { return _size; }
142 set { _size = value;
143 }
144 }
145 public override PrimitiveBaseShape Shape {
146 set { _pbs = value;
147 }
148 }
149 public override uint LocalID {
150 set { _localID = value;
151 }
152 get { return _localID; }
153 }
154 public override bool Grabbed {
155 set { _grabbed = value;
156 }
157 }
158 public override bool Selected {
159 set { _selected = value;
160 }
161 }
162 public override void CrossingFailure() { return; }
163 public override void link(PhysicsActor obj) { return; }
164 public override void delink() { return; }
165 public override void LockAngularMotion(Vector3 axis) { return; }
166
167 public override Vector3 Position {
168 get {
169 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
170 return _position;
171 }
172 set {
173 _position = value;
174 _scene.TaintedObject(delegate()
175 {
176 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
177 });
178 }
179 }
180 public override float Mass {
181 get {
182 return _mass;
183 }
184 }
185 public override Vector3 Force {
186 get { return _force; }
187 set {
188 _force = value;
189 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
190 _scene.TaintedObject(delegate()
191 {
192 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
193 });
194 }
195 }
196
197 public override int VehicleType {
198 get { return 0; }
199 set { return; }
200 }
201 public override void VehicleFloatParam(int param, float value) { }
202 public override void VehicleVectorParam(int param, Vector3 value) {}
203 public override void VehicleRotationParam(int param, Quaternion rotation) { }
204 public override void VehicleFlags(int param, bool remove) { }
205
206 // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
207 public override void SetVolumeDetect(int param) { return; }
208
209 public override Vector3 GeometricCenter { get { return Vector3.Zero; } }
210 public override Vector3 CenterOfMass { get { return Vector3.Zero; } }
211 public override Vector3 Velocity {
212 get { return _velocity; }
213 set {
214 _velocity = value;
215 _scene.TaintedObject(delegate()
216 {
217 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
218 });
219 }
220 }
221 public override Vector3 Torque {
222 get { return _torque; }
223 set { _torque = value;
224 }
225 }
226 public override float CollisionScore {
227 get { return _collisionScore; }
228 set { _collisionScore = value;
229 }
230 }
231 public override Vector3 Acceleration {
232 get { return _acceleration; }
233 }
234 public override Quaternion Orientation {
235 get { return _orientation; }
236 set {
237 _orientation = value;
238 _scene.TaintedObject(delegate()
239 {
240 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
241 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
242 });
243 }
244 }
245 public override int PhysicsActorType {
246 get { return _physicsActorType; }
247 set { _physicsActorType = value;
248 }
249 }
250 public override bool IsPhysical {
251 get { return _isPhysical; }
252 set { _isPhysical = value;
253 }
254 }
255 public override bool Flying {
256 get { return _flying; }
257 set {
258 _flying = value;
259 _scene.TaintedObject(delegate()
260 {
261 // simulate flying by changing the effect of gravity
262 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 1f : 0f);
263 });
264 }
265 }
266 public override bool
267 SetAlwaysRun {
268 get { return _setAlwaysRun; }
269 set { _setAlwaysRun = value; }
270 }
271 public override bool ThrottleUpdates {
272 get { return _throttleUpdates; }
273 set { _throttleUpdates = value; }
274 }
275 public override bool IsColliding {
276 get { return (_collidingStep == _scene.SimulationStep); }
277 set { _isColliding = value; }
278 }
279 public override bool CollidingGround {
280 get { return (_collidingGroundStep == _scene.SimulationStep); }
281 set { _collidingGround = value; }
282 }
283 public override bool CollidingObj {
284 get { return _collidingObj; }
285 set { _collidingObj = value; }
286 }
287 public override bool FloatOnWater {
288 set { _floatOnWater = value; }
289 }
290 public override Vector3 RotationalVelocity {
291 get { return _rotationalVelocity; }
292 set { _rotationalVelocity = value; }
293 }
294 public override bool Kinematic {
295 get { return _kinematic; }
296 set { _kinematic = value; }
297 }
298 public override float Buoyancy {
299 get { return _buoyancy; }
300 set { _buoyancy = value;
301 _scene.TaintedObject(delegate()
302 {
303 // simulate flying by changing the effect of gravity
304 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
305 });
306 }
307 }
308
309 // Used for MoveTo
310 public override Vector3 PIDTarget {
311 set { _PIDTarget = value; }
312 }
313 public override bool PIDActive {
314 set { _usePID = value; }
315 }
316 public override float PIDTau {
317 set { _PIDTau = value; }
318 }
319
320 // Used for llSetHoverHeight and maybe vehicle height
321 // Hover Height will override MoveTo target's Z
322 public override bool PIDHoverActive {
323 set { _useHoverPID = value; }
324 }
325 public override float PIDHoverHeight {
326 set { _PIDHoverHeight = value; }
327 }
328 public override PIDHoverType PIDHoverType {
329 set { _PIDHoverType = value; }
330 }
331 public override float PIDHoverTau {
332 set { _PIDHoverTao = value; }
333 }
334
335 // For RotLookAt
336 public override Quaternion APIDTarget { set { return; } }
337 public override bool APIDActive { set { return; } }
338 public override float APIDStrength { set { return; } }
339 public override float APIDDamping { set { return; } }
340
341 public override void AddForce(Vector3 force, bool pushforce) {
342 if (force.IsFinite())
343 {
344 _force.X += force.X;
345 _force.Y += force.Y;
346 _force.Z += force.Z;
347 _scene.TaintedObject(delegate()
348 {
349 BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
350 });
351 }
352 else
353 {
354 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
355 }
356 //m_lastUpdateSent = false;
357 }
358 public override void AddAngularForce(Vector3 force, bool pushforce) {
359 }
360 public override void SetMomentum(Vector3 momentum) {
361 }
362 public override void SubscribeEvents(int ms) {
363 _subscribedEventsMs = ms;
364 _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
365 }
366 public override void UnSubscribeEvents() {
367 _subscribedEventsMs = 0;
368 }
369 public override bool SubscribedEvents() {
370 return (_subscribedEventsMs > 0);
371 }
372
373 // The physics engine says that properties have updated. Update same and inform
374 // the world that things have changed.
375 public void UpdateProperties(EntityProperties entprop)
376 {
377 bool changed = false;
378 // we assign to the local variables so the normal set action does not happen
379 if (_position != entprop.Position)
380 {
381 _position = entprop.Position;
382 changed = true;
383 }
384 if (_orientation != entprop.Rotation)
385 {
386 _orientation = entprop.Rotation;
387 changed = true;
388 }
389 if (_velocity != entprop.Velocity)
390 {
391 _velocity = entprop.Velocity;
392 changed = true;
393 }
394 if (_acceleration != entprop.Acceleration)
395 {
396 _acceleration = entprop.Acceleration;
397 changed = true;
398 }
399 if (_rotationalVelocity != entprop.RotationalVelocity)
400 {
401 _rotationalVelocity = entprop.RotationalVelocity;
402 changed = true;
403 }
404 if (changed)
405 {
406 // base.RequestPhysicsterseUpdate();
407 }
408 }
409
410 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
411 {
412 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
413
414 // The following makes IsColliding() and IsCollidingGround() work
415 _collidingStep = _scene.SimulationStep;
416 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
417 {
418 _collidingGroundStep = _scene.SimulationStep;
419 }
420
421 // throttle collisions to the rate specified in the subscription
422 if (_subscribedEventsMs == 0) return; // don't want collisions
423 int nowTime = _scene.SimulationNowTime;
424 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
425 _lastCollisionTime = nowTime;
426
427 Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>();
428 contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
429 CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints);
430 base.SendCollisionUpdate(args);
431 }
432
433}
434}