aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/POSPlugin/POSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSScene.cs298
1 files changed, 298 insertions, 0 deletions
diff --git a/OpenSim/Region/Physics/POSPlugin/POSScene.cs b/OpenSim/Region/Physics/POSPlugin/POSScene.cs
new file mode 100644
index 0000000..e9ecaa5
--- /dev/null
+++ b/OpenSim/Region/Physics/POSPlugin/POSScene.cs
@@ -0,0 +1,298 @@
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 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 Nini.Config;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.POSPlugin
36{
37 public class POSScene : PhysicsScene
38 {
39 private List<POSCharacter> _characters = new List<POSCharacter>();
40 private List<POSPrim> _prims = new List<POSPrim>();
41 private float[] _heightMap;
42 private const float gravity = -9.8f;
43
44 public POSScene()
45 {
46 }
47
48 public override void Initialise(IMesher meshmerizer, IConfigSource config)
49 {
50 }
51
52 public override void Dispose()
53 {
54 }
55
56 public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
57 {
58 POSCharacter act = new POSCharacter();
59 act.Position = position;
60 _characters.Add(act);
61 return act;
62 }
63
64 public override void SetWaterLevel(float baseheight)
65 {
66 }
67
68 public override void RemovePrim(PhysicsActor prim)
69 {
70 POSPrim p = (POSPrim) prim;
71 if (_prims.Contains(p))
72 {
73 _prims.Remove(p);
74 }
75 }
76
77 public override void RemoveAvatar(PhysicsActor character)
78 {
79 POSCharacter act = (POSCharacter) character;
80 if (_characters.Contains(act))
81 {
82 _characters.Remove(act);
83 }
84 }
85
86/*
87 public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
88 {
89 return null;
90 }
91*/
92
93 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
94 PhysicsVector size, Quaternion rotation)
95 {
96 return AddPrimShape(primName, pbs, position, size, rotation, false);
97 }
98
99 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
100 PhysicsVector size, Quaternion rotation, bool isPhysical)
101 {
102 POSPrim prim = new POSPrim();
103 prim.Position = position;
104 prim.Orientation = rotation;
105 prim.Size = size;
106 _prims.Add(prim);
107 return prim;
108 }
109
110 private bool check_collision(POSCharacter c, POSPrim p)
111 {
112 /*
113 Console.WriteLine("checking whether " + c + " collides with " + p +
114 " absX: " + Math.Abs(p.Position.X - c.Position.X) +
115 " sizeX: " + p.Size.X * 0.5 + 0.5);
116 */
117
118 Vector3 rotatedPos = p.Orientation.Inverse() *
119 new Vector3(c.Position.X - p.Position.X, c.Position.Y - p.Position.Y,
120 c.Position.Z - p.Position.Z);
121 Vector3 avatarSize = p.Orientation.Inverse()*new Vector3(c.Size.X, c.Size.Y, c.Size.Z);
122
123 if (Math.Abs(rotatedPos.x) >= (p.Size.X*0.5 + Math.Abs(avatarSize.x)) ||
124 Math.Abs(rotatedPos.y) >= (p.Size.Y*0.5 + Math.Abs(avatarSize.y)) ||
125 Math.Abs(rotatedPos.z) >= (p.Size.Z*0.5 + Math.Abs(avatarSize.z)))
126 {
127 return false;
128 }
129 return true;
130 }
131
132 private bool check_all_prims(POSCharacter c)
133 {
134 for (int i = 0; i < _prims.Count; ++i)
135 {
136 if (check_collision(c, _prims[i]))
137 {
138 return true;
139 }
140 }
141
142 return false;
143 }
144
145 public override void AddPhysicsActorTaint(PhysicsActor prim)
146 {
147 }
148
149 public override float Simulate(float timeStep)
150 {
151 float fps = 0;
152 for (int i = 0; i < _characters.Count; ++i)
153 {
154 fps++;
155 POSCharacter character = _characters[i];
156
157 float oldposX = character.Position.X;
158 float oldposY = character.Position.Y;
159 float oldposZ = character.Position.Z;
160
161 if (!character.Flying)
162 {
163 character._target_velocity.Z += gravity*timeStep;
164 }
165
166 bool forcedZ = false;
167 character.Position.X += character._target_velocity.X*timeStep;
168 character.Position.Y += character._target_velocity.Y*timeStep;
169
170 if (character.Position.Y < 0)
171 {
172 character.Position.Y = 0.1F;
173 }
174 else if (character.Position.Y >= Constants.RegionSize)
175 {
176 character.Position.Y = Constants.RegionSize - 0.1f;
177 }
178
179 if (character.Position.X < 0)
180 {
181 character.Position.X = 0.1F;
182 }
183 else if (character.Position.X >= Constants.RegionSize)
184 {
185 character.Position.X = Constants.RegionSize - 0.1f;
186 }
187
188 float terrainheight = _heightMap[(int)character.Position.Y * Constants.RegionSize + (int)character.Position.X];
189 if (character.Position.Z + (character._target_velocity.Z*timeStep) < terrainheight + 2)
190 {
191 character.Position.Z = terrainheight + 1.0f;
192 forcedZ = true;
193 }
194 else
195 {
196 character.Position.Z += character._target_velocity.Z*timeStep;
197 }
198
199 /// this is it -- the magic you've all been waiting for! Ladies and gentlemen --
200 /// Completely Bogus Collision Detection!!!
201 /// better known as the CBCD algorithm
202
203 if (check_all_prims(character))
204 {
205 character.Position.Z = oldposZ; // first try Z axis
206 if (check_all_prims(character))
207 {
208 character.Position.Z = oldposZ + 0.4f; // try harder
209 if (check_all_prims(character))
210 {
211 character.Position.X = oldposX;
212 character.Position.Y = oldposY;
213 character.Position.Z = oldposZ;
214 character.Position.X += character._target_velocity.X * timeStep;
215 if (check_all_prims(character))
216 {
217 character.Position.X = oldposX;
218 }
219 character.Position.Y += character._target_velocity.Y * timeStep;
220 if (check_all_prims(character))
221 {
222 character.Position.Y = oldposY;
223 }
224 }
225 else
226 {
227 forcedZ = true;
228 }
229 }
230 else
231 {
232 forcedZ = true;
233 }
234 }
235
236 if (character.Position.Y < 0)
237 {
238 character.Position.Y = 0.1F;
239 }
240 else if (character.Position.Y >= Constants.RegionSize)
241 {
242 character.Position.Y = Constants.RegionSize - 0.1f;
243 }
244
245 if (character.Position.X < 0)
246 {
247 character.Position.X = 0.1F;
248 }
249 else if (character.Position.X >= Constants.RegionSize)
250 {
251 character.Position.X = Constants.RegionSize - 0.1f;
252 }
253
254 character._velocity.X = (character.Position.X - oldposX)/timeStep;
255 character._velocity.Y = (character.Position.Y - oldposY)/timeStep;
256
257 if (forcedZ)
258 {
259 character._velocity.Z = 0;
260 character._target_velocity.Z = 0;
261 ((PhysicsActor)character).IsColliding = true;
262 character.RequestPhysicsterseUpdate();
263 }
264 else
265 {
266 ((PhysicsActor)character).IsColliding = false;
267 character._velocity.Z = (character.Position.Z - oldposZ)/timeStep;
268 }
269 }
270 return fps;
271 }
272
273 public override void GetResults()
274 {
275 }
276
277 public override bool IsThreaded
278 {
279 // for now we won't be multithreaded
280 get { return (false); }
281 }
282
283 public override void SetTerrain(float[] heightMap)
284 {
285 _heightMap = heightMap;
286 }
287
288 public override void DeleteTerrain()
289 {
290 }
291
292 public override Dictionary<uint, float> GetTopColliders()
293 {
294 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
295 return returncolliders;
296 }
297 }
298}