aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs457
1 files changed, 457 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
new file mode 100644
index 0000000..2780188
--- /dev/null
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -0,0 +1,457 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 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 OpenSim 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*/
28using System;
29using System.Collections.Generic;
30using Axiom.Math;
31using Ode.NET;
32using OpenSim.Physics.Manager;
33
34namespace OpenSim.Region.Physics.OdePlugin
35{
36 /// <summary>
37 /// ODE plugin
38 /// </summary>
39 public class OdePlugin : IPhysicsPlugin
40 {
41 private OdeScene _mScene;
42
43 public OdePlugin()
44 {
45
46 }
47
48 public bool Init()
49 {
50 return true;
51 }
52
53 public PhysicsScene GetScene()
54 {
55 if (_mScene == null)
56 {
57 _mScene = new OdeScene();
58 }
59 return (_mScene);
60 }
61
62 public string GetName()
63 {
64 return ("OpenDynamicsEngine");
65 }
66
67 public void Dispose()
68 {
69
70 }
71 }
72
73 public class OdeScene : PhysicsScene
74 {
75 static public IntPtr world;
76 static public IntPtr space;
77 static private IntPtr contactgroup;
78 static private IntPtr LandGeom;
79 //static private IntPtr Land;
80 private double[] _heightmap;
81 static private d.NearCallback nearCallback = near;
82 private List<OdeCharacter> _characters = new List<OdeCharacter>();
83 private static d.ContactGeom[] contacts = new d.ContactGeom[30];
84 private static d.Contact contact;
85
86 public OdeScene()
87 {
88 contact.surface.mode = d.ContactFlags.Bounce | d.ContactFlags.SoftCFM;
89 contact.surface.mu = d.Infinity;
90 contact.surface.mu2 = 0.0f;
91 contact.surface.bounce = 0.1f;
92 contact.surface.bounce_vel = 0.1f;
93 contact.surface.soft_cfm = 0.01f;
94
95 world = d.WorldCreate();
96 space = d.HashSpaceCreate(IntPtr.Zero);
97 contactgroup = d.JointGroupCreate(0);
98 d.WorldSetGravity(world, 0.0f, 0.0f, -0.5f);
99 //d.WorldSetCFM(world, 1e-5f);
100 d.WorldSetAutoDisableFlag(world, false);
101 d.WorldSetContactSurfaceLayer(world, 0.001f);
102 // d.CreatePlane(space, 0, 0, 1, 0);
103 this._heightmap = new double[65536];
104 }
105
106 // This function blatantly ripped off from BoxStack.cs
107 static private void near(IntPtr space, IntPtr g1, IntPtr g2)
108 {
109 IntPtr b1 = d.GeomGetBody(g1);
110 IntPtr b2 = d.GeomGetBody(g2);
111 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
112 return;
113
114 int count = d.Collide(g1, g2, 500, contacts, d.ContactGeom.SizeOf);
115 for (int i = 0; i < count; ++i)
116 {
117 contact.geom = contacts[i];
118 IntPtr joint = d.JointCreateContact(world, contactgroup, ref contact);
119 d.JointAttach(joint, b1, b2);
120 }
121
122 }
123
124 public override PhysicsActor AddAvatar(PhysicsVector position)
125 {
126 PhysicsVector pos = new PhysicsVector();
127 pos.X = position.X;
128 pos.Y = position.Y;
129 pos.Z = position.Z + 20;
130 OdeCharacter newAv = new OdeCharacter(this, pos);
131 this._characters.Add(newAv);
132 return newAv;
133 }
134
135 public override void RemoveAvatar(PhysicsActor actor)
136 {
137
138 }
139
140 public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size)
141 {
142 PhysicsVector pos = new PhysicsVector();
143 pos.X = position.X;
144 pos.Y = position.Y;
145 pos.Z = position.Z;
146 PhysicsVector siz = new PhysicsVector();
147 siz.X = size.X;
148 siz.Y = size.Y;
149 siz.Z = size.Z;
150 return new OdePrim();
151 }
152
153 public override void Simulate(float timeStep)
154 {
155 foreach (OdeCharacter actor in _characters)
156 {
157 actor.Move(timeStep * 5f);
158 }
159 d.SpaceCollide(space, IntPtr.Zero, nearCallback);
160 d.WorldQuickStep(world, timeStep * 5f);
161 d.JointGroupEmpty(contactgroup);
162 foreach (OdeCharacter actor in _characters)
163 {
164 actor.UpdatePosition();
165 }
166
167 }
168
169 public override void GetResults()
170 {
171
172 }
173
174 public override bool IsThreaded
175 {
176 get
177 {
178 return (false); // for now we won't be multithreaded
179 }
180 }
181
182 public override void SetTerrain(float[] heightMap)
183 {
184 for (int i = 0; i < 65536; i++)
185 {
186 // this._heightmap[i] = (double)heightMap[i];
187 // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
188 int x = i & 0xff;
189 int y = i >> 8;
190 this._heightmap[i] = (double)heightMap[x * 256 + y];
191 }
192 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
193 d.GeomHeightfieldDataBuildDouble(HeightmapData, _heightmap, 0, 256, 256, 256, 256, 1.0f, 0.0f, 2.0f, 0);
194 d.GeomHeightfieldDataSetBounds(HeightmapData, 256, 256);
195 LandGeom = d.CreateHeightfield(space, HeightmapData, 1);
196 d.Matrix3 R = new d.Matrix3();
197
198 Quaternion q1 =Quaternion.FromAngleAxis(1.5707f, new Vector3(1,0,0));
199 Quaternion q2 =Quaternion.FromAngleAxis(1.5707f, new Vector3(0,1,0));
200 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
201
202 q1 = q1 * q2;
203 //q1 = q1 * q3;
204 Vector3 v3 = new Vector3();
205 float angle = 0;
206 q1.ToAngleAxis(ref angle, ref v3);
207
208 d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle);
209 d.GeomSetRotation(LandGeom, ref R);
210 d.GeomSetPosition(LandGeom, 128, 128, 0);
211 }
212
213 public override void DeleteTerrain()
214 {
215
216 }
217 }
218
219 public class OdeCharacter : PhysicsActor
220 {
221 private PhysicsVector _position;
222 private PhysicsVector _velocity;
223 private PhysicsVector _acceleration;
224 private bool flying;
225 //private float gravityAccel;
226 private IntPtr BoundingCapsule;
227 IntPtr capsule_geom;
228 d.Mass capsule_mass;
229
230 public OdeCharacter(OdeScene parent_scene, PhysicsVector pos)
231 {
232 _velocity = new PhysicsVector();
233 _position = pos;
234 _acceleration = new PhysicsVector();
235 d.MassSetCapsule(out capsule_mass, 5.0f, 3, 0.5f, 2f);
236 capsule_geom = d.CreateCapsule(OdeScene.space, 0.5f, 2f);
237 this.BoundingCapsule = d.BodyCreate(OdeScene.world);
238 d.BodySetMass(BoundingCapsule, ref capsule_mass);
239 d.BodySetPosition(BoundingCapsule, pos.X, pos.Y, pos.Z);
240 d.GeomSetBody(capsule_geom, BoundingCapsule);
241 }
242
243 public override bool Flying
244 {
245 get
246 {
247 return flying;
248 }
249 set
250 {
251 flying = value;
252 }
253 }
254
255 public override PhysicsVector Position
256 {
257 get
258 {
259 return _position;
260 }
261 set
262 {
263 _position = value;
264 }
265 }
266
267 public override PhysicsVector Velocity
268 {
269 get
270 {
271 return _velocity;
272 }
273 set
274 {
275 _velocity = value;
276 }
277 }
278
279 public override bool Kinematic
280 {
281 get
282 {
283 return false;
284 }
285 set
286 {
287
288 }
289 }
290
291 public override Quaternion Orientation
292 {
293 get
294 {
295 return Quaternion.Identity;
296 }
297 set
298 {
299
300 }
301 }
302
303 public override PhysicsVector Acceleration
304 {
305 get
306 {
307 return _acceleration;
308 }
309
310 }
311 public void SetAcceleration(PhysicsVector accel)
312 {
313 this._acceleration = accel;
314 }
315
316 public override void AddForce(PhysicsVector force)
317 {
318
319 }
320
321 public override void SetMomentum(PhysicsVector momentum)
322 {
323
324 }
325
326 public void Move(float timeStep)
327 {
328 PhysicsVector vec = new PhysicsVector();
329 vec.X = this._velocity.X * timeStep;
330 vec.Y = this._velocity.Y * timeStep;
331 if (flying)
332 {
333 vec.Z = (this._velocity.Z + 0.5f) * timeStep;
334 }
335 d.BodySetLinearVel(this.BoundingCapsule, vec.X, vec.Y, vec.Z);
336 }
337
338 public void UpdatePosition()
339 {
340 d.Vector3 vec = d.BodyGetPosition(BoundingCapsule);
341 this._position.X = vec.X;
342 this._position.Y = vec.Y;
343 this._position.Z = vec.Z+1.0f;
344 }
345 }
346
347 public class OdePrim : PhysicsActor
348 {
349 private PhysicsVector _position;
350 private PhysicsVector _velocity;
351 private PhysicsVector _acceleration;
352
353 public OdePrim()
354 {
355 _velocity = new PhysicsVector();
356 _position = new PhysicsVector();
357 _acceleration = new PhysicsVector();
358 }
359 public override bool Flying
360 {
361 get
362 {
363 return false; //no flying prims for you
364 }
365 set
366 {
367
368 }
369 }
370 public override PhysicsVector Position
371 {
372 get
373 {
374 PhysicsVector pos = new PhysicsVector();
375 // PhysicsVector vec = this._prim.Position;
376 //pos.X = vec.X;
377 //pos.Y = vec.Y;
378 //pos.Z = vec.Z;
379 return pos;
380
381 }
382 set
383 {
384 /*PhysicsVector vec = value;
385 PhysicsVector pos = new PhysicsVector();
386 pos.X = vec.X;
387 pos.Y = vec.Y;
388 pos.Z = vec.Z;
389 this._prim.Position = pos;*/
390 }
391 }
392
393 public override PhysicsVector Velocity
394 {
395 get
396 {
397 return _velocity;
398 }
399 set
400 {
401 _velocity = value;
402 }
403 }
404
405 public override bool Kinematic
406 {
407 get
408 {
409 return false;
410 //return this._prim.Kinematic;
411 }
412 set
413 {
414 //this._prim.Kinematic = value;
415 }
416 }
417
418 public override Quaternion Orientation
419 {
420 get
421 {
422 Quaternion res = new Quaternion();
423 return res;
424 }
425 set
426 {
427
428 }
429 }
430
431 public override PhysicsVector Acceleration
432 {
433 get
434 {
435 return _acceleration;
436 }
437
438 }
439 public void SetAcceleration(PhysicsVector accel)
440 {
441 this._acceleration = accel;
442 }
443
444 public override void AddForce(PhysicsVector force)
445 {
446
447 }
448
449 public override void SetMomentum(PhysicsVector momentum)
450 {
451
452 }
453
454
455 }
456
457}