opensim – Blame information for rev 1

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