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