aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/POS/POSScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/PhysicsModules/POS/POSScene.cs')
-rw-r--r--OpenSim/Region/PhysicsModules/POS/POSScene.cs273
1 files changed, 273 insertions, 0 deletions
diff --git a/OpenSim/Region/PhysicsModules/POS/POSScene.cs b/OpenSim/Region/PhysicsModules/POS/POSScene.cs
new file mode 100644
index 0000000..080c6ab
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/POS/POSScene.cs
@@ -0,0 +1,273 @@
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 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
28using System;
29using System.Collections.Generic;
30using Nini.Config;
31using OpenMetaverse;
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 //protected internal string sceneIdentifier;
45
46 public POSScene(string engineType, String _sceneIdentifier)
47 {
48 EngineType = engineType;
49 Name = EngineType + "/" + _sceneIdentifier;
50 //sceneIdentifier = _sceneIdentifier;
51 }
52
53 public override void Initialise(IMesher meshmerizer, IConfigSource config)
54 {
55 }
56
57 public override void Dispose()
58 {
59 }
60
61 public override PhysicsActor AddAvatar(
62 string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying)
63 {
64 POSCharacter act = new POSCharacter();
65 act.Position = position;
66 act.Flying = isFlying;
67 _characters.Add(act);
68 return act;
69 }
70
71 public override void RemovePrim(PhysicsActor prim)
72 {
73 POSPrim p = (POSPrim) prim;
74 if (_prims.Contains(p))
75 {
76 _prims.Remove(p);
77 }
78 }
79
80 public override void RemoveAvatar(PhysicsActor character)
81 {
82 POSCharacter act = (POSCharacter) character;
83 if (_characters.Contains(act))
84 {
85 _characters.Remove(act);
86 }
87 }
88
89/*
90 public override PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation)
91 {
92 return null;
93 }
94*/
95
96 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
97 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
98 {
99 POSPrim prim = new POSPrim();
100 prim.Position = position;
101 prim.Orientation = rotation;
102 prim.Size = size;
103 _prims.Add(prim);
104 return prim;
105 }
106
107 private bool isColliding(POSCharacter c, POSPrim p)
108 {
109 Vector3 rotatedPos = new Vector3(c.Position.X - p.Position.X, c.Position.Y - p.Position.Y,
110 c.Position.Z - p.Position.Z) * Quaternion.Inverse(p.Orientation);
111 Vector3 avatarSize = new Vector3(c.Size.X, c.Size.Y, c.Size.Z) * Quaternion.Inverse(p.Orientation);
112
113 return (Math.Abs(rotatedPos.X) < (p.Size.X*0.5 + Math.Abs(avatarSize.X)) &&
114 Math.Abs(rotatedPos.Y) < (p.Size.Y*0.5 + Math.Abs(avatarSize.Y)) &&
115 Math.Abs(rotatedPos.Z) < (p.Size.Z*0.5 + Math.Abs(avatarSize.Z)));
116 }
117
118 private bool isCollidingWithPrim(POSCharacter c)
119 {
120 foreach (POSPrim p in _prims)
121 {
122 if (isColliding(c, p))
123 {
124 return true;
125 }
126 }
127
128 return false;
129 }
130
131 public override void AddPhysicsActorTaint(PhysicsActor prim)
132 {
133 }
134
135 public override float Simulate(float timeStep)
136 {
137 float fps = 0;
138 for (int i = 0; i < _characters.Count; ++i)
139 {
140 fps++;
141 POSCharacter character = _characters[i];
142
143 float oldposX = character.Position.X;
144 float oldposY = character.Position.Y;
145 float oldposZ = character.Position.Z;
146
147 if (!character.Flying)
148 {
149 character._target_velocity.Z += gravity * timeStep;
150 }
151
152 Vector3 characterPosition = character.Position;
153
154 characterPosition.X += character._target_velocity.X * timeStep;
155 characterPosition.Y += character._target_velocity.Y * timeStep;
156
157 characterPosition.X = Util.Clamp(character.Position.X, 0.01f, Constants.RegionSize - 0.01f);
158 characterPosition.Y = Util.Clamp(character.Position.Y, 0.01f, Constants.RegionSize - 0.01f);
159
160 bool forcedZ = false;
161
162 float terrainheight = _heightMap[(int)character.Position.Y * Constants.RegionSize + (int)character.Position.X];
163 if (character.Position.Z + (character._target_velocity.Z * timeStep) < terrainheight + 2)
164 {
165 characterPosition.Z = terrainheight + character.Size.Z;
166 forcedZ = true;
167 }
168 else
169 {
170 characterPosition.Z += character._target_velocity.Z*timeStep;
171 }
172
173 /// this is it -- the magic you've all been waiting for! Ladies and gentlemen --
174 /// Completely Bogus Collision Detection!!!
175 /// better known as the CBCD algorithm
176
177 if (isCollidingWithPrim(character))
178 {
179 characterPosition.Z = oldposZ; // first try Z axis
180 if (isCollidingWithPrim(character))
181 {
182 characterPosition.Z = oldposZ + character.Size.Z / 4.4f; // try harder
183 if (isCollidingWithPrim(character))
184 {
185 characterPosition.Z = oldposZ + character.Size.Z / 2.2f; // try very hard
186 if (isCollidingWithPrim(character))
187 {
188 characterPosition.X = oldposX;
189 characterPosition.Y = oldposY;
190 characterPosition.Z = oldposZ;
191
192 characterPosition.X += character._target_velocity.X * timeStep;
193 if (isCollidingWithPrim(character))
194 {
195 characterPosition.X = oldposX;
196 }
197
198 characterPosition.Y += character._target_velocity.Y * timeStep;
199 if (isCollidingWithPrim(character))
200 {
201 characterPosition.Y = oldposY;
202 }
203 }
204 else
205 {
206 forcedZ = true;
207 }
208 }
209 else
210 {
211 forcedZ = true;
212 }
213 }
214 else
215 {
216 forcedZ = true;
217 }
218 }
219
220 characterPosition.X = Util.Clamp(character.Position.X, 0.01f, Constants.RegionSize - 0.01f);
221 characterPosition.Y = Util.Clamp(character.Position.Y, 0.01f, Constants.RegionSize - 0.01f);
222
223 character.Position = characterPosition;
224
225 character._velocity.X = (character.Position.X - oldposX)/timeStep;
226 character._velocity.Y = (character.Position.Y - oldposY)/timeStep;
227
228 if (forcedZ)
229 {
230 character._velocity.Z = 0;
231 character._target_velocity.Z = 0;
232 ((PhysicsActor)character).IsColliding = true;
233 character.RequestPhysicsterseUpdate();
234 }
235 else
236 {
237 ((PhysicsActor)character).IsColliding = false;
238 character._velocity.Z = (character.Position.Z - oldposZ)/timeStep;
239 }
240 }
241 return fps;
242 }
243
244 public override void GetResults()
245 {
246 }
247
248 public override bool IsThreaded
249 {
250 // for now we won't be multithreaded
251 get { return (false); }
252 }
253
254 public override void SetTerrain(float[] heightMap)
255 {
256 _heightMap = heightMap;
257 }
258
259 public override void DeleteTerrain()
260 {
261 }
262
263 public override void SetWaterLevel(float baseheight)
264 {
265 }
266
267 public override Dictionary<uint, float> GetTopColliders()
268 {
269 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
270 return returncolliders;
271 }
272 }
273}