diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 43 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 7434 |
2 files changed, 3750 insertions, 3727 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a494864..51a3c18 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -1497,6 +1497,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1497 | get { return m_physicsShapeType; } | 1497 | get { return m_physicsShapeType; } |
1498 | set | 1498 | set |
1499 | { | 1499 | { |
1500 | byte oldv = m_physicsShapeType; | ||
1500 | if (value >= 0 && value <= (byte)PhysShapeType.convex) | 1501 | if (value >= 0 && value <= (byte)PhysShapeType.convex) |
1501 | { | 1502 | { |
1502 | if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this) | 1503 | if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this) |
@@ -1507,11 +1508,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1507 | else | 1508 | else |
1508 | m_physicsShapeType = DefaultPhysicsShapeType(); | 1509 | m_physicsShapeType = DefaultPhysicsShapeType(); |
1509 | 1510 | ||
1510 | if (ParentGroup != null) | ||
1511 | ParentGroup.HasGroupChanged = true; | ||
1512 | 1511 | ||
1513 | if(m_physicsShapeType != value) | 1512 | if (m_physicsShapeType != oldv && ParentGroup != null) |
1513 | { | ||
1514 | if (m_physicsShapeType == (byte)PhysShapeType.none) | ||
1515 | { | ||
1516 | if (PhysActor != null) | ||
1517 | { | ||
1518 | Velocity = new Vector3(0, 0, 0); | ||
1519 | Acceleration = new Vector3(0, 0, 0); | ||
1520 | if (ParentGroup.RootPart == this) | ||
1521 | AngularVelocity = new Vector3(0, 0, 0); | ||
1522 | ParentGroup.Scene.RemovePhysicalPrim(1); | ||
1523 | RemoveFromPhysics(); | ||
1524 | } | ||
1525 | } | ||
1526 | else if (PhysActor == null) | ||
1527 | ApplyPhysics((uint)Flags, VolumeDetectActive, false); | ||
1528 | else | ||
1529 | PhysActor.PhysicsShapeType = m_physicsShapeType; | ||
1530 | } | ||
1531 | if (m_physicsShapeType != value) | ||
1532 | { | ||
1533 | if (ParentGroup != null) | ||
1534 | ParentGroup.HasGroupChanged = true; | ||
1535 | |||
1514 | UpdatePhysRequired = true; | 1536 | UpdatePhysRequired = true; |
1537 | } | ||
1515 | } | 1538 | } |
1516 | } | 1539 | } |
1517 | 1540 | ||
@@ -4575,20 +4598,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
4575 | { | 4598 | { |
4576 | PhysicsShapeType = (byte)physdata.PhysShapeType; | 4599 | PhysicsShapeType = (byte)physdata.PhysShapeType; |
4577 | 4600 | ||
4578 | if (PhysicsShapeType == (byte)PhysShapeType.none) | ||
4579 | { | ||
4580 | if (PhysActor != null) | ||
4581 | { | ||
4582 | Velocity = new Vector3(0, 0, 0); | ||
4583 | Acceleration = new Vector3(0, 0, 0); | ||
4584 | if (ParentGroup.RootPart == this) | ||
4585 | AngularVelocity = new Vector3(0, 0, 0); | ||
4586 | ParentGroup.Scene.RemovePhysicalPrim(1); | ||
4587 | RemoveFromPhysics(); | ||
4588 | } | ||
4589 | } | ||
4590 | else if (PhysActor == null) | ||
4591 | ApplyPhysics((uint)Flags, VolumeDetectActive, false); | ||
4592 | } | 4601 | } |
4593 | 4602 | ||
4594 | if(Density != physdata.Density) | 4603 | if(Density != physdata.Density) |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index fd2f88f..71aec4c 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -1,3711 +1,3725 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* Revision 2011/12 by Ubit Umarov | 28 | /* Revision 2011/12 by Ubit Umarov |
29 | * | 29 | * |
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces | 34 | * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces |
35 | * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: | 35 | * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: |
36 | * ODEPrim.cs contains methods dealing with Prim editing, Prim | 36 | * ODEPrim.cs contains methods dealing with Prim editing, Prim |
37 | * characteristics and Kinetic motion. | 37 | * characteristics and Kinetic motion. |
38 | * ODEDynamics.cs contains methods dealing with Prim Physical motion | 38 | * ODEDynamics.cs contains methods dealing with Prim Physical motion |
39 | * (dynamics) and the associated settings. Old Linear and angular | 39 | * (dynamics) and the associated settings. Old Linear and angular |
40 | * motors for dynamic motion have been replace with MoveLinear() | 40 | * motors for dynamic motion have been replace with MoveLinear() |
41 | * and MoveAngular(); 'Physical' is used only to switch ODE dynamic | 41 | * and MoveAngular(); 'Physical' is used only to switch ODE dynamic |
42 | * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to | 42 | * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to |
43 | * switch between 'VEHICLE' parameter use and general dynamics | 43 | * switch between 'VEHICLE' parameter use and general dynamics |
44 | * settings use. | 44 | * settings use. |
45 | */ | 45 | */ |
46 | 46 | ||
47 | //#define SPAM | 47 | //#define SPAM |
48 | 48 | ||
49 | using System; | 49 | using System; |
50 | using System.Collections.Generic; | 50 | using System.Collections.Generic; |
51 | using System.Reflection; | 51 | using System.Reflection; |
52 | using System.Runtime.InteropServices; | 52 | using System.Runtime.InteropServices; |
53 | using System.Threading; | 53 | using System.Threading; |
54 | using log4net; | 54 | using log4net; |
55 | using OpenMetaverse; | 55 | using OpenMetaverse; |
56 | using OdeAPI; | 56 | using OdeAPI; |
57 | using OpenSim.Framework; | 57 | using OpenSim.Framework; |
58 | using OpenSim.Region.Physics.Manager; | 58 | using OpenSim.Region.Physics.Manager; |
59 | 59 | ||
60 | 60 | ||
61 | namespace OpenSim.Region.Physics.OdePlugin | 61 | namespace OpenSim.Region.Physics.OdePlugin |
62 | { | 62 | { |
63 | public class OdePrim : PhysicsActor | 63 | public class OdePrim : PhysicsActor |
64 | { | 64 | { |
65 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 65 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
66 | 66 | ||
67 | private bool m_isphysical; | 67 | private bool m_isphysical; |
68 | private bool m_fakeisphysical; | 68 | private bool m_fakeisphysical; |
69 | private bool m_isphantom; | 69 | private bool m_isphantom; |
70 | private bool m_fakeisphantom; | 70 | private bool m_fakeisphantom; |
71 | 71 | ||
72 | protected bool m_building; | 72 | protected bool m_building; |
73 | private Quaternion m_lastorientation = new Quaternion(); | 73 | private Quaternion m_lastorientation = new Quaternion(); |
74 | private Quaternion _orientation; | 74 | private Quaternion _orientation; |
75 | 75 | ||
76 | private Vector3 _position; | 76 | private Vector3 _position; |
77 | private Vector3 _velocity; | 77 | private Vector3 _velocity; |
78 | private Vector3 _torque; | 78 | private Vector3 _torque; |
79 | private Vector3 m_lastVelocity; | 79 | private Vector3 m_lastVelocity; |
80 | private Vector3 m_lastposition; | 80 | private Vector3 m_lastposition; |
81 | private Vector3 m_rotationalVelocity; | 81 | private Vector3 m_rotationalVelocity; |
82 | private Vector3 _size; | 82 | private Vector3 _size; |
83 | private Vector3 _acceleration; | 83 | private Vector3 _acceleration; |
84 | private Vector3 m_angularlock = Vector3.One; | 84 | private Vector3 m_angularlock = Vector3.One; |
85 | private IntPtr Amotor = IntPtr.Zero; | 85 | private IntPtr Amotor = IntPtr.Zero; |
86 | 86 | ||
87 | private Vector3 m_force; | 87 | private Vector3 m_force; |
88 | private Vector3 m_forceacc; | 88 | private Vector3 m_forceacc; |
89 | private Vector3 m_angularForceacc; | 89 | private Vector3 m_angularForceacc; |
90 | 90 | ||
91 | private Vector3 m_PIDTarget; | 91 | private Vector3 m_PIDTarget; |
92 | private float m_PIDTau; | 92 | private float m_PIDTau; |
93 | private float PID_D = 35f; | 93 | private float PID_D = 35f; |
94 | private float PID_G = 25f; | 94 | private float PID_G = 25f; |
95 | private bool m_usePID; | 95 | private bool m_usePID; |
96 | 96 | ||
97 | // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), | 97 | // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), |
98 | // and are for non-VEHICLES only. | 98 | // and are for non-VEHICLES only. |
99 | 99 | ||
100 | private float m_PIDHoverHeight; | 100 | private float m_PIDHoverHeight; |
101 | private float m_PIDHoverTau; | 101 | private float m_PIDHoverTau; |
102 | private bool m_useHoverPID; | 102 | private bool m_useHoverPID; |
103 | private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; | 103 | private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; |
104 | private float m_targetHoverHeight; | 104 | private float m_targetHoverHeight; |
105 | private float m_groundHeight; | 105 | private float m_groundHeight; |
106 | private float m_waterHeight; | 106 | private float m_waterHeight; |
107 | private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. | 107 | private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. |
108 | 108 | ||
109 | private int body_autodisable_frames = 20; | 109 | private int body_autodisable_frames = 20; |
110 | 110 | ||
111 | private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom | 111 | private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom |
112 | | CollisionCategories.Space | 112 | | CollisionCategories.Space |
113 | | CollisionCategories.Body | 113 | | CollisionCategories.Body |
114 | | CollisionCategories.Character | 114 | | CollisionCategories.Character |
115 | ); | 115 | ); |
116 | // private bool m_collidesLand = true; | 116 | // private bool m_collidesLand = true; |
117 | private bool m_collidesWater; | 117 | private bool m_collidesWater; |
118 | public bool m_returnCollisions; | 118 | public bool m_returnCollisions; |
119 | private bool m_softcolide; | 119 | private bool m_softcolide; |
120 | 120 | ||
121 | private bool m_NoColide; // for now only for internal use for bad meshs | 121 | private bool m_NoColide; // for now only for internal use for bad meshs |
122 | 122 | ||
123 | // Default we're a Geometry | 123 | // Default we're a Geometry |
124 | private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); | 124 | private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); |
125 | 125 | ||
126 | // Default, Collide with Other Geometries, spaces and Bodies | 126 | // Default, Collide with Other Geometries, spaces and Bodies |
127 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; | 127 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; |
128 | 128 | ||
129 | public bool m_disabled; | 129 | public bool m_disabled; |
130 | 130 | ||
131 | 131 | ||
132 | public uint m_localID; | 132 | public uint m_localID; |
133 | 133 | ||
134 | private PrimitiveBaseShape _pbs; | 134 | private PrimitiveBaseShape _pbs; |
135 | public OdeScene _parent_scene; | 135 | public OdeScene _parent_scene; |
136 | 136 | ||
137 | /// <summary> | 137 | /// <summary> |
138 | /// The physics space which contains prim geometry | 138 | /// The physics space which contains prim geometry |
139 | /// </summary> | 139 | /// </summary> |
140 | public IntPtr m_targetSpace = IntPtr.Zero; | 140 | public IntPtr m_targetSpace = IntPtr.Zero; |
141 | 141 | ||
142 | public IntPtr prim_geom; | 142 | public IntPtr prim_geom; |
143 | public IntPtr _triMeshData; | 143 | public IntPtr _triMeshData; |
144 | 144 | ||
145 | private PhysicsActor _parent; | 145 | private PhysicsActor _parent; |
146 | 146 | ||
147 | private List<OdePrim> childrenPrim = new List<OdePrim>(); | 147 | private List<OdePrim> childrenPrim = new List<OdePrim>(); |
148 | 148 | ||
149 | private bool m_iscolliding; | 149 | private bool m_iscolliding; |
150 | 150 | ||
151 | public bool m_isSelected; | 151 | public bool m_isSelected; |
152 | private bool m_delaySelect; | 152 | private bool m_delaySelect; |
153 | private bool m_lastdoneSelected; | 153 | private bool m_lastdoneSelected; |
154 | public bool m_outbounds; | 154 | public bool m_outbounds; |
155 | 155 | ||
156 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively | 156 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively |
157 | 157 | ||
158 | private bool m_throttleUpdates; | 158 | private bool m_throttleUpdates; |
159 | private int throttleCounter; | 159 | private int throttleCounter; |
160 | public float m_collisionscore; | 160 | public float m_collisionscore; |
161 | int m_colliderfilter = 0; | 161 | int m_colliderfilter = 0; |
162 | 162 | ||
163 | public IntPtr collide_geom; // for objects: geom if single prim space it linkset | 163 | public IntPtr collide_geom; // for objects: geom if single prim space it linkset |
164 | 164 | ||
165 | private float m_density = 10.000006836f; // Aluminum g/cm3; | 165 | private float m_density = 10.000006836f; // Aluminum g/cm3; |
166 | private byte m_shapetype; | 166 | private byte m_shapetype; |
167 | public bool _zeroFlag; | 167 | public bool _zeroFlag; |
168 | private bool m_lastUpdateSent; | 168 | private bool m_lastUpdateSent; |
169 | 169 | ||
170 | public IntPtr Body = IntPtr.Zero; | 170 | public IntPtr Body = IntPtr.Zero; |
171 | public String Name { get; private set; } | 171 | public String Name { get; private set; } |
172 | private Vector3 _target_velocity; | 172 | private Vector3 _target_velocity; |
173 | 173 | ||
174 | public Vector3 primOOBsize; // prim real dimensions from mesh | 174 | public Vector3 primOOBsize; // prim real dimensions from mesh |
175 | public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb | 175 | public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb |
176 | public float primOOBradiusSQ; | 176 | public float primOOBradiusSQ; |
177 | public d.Mass primdMass; // prim inertia information on it's own referencial | 177 | public d.Mass primdMass; // prim inertia information on it's own referencial |
178 | float primMass; // prim own mass | 178 | float primMass; // prim own mass |
179 | float _mass; // object mass acording to case | 179 | float _mass; // object mass acording to case |
180 | private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb | 180 | private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb |
181 | 181 | ||
182 | public int givefakepos = 0; | 182 | public int givefakepos = 0; |
183 | private Vector3 fakepos; | 183 | private Vector3 fakepos; |
184 | public int givefakeori = 0; | 184 | public int givefakeori = 0; |
185 | private Quaternion fakeori; | 185 | private Quaternion fakeori; |
186 | 186 | ||
187 | public int m_eventsubscription; | 187 | public int m_eventsubscription; |
188 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); | 188 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); |
189 | 189 | ||
190 | public volatile bool childPrim; | 190 | public volatile bool childPrim; |
191 | 191 | ||
192 | public ODEDynamics m_vehicle; | 192 | public ODEDynamics m_vehicle; |
193 | 193 | ||
194 | internal int m_material = (int)Material.Wood; | 194 | internal int m_material = (int)Material.Wood; |
195 | private float mu; | 195 | private float mu; |
196 | private float bounce; | 196 | private float bounce; |
197 | 197 | ||
198 | /// <summary> | 198 | /// <summary> |
199 | /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. | 199 | /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. |
200 | /// </summary> | 200 | /// </summary> |
201 | public override bool IsPhysical // this is not reliable for internal use | 201 | public override bool IsPhysical // this is not reliable for internal use |
202 | { | 202 | { |
203 | get { return m_fakeisphysical; } | 203 | get { return m_fakeisphysical; } |
204 | set | 204 | set |
205 | { | 205 | { |
206 | m_fakeisphysical = value; // we show imediatly to outside that we changed physical | 206 | m_fakeisphysical = value; // we show imediatly to outside that we changed physical |
207 | // and also to stop imediatly some updates | 207 | // and also to stop imediatly some updates |
208 | // but real change will only happen in taintprocessing | 208 | // but real change will only happen in taintprocessing |
209 | 209 | ||
210 | if (!value) // Zero the remembered last velocity | 210 | if (!value) // Zero the remembered last velocity |
211 | m_lastVelocity = Vector3.Zero; | 211 | m_lastVelocity = Vector3.Zero; |
212 | AddChange(changes.Physical, value); | 212 | AddChange(changes.Physical, value); |
213 | } | 213 | } |
214 | } | 214 | } |
215 | 215 | ||
216 | public override bool Phantom // this is not reliable for internal use | 216 | public override bool Phantom // this is not reliable for internal use |
217 | { | 217 | { |
218 | get { return m_fakeisphantom; } | 218 | get { return m_fakeisphantom; } |
219 | set | 219 | set |
220 | { | 220 | { |
221 | m_fakeisphantom = value; // we show imediatly to outside that we changed physical | 221 | m_fakeisphantom = value; // we show imediatly to outside that we changed physical |
222 | // and also to stop imediatly some updates | 222 | // and also to stop imediatly some updates |
223 | // but real change will only happen in taintprocessing | 223 | // but real change will only happen in taintprocessing |
224 | 224 | ||
225 | AddChange(changes.Phantom, value); | 225 | AddChange(changes.Phantom, value); |
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | public override bool Building // this is not reliable for internal use | 229 | public override bool Building // this is not reliable for internal use |
230 | { | 230 | { |
231 | get { return m_building; } | 231 | get { return m_building; } |
232 | set | 232 | set |
233 | { | 233 | { |
234 | if (value) | 234 | if (value) |
235 | m_building = true; | 235 | m_building = true; |
236 | AddChange(changes.building, value); | 236 | AddChange(changes.building, value); |
237 | } | 237 | } |
238 | } | 238 | } |
239 | 239 | ||
240 | public override void getContactData(ref ContactData cdata) | 240 | public override void getContactData(ref ContactData cdata) |
241 | { | 241 | { |
242 | cdata.mu = mu; | 242 | cdata.mu = mu; |
243 | cdata.bounce = bounce; | 243 | cdata.bounce = bounce; |
244 | 244 | ||
245 | // cdata.softcolide = m_softcolide; | 245 | // cdata.softcolide = m_softcolide; |
246 | cdata.softcolide = false; | 246 | cdata.softcolide = false; |
247 | 247 | ||
248 | if (m_isphysical) | 248 | if (m_isphysical) |
249 | { | 249 | { |
250 | ODEDynamics veh; | 250 | ODEDynamics veh; |
251 | if (_parent != null) | 251 | if (_parent != null) |
252 | veh = ((OdePrim)_parent).m_vehicle; | 252 | veh = ((OdePrim)_parent).m_vehicle; |
253 | else | 253 | else |
254 | veh = m_vehicle; | 254 | veh = m_vehicle; |
255 | 255 | ||
256 | if (veh != null && veh.Type != Vehicle.TYPE_NONE) | 256 | if (veh != null && veh.Type != Vehicle.TYPE_NONE) |
257 | cdata.mu *= veh.FrictionFactor; | 257 | cdata.mu *= veh.FrictionFactor; |
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
261 | public override int PhysicsActorType | 261 | public override int PhysicsActorType |
262 | { | 262 | { |
263 | get { return (int)ActorTypes.Prim; } | 263 | get { return (int)ActorTypes.Prim; } |
264 | set { return; } | 264 | set { return; } |
265 | } | 265 | } |
266 | 266 | ||
267 | public override bool SetAlwaysRun | 267 | public override bool SetAlwaysRun |
268 | { | 268 | { |
269 | get { return false; } | 269 | get { return false; } |
270 | set { return; } | 270 | set { return; } |
271 | } | 271 | } |
272 | 272 | ||
273 | public override uint LocalID | 273 | public override uint LocalID |
274 | { | 274 | { |
275 | get | 275 | get |
276 | { | 276 | { |
277 | return m_localID; | 277 | return m_localID; |
278 | } | 278 | } |
279 | set | 279 | set |
280 | { | 280 | { |
281 | //m_log.Info("[PHYSICS]: Setting TrackerID: " + value); | 281 | //m_log.Info("[PHYSICS]: Setting TrackerID: " + value); |
282 | m_localID = value; | 282 | m_localID = value; |
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | public override bool Grabbed | 286 | public override bool Grabbed |
287 | { | 287 | { |
288 | set { return; } | 288 | set { return; } |
289 | } | 289 | } |
290 | 290 | ||
291 | public override bool Selected | 291 | public override bool Selected |
292 | { | 292 | { |
293 | set | 293 | set |
294 | { | 294 | { |
295 | if (value) | 295 | if (value) |
296 | m_isSelected = value; // if true set imediatly to stop moves etc | 296 | m_isSelected = value; // if true set imediatly to stop moves etc |
297 | AddChange(changes.Selected, value); | 297 | AddChange(changes.Selected, value); |
298 | } | 298 | } |
299 | } | 299 | } |
300 | 300 | ||
301 | public override bool Flying | 301 | public override bool Flying |
302 | { | 302 | { |
303 | // no flying prims for you | 303 | // no flying prims for you |
304 | get { return false; } | 304 | get { return false; } |
305 | set { } | 305 | set { } |
306 | } | 306 | } |
307 | 307 | ||
308 | public override bool IsColliding | 308 | public override bool IsColliding |
309 | { | 309 | { |
310 | get { return m_iscolliding; } | 310 | get { return m_iscolliding; } |
311 | set | 311 | set |
312 | { | 312 | { |
313 | if (value) | 313 | if (value) |
314 | { | 314 | { |
315 | m_colliderfilter += 2; | 315 | m_colliderfilter += 2; |
316 | if (m_colliderfilter > 2) | 316 | if (m_colliderfilter > 2) |
317 | m_colliderfilter = 2; | 317 | m_colliderfilter = 2; |
318 | } | 318 | } |
319 | else | 319 | else |
320 | { | 320 | { |
321 | m_colliderfilter--; | 321 | m_colliderfilter--; |
322 | if (m_colliderfilter < 0) | 322 | if (m_colliderfilter < 0) |
323 | m_colliderfilter = 0; | 323 | m_colliderfilter = 0; |
324 | } | 324 | } |
325 | 325 | ||
326 | if (m_colliderfilter == 0) | 326 | if (m_colliderfilter == 0) |
327 | { | 327 | { |
328 | m_softcolide = false; | 328 | m_softcolide = false; |
329 | m_iscolliding = false; | 329 | m_iscolliding = false; |
330 | } | 330 | } |
331 | else | 331 | else |
332 | m_iscolliding = true; | 332 | m_iscolliding = true; |
333 | } | 333 | } |
334 | } | 334 | } |
335 | 335 | ||
336 | public override bool CollidingGround | 336 | public override bool CollidingGround |
337 | { | 337 | { |
338 | get { return false; } | 338 | get { return false; } |
339 | set { return; } | 339 | set { return; } |
340 | } | 340 | } |
341 | 341 | ||
342 | public override bool CollidingObj | 342 | public override bool CollidingObj |
343 | { | 343 | { |
344 | get { return false; } | 344 | get { return false; } |
345 | set { return; } | 345 | set { return; } |
346 | } | 346 | } |
347 | 347 | ||
348 | public override bool ThrottleUpdates | 348 | public override bool ThrottleUpdates |
349 | { | 349 | { |
350 | get { return m_throttleUpdates; } | 350 | get { return m_throttleUpdates; } |
351 | set { m_throttleUpdates = value; } | 351 | set { m_throttleUpdates = value; } |
352 | } | 352 | } |
353 | 353 | ||
354 | public override bool Stopped | 354 | public override bool Stopped |
355 | { | 355 | { |
356 | get { return _zeroFlag; } | 356 | get { return _zeroFlag; } |
357 | } | 357 | } |
358 | 358 | ||
359 | public override Vector3 Position | 359 | public override Vector3 Position |
360 | { | 360 | { |
361 | get | 361 | get |
362 | { | 362 | { |
363 | if (givefakepos > 0) | 363 | if (givefakepos > 0) |
364 | return fakepos; | 364 | return fakepos; |
365 | else | 365 | else |
366 | return _position; | 366 | return _position; |
367 | } | 367 | } |
368 | 368 | ||
369 | set | 369 | set |
370 | { | 370 | { |
371 | fakepos = value; | 371 | fakepos = value; |
372 | givefakepos++; | 372 | givefakepos++; |
373 | AddChange(changes.Position, value); | 373 | AddChange(changes.Position, value); |
374 | } | 374 | } |
375 | } | 375 | } |
376 | 376 | ||
377 | public override Vector3 Size | 377 | public override Vector3 Size |
378 | { | 378 | { |
379 | get { return _size; } | 379 | get { return _size; } |
380 | set | 380 | set |
381 | { | 381 | { |
382 | if (value.IsFinite()) | 382 | if (value.IsFinite()) |
383 | { | 383 | { |
384 | AddChange(changes.Size, value); | 384 | AddChange(changes.Size, value); |
385 | } | 385 | } |
386 | else | 386 | else |
387 | { | 387 | { |
388 | m_log.WarnFormat("[PHYSICS]: Got NaN Size on object {0}", Name); | 388 | m_log.WarnFormat("[PHYSICS]: Got NaN Size on object {0}", Name); |
389 | } | 389 | } |
390 | } | 390 | } |
391 | } | 391 | } |
392 | 392 | ||
393 | public override float Mass | 393 | public override float Mass |
394 | { | 394 | { |
395 | get { return _mass; } | 395 | get { return _mass; } |
396 | } | 396 | } |
397 | 397 | ||
398 | public override Vector3 Force | 398 | public override Vector3 Force |
399 | { | 399 | { |
400 | //get { return Vector3.Zero; } | 400 | //get { return Vector3.Zero; } |
401 | get { return m_force; } | 401 | get { return m_force; } |
402 | set | 402 | set |
403 | { | 403 | { |
404 | if (value.IsFinite()) | 404 | if (value.IsFinite()) |
405 | { | 405 | { |
406 | AddChange(changes.Force, value); | 406 | AddChange(changes.Force, value); |
407 | } | 407 | } |
408 | else | 408 | else |
409 | { | 409 | { |
410 | m_log.WarnFormat("[PHYSICS]: NaN in Force Applied to an Object {0}", Name); | 410 | m_log.WarnFormat("[PHYSICS]: NaN in Force Applied to an Object {0}", Name); |
411 | } | 411 | } |
412 | } | 412 | } |
413 | } | 413 | } |
414 | 414 | ||
415 | public override void SetVolumeDetect(int param) | 415 | public override void SetVolumeDetect(int param) |
416 | { | 416 | { |
417 | AddChange(changes.VolumeDtc, (param != 0)); | 417 | AddChange(changes.VolumeDtc, (param != 0)); |
418 | } | 418 | } |
419 | 419 | ||
420 | public override Vector3 GeometricCenter | 420 | public override Vector3 GeometricCenter |
421 | { | 421 | { |
422 | get | 422 | get |
423 | { | 423 | { |
424 | return Vector3.Zero; | 424 | return Vector3.Zero; |
425 | } | 425 | } |
426 | } | 426 | } |
427 | 427 | ||
428 | public override Vector3 CenterOfMass | 428 | public override Vector3 CenterOfMass |
429 | { | 429 | { |
430 | get | 430 | get |
431 | { | 431 | { |
432 | d.Vector3 dtmp; | 432 | d.Vector3 dtmp; |
433 | if (IsPhysical && !childPrim && Body != IntPtr.Zero) | 433 | if (IsPhysical && !childPrim && Body != IntPtr.Zero) |
434 | { | 434 | { |
435 | dtmp = d.BodyGetPosition(Body); | 435 | dtmp = d.BodyGetPosition(Body); |
436 | return new Vector3(dtmp.X, dtmp.Y, dtmp.Z); | 436 | return new Vector3(dtmp.X, dtmp.Y, dtmp.Z); |
437 | } | 437 | } |
438 | else if (prim_geom != IntPtr.Zero) | 438 | else if (prim_geom != IntPtr.Zero) |
439 | { | 439 | { |
440 | d.Quaternion dq; | 440 | d.Quaternion dq; |
441 | d.GeomCopyQuaternion(prim_geom, out dq); | 441 | d.GeomCopyQuaternion(prim_geom, out dq); |
442 | Quaternion q; | 442 | Quaternion q; |
443 | q.X = dq.X; | 443 | q.X = dq.X; |
444 | q.Y = dq.Y; | 444 | q.Y = dq.Y; |
445 | q.Z = dq.Z; | 445 | q.Z = dq.Z; |
446 | q.W = dq.W; | 446 | q.W = dq.W; |
447 | 447 | ||
448 | Vector3 vtmp = primOOBoffset * q; | 448 | Vector3 vtmp = primOOBoffset * q; |
449 | dtmp = d.GeomGetPosition(prim_geom); | 449 | dtmp = d.GeomGetPosition(prim_geom); |
450 | return new Vector3(dtmp.X + vtmp.X, dtmp.Y + vtmp.Y, dtmp.Z + vtmp.Z); | 450 | return new Vector3(dtmp.X + vtmp.X, dtmp.Y + vtmp.Y, dtmp.Z + vtmp.Z); |
451 | } | 451 | } |
452 | else | 452 | else |
453 | return Vector3.Zero; | 453 | return Vector3.Zero; |
454 | } | 454 | } |
455 | } | 455 | } |
456 | /* | 456 | /* |
457 | public override Vector3 PrimOOBsize | 457 | public override Vector3 PrimOOBsize |
458 | { | 458 | { |
459 | get | 459 | get |
460 | { | 460 | { |
461 | return primOOBsize; | 461 | return primOOBsize; |
462 | } | 462 | } |
463 | } | 463 | } |
464 | 464 | ||
465 | public override Vector3 PrimOOBoffset | 465 | public override Vector3 PrimOOBoffset |
466 | { | 466 | { |
467 | get | 467 | get |
468 | { | 468 | { |
469 | return primOOBoffset; | 469 | return primOOBoffset; |
470 | } | 470 | } |
471 | } | 471 | } |
472 | 472 | ||
473 | public override float PrimOOBRadiusSQ | 473 | public override float PrimOOBRadiusSQ |
474 | { | 474 | { |
475 | get | 475 | get |
476 | { | 476 | { |
477 | return primOOBradiusSQ; | 477 | return primOOBradiusSQ; |
478 | } | 478 | } |
479 | } | 479 | } |
480 | */ | 480 | */ |
481 | public override PrimitiveBaseShape Shape | 481 | public override PrimitiveBaseShape Shape |
482 | { | 482 | { |
483 | set | 483 | set |
484 | { | 484 | { |
485 | AddChange(changes.Shape, value); | 485 | AddChange(changes.Shape, value); |
486 | } | 486 | } |
487 | } | 487 | } |
488 | 488 | ||
489 | public override Vector3 Velocity | 489 | public override byte PhysicsShapeType |
490 | { | 490 | { |
491 | get | 491 | get |
492 | { | 492 | { |
493 | if (_zeroFlag) | 493 | return m_shapetype; |
494 | return Vector3.Zero; | 494 | } |
495 | return _velocity; | 495 | set |
496 | } | 496 | { |
497 | set | 497 | m_shapetype = value; |
498 | { | 498 | AddChange(changes.Shape, null); |
499 | if (value.IsFinite()) | 499 | } |
500 | { | 500 | } |
501 | AddChange(changes.Velocity, value); | 501 | |
502 | // _velocity = value; | 502 | public override Vector3 Velocity |
503 | 503 | { | |
504 | } | 504 | get |
505 | else | 505 | { |
506 | { | 506 | if (_zeroFlag) |
507 | m_log.WarnFormat("[PHYSICS]: Got NaN Velocity in Object {0}", Name); | 507 | return Vector3.Zero; |
508 | } | 508 | return _velocity; |
509 | 509 | } | |
510 | } | 510 | set |
511 | } | 511 | { |
512 | 512 | if (value.IsFinite()) | |
513 | public override Vector3 Torque | 513 | { |
514 | { | 514 | AddChange(changes.Velocity, value); |
515 | get | 515 | // _velocity = value; |
516 | { | 516 | |
517 | if (!IsPhysical || Body == IntPtr.Zero) | 517 | } |
518 | return Vector3.Zero; | 518 | else |
519 | 519 | { | |
520 | return _torque; | 520 | m_log.WarnFormat("[PHYSICS]: Got NaN Velocity in Object {0}", Name); |
521 | } | 521 | } |
522 | 522 | ||
523 | set | 523 | } |
524 | { | 524 | } |
525 | if (value.IsFinite()) | 525 | |
526 | { | 526 | public override Vector3 Torque |
527 | AddChange(changes.Torque, value); | 527 | { |
528 | } | 528 | get |
529 | else | 529 | { |
530 | { | 530 | if (!IsPhysical || Body == IntPtr.Zero) |
531 | m_log.WarnFormat("[PHYSICS]: Got NaN Torque in Object {0}", Name); | 531 | return Vector3.Zero; |
532 | } | 532 | |
533 | } | 533 | return _torque; |
534 | } | 534 | } |
535 | 535 | ||
536 | public override float CollisionScore | 536 | set |
537 | { | 537 | { |
538 | get { return m_collisionscore; } | 538 | if (value.IsFinite()) |
539 | set { m_collisionscore = value; } | 539 | { |
540 | } | 540 | AddChange(changes.Torque, value); |
541 | 541 | } | |
542 | public override bool Kinematic | 542 | else |
543 | { | 543 | { |
544 | get { return false; } | 544 | m_log.WarnFormat("[PHYSICS]: Got NaN Torque in Object {0}", Name); |
545 | set { } | 545 | } |
546 | } | 546 | } |
547 | 547 | } | |
548 | public override Quaternion Orientation | 548 | |
549 | { | 549 | public override float CollisionScore |
550 | get | 550 | { |
551 | { | 551 | get { return m_collisionscore; } |
552 | if (givefakeori > 0) | 552 | set { m_collisionscore = value; } |
553 | return fakeori; | 553 | } |
554 | else | 554 | |
555 | 555 | public override bool Kinematic | |
556 | return _orientation; | 556 | { |
557 | } | 557 | get { return false; } |
558 | set | 558 | set { } |
559 | { | 559 | } |
560 | if (QuaternionIsFinite(value)) | 560 | |
561 | { | 561 | public override Quaternion Orientation |
562 | fakeori = value; | 562 | { |
563 | givefakeori++; | 563 | get |
564 | AddChange(changes.Orientation, value); | 564 | { |
565 | } | 565 | if (givefakeori > 0) |
566 | else | 566 | return fakeori; |
567 | m_log.WarnFormat("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object {0}", Name); | 567 | else |
568 | 568 | ||
569 | } | 569 | return _orientation; |
570 | } | 570 | } |
571 | 571 | set | |
572 | public override Vector3 Acceleration | 572 | { |
573 | { | 573 | if (QuaternionIsFinite(value)) |
574 | get { return _acceleration; } | 574 | { |
575 | set { } | 575 | fakeori = value; |
576 | } | 576 | givefakeori++; |
577 | 577 | AddChange(changes.Orientation, value); | |
578 | public override Vector3 RotationalVelocity | 578 | } |
579 | { | 579 | else |
580 | get | 580 | m_log.WarnFormat("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object {0}", Name); |
581 | { | 581 | |
582 | Vector3 pv = Vector3.Zero; | 582 | } |
583 | if (_zeroFlag) | 583 | } |
584 | return pv; | 584 | |
585 | m_lastUpdateSent = false; | 585 | public override Vector3 Acceleration |
586 | 586 | { | |
587 | if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f)) | 587 | get { return _acceleration; } |
588 | return pv; | 588 | set { } |
589 | 589 | } | |
590 | return m_rotationalVelocity; | 590 | |
591 | } | 591 | public override Vector3 RotationalVelocity |
592 | set | 592 | { |
593 | { | 593 | get |
594 | if (value.IsFinite()) | 594 | { |
595 | { | 595 | Vector3 pv = Vector3.Zero; |
596 | m_rotationalVelocity = value; | 596 | if (_zeroFlag) |
597 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | 597 | return pv; |
598 | d.BodyEnable(Body); | 598 | m_lastUpdateSent = false; |
599 | } | 599 | |
600 | else | 600 | if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f)) |
601 | { | 601 | return pv; |
602 | m_log.WarnFormat("[PHYSICS]: Got NaN RotationalVelocity in Object {0}", Name); | 602 | |
603 | } | 603 | return m_rotationalVelocity; |
604 | } | 604 | } |
605 | } | 605 | set |
606 | 606 | { | |
607 | 607 | if (value.IsFinite()) | |
608 | public override float Buoyancy | 608 | { |
609 | { | 609 | m_rotationalVelocity = value; |
610 | get { return m_buoyancy; } | 610 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) |
611 | set | 611 | d.BodyEnable(Body); |
612 | { | 612 | } |
613 | m_buoyancy = value; | 613 | else |
614 | } | 614 | { |
615 | } | 615 | m_log.WarnFormat("[PHYSICS]: Got NaN RotationalVelocity in Object {0}", Name); |
616 | 616 | } | |
617 | public override bool FloatOnWater | 617 | } |
618 | { | 618 | } |
619 | set | 619 | |
620 | { | 620 | |
621 | AddChange(changes.CollidesWater, value); | 621 | public override float Buoyancy |
622 | } | 622 | { |
623 | } | 623 | get { return m_buoyancy; } |
624 | 624 | set | |
625 | public override Vector3 PIDTarget | 625 | { |
626 | { | 626 | m_buoyancy = value; |
627 | set | 627 | } |
628 | { | 628 | } |
629 | if (value.IsFinite()) | 629 | |
630 | { | 630 | public override bool FloatOnWater |
631 | m_PIDTarget = value; | 631 | { |
632 | } | 632 | set |
633 | else | 633 | { |
634 | m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name); | 634 | AddChange(changes.CollidesWater, value); |
635 | } | 635 | } |
636 | } | 636 | } |
637 | 637 | ||
638 | public override bool PIDActive { set { m_usePID = value; } } | 638 | public override Vector3 PIDTarget |
639 | public override float PIDTau { set { m_PIDTau = value; } } | 639 | { |
640 | 640 | set | |
641 | public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } | 641 | { |
642 | public override bool PIDHoverActive { set { m_useHoverPID = value; } } | 642 | if (value.IsFinite()) |
643 | public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } | 643 | { |
644 | public override float PIDHoverTau { set { m_PIDHoverTau = value; } } | 644 | m_PIDTarget = value; |
645 | 645 | } | |
646 | public override Quaternion APIDTarget { set { return; } } | 646 | else |
647 | 647 | m_log.WarnFormat("[PHYSICS]: Got NaN PIDTarget from Scene on Object {0}", Name); | |
648 | public override bool APIDActive { set { return; } } | 648 | } |
649 | 649 | } | |
650 | public override float APIDStrength { set { return; } } | 650 | |
651 | 651 | public override bool PIDActive { set { m_usePID = value; } } | |
652 | public override float APIDDamping { set { return; } } | 652 | public override float PIDTau { set { m_PIDTau = value; } } |
653 | 653 | ||
654 | public override int VehicleType | 654 | public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } |
655 | { | 655 | public override bool PIDHoverActive { set { m_useHoverPID = value; } } |
656 | // we may need to put a fake on this | 656 | public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } |
657 | get | 657 | public override float PIDHoverTau { set { m_PIDHoverTau = value; } } |
658 | { | 658 | |
659 | if (m_vehicle == null) | 659 | public override Quaternion APIDTarget { set { return; } } |
660 | return (int)Vehicle.TYPE_NONE; | 660 | |
661 | else | 661 | public override bool APIDActive { set { return; } } |
662 | return (int)m_vehicle.Type; | 662 | |
663 | } | 663 | public override float APIDStrength { set { return; } } |
664 | set | 664 | |
665 | { | 665 | public override float APIDDamping { set { return; } } |
666 | AddChange(changes.VehicleType, value); | 666 | |
667 | } | 667 | public override int VehicleType |
668 | } | 668 | { |
669 | 669 | // we may need to put a fake on this | |
670 | public override void VehicleFloatParam(int param, float value) | 670 | get |
671 | { | 671 | { |
672 | strVehicleFloatParam fp = new strVehicleFloatParam(); | 672 | if (m_vehicle == null) |
673 | fp.param = param; | 673 | return (int)Vehicle.TYPE_NONE; |
674 | fp.value = value; | 674 | else |
675 | AddChange(changes.VehicleFloatParam, fp); | 675 | return (int)m_vehicle.Type; |
676 | } | 676 | } |
677 | 677 | set | |
678 | public override void VehicleVectorParam(int param, Vector3 value) | 678 | { |
679 | { | 679 | AddChange(changes.VehicleType, value); |
680 | strVehicleVectorParam fp = new strVehicleVectorParam(); | 680 | } |
681 | fp.param = param; | 681 | } |
682 | fp.value = value; | 682 | |
683 | AddChange(changes.VehicleVectorParam, fp); | 683 | public override void VehicleFloatParam(int param, float value) |
684 | } | 684 | { |
685 | 685 | strVehicleFloatParam fp = new strVehicleFloatParam(); | |
686 | public override void VehicleRotationParam(int param, Quaternion value) | 686 | fp.param = param; |
687 | { | 687 | fp.value = value; |
688 | strVehicleQuatParam fp = new strVehicleQuatParam(); | 688 | AddChange(changes.VehicleFloatParam, fp); |
689 | fp.param = param; | 689 | } |
690 | fp.value = value; | 690 | |
691 | AddChange(changes.VehicleRotationParam, fp); | 691 | public override void VehicleVectorParam(int param, Vector3 value) |
692 | } | 692 | { |
693 | 693 | strVehicleVectorParam fp = new strVehicleVectorParam(); | |
694 | public override void VehicleFlags(int param, bool value) | 694 | fp.param = param; |
695 | { | 695 | fp.value = value; |
696 | strVehicleBoolParam bp = new strVehicleBoolParam(); | 696 | AddChange(changes.VehicleVectorParam, fp); |
697 | bp.param = param; | 697 | } |
698 | bp.value = value; | 698 | |
699 | AddChange(changes.VehicleFlags, bp); | 699 | public override void VehicleRotationParam(int param, Quaternion value) |
700 | } | 700 | { |
701 | 701 | strVehicleQuatParam fp = new strVehicleQuatParam(); | |
702 | public override void SetVehicle(object vdata) | 702 | fp.param = param; |
703 | { | 703 | fp.value = value; |
704 | AddChange(changes.SetVehicle, vdata); | 704 | AddChange(changes.VehicleRotationParam, fp); |
705 | } | 705 | } |
706 | public void SetAcceleration(Vector3 accel) | 706 | |
707 | { | 707 | public override void VehicleFlags(int param, bool value) |
708 | _acceleration = accel; | 708 | { |
709 | } | 709 | strVehicleBoolParam bp = new strVehicleBoolParam(); |
710 | 710 | bp.param = param; | |
711 | public override void AddForce(Vector3 force, bool pushforce) | 711 | bp.value = value; |
712 | { | 712 | AddChange(changes.VehicleFlags, bp); |
713 | if (force.IsFinite()) | 713 | } |
714 | { | 714 | |
715 | AddChange(changes.AddForce, force / _parent_scene.ODE_STEPSIZE); | 715 | public override void SetVehicle(object vdata) |
716 | } | 716 | { |
717 | else | 717 | AddChange(changes.SetVehicle, vdata); |
718 | { | 718 | } |
719 | m_log.WarnFormat("[PHYSICS]: Got Invalid linear force vector from Scene in Object {0}", Name); | 719 | public void SetAcceleration(Vector3 accel) |
720 | } | 720 | { |
721 | //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString()); | 721 | _acceleration = accel; |
722 | } | 722 | } |
723 | 723 | ||
724 | public override void AddAngularForce(Vector3 force, bool pushforce) | 724 | public override void AddForce(Vector3 force, bool pushforce) |
725 | { | 725 | { |
726 | if (force.IsFinite()) | 726 | if (force.IsFinite()) |
727 | { | 727 | { |
728 | AddChange(changes.AddAngForce, force / _parent_scene.ODE_STEPSIZE); | 728 | AddChange(changes.AddForce, force / _parent_scene.ODE_STEPSIZE); |
729 | } | 729 | } |
730 | else | 730 | else |
731 | { | 731 | { |
732 | m_log.WarnFormat("[PHYSICS]: Got Invalid Angular force vector from Scene in Object {0}", Name); | 732 | m_log.WarnFormat("[PHYSICS]: Got Invalid linear force vector from Scene in Object {0}", Name); |
733 | } | 733 | } |
734 | } | 734 | //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString()); |
735 | 735 | } | |
736 | public override void CrossingFailure() | 736 | |
737 | { | 737 | public override void AddAngularForce(Vector3 force, bool pushforce) |
738 | if (m_outbounds) | 738 | { |
739 | { | 739 | if (force.IsFinite()) |
740 | _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); | 740 | { |
741 | _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); | 741 | AddChange(changes.AddAngForce, force / _parent_scene.ODE_STEPSIZE); |
742 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | 742 | } |
743 | 743 | else | |
744 | m_lastposition = _position; | 744 | { |
745 | _velocity.X = 0; | 745 | m_log.WarnFormat("[PHYSICS]: Got Invalid Angular force vector from Scene in Object {0}", Name); |
746 | _velocity.Y = 0; | 746 | } |
747 | _velocity.Z = 0; | 747 | } |
748 | 748 | ||
749 | m_lastVelocity = _velocity; | 749 | public override void CrossingFailure() |
750 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | 750 | { |
751 | m_vehicle.Stop(); | 751 | if (m_outbounds) |
752 | 752 | { | |
753 | if(Body != IntPtr.Zero) | 753 | _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); |
754 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | 754 | _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); |
755 | if (prim_geom != IntPtr.Zero) | 755 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); |
756 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 756 | |
757 | 757 | m_lastposition = _position; | |
758 | m_outbounds = false; | 758 | _velocity.X = 0; |
759 | changeDisable(false); | 759 | _velocity.Y = 0; |
760 | base.RequestPhysicsterseUpdate(); | 760 | _velocity.Z = 0; |
761 | } | 761 | |
762 | } | 762 | m_lastVelocity = _velocity; |
763 | 763 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | |
764 | public override void SetMomentum(Vector3 momentum) | 764 | m_vehicle.Stop(); |
765 | { | 765 | |
766 | } | 766 | if(Body != IntPtr.Zero) |
767 | 767 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | |
768 | public override void SetMaterial(int pMaterial) | 768 | if (prim_geom != IntPtr.Zero) |
769 | { | 769 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
770 | m_material = pMaterial; | 770 | |
771 | mu = _parent_scene.m_materialContactsData[pMaterial].mu; | 771 | m_outbounds = false; |
772 | bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; | 772 | changeDisable(false); |
773 | } | 773 | base.RequestPhysicsterseUpdate(); |
774 | 774 | } | |
775 | public void setPrimForRemoval() | 775 | } |
776 | { | 776 | |
777 | AddChange(changes.Remove, null); | 777 | public override void SetMomentum(Vector3 momentum) |
778 | } | 778 | { |
779 | 779 | } | |
780 | public override void link(PhysicsActor obj) | 780 | |
781 | { | 781 | public override void SetMaterial(int pMaterial) |
782 | AddChange(changes.Link, obj); | 782 | { |
783 | } | 783 | m_material = pMaterial; |
784 | 784 | mu = _parent_scene.m_materialContactsData[pMaterial].mu; | |
785 | public override void delink() | 785 | bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; |
786 | { | 786 | } |
787 | AddChange(changes.DeLink, null); | 787 | |
788 | } | 788 | public void setPrimForRemoval() |
789 | 789 | { | |
790 | public override void LockAngularMotion(Vector3 axis) | 790 | AddChange(changes.Remove, null); |
791 | { | 791 | } |
792 | // reverse the zero/non zero values for ODE. | 792 | |
793 | if (axis.IsFinite()) | 793 | public override void link(PhysicsActor obj) |
794 | { | 794 | { |
795 | axis.X = (axis.X > 0) ? 1f : 0f; | 795 | AddChange(changes.Link, obj); |
796 | axis.Y = (axis.Y > 0) ? 1f : 0f; | 796 | } |
797 | axis.Z = (axis.Z > 0) ? 1f : 0f; | 797 | |
798 | m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); | 798 | public override void delink() |
799 | AddChange(changes.AngLock, axis); | 799 | { |
800 | } | 800 | AddChange(changes.DeLink, null); |
801 | else | 801 | } |
802 | { | 802 | |
803 | m_log.WarnFormat("[PHYSICS]: Got NaN locking axis from Scene on Object {0}", Name); | 803 | public override void LockAngularMotion(Vector3 axis) |
804 | } | 804 | { |
805 | } | 805 | // reverse the zero/non zero values for ODE. |
806 | 806 | if (axis.IsFinite()) | |
807 | public override void SubscribeEvents(int ms) | 807 | { |
808 | { | 808 | axis.X = (axis.X > 0) ? 1f : 0f; |
809 | m_eventsubscription = ms; | 809 | axis.Y = (axis.Y > 0) ? 1f : 0f; |
810 | _parent_scene.AddCollisionEventReporting(this); | 810 | axis.Z = (axis.Z > 0) ? 1f : 0f; |
811 | } | 811 | m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); |
812 | 812 | AddChange(changes.AngLock, axis); | |
813 | public override void UnSubscribeEvents() | 813 | } |
814 | { | 814 | else |
815 | _parent_scene.RemoveCollisionEventReporting(this); | 815 | { |
816 | m_eventsubscription = 0; | 816 | m_log.WarnFormat("[PHYSICS]: Got NaN locking axis from Scene on Object {0}", Name); |
817 | } | 817 | } |
818 | 818 | } | |
819 | public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) | 819 | |
820 | { | 820 | public override void SubscribeEvents(int ms) |
821 | if (CollisionEventsThisFrame == null) | 821 | { |
822 | CollisionEventsThisFrame = new CollisionEventUpdate(); | 822 | m_eventsubscription = ms; |
823 | 823 | _parent_scene.AddCollisionEventReporting(this); | |
824 | CollisionEventsThisFrame.AddCollider(CollidedWith, contact); | 824 | } |
825 | } | 825 | |
826 | 826 | public override void UnSubscribeEvents() | |
827 | public void SendCollisions() | 827 | { |
828 | { | 828 | _parent_scene.RemoveCollisionEventReporting(this); |
829 | if (CollisionEventsThisFrame == null) | 829 | m_eventsubscription = 0; |
830 | return; | 830 | } |
831 | 831 | ||
832 | base.SendCollisionUpdate(CollisionEventsThisFrame); | 832 | public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) |
833 | 833 | { | |
834 | if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) | 834 | if (CollisionEventsThisFrame == null) |
835 | CollisionEventsThisFrame = null; | 835 | CollisionEventsThisFrame = new CollisionEventUpdate(); |
836 | else | 836 | |
837 | CollisionEventsThisFrame = new CollisionEventUpdate(); | 837 | CollisionEventsThisFrame.AddCollider(CollidedWith, contact); |
838 | } | 838 | } |
839 | 839 | ||
840 | public override bool SubscribedEvents() | 840 | public void SendCollisions() |
841 | { | 841 | { |
842 | if (m_eventsubscription > 0) | 842 | if (CollisionEventsThisFrame == null) |
843 | return true; | 843 | return; |
844 | return false; | 844 | |
845 | } | 845 | base.SendCollisionUpdate(CollisionEventsThisFrame); |
846 | 846 | ||
847 | 847 | if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) | |
848 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, | 848 | CollisionEventsThisFrame = null; |
849 | Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical,bool pisPhantom,byte _shapeType,uint plocalID) | 849 | else |
850 | { | 850 | CollisionEventsThisFrame = new CollisionEventUpdate(); |
851 | Name = primName; | 851 | } |
852 | LocalID = plocalID; | 852 | |
853 | 853 | public override bool SubscribedEvents() | |
854 | m_vehicle = null; | 854 | { |
855 | 855 | if (m_eventsubscription > 0) | |
856 | if (!pos.IsFinite()) | 856 | return true; |
857 | { | 857 | return false; |
858 | pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), | 858 | } |
859 | parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f); | 859 | |
860 | m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Position for {0}", Name); | 860 | |
861 | } | 861 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, |
862 | _position = pos; | 862 | Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical,bool pisPhantom,byte _shapeType,uint plocalID) |
863 | givefakepos = 0; | 863 | { |
864 | 864 | Name = primName; | |
865 | PID_D = parent_scene.bodyPIDD; | 865 | LocalID = plocalID; |
866 | PID_G = parent_scene.bodyPIDG; | 866 | |
867 | m_density = parent_scene.geomDefaultDensity; | 867 | m_vehicle = null; |
868 | // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; | 868 | |
869 | body_autodisable_frames = parent_scene.bodyFramesAutoDisable; | 869 | if (!pos.IsFinite()) |
870 | 870 | { | |
871 | prim_geom = IntPtr.Zero; | 871 | pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), |
872 | collide_geom = IntPtr.Zero; | 872 | parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f); |
873 | Body = IntPtr.Zero; | 873 | m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Position for {0}", Name); |
874 | 874 | } | |
875 | if (!size.IsFinite()) | 875 | _position = pos; |
876 | { | 876 | givefakepos = 0; |
877 | size = new Vector3(0.5f, 0.5f, 0.5f); | 877 | |
878 | m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Size for {0}", Name); | 878 | PID_D = parent_scene.bodyPIDD; |
879 | } | 879 | PID_G = parent_scene.bodyPIDG; |
880 | 880 | m_density = parent_scene.geomDefaultDensity; | |
881 | if (size.X <= 0) size.X = 0.01f; | 881 | // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; |
882 | if (size.Y <= 0) size.Y = 0.01f; | 882 | body_autodisable_frames = parent_scene.bodyFramesAutoDisable; |
883 | if (size.Z <= 0) size.Z = 0.01f; | 883 | |
884 | 884 | prim_geom = IntPtr.Zero; | |
885 | _size = size; | 885 | collide_geom = IntPtr.Zero; |
886 | 886 | Body = IntPtr.Zero; | |
887 | if (!QuaternionIsFinite(rotation)) | 887 | |
888 | { | 888 | if (!size.IsFinite()) |
889 | rotation = Quaternion.Identity; | 889 | { |
890 | m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Rotation for {0}", Name); | 890 | size = new Vector3(0.5f, 0.5f, 0.5f); |
891 | } | 891 | m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Size for {0}", Name); |
892 | 892 | } | |
893 | _orientation = rotation; | 893 | |
894 | givefakeori = 0; | 894 | if (size.X <= 0) size.X = 0.01f; |
895 | 895 | if (size.Y <= 0) size.Y = 0.01f; | |
896 | _pbs = pbs; | 896 | if (size.Z <= 0) size.Z = 0.01f; |
897 | 897 | ||
898 | _parent_scene = parent_scene; | 898 | _size = size; |
899 | m_targetSpace = IntPtr.Zero; | 899 | |
900 | 900 | if (!QuaternionIsFinite(rotation)) | |
901 | if (pos.Z < 0) | 901 | { |
902 | { | 902 | rotation = Quaternion.Identity; |
903 | m_isphysical = false; | 903 | m_log.WarnFormat("[PHYSICS]: Got nonFinite Object create Rotation for {0}", Name); |
904 | } | 904 | } |
905 | else | 905 | |
906 | { | 906 | _orientation = rotation; |
907 | m_isphysical = pisPhysical; | 907 | givefakeori = 0; |
908 | } | 908 | |
909 | m_fakeisphysical = m_isphysical; | 909 | _pbs = pbs; |
910 | 910 | ||
911 | m_isVolumeDetect = false; | 911 | _parent_scene = parent_scene; |
912 | 912 | m_targetSpace = IntPtr.Zero; | |
913 | m_force = Vector3.Zero; | 913 | |
914 | 914 | if (pos.Z < 0) | |
915 | m_iscolliding = false; | 915 | { |
916 | m_colliderfilter = 0; | 916 | m_isphysical = false; |
917 | m_softcolide = true; | 917 | } |
918 | m_NoColide = false; | 918 | else |
919 | 919 | { | |
920 | hasOOBoffsetFromMesh = false; | 920 | m_isphysical = pisPhysical; |
921 | _triMeshData = IntPtr.Zero; | 921 | } |
922 | 922 | m_fakeisphysical = m_isphysical; | |
923 | m_shapetype = _shapeType; | 923 | |
924 | 924 | m_isVolumeDetect = false; | |
925 | m_lastdoneSelected = false; | 925 | |
926 | m_isSelected = false; | 926 | m_force = Vector3.Zero; |
927 | m_delaySelect = false; | 927 | |
928 | 928 | m_iscolliding = false; | |
929 | m_isphantom = pisPhantom; | 929 | m_colliderfilter = 0; |
930 | m_fakeisphantom = pisPhantom; | 930 | m_softcolide = true; |
931 | 931 | m_NoColide = false; | |
932 | mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; | 932 | |
933 | bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; | 933 | hasOOBoffsetFromMesh = false; |
934 | 934 | _triMeshData = IntPtr.Zero; | |
935 | CalcPrimBodyData(); | 935 | |
936 | 936 | m_shapetype = _shapeType; | |
937 | m_building = true; // control must set this to false when done | 937 | |
938 | 938 | m_lastdoneSelected = false; | |
939 | AddChange(changes.Add, null); | 939 | m_isSelected = false; |
940 | } | 940 | m_delaySelect = false; |
941 | 941 | ||
942 | private void resetCollisionAccounting() | 942 | m_isphantom = pisPhantom; |
943 | { | 943 | m_fakeisphantom = pisPhantom; |
944 | m_collisionscore = 0; | 944 | |
945 | } | 945 | mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; |
946 | 946 | bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; | |
947 | private void createAMotor(Vector3 axis) | 947 | |
948 | { | 948 | CalcPrimBodyData(); |
949 | if (Body == IntPtr.Zero) | 949 | |
950 | return; | 950 | m_building = true; // control must set this to false when done |
951 | 951 | ||
952 | if (Amotor != IntPtr.Zero) | 952 | AddChange(changes.Add, null); |
953 | { | 953 | } |
954 | d.JointDestroy(Amotor); | 954 | |
955 | Amotor = IntPtr.Zero; | 955 | private void resetCollisionAccounting() |
956 | } | 956 | { |
957 | 957 | m_collisionscore = 0; | |
958 | int axisnum = 3 - (int)(axis.X + axis.Y + axis.Z); | 958 | } |
959 | 959 | ||
960 | if (axisnum <= 0) | 960 | private void createAMotor(Vector3 axis) |
961 | return; | 961 | { |
962 | 962 | if (Body == IntPtr.Zero) | |
963 | // stop it | 963 | return; |
964 | d.BodySetTorque(Body, 0, 0, 0); | 964 | |
965 | d.BodySetAngularVel(Body, 0, 0, 0); | 965 | if (Amotor != IntPtr.Zero) |
966 | 966 | { | |
967 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); | 967 | d.JointDestroy(Amotor); |
968 | d.JointAttach(Amotor, Body, IntPtr.Zero); | 968 | Amotor = IntPtr.Zero; |
969 | 969 | } | |
970 | d.JointSetAMotorMode(Amotor, 0); | 970 | |
971 | 971 | int axisnum = 3 - (int)(axis.X + axis.Y + axis.Z); | |
972 | d.JointSetAMotorNumAxes(Amotor, axisnum); | 972 | |
973 | 973 | if (axisnum <= 0) | |
974 | // get current orientation to lock | 974 | return; |
975 | 975 | ||
976 | d.Quaternion dcur = d.BodyGetQuaternion(Body); | 976 | // stop it |
977 | Quaternion curr; // crap convertion between identical things | 977 | d.BodySetTorque(Body, 0, 0, 0); |
978 | curr.X = dcur.X; | 978 | d.BodySetAngularVel(Body, 0, 0, 0); |
979 | curr.Y = dcur.Y; | 979 | |
980 | curr.Z = dcur.Z; | 980 | Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); |
981 | curr.W = dcur.W; | 981 | d.JointAttach(Amotor, Body, IntPtr.Zero); |
982 | Vector3 ax; | 982 | |
983 | 983 | d.JointSetAMotorMode(Amotor, 0); | |
984 | int i = 0; | 984 | |
985 | int j = 0; | 985 | d.JointSetAMotorNumAxes(Amotor, axisnum); |
986 | if (axis.X == 0) | 986 | |
987 | { | 987 | // get current orientation to lock |
988 | ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X | 988 | |
989 | // ODE should do this with axis relative to body 1 but seems to fail | 989 | d.Quaternion dcur = d.BodyGetQuaternion(Body); |
990 | d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); | 990 | Quaternion curr; // crap convertion between identical things |
991 | d.JointSetAMotorAngle(Amotor, 0, 0); | 991 | curr.X = dcur.X; |
992 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, -0.000001f); | 992 | curr.Y = dcur.Y; |
993 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0.000001f); | 993 | curr.Z = dcur.Z; |
994 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); | 994 | curr.W = dcur.W; |
995 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); | 995 | Vector3 ax; |
996 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); | 996 | |
997 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); | 997 | int i = 0; |
998 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); | 998 | int j = 0; |
999 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); | 999 | if (axis.X == 0) |
1000 | i++; | 1000 | { |
1001 | j = 256; // move to next axis set | 1001 | ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X |
1002 | } | 1002 | // ODE should do this with axis relative to body 1 but seems to fail |
1003 | 1003 | d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); | |
1004 | if (axis.Y == 0) | 1004 | d.JointSetAMotorAngle(Amotor, 0, 0); |
1005 | { | 1005 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, -0.000001f); |
1006 | ax = (new Vector3(0, 1, 0)) * curr; | 1006 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0.000001f); |
1007 | d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); | 1007 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); |
1008 | d.JointSetAMotorAngle(Amotor, i, 0); | 1008 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); |
1009 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, -0.000001f); | 1009 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); |
1010 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0.000001f); | 1010 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); |
1011 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); | 1011 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); |
1012 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | 1012 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); |
1013 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | 1013 | i++; |
1014 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | 1014 | j = 256; // move to next axis set |
1015 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); | 1015 | } |
1016 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); | 1016 | |
1017 | i++; | 1017 | if (axis.Y == 0) |
1018 | j += 256; | 1018 | { |
1019 | } | 1019 | ax = (new Vector3(0, 1, 0)) * curr; |
1020 | 1020 | d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); | |
1021 | if (axis.Z == 0) | 1021 | d.JointSetAMotorAngle(Amotor, i, 0); |
1022 | { | 1022 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, -0.000001f); |
1023 | ax = (new Vector3(0, 0, 1)) * curr; | 1023 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0.000001f); |
1024 | d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); | 1024 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); |
1025 | d.JointSetAMotorAngle(Amotor, i, 0); | 1025 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); |
1026 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, -0.000001f); | 1026 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); |
1027 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0.000001f); | 1027 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); |
1028 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); | 1028 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); |
1029 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | 1029 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); |
1030 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | 1030 | i++; |
1031 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | 1031 | j += 256; |
1032 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); | 1032 | } |
1033 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); | 1033 | |
1034 | } | 1034 | if (axis.Z == 0) |
1035 | } | 1035 | { |
1036 | 1036 | ax = (new Vector3(0, 0, 1)) * curr; | |
1037 | private bool setMesh(OdeScene parent_scene) | 1037 | d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); |
1038 | { | 1038 | d.JointSetAMotorAngle(Amotor, i, 0); |
1039 | if (Body != IntPtr.Zero) | 1039 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, -0.000001f); |
1040 | { | 1040 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0.000001f); |
1041 | if (childPrim) | 1041 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); |
1042 | { | 1042 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); |
1043 | if (_parent != null) | 1043 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); |
1044 | { | 1044 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); |
1045 | OdePrim parent = (OdePrim)_parent; | 1045 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); |
1046 | parent.ChildDelink(this, false); | 1046 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); |
1047 | } | 1047 | } |
1048 | } | 1048 | } |
1049 | else | 1049 | |
1050 | { | 1050 | private bool setMesh(OdeScene parent_scene) |
1051 | DestroyBody(); | 1051 | { |
1052 | } | 1052 | if (Body != IntPtr.Zero) |
1053 | } | 1053 | { |
1054 | 1054 | if (childPrim) | |
1055 | bool convex; | 1055 | { |
1056 | if (m_shapetype == 0) | 1056 | if (_parent != null) |
1057 | convex = false; | 1057 | { |
1058 | else | 1058 | OdePrim parent = (OdePrim)_parent; |
1059 | convex = true; | 1059 | parent.ChildDelink(this, false); |
1060 | 1060 | } | |
1061 | IMesh mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true,convex); | 1061 | } |
1062 | if (mesh == null) | 1062 | else |
1063 | { | 1063 | { |
1064 | m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z); | 1064 | DestroyBody(); |
1065 | return false; | 1065 | } |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | IntPtr vertices, indices; | 1068 | bool convex; |
1069 | int vertexCount, indexCount; | 1069 | if (m_shapetype == 0) |
1070 | int vertexStride, triStride; | 1070 | convex = false; |
1071 | 1071 | else | |
1072 | mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap | 1072 | convex = true; |
1073 | mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage | 1073 | |
1074 | 1074 | IMesh mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true,convex); | |
1075 | if (vertexCount == 0 || indexCount == 0) | 1075 | if (mesh == null) |
1076 | { | 1076 | { |
1077 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", | 1077 | m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z); |
1078 | Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); | 1078 | return false; |
1079 | mesh.releaseSourceMeshData(); | 1079 | } |
1080 | return false; | 1080 | |
1081 | } | 1081 | IntPtr vertices, indices; |
1082 | 1082 | int vertexCount, indexCount; | |
1083 | primOOBoffset = mesh.GetCentroid(); | 1083 | int vertexStride, triStride; |
1084 | hasOOBoffsetFromMesh = true; | 1084 | |
1085 | 1085 | mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap | |
1086 | mesh.releaseSourceMeshData(); | 1086 | mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage |
1087 | 1087 | ||
1088 | IntPtr geo = IntPtr.Zero; | 1088 | if (vertexCount == 0 || indexCount == 0) |
1089 | 1089 | { | |
1090 | try | 1090 | m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", |
1091 | { | 1091 | Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); |
1092 | _triMeshData = d.GeomTriMeshDataCreate(); | 1092 | mesh.releaseSourceMeshData(); |
1093 | 1093 | return false; | |
1094 | d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); | 1094 | } |
1095 | d.GeomTriMeshDataPreprocess(_triMeshData); | 1095 | |
1096 | 1096 | primOOBoffset = mesh.GetCentroid(); | |
1097 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1097 | hasOOBoffsetFromMesh = true; |
1098 | geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); | 1098 | |
1099 | } | 1099 | mesh.releaseSourceMeshData(); |
1100 | 1100 | ||
1101 | catch (Exception e) | 1101 | IntPtr geo = IntPtr.Zero; |
1102 | { | 1102 | |
1103 | m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); | 1103 | try |
1104 | if (_triMeshData != IntPtr.Zero) | 1104 | { |
1105 | { | 1105 | _triMeshData = d.GeomTriMeshDataCreate(); |
1106 | d.GeomTriMeshDataDestroy(_triMeshData); | 1106 | |
1107 | _triMeshData = IntPtr.Zero; | 1107 | d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); |
1108 | } | 1108 | d.GeomTriMeshDataPreprocess(_triMeshData); |
1109 | return false; | 1109 | |
1110 | } | 1110 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1111 | 1111 | geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); | |
1112 | SetGeom(geo); | 1112 | } |
1113 | return true; | 1113 | |
1114 | } | 1114 | catch (Exception e) |
1115 | 1115 | { | |
1116 | private void SetGeom(IntPtr geom) | 1116 | m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); |
1117 | { | 1117 | if (_triMeshData != IntPtr.Zero) |
1118 | prim_geom = geom; | 1118 | { |
1119 | //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); | 1119 | d.GeomTriMeshDataDestroy(_triMeshData); |
1120 | if (prim_geom != IntPtr.Zero) | 1120 | _triMeshData = IntPtr.Zero; |
1121 | { | 1121 | } |
1122 | if (m_NoColide) | 1122 | return false; |
1123 | { | 1123 | } |
1124 | d.GeomSetCategoryBits(prim_geom, 0); | 1124 | |
1125 | if (m_isphysical) | 1125 | SetGeom(geo); |
1126 | { | 1126 | return true; |
1127 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | 1127 | } |
1128 | } | 1128 | |
1129 | else | 1129 | private void SetGeom(IntPtr geom) |
1130 | { | 1130 | { |
1131 | d.GeomSetCollideBits(prim_geom, 0); | 1131 | prim_geom = geom; |
1132 | d.GeomDisable(prim_geom); | 1132 | //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); |
1133 | } | 1133 | if (prim_geom != IntPtr.Zero) |
1134 | } | 1134 | { |
1135 | else | 1135 | if (m_NoColide) |
1136 | { | 1136 | { |
1137 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1137 | d.GeomSetCategoryBits(prim_geom, 0); |
1138 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1138 | if (m_isphysical) |
1139 | } | 1139 | { |
1140 | 1140 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | |
1141 | CalcPrimBodyData(); | 1141 | } |
1142 | 1142 | else | |
1143 | _parent_scene.geom_name_map[prim_geom] = Name; | 1143 | { |
1144 | _parent_scene.actor_name_map[prim_geom] = this; | 1144 | d.GeomSetCollideBits(prim_geom, 0); |
1145 | 1145 | d.GeomDisable(prim_geom); | |
1146 | } | 1146 | } |
1147 | else | 1147 | } |
1148 | m_log.Warn("Setting bad Geom"); | 1148 | else |
1149 | } | 1149 | { |
1150 | 1150 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | |
1151 | 1151 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | |
1152 | /// <summary> | 1152 | } |
1153 | /// Create a geometry for the given mesh in the given target space. | 1153 | |
1154 | /// </summary> | 1154 | CalcPrimBodyData(); |
1155 | /// <param name="m_targetSpace"></param> | 1155 | |
1156 | /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param> | 1156 | _parent_scene.geom_name_map[prim_geom] = Name; |
1157 | private void CreateGeom() | 1157 | _parent_scene.actor_name_map[prim_geom] = this; |
1158 | { | 1158 | |
1159 | if (_triMeshData != IntPtr.Zero) | 1159 | } |
1160 | { | 1160 | else |
1161 | d.GeomTriMeshDataDestroy(_triMeshData); | 1161 | m_log.Warn("Setting bad Geom"); |
1162 | _triMeshData = IntPtr.Zero; | 1162 | } |
1163 | } | 1163 | |
1164 | 1164 | ||
1165 | bool haveMesh = false; | 1165 | /// <summary> |
1166 | hasOOBoffsetFromMesh = false; | 1166 | /// Create a geometry for the given mesh in the given target space. |
1167 | m_NoColide = false; | 1167 | /// </summary> |
1168 | 1168 | /// <param name="m_targetSpace"></param> | |
1169 | if (_parent_scene.needsMeshing(_pbs)) | 1169 | /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param> |
1170 | { | 1170 | private void CreateGeom() |
1171 | haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims | 1171 | { |
1172 | if (!haveMesh) | 1172 | if (_triMeshData != IntPtr.Zero) |
1173 | m_NoColide = true; | 1173 | { |
1174 | } | 1174 | d.GeomTriMeshDataDestroy(_triMeshData); |
1175 | 1175 | _triMeshData = IntPtr.Zero; | |
1176 | if (!haveMesh) | 1176 | } |
1177 | { | 1177 | |
1178 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 | 1178 | bool haveMesh = false; |
1179 | && _size.X == _size.Y && _size.Y == _size.Z) | 1179 | hasOOBoffsetFromMesh = false; |
1180 | { // it's a sphere | 1180 | m_NoColide = false; |
1181 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1181 | |
1182 | try | 1182 | if (_parent_scene.needsMeshing(_pbs)) |
1183 | { | 1183 | { |
1184 | SetGeom(d.CreateSphere(m_targetSpace, _size.X * 0.5f)); | 1184 | haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims |
1185 | } | 1185 | if (!haveMesh) |
1186 | catch (Exception e) | 1186 | m_NoColide = true; |
1187 | { | 1187 | } |
1188 | m_log.WarnFormat("[PHYSICS]: Create sphere failed: {0}", e); | 1188 | |
1189 | return; | 1189 | if (!haveMesh) |
1190 | } | 1190 | { |
1191 | } | 1191 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 |
1192 | else | 1192 | && _size.X == _size.Y && _size.Y == _size.Z) |
1193 | {// do it as a box | 1193 | { // it's a sphere |
1194 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1194 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1195 | try | 1195 | try |
1196 | { | 1196 | { |
1197 | //Console.WriteLine(" CreateGeom 4"); | 1197 | SetGeom(d.CreateSphere(m_targetSpace, _size.X * 0.5f)); |
1198 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); | 1198 | } |
1199 | } | 1199 | catch (Exception e) |
1200 | catch (Exception e) | 1200 | { |
1201 | { | 1201 | m_log.WarnFormat("[PHYSICS]: Create sphere failed: {0}", e); |
1202 | m_log.Warn("[PHYSICS]: Create box failed: {0}", e); | 1202 | return; |
1203 | return; | 1203 | } |
1204 | } | 1204 | } |
1205 | } | 1205 | else |
1206 | } | 1206 | {// do it as a box |
1207 | } | 1207 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1208 | 1208 | try | |
1209 | /// <summary> | 1209 | { |
1210 | /// Set a new geometry for this prim. | 1210 | //Console.WriteLine(" CreateGeom 4"); |
1211 | /// </summary> | 1211 | SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); |
1212 | /// <param name="geom"></param> | 1212 | } |
1213 | private void RemoveGeom() | 1213 | catch (Exception e) |
1214 | { | 1214 | { |
1215 | if (prim_geom != IntPtr.Zero) | 1215 | m_log.Warn("[PHYSICS]: Create box failed: {0}", e); |
1216 | { | 1216 | return; |
1217 | _parent_scene.geom_name_map.Remove(prim_geom); | 1217 | } |
1218 | _parent_scene.actor_name_map.Remove(prim_geom); | 1218 | } |
1219 | try | 1219 | } |
1220 | { | 1220 | } |
1221 | d.GeomDestroy(prim_geom); | 1221 | |
1222 | if (_triMeshData != IntPtr.Zero) | 1222 | /// <summary> |
1223 | { | 1223 | /// Set a new geometry for this prim. |
1224 | d.GeomTriMeshDataDestroy(_triMeshData); | 1224 | /// </summary> |
1225 | _triMeshData = IntPtr.Zero; | 1225 | /// <param name="geom"></param> |
1226 | } | 1226 | private void RemoveGeom() |
1227 | } | 1227 | { |
1228 | // catch (System.AccessViolationException) | 1228 | if (prim_geom != IntPtr.Zero) |
1229 | catch (Exception e) | 1229 | { |
1230 | { | 1230 | _parent_scene.geom_name_map.Remove(prim_geom); |
1231 | m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e); | 1231 | _parent_scene.actor_name_map.Remove(prim_geom); |
1232 | } | 1232 | try |
1233 | 1233 | { | |
1234 | prim_geom = IntPtr.Zero; | 1234 | d.GeomDestroy(prim_geom); |
1235 | } | 1235 | if (_triMeshData != IntPtr.Zero) |
1236 | else | 1236 | { |
1237 | { | 1237 | d.GeomTriMeshDataDestroy(_triMeshData); |
1238 | m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); | 1238 | _triMeshData = IntPtr.Zero; |
1239 | } | 1239 | } |
1240 | Body = IntPtr.Zero; | 1240 | } |
1241 | hasOOBoffsetFromMesh = false; | 1241 | // catch (System.AccessViolationException) |
1242 | CalcPrimBodyData(); | 1242 | catch (Exception e) |
1243 | } | 1243 | { |
1244 | 1244 | m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e); | |
1245 | private void ChildSetGeom(OdePrim odePrim) | 1245 | } |
1246 | { | 1246 | |
1247 | // well.. | 1247 | prim_geom = IntPtr.Zero; |
1248 | DestroyBody(); | 1248 | } |
1249 | MakeBody(); | 1249 | else |
1250 | } | 1250 | { |
1251 | 1251 | m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); | |
1252 | //sets non physical prim m_targetSpace to right space in spaces grid for static prims | 1252 | } |
1253 | // should only be called for non physical prims unless they are becoming non physical | 1253 | Body = IntPtr.Zero; |
1254 | private void SetInStaticSpace(OdePrim prim) | 1254 | hasOOBoffsetFromMesh = false; |
1255 | { | 1255 | CalcPrimBodyData(); |
1256 | IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace); | 1256 | } |
1257 | prim.m_targetSpace = targetSpace; | 1257 | |
1258 | d.GeomEnable(prim_geom); | 1258 | private void ChildSetGeom(OdePrim odePrim) |
1259 | } | 1259 | { |
1260 | 1260 | // well.. | |
1261 | public void enableBodySoft() | 1261 | DestroyBody(); |
1262 | { | 1262 | MakeBody(); |
1263 | if (!childPrim && !m_isSelected) | 1263 | } |
1264 | { | 1264 | |
1265 | if (m_isphysical && Body != IntPtr.Zero) | 1265 | //sets non physical prim m_targetSpace to right space in spaces grid for static prims |
1266 | { | 1266 | // should only be called for non physical prims unless they are becoming non physical |
1267 | if (m_isphantom && !m_isVolumeDetect) | 1267 | private void SetInStaticSpace(OdePrim prim) |
1268 | { | 1268 | { |
1269 | m_collisionCategories = 0; | 1269 | IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace); |
1270 | m_collisionFlags = CollisionCategories.Land; | 1270 | prim.m_targetSpace = targetSpace; |
1271 | } | 1271 | d.GeomEnable(prim_geom); |
1272 | else | 1272 | } |
1273 | { | 1273 | |
1274 | m_collisionCategories |= CollisionCategories.Body; | 1274 | public void enableBodySoft() |
1275 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1275 | { |
1276 | } | 1276 | if (!childPrim && !m_isSelected) |
1277 | 1277 | { | |
1278 | foreach (OdePrim prm in childrenPrim) | 1278 | if (m_isphysical && Body != IntPtr.Zero) |
1279 | { | 1279 | { |
1280 | prm.m_collisionCategories = m_collisionCategories; | 1280 | if (m_isphantom && !m_isVolumeDetect) |
1281 | prm.m_collisionFlags = m_collisionFlags; | 1281 | { |
1282 | 1282 | m_collisionCategories = 0; | |
1283 | if (prm.prim_geom != IntPtr.Zero) | 1283 | m_collisionFlags = CollisionCategories.Land; |
1284 | { | 1284 | } |
1285 | if (prm.m_NoColide) | 1285 | else |
1286 | { | 1286 | { |
1287 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 1287 | m_collisionCategories |= CollisionCategories.Body; |
1288 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); | 1288 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1289 | } | 1289 | } |
1290 | else | 1290 | |
1291 | { | 1291 | foreach (OdePrim prm in childrenPrim) |
1292 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); | 1292 | { |
1293 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); | 1293 | prm.m_collisionCategories = m_collisionCategories; |
1294 | } | 1294 | prm.m_collisionFlags = m_collisionFlags; |
1295 | d.GeomEnable(prm.prim_geom); | 1295 | |
1296 | } | 1296 | if (prm.prim_geom != IntPtr.Zero) |
1297 | } | 1297 | { |
1298 | 1298 | if (prm.m_NoColide) | |
1299 | if (prim_geom != IntPtr.Zero) | 1299 | { |
1300 | { | 1300 | d.GeomSetCategoryBits(prm.prim_geom, 0); |
1301 | if (m_NoColide) | 1301 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); |
1302 | { | 1302 | } |
1303 | d.GeomSetCategoryBits(prim_geom, 0); | 1303 | else |
1304 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | 1304 | { |
1305 | } | 1305 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); |
1306 | else | 1306 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); |
1307 | { | 1307 | } |
1308 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1308 | d.GeomEnable(prm.prim_geom); |
1309 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1309 | } |
1310 | } | 1310 | } |
1311 | d.GeomEnable(prim_geom); | 1311 | |
1312 | } | 1312 | if (prim_geom != IntPtr.Zero) |
1313 | d.BodyEnable(Body); | 1313 | { |
1314 | } | 1314 | if (m_NoColide) |
1315 | } | 1315 | { |
1316 | m_disabled = false; | 1316 | d.GeomSetCategoryBits(prim_geom, 0); |
1317 | resetCollisionAccounting(); // this sets m_disable to false | 1317 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); |
1318 | } | 1318 | } |
1319 | 1319 | else | |
1320 | private void disableBodySoft() | 1320 | { |
1321 | { | 1321 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1322 | m_disabled = true; | 1322 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1323 | if (!childPrim) | 1323 | } |
1324 | { | 1324 | d.GeomEnable(prim_geom); |
1325 | if (m_isphysical && Body != IntPtr.Zero) | 1325 | } |
1326 | { | 1326 | d.BodyEnable(Body); |
1327 | m_collisionCategories &= ~CollisionCategories.Body; | 1327 | } |
1328 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); | 1328 | } |
1329 | 1329 | m_disabled = false; | |
1330 | foreach (OdePrim prm in childrenPrim) | 1330 | resetCollisionAccounting(); // this sets m_disable to false |
1331 | { | 1331 | } |
1332 | prm.m_collisionCategories = m_collisionCategories; | 1332 | |
1333 | prm.m_collisionFlags = m_collisionFlags; | 1333 | private void disableBodySoft() |
1334 | 1334 | { | |
1335 | if (prm.prim_geom != IntPtr.Zero) | 1335 | m_disabled = true; |
1336 | { | 1336 | if (!childPrim) |
1337 | if (prm.m_NoColide) | 1337 | { |
1338 | { | 1338 | if (m_isphysical && Body != IntPtr.Zero) |
1339 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 1339 | { |
1340 | d.GeomSetCollideBits(prm.prim_geom, 0); | 1340 | m_collisionCategories &= ~CollisionCategories.Body; |
1341 | } | 1341 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); |
1342 | else | 1342 | |
1343 | { | 1343 | foreach (OdePrim prm in childrenPrim) |
1344 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); | 1344 | { |
1345 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); | 1345 | prm.m_collisionCategories = m_collisionCategories; |
1346 | } | 1346 | prm.m_collisionFlags = m_collisionFlags; |
1347 | d.GeomDisable(prm.prim_geom); | 1347 | |
1348 | } | 1348 | if (prm.prim_geom != IntPtr.Zero) |
1349 | } | 1349 | { |
1350 | 1350 | if (prm.m_NoColide) | |
1351 | if (prim_geom != IntPtr.Zero) | 1351 | { |
1352 | { | 1352 | d.GeomSetCategoryBits(prm.prim_geom, 0); |
1353 | if (m_NoColide) | 1353 | d.GeomSetCollideBits(prm.prim_geom, 0); |
1354 | { | 1354 | } |
1355 | d.GeomSetCategoryBits(prim_geom, 0); | 1355 | else |
1356 | d.GeomSetCollideBits(prim_geom, 0); | 1356 | { |
1357 | } | 1357 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); |
1358 | else | 1358 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); |
1359 | { | 1359 | } |
1360 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1360 | d.GeomDisable(prm.prim_geom); |
1361 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1361 | } |
1362 | } | 1362 | } |
1363 | d.GeomDisable(prim_geom); | 1363 | |
1364 | } | 1364 | if (prim_geom != IntPtr.Zero) |
1365 | 1365 | { | |
1366 | d.BodyDisable(Body); | 1366 | if (m_NoColide) |
1367 | } | 1367 | { |
1368 | } | 1368 | d.GeomSetCategoryBits(prim_geom, 0); |
1369 | } | 1369 | d.GeomSetCollideBits(prim_geom, 0); |
1370 | 1370 | } | |
1371 | private void MakeBody() | 1371 | else |
1372 | { | 1372 | { |
1373 | if (!m_isphysical) // only physical get bodies | 1373 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1374 | return; | 1374 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1375 | 1375 | } | |
1376 | if (childPrim) // child prims don't get bodies; | 1376 | d.GeomDisable(prim_geom); |
1377 | return; | 1377 | } |
1378 | 1378 | ||
1379 | if (m_building) | 1379 | d.BodyDisable(Body); |
1380 | return; | 1380 | } |
1381 | 1381 | } | |
1382 | if (prim_geom == IntPtr.Zero) | 1382 | } |
1383 | { | 1383 | |
1384 | m_log.Warn("[PHYSICS]: Unable to link the linkset. Root has no geom yet"); | 1384 | private void MakeBody() |
1385 | return; | 1385 | { |
1386 | } | 1386 | if (!m_isphysical) // only physical get bodies |
1387 | 1387 | return; | |
1388 | if (Body != IntPtr.Zero) | 1388 | |
1389 | { | 1389 | if (childPrim) // child prims don't get bodies; |
1390 | d.BodyDestroy(Body); | 1390 | return; |
1391 | Body = IntPtr.Zero; | 1391 | |
1392 | m_log.Warn("[PHYSICS]: MakeBody called having a body"); | 1392 | if (m_building) |
1393 | } | 1393 | return; |
1394 | 1394 | ||
1395 | 1395 | if (prim_geom == IntPtr.Zero) | |
1396 | if (d.GeomGetBody(prim_geom) != IntPtr.Zero) | 1396 | { |
1397 | { | 1397 | m_log.Warn("[PHYSICS]: Unable to link the linkset. Root has no geom yet"); |
1398 | d.GeomSetBody(prim_geom, IntPtr.Zero); | 1398 | return; |
1399 | m_log.Warn("[PHYSICS]: MakeBody root geom already had a body"); | 1399 | } |
1400 | } | 1400 | |
1401 | 1401 | if (Body != IntPtr.Zero) | |
1402 | d.Matrix3 mymat = new d.Matrix3(); | 1402 | { |
1403 | d.Quaternion myrot = new d.Quaternion(); | 1403 | d.BodyDestroy(Body); |
1404 | d.Mass objdmass = new d.Mass { }; | 1404 | Body = IntPtr.Zero; |
1405 | 1405 | m_log.Warn("[PHYSICS]: MakeBody called having a body"); | |
1406 | Body = d.BodyCreate(_parent_scene.world); | 1406 | } |
1407 | 1407 | ||
1408 | DMassDup(ref primdMass, out objdmass); | 1408 | |
1409 | 1409 | if (d.GeomGetBody(prim_geom) != IntPtr.Zero) | |
1410 | // rotate inertia | 1410 | { |
1411 | myrot.X = _orientation.X; | 1411 | d.GeomSetBody(prim_geom, IntPtr.Zero); |
1412 | myrot.Y = _orientation.Y; | 1412 | m_log.Warn("[PHYSICS]: MakeBody root geom already had a body"); |
1413 | myrot.Z = _orientation.Z; | 1413 | } |
1414 | myrot.W = _orientation.W; | 1414 | |
1415 | 1415 | d.Matrix3 mymat = new d.Matrix3(); | |
1416 | d.RfromQ(out mymat, ref myrot); | 1416 | d.Quaternion myrot = new d.Quaternion(); |
1417 | d.MassRotate(ref objdmass, ref mymat); | 1417 | d.Mass objdmass = new d.Mass { }; |
1418 | 1418 | ||
1419 | // set the body rotation and position | 1419 | Body = d.BodyCreate(_parent_scene.world); |
1420 | d.BodySetRotation(Body, ref mymat); | 1420 | |
1421 | 1421 | DMassDup(ref primdMass, out objdmass); | |
1422 | // recompute full object inertia if needed | 1422 | |
1423 | if (childrenPrim.Count > 0) | 1423 | // rotate inertia |
1424 | { | 1424 | myrot.X = _orientation.X; |
1425 | d.Matrix3 mat = new d.Matrix3(); | 1425 | myrot.Y = _orientation.Y; |
1426 | d.Quaternion quat = new d.Quaternion(); | 1426 | myrot.Z = _orientation.Z; |
1427 | d.Mass tmpdmass = new d.Mass { }; | 1427 | myrot.W = _orientation.W; |
1428 | Vector3 rcm; | 1428 | |
1429 | 1429 | d.RfromQ(out mymat, ref myrot); | |
1430 | rcm.X = _position.X + objdmass.c.X; | 1430 | d.MassRotate(ref objdmass, ref mymat); |
1431 | rcm.Y = _position.Y + objdmass.c.Y; | 1431 | |
1432 | rcm.Z = _position.Z + objdmass.c.Z; | 1432 | // set the body rotation and position |
1433 | 1433 | d.BodySetRotation(Body, ref mymat); | |
1434 | lock (childrenPrim) | 1434 | |
1435 | { | 1435 | // recompute full object inertia if needed |
1436 | foreach (OdePrim prm in childrenPrim) | 1436 | if (childrenPrim.Count > 0) |
1437 | { | 1437 | { |
1438 | if (prm.prim_geom == IntPtr.Zero) | 1438 | d.Matrix3 mat = new d.Matrix3(); |
1439 | { | 1439 | d.Quaternion quat = new d.Quaternion(); |
1440 | m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements, skipping it. No geom yet"); | 1440 | d.Mass tmpdmass = new d.Mass { }; |
1441 | continue; | 1441 | Vector3 rcm; |
1442 | } | 1442 | |
1443 | 1443 | rcm.X = _position.X + objdmass.c.X; | |
1444 | DMassCopy(ref prm.primdMass, ref tmpdmass); | 1444 | rcm.Y = _position.Y + objdmass.c.Y; |
1445 | 1445 | rcm.Z = _position.Z + objdmass.c.Z; | |
1446 | // apply prim current rotation to inertia | 1446 | |
1447 | quat.X = prm._orientation.X; | 1447 | lock (childrenPrim) |
1448 | quat.Y = prm._orientation.Y; | 1448 | { |
1449 | quat.Z = prm._orientation.Z; | 1449 | foreach (OdePrim prm in childrenPrim) |
1450 | quat.W = prm._orientation.W; | 1450 | { |
1451 | d.RfromQ(out mat, ref quat); | 1451 | if (prm.prim_geom == IntPtr.Zero) |
1452 | d.MassRotate(ref tmpdmass, ref mat); | 1452 | { |
1453 | 1453 | m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements, skipping it. No geom yet"); | |
1454 | Vector3 ppos = prm._position; | 1454 | continue; |
1455 | ppos.X += tmpdmass.c.X - rcm.X; | 1455 | } |
1456 | ppos.Y += tmpdmass.c.Y - rcm.Y; | 1456 | |
1457 | ppos.Z += tmpdmass.c.Z - rcm.Z; | 1457 | DMassCopy(ref prm.primdMass, ref tmpdmass); |
1458 | 1458 | ||
1459 | // refer inertia to root prim center of mass position | 1459 | // apply prim current rotation to inertia |
1460 | d.MassTranslate(ref tmpdmass, | 1460 | quat.X = prm._orientation.X; |
1461 | ppos.X, | 1461 | quat.Y = prm._orientation.Y; |
1462 | ppos.Y, | 1462 | quat.Z = prm._orientation.Z; |
1463 | ppos.Z); | 1463 | quat.W = prm._orientation.W; |
1464 | 1464 | d.RfromQ(out mat, ref quat); | |
1465 | d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia | 1465 | d.MassRotate(ref tmpdmass, ref mat); |
1466 | // fix prim colision cats | 1466 | |
1467 | 1467 | Vector3 ppos = prm._position; | |
1468 | if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero) | 1468 | ppos.X += tmpdmass.c.X - rcm.X; |
1469 | { | 1469 | ppos.Y += tmpdmass.c.Y - rcm.Y; |
1470 | d.GeomSetBody(prm.prim_geom, IntPtr.Zero); | 1470 | ppos.Z += tmpdmass.c.Z - rcm.Z; |
1471 | m_log.Warn("[PHYSICS]: MakeBody child geom already had a body"); | 1471 | |
1472 | } | 1472 | // refer inertia to root prim center of mass position |
1473 | 1473 | d.MassTranslate(ref tmpdmass, | |
1474 | d.GeomClearOffset(prm.prim_geom); | 1474 | ppos.X, |
1475 | d.GeomSetBody(prm.prim_geom, Body); | 1475 | ppos.Y, |
1476 | prm.Body = Body; | 1476 | ppos.Z); |
1477 | d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation | 1477 | |
1478 | } | 1478 | d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia |
1479 | } | 1479 | // fix prim colision cats |
1480 | } | 1480 | |
1481 | 1481 | if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero) | |
1482 | d.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset | 1482 | { |
1483 | // associate root geom with body | 1483 | d.GeomSetBody(prm.prim_geom, IntPtr.Zero); |
1484 | d.GeomSetBody(prim_geom, Body); | 1484 | m_log.Warn("[PHYSICS]: MakeBody child geom already had a body"); |
1485 | 1485 | } | |
1486 | d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); | 1486 | |
1487 | d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); | 1487 | d.GeomClearOffset(prm.prim_geom); |
1488 | 1488 | d.GeomSetBody(prm.prim_geom, Body); | |
1489 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body | 1489 | prm.Body = Body; |
1490 | myrot.W = -myrot.W; | 1490 | d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation |
1491 | d.RfromQ(out mymat, ref myrot); | 1491 | } |
1492 | d.MassRotate(ref objdmass, ref mymat); | 1492 | } |
1493 | d.BodySetMass(Body, ref objdmass); | 1493 | } |
1494 | _mass = objdmass.mass; | 1494 | |
1495 | 1495 | d.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset | |
1496 | // disconnect from world gravity so we can apply buoyancy | 1496 | // associate root geom with body |
1497 | d.BodySetGravityMode(Body, false); | 1497 | d.GeomSetBody(prim_geom, Body); |
1498 | 1498 | ||
1499 | d.BodySetAutoDisableFlag(Body, true); | 1499 | d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); |
1500 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1500 | d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); |
1501 | // d.BodySetLinearDampingThreshold(Body, 0.01f); | 1501 | |
1502 | // d.BodySetAngularDampingThreshold(Body, 0.001f); | 1502 | d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body |
1503 | d.BodySetDamping(Body, .002f, .002f); | 1503 | myrot.W = -myrot.W; |
1504 | 1504 | d.RfromQ(out mymat, ref myrot); | |
1505 | 1505 | d.MassRotate(ref objdmass, ref mymat); | |
1506 | if (m_targetSpace != IntPtr.Zero) | 1506 | d.BodySetMass(Body, ref objdmass); |
1507 | { | 1507 | _mass = objdmass.mass; |
1508 | _parent_scene.waitForSpaceUnlock(m_targetSpace); | 1508 | |
1509 | if (d.SpaceQuery(m_targetSpace, prim_geom)) | 1509 | // disconnect from world gravity so we can apply buoyancy |
1510 | d.SpaceRemove(m_targetSpace, prim_geom); | 1510 | d.BodySetGravityMode(Body, false); |
1511 | } | 1511 | |
1512 | 1512 | d.BodySetAutoDisableFlag(Body, true); | |
1513 | 1513 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | |
1514 | if (childrenPrim.Count == 0) | 1514 | // d.BodySetLinearDampingThreshold(Body, 0.01f); |
1515 | { | 1515 | // d.BodySetAngularDampingThreshold(Body, 0.001f); |
1516 | collide_geom = prim_geom; | 1516 | d.BodySetDamping(Body, .002f, .002f); |
1517 | m_targetSpace = _parent_scene.ActiveSpace; | 1517 | |
1518 | d.SpaceAdd(m_targetSpace, prim_geom); | 1518 | |
1519 | } | 1519 | if (m_targetSpace != IntPtr.Zero) |
1520 | else | 1520 | { |
1521 | { | 1521 | _parent_scene.waitForSpaceUnlock(m_targetSpace); |
1522 | m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace); | 1522 | if (d.SpaceQuery(m_targetSpace, prim_geom)) |
1523 | d.HashSpaceSetLevels(m_targetSpace, -2, 8); | 1523 | d.SpaceRemove(m_targetSpace, prim_geom); |
1524 | d.SpaceSetSublevel(m_targetSpace, 3); | 1524 | } |
1525 | d.SpaceSetCleanup(m_targetSpace, false); | 1525 | |
1526 | d.SpaceAdd(m_targetSpace, prim_geom); | 1526 | |
1527 | collide_geom = m_targetSpace; | 1527 | if (childrenPrim.Count == 0) |
1528 | } | 1528 | { |
1529 | 1529 | collide_geom = prim_geom; | |
1530 | if (m_delaySelect) | 1530 | m_targetSpace = _parent_scene.ActiveSpace; |
1531 | { | 1531 | d.SpaceAdd(m_targetSpace, prim_geom); |
1532 | m_isSelected = true; | 1532 | } |
1533 | m_delaySelect = false; | 1533 | else |
1534 | } | 1534 | { |
1535 | 1535 | m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace); | |
1536 | lock (childrenPrim) | 1536 | d.HashSpaceSetLevels(m_targetSpace, -2, 8); |
1537 | { | 1537 | d.SpaceSetSublevel(m_targetSpace, 3); |
1538 | foreach (OdePrim prm in childrenPrim) | 1538 | d.SpaceSetCleanup(m_targetSpace, false); |
1539 | { | 1539 | d.SpaceAdd(m_targetSpace, prim_geom); |
1540 | if (prm.prim_geom == IntPtr.Zero) | 1540 | collide_geom = m_targetSpace; |
1541 | continue; | 1541 | } |
1542 | 1542 | ||
1543 | Vector3 ppos = prm._position; | 1543 | if (m_delaySelect) |
1544 | d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position | 1544 | { |
1545 | 1545 | m_isSelected = true; | |
1546 | if (prm.m_targetSpace != m_targetSpace) | 1546 | m_delaySelect = false; |
1547 | { | 1547 | } |
1548 | if (prm.m_targetSpace != IntPtr.Zero) | 1548 | |
1549 | { | 1549 | lock (childrenPrim) |
1550 | _parent_scene.waitForSpaceUnlock(prm.m_targetSpace); | 1550 | { |
1551 | if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) | 1551 | foreach (OdePrim prm in childrenPrim) |
1552 | d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); | 1552 | { |
1553 | } | 1553 | if (prm.prim_geom == IntPtr.Zero) |
1554 | prm.m_targetSpace = m_targetSpace; | 1554 | continue; |
1555 | d.SpaceAdd(m_targetSpace, prm.prim_geom); | 1555 | |
1556 | } | 1556 | Vector3 ppos = prm._position; |
1557 | 1557 | d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position | |
1558 | if (m_isSelected || m_disabled) | 1558 | |
1559 | { | 1559 | if (prm.m_targetSpace != m_targetSpace) |
1560 | prm.m_collisionCategories &= ~CollisionCategories.Body; | 1560 | { |
1561 | prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind); | 1561 | if (prm.m_targetSpace != IntPtr.Zero) |
1562 | d.GeomDisable(prm.prim_geom); | 1562 | { |
1563 | } | 1563 | _parent_scene.waitForSpaceUnlock(prm.m_targetSpace); |
1564 | else | 1564 | if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) |
1565 | { | 1565 | d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); |
1566 | if (m_isphantom && !m_isVolumeDetect) | 1566 | } |
1567 | { | 1567 | prm.m_targetSpace = m_targetSpace; |
1568 | prm.m_collisionCategories = 0; | 1568 | d.SpaceAdd(m_targetSpace, prm.prim_geom); |
1569 | prm.m_collisionFlags = CollisionCategories.Land; | 1569 | } |
1570 | } | 1570 | |
1571 | else | 1571 | if (m_isSelected || m_disabled) |
1572 | { | 1572 | { |
1573 | prm.m_collisionCategories |= CollisionCategories.Body; | 1573 | prm.m_collisionCategories &= ~CollisionCategories.Body; |
1574 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1574 | prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind); |
1575 | } | 1575 | d.GeomDisable(prm.prim_geom); |
1576 | d.GeomEnable(prm.prim_geom); | 1576 | } |
1577 | } | 1577 | else |
1578 | 1578 | { | |
1579 | if (prm.m_NoColide) | 1579 | if (m_isphantom && !m_isVolumeDetect) |
1580 | { | 1580 | { |
1581 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 1581 | prm.m_collisionCategories = 0; |
1582 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); | 1582 | prm.m_collisionFlags = CollisionCategories.Land; |
1583 | d.GeomEnable(prm.prim_geom); | 1583 | } |
1584 | } | 1584 | else |
1585 | else | 1585 | { |
1586 | { | 1586 | prm.m_collisionCategories |= CollisionCategories.Body; |
1587 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); | 1587 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1588 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); | 1588 | } |
1589 | } | 1589 | d.GeomEnable(prm.prim_geom); |
1590 | prm.m_collisionscore = 0; | 1590 | } |
1591 | 1591 | ||
1592 | if(!m_disabled) | 1592 | if (prm.m_NoColide) |
1593 | prm.m_disabled = false; | 1593 | { |
1594 | 1594 | d.GeomSetCategoryBits(prm.prim_geom, 0); | |
1595 | _parent_scene.addActivePrim(prm); | 1595 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); |
1596 | } | 1596 | d.GeomEnable(prm.prim_geom); |
1597 | } | 1597 | } |
1598 | 1598 | else | |
1599 | // The body doesn't already have a finite rotation mode set here | 1599 | { |
1600 | if ((!m_angularlock.ApproxEquals(Vector3.One, 0.0f)) && _parent == null) | 1600 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); |
1601 | { | 1601 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); |
1602 | createAMotor(m_angularlock); | 1602 | } |
1603 | } | 1603 | prm.m_collisionscore = 0; |
1604 | 1604 | ||
1605 | if (m_isSelected || m_disabled) | 1605 | if(!m_disabled) |
1606 | { | 1606 | prm.m_disabled = false; |
1607 | m_collisionCategories &= ~CollisionCategories.Body; | 1607 | |
1608 | m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind); | 1608 | _parent_scene.addActivePrim(prm); |
1609 | 1609 | } | |
1610 | d.GeomDisable(prim_geom); | 1610 | } |
1611 | d.BodyDisable(Body); | 1611 | |
1612 | } | 1612 | // The body doesn't already have a finite rotation mode set here |
1613 | else | 1613 | if ((!m_angularlock.ApproxEquals(Vector3.One, 0.0f)) && _parent == null) |
1614 | { | 1614 | { |
1615 | if (m_isphantom && !m_isVolumeDetect) | 1615 | createAMotor(m_angularlock); |
1616 | { | 1616 | } |
1617 | m_collisionCategories = 0; | 1617 | |
1618 | m_collisionFlags = CollisionCategories.Land; | 1618 | if (m_isSelected || m_disabled) |
1619 | } | 1619 | { |
1620 | else | 1620 | m_collisionCategories &= ~CollisionCategories.Body; |
1621 | { | 1621 | m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind); |
1622 | m_collisionCategories |= CollisionCategories.Body; | 1622 | |
1623 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1623 | d.GeomDisable(prim_geom); |
1624 | } | 1624 | d.BodyDisable(Body); |
1625 | 1625 | } | |
1626 | d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); | 1626 | else |
1627 | d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); | 1627 | { |
1628 | } | 1628 | if (m_isphantom && !m_isVolumeDetect) |
1629 | 1629 | { | |
1630 | if (m_NoColide) | 1630 | m_collisionCategories = 0; |
1631 | { | 1631 | m_collisionFlags = CollisionCategories.Land; |
1632 | d.GeomSetCategoryBits(prim_geom, 0); | 1632 | } |
1633 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | 1633 | else |
1634 | } | 1634 | { |
1635 | else | 1635 | m_collisionCategories |= CollisionCategories.Body; |
1636 | { | 1636 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1637 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1637 | } |
1638 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1638 | |
1639 | } | 1639 | d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); |
1640 | 1640 | d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); | |
1641 | m_collisionscore = 0; | 1641 | } |
1642 | 1642 | ||
1643 | m_softcolide = true; | 1643 | if (m_NoColide) |
1644 | _parent_scene.addActivePrim(this); | 1644 | { |
1645 | _parent_scene.addActiveGroups(this); | 1645 | d.GeomSetCategoryBits(prim_geom, 0); |
1646 | } | 1646 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); |
1647 | 1647 | } | |
1648 | private void DestroyBody() | 1648 | else |
1649 | { | 1649 | { |
1650 | if (Body != IntPtr.Zero) | 1650 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1651 | { | 1651 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1652 | _parent_scene.remActivePrim(this); | 1652 | } |
1653 | m_collisionCategories &= ~CollisionCategories.Body; | 1653 | |
1654 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); | 1654 | m_collisionscore = 0; |
1655 | if (prim_geom != IntPtr.Zero) | 1655 | |
1656 | { | 1656 | m_softcolide = true; |
1657 | if (m_NoColide) | 1657 | _parent_scene.addActivePrim(this); |
1658 | { | 1658 | _parent_scene.addActiveGroups(this); |
1659 | d.GeomSetCategoryBits(prim_geom, 0); | 1659 | } |
1660 | d.GeomSetCollideBits(prim_geom, 0); | 1660 | |
1661 | } | 1661 | private void DestroyBody() |
1662 | else | 1662 | { |
1663 | { | 1663 | if (Body != IntPtr.Zero) |
1664 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1664 | { |
1665 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1665 | _parent_scene.remActivePrim(this); |
1666 | } | 1666 | m_collisionCategories &= ~CollisionCategories.Body; |
1667 | UpdateDataFromGeom(); | 1667 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); |
1668 | d.GeomSetBody(prim_geom, IntPtr.Zero); | 1668 | if (prim_geom != IntPtr.Zero) |
1669 | SetInStaticSpace(this); | 1669 | { |
1670 | } | 1670 | if (m_NoColide) |
1671 | 1671 | { | |
1672 | if (!childPrim) | 1672 | d.GeomSetCategoryBits(prim_geom, 0); |
1673 | { | 1673 | d.GeomSetCollideBits(prim_geom, 0); |
1674 | lock (childrenPrim) | 1674 | } |
1675 | { | 1675 | else |
1676 | foreach (OdePrim prm in childrenPrim) | 1676 | { |
1677 | { | 1677 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1678 | _parent_scene.remActivePrim(prm); | 1678 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1679 | prm.m_collisionCategories = m_collisionCategories; | 1679 | } |
1680 | prm.m_collisionFlags = m_collisionFlags; | 1680 | UpdateDataFromGeom(); |
1681 | if (prm.prim_geom != IntPtr.Zero) | 1681 | d.GeomSetBody(prim_geom, IntPtr.Zero); |
1682 | { | 1682 | SetInStaticSpace(this); |
1683 | if (prm.m_NoColide) | 1683 | } |
1684 | { | 1684 | |
1685 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 1685 | if (!childPrim) |
1686 | d.GeomSetCollideBits(prm.prim_geom, 0); | 1686 | { |
1687 | } | 1687 | lock (childrenPrim) |
1688 | else | 1688 | { |
1689 | { | 1689 | foreach (OdePrim prm in childrenPrim) |
1690 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); | 1690 | { |
1691 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); | 1691 | _parent_scene.remActivePrim(prm); |
1692 | } | 1692 | prm.m_collisionCategories = m_collisionCategories; |
1693 | prm.UpdateDataFromGeom(); | 1693 | prm.m_collisionFlags = m_collisionFlags; |
1694 | SetInStaticSpace(prm); | 1694 | if (prm.prim_geom != IntPtr.Zero) |
1695 | } | 1695 | { |
1696 | prm.Body = IntPtr.Zero; | 1696 | if (prm.m_NoColide) |
1697 | prm._mass = prm.primMass; | 1697 | { |
1698 | prm.m_collisionscore = 0; | 1698 | d.GeomSetCategoryBits(prm.prim_geom, 0); |
1699 | } | 1699 | d.GeomSetCollideBits(prm.prim_geom, 0); |
1700 | } | 1700 | } |
1701 | if (Amotor != IntPtr.Zero) | 1701 | else |
1702 | { | 1702 | { |
1703 | d.JointDestroy(Amotor); | 1703 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); |
1704 | Amotor = IntPtr.Zero; | 1704 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); |
1705 | } | 1705 | } |
1706 | _parent_scene.remActiveGroup(this); | 1706 | prm.UpdateDataFromGeom(); |
1707 | d.BodyDestroy(Body); | 1707 | SetInStaticSpace(prm); |
1708 | } | 1708 | } |
1709 | Body = IntPtr.Zero; | 1709 | prm.Body = IntPtr.Zero; |
1710 | } | 1710 | prm._mass = prm.primMass; |
1711 | _mass = primMass; | 1711 | prm.m_collisionscore = 0; |
1712 | m_collisionscore = 0; | 1712 | } |
1713 | } | 1713 | } |
1714 | 1714 | if (Amotor != IntPtr.Zero) | |
1715 | #region Mass Calculation | 1715 | { |
1716 | 1716 | d.JointDestroy(Amotor); | |
1717 | private float CalculatePrimVolume() | 1717 | Amotor = IntPtr.Zero; |
1718 | { | 1718 | } |
1719 | float volume = _size.X * _size.Y * _size.Z; // default | 1719 | _parent_scene.remActiveGroup(this); |
1720 | float tmp; | 1720 | d.BodyDestroy(Body); |
1721 | 1721 | } | |
1722 | float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; | 1722 | Body = IntPtr.Zero; |
1723 | float hollowVolume = hollowAmount * hollowAmount; | 1723 | } |
1724 | 1724 | _mass = primMass; | |
1725 | switch (_pbs.ProfileShape) | 1725 | m_collisionscore = 0; |
1726 | { | 1726 | } |
1727 | case ProfileShape.Square: | 1727 | |
1728 | // default box | 1728 | #region Mass Calculation |
1729 | 1729 | ||
1730 | if (_pbs.PathCurve == (byte)Extrusion.Straight) | 1730 | private float CalculatePrimVolume() |
1731 | { | 1731 | { |
1732 | if (hollowAmount > 0.0) | 1732 | float volume = _size.X * _size.Y * _size.Z; // default |
1733 | { | 1733 | float tmp; |
1734 | switch (_pbs.HollowShape) | 1734 | |
1735 | { | 1735 | float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; |
1736 | case HollowShape.Square: | 1736 | float hollowVolume = hollowAmount * hollowAmount; |
1737 | case HollowShape.Same: | 1737 | |
1738 | break; | 1738 | switch (_pbs.ProfileShape) |
1739 | 1739 | { | |
1740 | case HollowShape.Circle: | 1740 | case ProfileShape.Square: |
1741 | 1741 | // default box | |
1742 | hollowVolume *= 0.78539816339f; | 1742 | |
1743 | break; | 1743 | if (_pbs.PathCurve == (byte)Extrusion.Straight) |
1744 | 1744 | { | |
1745 | case HollowShape.Triangle: | 1745 | if (hollowAmount > 0.0) |
1746 | 1746 | { | |
1747 | hollowVolume *= (0.5f * .5f); | 1747 | switch (_pbs.HollowShape) |
1748 | break; | 1748 | { |
1749 | 1749 | case HollowShape.Square: | |
1750 | default: | 1750 | case HollowShape.Same: |
1751 | hollowVolume = 0; | 1751 | break; |
1752 | break; | 1752 | |
1753 | } | 1753 | case HollowShape.Circle: |
1754 | volume *= (1.0f - hollowVolume); | 1754 | |
1755 | } | 1755 | hollowVolume *= 0.78539816339f; |
1756 | } | 1756 | break; |
1757 | 1757 | ||
1758 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1758 | case HollowShape.Triangle: |
1759 | { | 1759 | |
1760 | //a tube | 1760 | hollowVolume *= (0.5f * .5f); |
1761 | 1761 | break; | |
1762 | volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); | 1762 | |
1763 | tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY); | 1763 | default: |
1764 | volume -= volume * tmp * tmp; | 1764 | hollowVolume = 0; |
1765 | 1765 | break; | |
1766 | if (hollowAmount > 0.0) | 1766 | } |
1767 | { | 1767 | volume *= (1.0f - hollowVolume); |
1768 | hollowVolume *= hollowAmount; | 1768 | } |
1769 | 1769 | } | |
1770 | switch (_pbs.HollowShape) | 1770 | |
1771 | { | 1771 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) |
1772 | case HollowShape.Square: | 1772 | { |
1773 | case HollowShape.Same: | 1773 | //a tube |
1774 | break; | 1774 | |
1775 | 1775 | volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); | |
1776 | case HollowShape.Circle: | 1776 | tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY); |
1777 | hollowVolume *= 0.78539816339f; | 1777 | volume -= volume * tmp * tmp; |
1778 | break; | 1778 | |
1779 | 1779 | if (hollowAmount > 0.0) | |
1780 | case HollowShape.Triangle: | 1780 | { |
1781 | hollowVolume *= 0.5f * 0.5f; | 1781 | hollowVolume *= hollowAmount; |
1782 | break; | 1782 | |
1783 | default: | 1783 | switch (_pbs.HollowShape) |
1784 | hollowVolume = 0; | 1784 | { |
1785 | break; | 1785 | case HollowShape.Square: |
1786 | } | 1786 | case HollowShape.Same: |
1787 | volume *= (1.0f - hollowVolume); | 1787 | break; |
1788 | } | 1788 | |
1789 | } | 1789 | case HollowShape.Circle: |
1790 | 1790 | hollowVolume *= 0.78539816339f; | |
1791 | break; | 1791 | break; |
1792 | 1792 | ||
1793 | case ProfileShape.Circle: | 1793 | case HollowShape.Triangle: |
1794 | 1794 | hollowVolume *= 0.5f * 0.5f; | |
1795 | if (_pbs.PathCurve == (byte)Extrusion.Straight) | 1795 | break; |
1796 | { | 1796 | default: |
1797 | volume *= 0.78539816339f; // elipse base | 1797 | hollowVolume = 0; |
1798 | 1798 | break; | |
1799 | if (hollowAmount > 0.0) | 1799 | } |
1800 | { | 1800 | volume *= (1.0f - hollowVolume); |
1801 | switch (_pbs.HollowShape) | 1801 | } |
1802 | { | 1802 | } |
1803 | case HollowShape.Same: | 1803 | |
1804 | case HollowShape.Circle: | 1804 | break; |
1805 | break; | 1805 | |
1806 | 1806 | case ProfileShape.Circle: | |
1807 | case HollowShape.Square: | 1807 | |
1808 | hollowVolume *= 0.5f * 2.5984480504799f; | 1808 | if (_pbs.PathCurve == (byte)Extrusion.Straight) |
1809 | break; | 1809 | { |
1810 | 1810 | volume *= 0.78539816339f; // elipse base | |
1811 | case HollowShape.Triangle: | 1811 | |
1812 | hollowVolume *= .5f * 1.27323954473516f; | 1812 | if (hollowAmount > 0.0) |
1813 | break; | 1813 | { |
1814 | 1814 | switch (_pbs.HollowShape) | |
1815 | default: | 1815 | { |
1816 | hollowVolume = 0; | 1816 | case HollowShape.Same: |
1817 | break; | 1817 | case HollowShape.Circle: |
1818 | } | 1818 | break; |
1819 | volume *= (1.0f - hollowVolume); | 1819 | |
1820 | } | 1820 | case HollowShape.Square: |
1821 | } | 1821 | hollowVolume *= 0.5f * 2.5984480504799f; |
1822 | 1822 | break; | |
1823 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1823 | |
1824 | { | 1824 | case HollowShape.Triangle: |
1825 | volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); | 1825 | hollowVolume *= .5f * 1.27323954473516f; |
1826 | tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); | 1826 | break; |
1827 | volume *= (1.0f - tmp * tmp); | 1827 | |
1828 | 1828 | default: | |
1829 | if (hollowAmount > 0.0) | 1829 | hollowVolume = 0; |
1830 | { | 1830 | break; |
1831 | 1831 | } | |
1832 | // calculate the hollow volume by it's shape compared to the prim shape | 1832 | volume *= (1.0f - hollowVolume); |
1833 | hollowVolume *= hollowAmount; | 1833 | } |
1834 | 1834 | } | |
1835 | switch (_pbs.HollowShape) | 1835 | |
1836 | { | 1836 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) |
1837 | case HollowShape.Same: | 1837 | { |
1838 | case HollowShape.Circle: | 1838 | volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); |
1839 | break; | 1839 | tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); |
1840 | 1840 | volume *= (1.0f - tmp * tmp); | |
1841 | case HollowShape.Square: | 1841 | |
1842 | hollowVolume *= 0.5f * 2.5984480504799f; | 1842 | if (hollowAmount > 0.0) |
1843 | break; | 1843 | { |
1844 | 1844 | ||
1845 | case HollowShape.Triangle: | 1845 | // calculate the hollow volume by it's shape compared to the prim shape |
1846 | hollowVolume *= .5f * 1.27323954473516f; | 1846 | hollowVolume *= hollowAmount; |
1847 | break; | 1847 | |
1848 | 1848 | switch (_pbs.HollowShape) | |
1849 | default: | 1849 | { |
1850 | hollowVolume = 0; | 1850 | case HollowShape.Same: |
1851 | break; | 1851 | case HollowShape.Circle: |
1852 | } | 1852 | break; |
1853 | volume *= (1.0f - hollowVolume); | 1853 | |
1854 | } | 1854 | case HollowShape.Square: |
1855 | } | 1855 | hollowVolume *= 0.5f * 2.5984480504799f; |
1856 | break; | 1856 | break; |
1857 | 1857 | ||
1858 | case ProfileShape.HalfCircle: | 1858 | case HollowShape.Triangle: |
1859 | if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1859 | hollowVolume *= .5f * 1.27323954473516f; |
1860 | { | 1860 | break; |
1861 | volume *= 0.52359877559829887307710723054658f; | 1861 | |
1862 | } | 1862 | default: |
1863 | break; | 1863 | hollowVolume = 0; |
1864 | 1864 | break; | |
1865 | case ProfileShape.EquilateralTriangle: | 1865 | } |
1866 | 1866 | volume *= (1.0f - hollowVolume); | |
1867 | if (_pbs.PathCurve == (byte)Extrusion.Straight) | 1867 | } |
1868 | { | 1868 | } |
1869 | volume *= 0.32475953f; | 1869 | break; |
1870 | 1870 | ||
1871 | if (hollowAmount > 0.0) | 1871 | case ProfileShape.HalfCircle: |
1872 | { | 1872 | if (_pbs.PathCurve == (byte)Extrusion.Curve1) |
1873 | 1873 | { | |
1874 | // calculate the hollow volume by it's shape compared to the prim shape | 1874 | volume *= 0.52359877559829887307710723054658f; |
1875 | switch (_pbs.HollowShape) | 1875 | } |
1876 | { | 1876 | break; |
1877 | case HollowShape.Same: | 1877 | |
1878 | case HollowShape.Triangle: | 1878 | case ProfileShape.EquilateralTriangle: |
1879 | hollowVolume *= .25f; | 1879 | |
1880 | break; | 1880 | if (_pbs.PathCurve == (byte)Extrusion.Straight) |
1881 | 1881 | { | |
1882 | case HollowShape.Square: | 1882 | volume *= 0.32475953f; |
1883 | hollowVolume *= 0.499849f * 3.07920140172638f; | 1883 | |
1884 | break; | 1884 | if (hollowAmount > 0.0) |
1885 | 1885 | { | |
1886 | case HollowShape.Circle: | 1886 | |
1887 | // Hollow shape is a perfect cyllinder in respect to the cube's scale | 1887 | // calculate the hollow volume by it's shape compared to the prim shape |
1888 | // Cyllinder hollow volume calculation | 1888 | switch (_pbs.HollowShape) |
1889 | 1889 | { | |
1890 | hollowVolume *= 0.1963495f * 3.07920140172638f; | 1890 | case HollowShape.Same: |
1891 | break; | 1891 | case HollowShape.Triangle: |
1892 | 1892 | hollowVolume *= .25f; | |
1893 | default: | 1893 | break; |
1894 | hollowVolume = 0; | 1894 | |
1895 | break; | 1895 | case HollowShape.Square: |
1896 | } | 1896 | hollowVolume *= 0.499849f * 3.07920140172638f; |
1897 | volume *= (1.0f - hollowVolume); | 1897 | break; |
1898 | } | 1898 | |
1899 | } | 1899 | case HollowShape.Circle: |
1900 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) | 1900 | // Hollow shape is a perfect cyllinder in respect to the cube's scale |
1901 | { | 1901 | // Cyllinder hollow volume calculation |
1902 | volume *= 0.32475953f; | 1902 | |
1903 | volume *= 0.01f * (float)(200 - _pbs.PathScaleX); | 1903 | hollowVolume *= 0.1963495f * 3.07920140172638f; |
1904 | tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); | 1904 | break; |
1905 | volume *= (1.0f - tmp * tmp); | 1905 | |
1906 | 1906 | default: | |
1907 | if (hollowAmount > 0.0) | 1907 | hollowVolume = 0; |
1908 | { | 1908 | break; |
1909 | 1909 | } | |
1910 | hollowVolume *= hollowAmount; | 1910 | volume *= (1.0f - hollowVolume); |
1911 | 1911 | } | |
1912 | switch (_pbs.HollowShape) | 1912 | } |
1913 | { | 1913 | else if (_pbs.PathCurve == (byte)Extrusion.Curve1) |
1914 | case HollowShape.Same: | 1914 | { |
1915 | case HollowShape.Triangle: | 1915 | volume *= 0.32475953f; |
1916 | hollowVolume *= .25f; | 1916 | volume *= 0.01f * (float)(200 - _pbs.PathScaleX); |
1917 | break; | 1917 | tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); |
1918 | 1918 | volume *= (1.0f - tmp * tmp); | |
1919 | case HollowShape.Square: | 1919 | |
1920 | hollowVolume *= 0.499849f * 3.07920140172638f; | 1920 | if (hollowAmount > 0.0) |
1921 | break; | 1921 | { |
1922 | 1922 | ||
1923 | case HollowShape.Circle: | 1923 | hollowVolume *= hollowAmount; |
1924 | 1924 | ||
1925 | hollowVolume *= 0.1963495f * 3.07920140172638f; | 1925 | switch (_pbs.HollowShape) |
1926 | break; | 1926 | { |
1927 | 1927 | case HollowShape.Same: | |
1928 | default: | 1928 | case HollowShape.Triangle: |
1929 | hollowVolume = 0; | 1929 | hollowVolume *= .25f; |
1930 | break; | 1930 | break; |
1931 | } | 1931 | |
1932 | volume *= (1.0f - hollowVolume); | 1932 | case HollowShape.Square: |
1933 | } | 1933 | hollowVolume *= 0.499849f * 3.07920140172638f; |
1934 | } | 1934 | break; |
1935 | break; | 1935 | |
1936 | 1936 | case HollowShape.Circle: | |
1937 | default: | 1937 | |
1938 | break; | 1938 | hollowVolume *= 0.1963495f * 3.07920140172638f; |
1939 | } | 1939 | break; |
1940 | 1940 | ||
1941 | float taperX1; | 1941 | default: |
1942 | float taperY1; | 1942 | hollowVolume = 0; |
1943 | float taperX; | 1943 | break; |
1944 | float taperY; | 1944 | } |
1945 | float pathBegin; | 1945 | volume *= (1.0f - hollowVolume); |
1946 | float pathEnd; | 1946 | } |
1947 | float profileBegin; | 1947 | } |
1948 | float profileEnd; | 1948 | break; |
1949 | 1949 | ||
1950 | if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) | 1950 | default: |
1951 | { | 1951 | break; |
1952 | taperX1 = _pbs.PathScaleX * 0.01f; | 1952 | } |
1953 | if (taperX1 > 1.0f) | 1953 | |
1954 | taperX1 = 2.0f - taperX1; | 1954 | float taperX1; |
1955 | taperX = 1.0f - taperX1; | 1955 | float taperY1; |
1956 | 1956 | float taperX; | |
1957 | taperY1 = _pbs.PathScaleY * 0.01f; | 1957 | float taperY; |
1958 | if (taperY1 > 1.0f) | 1958 | float pathBegin; |
1959 | taperY1 = 2.0f - taperY1; | 1959 | float pathEnd; |
1960 | taperY = 1.0f - taperY1; | 1960 | float profileBegin; |
1961 | } | 1961 | float profileEnd; |
1962 | else | 1962 | |
1963 | { | 1963 | if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) |
1964 | taperX = _pbs.PathTaperX * 0.01f; | 1964 | { |
1965 | if (taperX < 0.0f) | 1965 | taperX1 = _pbs.PathScaleX * 0.01f; |
1966 | taperX = -taperX; | 1966 | if (taperX1 > 1.0f) |
1967 | taperX1 = 1.0f - taperX; | 1967 | taperX1 = 2.0f - taperX1; |
1968 | 1968 | taperX = 1.0f - taperX1; | |
1969 | taperY = _pbs.PathTaperY * 0.01f; | 1969 | |
1970 | if (taperY < 0.0f) | 1970 | taperY1 = _pbs.PathScaleY * 0.01f; |
1971 | taperY = -taperY; | 1971 | if (taperY1 > 1.0f) |
1972 | taperY1 = 1.0f - taperY; | 1972 | taperY1 = 2.0f - taperY1; |
1973 | } | 1973 | taperY = 1.0f - taperY1; |
1974 | 1974 | } | |
1975 | volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); | 1975 | else |
1976 | 1976 | { | |
1977 | pathBegin = (float)_pbs.PathBegin * 2.0e-5f; | 1977 | taperX = _pbs.PathTaperX * 0.01f; |
1978 | pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; | 1978 | if (taperX < 0.0f) |
1979 | volume *= (pathEnd - pathBegin); | 1979 | taperX = -taperX; |
1980 | 1980 | taperX1 = 1.0f - taperX; | |
1981 | // this is crude aproximation | 1981 | |
1982 | profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; | 1982 | taperY = _pbs.PathTaperY * 0.01f; |
1983 | profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; | 1983 | if (taperY < 0.0f) |
1984 | volume *= (profileEnd - profileBegin); | 1984 | taperY = -taperY; |
1985 | 1985 | taperY1 = 1.0f - taperY; | |
1986 | return volume; | 1986 | } |
1987 | } | 1987 | |
1988 | 1988 | volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); | |
1989 | 1989 | ||
1990 | private void CalcPrimBodyData() | 1990 | pathBegin = (float)_pbs.PathBegin * 2.0e-5f; |
1991 | { | 1991 | pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; |
1992 | float volume; | 1992 | volume *= (pathEnd - pathBegin); |
1993 | 1993 | ||
1994 | if (prim_geom == IntPtr.Zero) | 1994 | // this is crude aproximation |
1995 | { | 1995 | profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; |
1996 | // Ubit let's have a initial basic OOB | 1996 | profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; |
1997 | primOOBsize.X = _size.X; | 1997 | volume *= (profileEnd - profileBegin); |
1998 | primOOBsize.Y = _size.Y; | 1998 | |
1999 | primOOBsize.Z = _size.Z; | 1999 | return volume; |
2000 | primOOBoffset = Vector3.Zero; | 2000 | } |
2001 | } | 2001 | |
2002 | else | 2002 | |
2003 | { | 2003 | private void CalcPrimBodyData() |
2004 | d.AABB AABB; | 2004 | { |
2005 | d.GeomGetAABB(prim_geom, out AABB); // get the AABB from engine geom | 2005 | float volume; |
2006 | 2006 | ||
2007 | primOOBsize.X = (AABB.MaxX - AABB.MinX); | 2007 | if (prim_geom == IntPtr.Zero) |
2008 | primOOBsize.Y = (AABB.MaxY - AABB.MinY); | 2008 | { |
2009 | primOOBsize.Z = (AABB.MaxZ - AABB.MinZ); | 2009 | // Ubit let's have a initial basic OOB |
2010 | if (!hasOOBoffsetFromMesh) | 2010 | primOOBsize.X = _size.X; |
2011 | { | 2011 | primOOBsize.Y = _size.Y; |
2012 | primOOBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f; | 2012 | primOOBsize.Z = _size.Z; |
2013 | primOOBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f; | 2013 | primOOBoffset = Vector3.Zero; |
2014 | primOOBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f; | 2014 | } |
2015 | } | 2015 | else |
2016 | } | 2016 | { |
2017 | 2017 | d.AABB AABB; | |
2018 | // also its own inertia and mass | 2018 | d.GeomGetAABB(prim_geom, out AABB); // get the AABB from engine geom |
2019 | // keep using basic shape mass for now | 2019 | |
2020 | volume = CalculatePrimVolume(); | 2020 | primOOBsize.X = (AABB.MaxX - AABB.MinX); |
2021 | 2021 | primOOBsize.Y = (AABB.MaxY - AABB.MinY); | |
2022 | primMass = m_density * volume; | 2022 | primOOBsize.Z = (AABB.MaxZ - AABB.MinZ); |
2023 | 2023 | if (!hasOOBoffsetFromMesh) | |
2024 | if (primMass <= 0) | 2024 | { |
2025 | primMass = 0.0001f;//ckrinke: Mass must be greater then zero. | 2025 | primOOBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f; |
2026 | if (primMass > _parent_scene.maximumMassObject) | 2026 | primOOBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f; |
2027 | primMass = _parent_scene.maximumMassObject; | 2027 | primOOBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f; |
2028 | 2028 | } | |
2029 | _mass = primMass; // just in case | 2029 | } |
2030 | 2030 | ||
2031 | d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z); | 2031 | // also its own inertia and mass |
2032 | 2032 | // keep using basic shape mass for now | |
2033 | d.MassTranslate(ref primdMass, | 2033 | volume = CalculatePrimVolume(); |
2034 | primOOBoffset.X, | 2034 | |
2035 | primOOBoffset.Y, | 2035 | primMass = m_density * volume; |
2036 | primOOBoffset.Z); | 2036 | |
2037 | 2037 | if (primMass <= 0) | |
2038 | primOOBsize *= 0.5f; // let obb size be a corner coords | 2038 | primMass = 0.0001f;//ckrinke: Mass must be greater then zero. |
2039 | primOOBradiusSQ = primOOBsize.LengthSquared(); | 2039 | if (primMass > _parent_scene.maximumMassObject) |
2040 | } | 2040 | primMass = _parent_scene.maximumMassObject; |
2041 | 2041 | ||
2042 | 2042 | _mass = primMass; // just in case | |
2043 | #endregion | 2043 | |
2044 | 2044 | d.MassSetBoxTotal(out primdMass, primMass, primOOBsize.X, primOOBsize.Y, primOOBsize.Z); | |
2045 | 2045 | ||
2046 | /// <summary> | 2046 | d.MassTranslate(ref primdMass, |
2047 | /// Add a child prim to this parent prim. | 2047 | primOOBoffset.X, |
2048 | /// </summary> | 2048 | primOOBoffset.Y, |
2049 | /// <param name="prim">Child prim</param> | 2049 | primOOBoffset.Z); |
2050 | // I'm the parent | 2050 | |
2051 | // prim is the child | 2051 | primOOBsize *= 0.5f; // let obb size be a corner coords |
2052 | public void ParentPrim(OdePrim prim) | 2052 | primOOBradiusSQ = primOOBsize.LengthSquared(); |
2053 | { | 2053 | } |
2054 | //Console.WriteLine("ParentPrim " + m_primName); | 2054 | |
2055 | if (this.m_localID != prim.m_localID) | 2055 | |
2056 | { | 2056 | #endregion |
2057 | DestroyBody(); // for now we need to rebuil entire object on link change | 2057 | |
2058 | 2058 | ||
2059 | lock (childrenPrim) | 2059 | /// <summary> |
2060 | { | 2060 | /// Add a child prim to this parent prim. |
2061 | // adopt the prim | 2061 | /// </summary> |
2062 | if (!childrenPrim.Contains(prim)) | 2062 | /// <param name="prim">Child prim</param> |
2063 | childrenPrim.Add(prim); | 2063 | // I'm the parent |
2064 | 2064 | // prim is the child | |
2065 | // see if this prim has kids and adopt them also | 2065 | public void ParentPrim(OdePrim prim) |
2066 | // should not happen for now | 2066 | { |
2067 | foreach (OdePrim prm in prim.childrenPrim) | 2067 | //Console.WriteLine("ParentPrim " + m_primName); |
2068 | { | 2068 | if (this.m_localID != prim.m_localID) |
2069 | if (!childrenPrim.Contains(prm)) | 2069 | { |
2070 | { | 2070 | DestroyBody(); // for now we need to rebuil entire object on link change |
2071 | if (prm.Body != IntPtr.Zero) | 2071 | |
2072 | { | 2072 | lock (childrenPrim) |
2073 | if (prm.prim_geom != IntPtr.Zero) | 2073 | { |
2074 | d.GeomSetBody(prm.prim_geom, IntPtr.Zero); | 2074 | // adopt the prim |
2075 | if (prm.Body != prim.Body) | 2075 | if (!childrenPrim.Contains(prim)) |
2076 | prm.DestroyBody(); // don't loose bodies around | 2076 | childrenPrim.Add(prim); |
2077 | prm.Body = IntPtr.Zero; | 2077 | |
2078 | } | 2078 | // see if this prim has kids and adopt them also |
2079 | 2079 | // should not happen for now | |
2080 | childrenPrim.Add(prm); | 2080 | foreach (OdePrim prm in prim.childrenPrim) |
2081 | prm._parent = this; | 2081 | { |
2082 | } | 2082 | if (!childrenPrim.Contains(prm)) |
2083 | } | 2083 | { |
2084 | } | 2084 | if (prm.Body != IntPtr.Zero) |
2085 | //Remove old children from the prim | 2085 | { |
2086 | prim.childrenPrim.Clear(); | 2086 | if (prm.prim_geom != IntPtr.Zero) |
2087 | 2087 | d.GeomSetBody(prm.prim_geom, IntPtr.Zero); | |
2088 | if (prim.Body != IntPtr.Zero) | 2088 | if (prm.Body != prim.Body) |
2089 | { | 2089 | prm.DestroyBody(); // don't loose bodies around |
2090 | if (prim.prim_geom != IntPtr.Zero) | 2090 | prm.Body = IntPtr.Zero; |
2091 | d.GeomSetBody(prim.prim_geom, IntPtr.Zero); | 2091 | } |
2092 | prim.DestroyBody(); // don't loose bodies around | 2092 | |
2093 | prim.Body = IntPtr.Zero; | 2093 | childrenPrim.Add(prm); |
2094 | } | 2094 | prm._parent = this; |
2095 | 2095 | } | |
2096 | prim.childPrim = true; | 2096 | } |
2097 | prim._parent = this; | 2097 | } |
2098 | 2098 | //Remove old children from the prim | |
2099 | MakeBody(); // full nasty reconstruction | 2099 | prim.childrenPrim.Clear(); |
2100 | } | 2100 | |
2101 | } | 2101 | if (prim.Body != IntPtr.Zero) |
2102 | 2102 | { | |
2103 | private void UpdateChildsfromgeom() | 2103 | if (prim.prim_geom != IntPtr.Zero) |
2104 | { | 2104 | d.GeomSetBody(prim.prim_geom, IntPtr.Zero); |
2105 | if (childrenPrim.Count > 0) | 2105 | prim.DestroyBody(); // don't loose bodies around |
2106 | { | 2106 | prim.Body = IntPtr.Zero; |
2107 | foreach (OdePrim prm in childrenPrim) | 2107 | } |
2108 | prm.UpdateDataFromGeom(); | 2108 | |
2109 | } | 2109 | prim.childPrim = true; |
2110 | } | 2110 | prim._parent = this; |
2111 | 2111 | ||
2112 | private void UpdateDataFromGeom() | 2112 | MakeBody(); // full nasty reconstruction |
2113 | { | 2113 | } |
2114 | if (prim_geom != IntPtr.Zero) | 2114 | } |
2115 | { | 2115 | |
2116 | d.Vector3 lpos; | 2116 | private void UpdateChildsfromgeom() |
2117 | d.GeomCopyPosition(prim_geom, out lpos); | 2117 | { |
2118 | _position.X = lpos.X; | 2118 | if (childrenPrim.Count > 0) |
2119 | _position.Y = lpos.Y; | 2119 | { |
2120 | _position.Z = lpos.Z; | 2120 | foreach (OdePrim prm in childrenPrim) |
2121 | d.Quaternion qtmp = new d.Quaternion { }; | 2121 | prm.UpdateDataFromGeom(); |
2122 | d.GeomCopyQuaternion(prim_geom, out qtmp); | 2122 | } |
2123 | _orientation.W = qtmp.W; | 2123 | } |
2124 | _orientation.X = qtmp.X; | 2124 | |
2125 | _orientation.Y = qtmp.Y; | 2125 | private void UpdateDataFromGeom() |
2126 | _orientation.Z = qtmp.Z; | 2126 | { |
2127 | } | 2127 | if (prim_geom != IntPtr.Zero) |
2128 | } | 2128 | { |
2129 | 2129 | d.Vector3 lpos; | |
2130 | private void ChildDelink(OdePrim odePrim, bool remakebodies) | 2130 | d.GeomCopyPosition(prim_geom, out lpos); |
2131 | { | 2131 | _position.X = lpos.X; |
2132 | // Okay, we have a delinked child.. destroy all body and remake | 2132 | _position.Y = lpos.Y; |
2133 | if (odePrim != this && !childrenPrim.Contains(odePrim)) | 2133 | _position.Z = lpos.Z; |
2134 | return; | 2134 | d.Quaternion qtmp = new d.Quaternion { }; |
2135 | 2135 | d.GeomCopyQuaternion(prim_geom, out qtmp); | |
2136 | DestroyBody(); | 2136 | _orientation.W = qtmp.W; |
2137 | 2137 | _orientation.X = qtmp.X; | |
2138 | if (odePrim == this) // delinking the root prim | 2138 | _orientation.Y = qtmp.Y; |
2139 | { | 2139 | _orientation.Z = qtmp.Z; |
2140 | OdePrim newroot = null; | 2140 | } |
2141 | lock (childrenPrim) | 2141 | } |
2142 | { | 2142 | |
2143 | if (childrenPrim.Count > 0) | 2143 | private void ChildDelink(OdePrim odePrim, bool remakebodies) |
2144 | { | 2144 | { |
2145 | newroot = childrenPrim[0]; | 2145 | // Okay, we have a delinked child.. destroy all body and remake |
2146 | childrenPrim.RemoveAt(0); | 2146 | if (odePrim != this && !childrenPrim.Contains(odePrim)) |
2147 | foreach (OdePrim prm in childrenPrim) | 2147 | return; |
2148 | { | 2148 | |
2149 | newroot.childrenPrim.Add(prm); | 2149 | DestroyBody(); |
2150 | } | 2150 | |
2151 | childrenPrim.Clear(); | 2151 | if (odePrim == this) // delinking the root prim |
2152 | } | 2152 | { |
2153 | if (newroot != null) | 2153 | OdePrim newroot = null; |
2154 | { | 2154 | lock (childrenPrim) |
2155 | newroot.childPrim = false; | 2155 | { |
2156 | newroot._parent = null; | 2156 | if (childrenPrim.Count > 0) |
2157 | if (remakebodies) | 2157 | { |
2158 | newroot.MakeBody(); | 2158 | newroot = childrenPrim[0]; |
2159 | } | 2159 | childrenPrim.RemoveAt(0); |
2160 | } | 2160 | foreach (OdePrim prm in childrenPrim) |
2161 | } | 2161 | { |
2162 | 2162 | newroot.childrenPrim.Add(prm); | |
2163 | else | 2163 | } |
2164 | { | 2164 | childrenPrim.Clear(); |
2165 | lock (childrenPrim) | 2165 | } |
2166 | { | 2166 | if (newroot != null) |
2167 | childrenPrim.Remove(odePrim); | 2167 | { |
2168 | odePrim.childPrim = false; | 2168 | newroot.childPrim = false; |
2169 | odePrim._parent = null; | 2169 | newroot._parent = null; |
2170 | // odePrim.UpdateDataFromGeom(); | 2170 | if (remakebodies) |
2171 | if (remakebodies) | 2171 | newroot.MakeBody(); |
2172 | odePrim.MakeBody(); | 2172 | } |
2173 | } | 2173 | } |
2174 | } | 2174 | } |
2175 | if (remakebodies) | 2175 | |
2176 | MakeBody(); | 2176 | else |
2177 | } | 2177 | { |
2178 | 2178 | lock (childrenPrim) | |
2179 | protected void ChildRemove(OdePrim odePrim, bool reMakeBody) | 2179 | { |
2180 | { | 2180 | childrenPrim.Remove(odePrim); |
2181 | // Okay, we have a delinked child.. destroy all body and remake | 2181 | odePrim.childPrim = false; |
2182 | if (odePrim != this && !childrenPrim.Contains(odePrim)) | 2182 | odePrim._parent = null; |
2183 | return; | 2183 | // odePrim.UpdateDataFromGeom(); |
2184 | 2184 | if (remakebodies) | |
2185 | DestroyBody(); | 2185 | odePrim.MakeBody(); |
2186 | 2186 | } | |
2187 | if (odePrim == this) | 2187 | } |
2188 | { | 2188 | if (remakebodies) |
2189 | OdePrim newroot = null; | 2189 | MakeBody(); |
2190 | lock (childrenPrim) | 2190 | } |
2191 | { | 2191 | |
2192 | if (childrenPrim.Count > 0) | 2192 | protected void ChildRemove(OdePrim odePrim, bool reMakeBody) |
2193 | { | 2193 | { |
2194 | newroot = childrenPrim[0]; | 2194 | // Okay, we have a delinked child.. destroy all body and remake |
2195 | childrenPrim.RemoveAt(0); | 2195 | if (odePrim != this && !childrenPrim.Contains(odePrim)) |
2196 | foreach (OdePrim prm in childrenPrim) | 2196 | return; |
2197 | { | 2197 | |
2198 | newroot.childrenPrim.Add(prm); | 2198 | DestroyBody(); |
2199 | } | 2199 | |
2200 | childrenPrim.Clear(); | 2200 | if (odePrim == this) |
2201 | } | 2201 | { |
2202 | if (newroot != null) | 2202 | OdePrim newroot = null; |
2203 | { | 2203 | lock (childrenPrim) |
2204 | newroot.childPrim = false; | 2204 | { |
2205 | newroot._parent = null; | 2205 | if (childrenPrim.Count > 0) |
2206 | newroot.MakeBody(); | 2206 | { |
2207 | } | 2207 | newroot = childrenPrim[0]; |
2208 | } | 2208 | childrenPrim.RemoveAt(0); |
2209 | if (reMakeBody) | 2209 | foreach (OdePrim prm in childrenPrim) |
2210 | MakeBody(); | 2210 | { |
2211 | return; | 2211 | newroot.childrenPrim.Add(prm); |
2212 | } | 2212 | } |
2213 | else | 2213 | childrenPrim.Clear(); |
2214 | { | 2214 | } |
2215 | lock (childrenPrim) | 2215 | if (newroot != null) |
2216 | { | 2216 | { |
2217 | childrenPrim.Remove(odePrim); | 2217 | newroot.childPrim = false; |
2218 | odePrim.childPrim = false; | 2218 | newroot._parent = null; |
2219 | odePrim._parent = null; | 2219 | newroot.MakeBody(); |
2220 | if (reMakeBody) | 2220 | } |
2221 | odePrim.MakeBody(); | 2221 | } |
2222 | } | 2222 | if (reMakeBody) |
2223 | } | 2223 | MakeBody(); |
2224 | MakeBody(); | 2224 | return; |
2225 | } | 2225 | } |
2226 | 2226 | else | |
2227 | #region changes | 2227 | { |
2228 | 2228 | lock (childrenPrim) | |
2229 | private void changeadd() | 2229 | { |
2230 | { | 2230 | childrenPrim.Remove(odePrim); |
2231 | CreateGeom(); | 2231 | odePrim.childPrim = false; |
2232 | 2232 | odePrim._parent = null; | |
2233 | if (prim_geom != IntPtr.Zero) | 2233 | if (reMakeBody) |
2234 | { | 2234 | odePrim.MakeBody(); |
2235 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 2235 | } |
2236 | d.Quaternion myrot = new d.Quaternion(); | 2236 | } |
2237 | myrot.X = _orientation.X; | 2237 | MakeBody(); |
2238 | myrot.Y = _orientation.Y; | 2238 | } |
2239 | myrot.Z = _orientation.Z; | 2239 | |
2240 | myrot.W = _orientation.W; | 2240 | #region changes |
2241 | d.GeomSetQuaternion(prim_geom, ref myrot); | 2241 | |
2242 | 2242 | private void changeadd() | |
2243 | if (!m_isphysical) | 2243 | { |
2244 | SetInStaticSpace(this); | 2244 | CreateGeom(); |
2245 | } | 2245 | |
2246 | 2246 | if (prim_geom != IntPtr.Zero) | |
2247 | if (m_isphysical && Body == IntPtr.Zero) | 2247 | { |
2248 | { | 2248 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
2249 | MakeBody(); | 2249 | d.Quaternion myrot = new d.Quaternion(); |
2250 | } | 2250 | myrot.X = _orientation.X; |
2251 | } | 2251 | myrot.Y = _orientation.Y; |
2252 | 2252 | myrot.Z = _orientation.Z; | |
2253 | private void changeAngularLock(Vector3 newLock) | 2253 | myrot.W = _orientation.W; |
2254 | { | 2254 | d.GeomSetQuaternion(prim_geom, ref myrot); |
2255 | // do we have a Physical object? | 2255 | |
2256 | if (Body != IntPtr.Zero) | 2256 | if (!m_isphysical) |
2257 | { | 2257 | SetInStaticSpace(this); |
2258 | //Check that we have a Parent | 2258 | } |
2259 | //If we have a parent then we're not authorative here | 2259 | |
2260 | if (_parent == null) | 2260 | if (m_isphysical && Body == IntPtr.Zero) |
2261 | { | 2261 | { |
2262 | if (!newLock.ApproxEquals(Vector3.One, 0f)) | 2262 | MakeBody(); |
2263 | { | 2263 | } |
2264 | createAMotor(newLock); | 2264 | } |
2265 | } | 2265 | |
2266 | else | 2266 | private void changeAngularLock(Vector3 newLock) |
2267 | { | 2267 | { |
2268 | if (Amotor != IntPtr.Zero) | 2268 | // do we have a Physical object? |
2269 | { | 2269 | if (Body != IntPtr.Zero) |
2270 | d.JointDestroy(Amotor); | 2270 | { |
2271 | Amotor = IntPtr.Zero; | 2271 | //Check that we have a Parent |
2272 | } | 2272 | //If we have a parent then we're not authorative here |
2273 | } | 2273 | if (_parent == null) |
2274 | } | 2274 | { |
2275 | } | 2275 | if (!newLock.ApproxEquals(Vector3.One, 0f)) |
2276 | // Store this for later in case we get turned into a separate body | 2276 | { |
2277 | m_angularlock = newLock; | 2277 | createAMotor(newLock); |
2278 | } | 2278 | } |
2279 | 2279 | else | |
2280 | private void changeLink(OdePrim NewParent) | 2280 | { |
2281 | { | 2281 | if (Amotor != IntPtr.Zero) |
2282 | if (_parent == null && NewParent != null) | 2282 | { |
2283 | { | 2283 | d.JointDestroy(Amotor); |
2284 | NewParent.ParentPrim(this); | 2284 | Amotor = IntPtr.Zero; |
2285 | } | 2285 | } |
2286 | else if (_parent != null) | 2286 | } |
2287 | { | 2287 | } |
2288 | if (_parent is OdePrim) | 2288 | } |
2289 | { | 2289 | // Store this for later in case we get turned into a separate body |
2290 | if (NewParent != _parent) | 2290 | m_angularlock = newLock; |
2291 | { | 2291 | } |
2292 | (_parent as OdePrim).ChildDelink(this, false); // for now... | 2292 | |
2293 | childPrim = false; | 2293 | private void changeLink(OdePrim NewParent) |
2294 | 2294 | { | |
2295 | if (NewParent != null) | 2295 | if (_parent == null && NewParent != null) |
2296 | { | 2296 | { |
2297 | NewParent.ParentPrim(this); | 2297 | NewParent.ParentPrim(this); |
2298 | } | 2298 | } |
2299 | } | 2299 | else if (_parent != null) |
2300 | } | 2300 | { |
2301 | } | 2301 | if (_parent is OdePrim) |
2302 | _parent = NewParent; | 2302 | { |
2303 | } | 2303 | if (NewParent != _parent) |
2304 | 2304 | { | |
2305 | 2305 | (_parent as OdePrim).ChildDelink(this, false); // for now... | |
2306 | private void Stop() | 2306 | childPrim = false; |
2307 | { | 2307 | |
2308 | if (!childPrim) | 2308 | if (NewParent != null) |
2309 | { | 2309 | { |
2310 | m_force = Vector3.Zero; | 2310 | NewParent.ParentPrim(this); |
2311 | m_forceacc = Vector3.Zero; | 2311 | } |
2312 | m_angularForceacc = Vector3.Zero; | 2312 | } |
2313 | _torque = Vector3.Zero; | 2313 | } |
2314 | _velocity = Vector3.Zero; | 2314 | } |
2315 | _acceleration = Vector3.Zero; | 2315 | _parent = NewParent; |
2316 | m_rotationalVelocity = Vector3.Zero; | 2316 | } |
2317 | _target_velocity = Vector3.Zero; | 2317 | |
2318 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | 2318 | |
2319 | m_vehicle.Stop(); | 2319 | private void Stop() |
2320 | } | 2320 | { |
2321 | 2321 | if (!childPrim) | |
2322 | if (Body != IntPtr.Zero) | 2322 | { |
2323 | { | 2323 | m_force = Vector3.Zero; |
2324 | d.BodySetForce(Body, 0f, 0f, 0f); | 2324 | m_forceacc = Vector3.Zero; |
2325 | d.BodySetTorque(Body, 0f, 0f, 0f); | 2325 | m_angularForceacc = Vector3.Zero; |
2326 | d.BodySetLinearVel(Body, 0f, 0f, 0f); | 2326 | _torque = Vector3.Zero; |
2327 | d.BodySetAngularVel(Body, 0f, 0f, 0f); | 2327 | _velocity = Vector3.Zero; |
2328 | } | 2328 | _acceleration = Vector3.Zero; |
2329 | } | 2329 | m_rotationalVelocity = Vector3.Zero; |
2330 | 2330 | _target_velocity = Vector3.Zero; | |
2331 | 2331 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | |
2332 | private void changePhantomStatus(bool newval) | 2332 | m_vehicle.Stop(); |
2333 | { | 2333 | } |
2334 | m_isphantom = newval; | 2334 | |
2335 | 2335 | if (Body != IntPtr.Zero) | |
2336 | if (m_isSelected) | 2336 | { |
2337 | { | 2337 | d.BodySetForce(Body, 0f, 0f, 0f); |
2338 | m_collisionCategories = CollisionCategories.Selected; | 2338 | d.BodySetTorque(Body, 0f, 0f, 0f); |
2339 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); | 2339 | d.BodySetLinearVel(Body, 0f, 0f, 0f); |
2340 | } | 2340 | d.BodySetAngularVel(Body, 0f, 0f, 0f); |
2341 | else | 2341 | } |
2342 | { | 2342 | } |
2343 | if (m_isphantom && !m_isVolumeDetect) | 2343 | |
2344 | { | 2344 | |
2345 | m_collisionCategories = 0; | 2345 | private void changePhantomStatus(bool newval) |
2346 | if (m_isphysical) | 2346 | { |
2347 | m_collisionFlags = CollisionCategories.Land; | 2347 | m_isphantom = newval; |
2348 | else | 2348 | |
2349 | m_collisionFlags = 0; // should never happen | 2349 | if (m_isSelected) |
2350 | } | 2350 | { |
2351 | 2351 | m_collisionCategories = CollisionCategories.Selected; | |
2352 | else | 2352 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); |
2353 | { | 2353 | } |
2354 | m_collisionCategories = CollisionCategories.Geom; | 2354 | else |
2355 | if (m_isphysical) | 2355 | { |
2356 | m_collisionCategories |= CollisionCategories.Body; | 2356 | if (m_isphantom && !m_isVolumeDetect) |
2357 | 2357 | { | |
2358 | m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land; | 2358 | m_collisionCategories = 0; |
2359 | 2359 | if (m_isphysical) | |
2360 | if (m_collidesWater) | 2360 | m_collisionFlags = CollisionCategories.Land; |
2361 | m_collisionFlags |= CollisionCategories.Water; | 2361 | else |
2362 | } | 2362 | m_collisionFlags = 0; // should never happen |
2363 | } | 2363 | } |
2364 | 2364 | ||
2365 | if (!childPrim) | 2365 | else |
2366 | { | 2366 | { |
2367 | foreach (OdePrim prm in childrenPrim) | 2367 | m_collisionCategories = CollisionCategories.Geom; |
2368 | { | 2368 | if (m_isphysical) |
2369 | prm.m_collisionCategories = m_collisionCategories; | 2369 | m_collisionCategories |= CollisionCategories.Body; |
2370 | prm.m_collisionFlags = m_collisionFlags; | 2370 | |
2371 | 2371 | m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land; | |
2372 | if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero) | 2372 | |
2373 | { | 2373 | if (m_collidesWater) |
2374 | if (prm.m_NoColide) | 2374 | m_collisionFlags |= CollisionCategories.Water; |
2375 | { | 2375 | } |
2376 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 2376 | } |
2377 | if (m_isphysical) | 2377 | |
2378 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); | 2378 | if (!childPrim) |
2379 | else | 2379 | { |
2380 | d.GeomSetCollideBits(prm.prim_geom, 0); | 2380 | foreach (OdePrim prm in childrenPrim) |
2381 | } | 2381 | { |
2382 | else | 2382 | prm.m_collisionCategories = m_collisionCategories; |
2383 | { | 2383 | prm.m_collisionFlags = m_collisionFlags; |
2384 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); | 2384 | |
2385 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); | 2385 | if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero) |
2386 | } | 2386 | { |
2387 | if(!m_isSelected) | 2387 | if (prm.m_NoColide) |
2388 | d.GeomEnable(prm.prim_geom); | 2388 | { |
2389 | } | 2389 | d.GeomSetCategoryBits(prm.prim_geom, 0); |
2390 | } | 2390 | if (m_isphysical) |
2391 | } | 2391 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); |
2392 | 2392 | else | |
2393 | if (!m_disabled && prim_geom != IntPtr.Zero) | 2393 | d.GeomSetCollideBits(prm.prim_geom, 0); |
2394 | { | 2394 | } |
2395 | if (m_NoColide) | 2395 | else |
2396 | { | 2396 | { |
2397 | d.GeomSetCategoryBits(prim_geom, 0); | 2397 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); |
2398 | if (m_isphysical) | 2398 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); |
2399 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | 2399 | } |
2400 | else | 2400 | if(!m_isSelected) |
2401 | d.GeomSetCollideBits(prim_geom, 0); | 2401 | d.GeomEnable(prm.prim_geom); |
2402 | } | 2402 | } |
2403 | else | 2403 | } |
2404 | { | 2404 | } |
2405 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2405 | |
2406 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2406 | if (!m_disabled && prim_geom != IntPtr.Zero) |
2407 | } | 2407 | { |
2408 | if(!m_isSelected) | 2408 | if (m_NoColide) |
2409 | d.GeomEnable(prim_geom); | 2409 | { |
2410 | } | 2410 | d.GeomSetCategoryBits(prim_geom, 0); |
2411 | } | 2411 | if (m_isphysical) |
2412 | 2412 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | |
2413 | private void changeSelectedStatus(bool newval) | 2413 | else |
2414 | { | 2414 | d.GeomSetCollideBits(prim_geom, 0); |
2415 | if (m_lastdoneSelected == newval) | 2415 | } |
2416 | return; | 2416 | else |
2417 | 2417 | { | |
2418 | m_lastdoneSelected = newval; | 2418 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
2419 | DoSelectedStatus(newval); | 2419 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
2420 | } | 2420 | } |
2421 | 2421 | if(!m_isSelected) | |
2422 | private void CheckDelaySelect() | 2422 | d.GeomEnable(prim_geom); |
2423 | { | 2423 | } |
2424 | if (m_delaySelect) | 2424 | } |
2425 | { | 2425 | |
2426 | DoSelectedStatus(m_isSelected); | 2426 | private void changeSelectedStatus(bool newval) |
2427 | } | 2427 | { |
2428 | } | 2428 | if (m_lastdoneSelected == newval) |
2429 | 2429 | return; | |
2430 | private void DoSelectedStatus(bool newval) | 2430 | |
2431 | { | 2431 | m_lastdoneSelected = newval; |
2432 | m_isSelected = newval; | 2432 | DoSelectedStatus(newval); |
2433 | Stop(); | 2433 | } |
2434 | 2434 | ||
2435 | if (newval) | 2435 | private void CheckDelaySelect() |
2436 | { | 2436 | { |
2437 | if (!childPrim && Body != IntPtr.Zero) | 2437 | if (m_delaySelect) |
2438 | d.BodyDisable(Body); | 2438 | { |
2439 | 2439 | DoSelectedStatus(m_isSelected); | |
2440 | if (m_delaySelect || m_isphysical) | 2440 | } |
2441 | { | 2441 | } |
2442 | m_collisionCategories = CollisionCategories.Selected; | 2442 | |
2443 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); | 2443 | private void DoSelectedStatus(bool newval) |
2444 | 2444 | { | |
2445 | if (!childPrim) | 2445 | m_isSelected = newval; |
2446 | { | 2446 | Stop(); |
2447 | foreach (OdePrim prm in childrenPrim) | 2447 | |
2448 | { | 2448 | if (newval) |
2449 | prm.m_collisionCategories = m_collisionCategories; | 2449 | { |
2450 | prm.m_collisionFlags = m_collisionFlags; | 2450 | if (!childPrim && Body != IntPtr.Zero) |
2451 | 2451 | d.BodyDisable(Body); | |
2452 | if (prm.prim_geom != null) | 2452 | |
2453 | { | 2453 | if (m_delaySelect || m_isphysical) |
2454 | 2454 | { | |
2455 | if (prm.m_NoColide) | 2455 | m_collisionCategories = CollisionCategories.Selected; |
2456 | { | 2456 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); |
2457 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 2457 | |
2458 | d.GeomSetCollideBits(prm.prim_geom, 0); | 2458 | if (!childPrim) |
2459 | } | 2459 | { |
2460 | else | 2460 | foreach (OdePrim prm in childrenPrim) |
2461 | { | 2461 | { |
2462 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); | 2462 | prm.m_collisionCategories = m_collisionCategories; |
2463 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); | 2463 | prm.m_collisionFlags = m_collisionFlags; |
2464 | } | 2464 | |
2465 | d.GeomDisable(prm.prim_geom); | 2465 | if (prm.prim_geom != null) |
2466 | } | 2466 | { |
2467 | prm.m_delaySelect = false; | 2467 | |
2468 | } | 2468 | if (prm.m_NoColide) |
2469 | } | 2469 | { |
2470 | 2470 | d.GeomSetCategoryBits(prm.prim_geom, 0); | |
2471 | if (prim_geom != null) | 2471 | d.GeomSetCollideBits(prm.prim_geom, 0); |
2472 | { | 2472 | } |
2473 | if (m_NoColide) | 2473 | else |
2474 | { | 2474 | { |
2475 | d.GeomSetCategoryBits(prim_geom, 0); | 2475 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); |
2476 | d.GeomSetCollideBits(prim_geom, 0); | 2476 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); |
2477 | } | 2477 | } |
2478 | else | 2478 | d.GeomDisable(prm.prim_geom); |
2479 | { | 2479 | } |
2480 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2480 | prm.m_delaySelect = false; |
2481 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2481 | } |
2482 | } | 2482 | } |
2483 | d.GeomDisable(prim_geom); | 2483 | |
2484 | } | 2484 | if (prim_geom != null) |
2485 | 2485 | { | |
2486 | m_delaySelect = false; | 2486 | if (m_NoColide) |
2487 | } | 2487 | { |
2488 | else if(!m_isphysical) | 2488 | d.GeomSetCategoryBits(prim_geom, 0); |
2489 | { | 2489 | d.GeomSetCollideBits(prim_geom, 0); |
2490 | m_delaySelect = true; | 2490 | } |
2491 | } | 2491 | else |
2492 | } | 2492 | { |
2493 | else | 2493 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
2494 | { | 2494 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
2495 | if (!childPrim && Body != IntPtr.Zero && !m_disabled) | 2495 | } |
2496 | d.BodyEnable(Body); | 2496 | d.GeomDisable(prim_geom); |
2497 | 2497 | } | |
2498 | if (m_isphantom && !m_isVolumeDetect) | 2498 | |
2499 | { | 2499 | m_delaySelect = false; |
2500 | m_collisionCategories = 0; | 2500 | } |
2501 | if(m_isphysical) | 2501 | else if(!m_isphysical) |
2502 | m_collisionFlags = CollisionCategories.Land; | 2502 | { |
2503 | else | 2503 | m_delaySelect = true; |
2504 | m_collisionFlags = 0; | 2504 | } |
2505 | } | 2505 | } |
2506 | else | 2506 | else |
2507 | { | 2507 | { |
2508 | m_collisionCategories = CollisionCategories.Geom; | 2508 | if (!childPrim && Body != IntPtr.Zero && !m_disabled) |
2509 | if (m_isphysical) | 2509 | d.BodyEnable(Body); |
2510 | m_collisionCategories |= CollisionCategories.Body; | 2510 | |
2511 | 2511 | if (m_isphantom && !m_isVolumeDetect) | |
2512 | m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land; | 2512 | { |
2513 | 2513 | m_collisionCategories = 0; | |
2514 | if (m_collidesWater) | 2514 | if(m_isphysical) |
2515 | m_collisionFlags |= CollisionCategories.Water; | 2515 | m_collisionFlags = CollisionCategories.Land; |
2516 | } | 2516 | else |
2517 | 2517 | m_collisionFlags = 0; | |
2518 | if (!childPrim) | 2518 | } |
2519 | { | 2519 | else |
2520 | foreach (OdePrim prm in childrenPrim) | 2520 | { |
2521 | { | 2521 | m_collisionCategories = CollisionCategories.Geom; |
2522 | prm.m_collisionCategories = m_collisionCategories; | 2522 | if (m_isphysical) |
2523 | prm.m_collisionFlags = m_collisionFlags; | 2523 | m_collisionCategories |= CollisionCategories.Body; |
2524 | 2524 | ||
2525 | if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero) | 2525 | m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land; |
2526 | { | 2526 | |
2527 | if (prm.m_NoColide) | 2527 | if (m_collidesWater) |
2528 | { | 2528 | m_collisionFlags |= CollisionCategories.Water; |
2529 | d.GeomSetCategoryBits(prm.prim_geom, 0); | 2529 | } |
2530 | if (m_isphysical) | 2530 | |
2531 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); | 2531 | if (!childPrim) |
2532 | else | 2532 | { |
2533 | d.GeomSetCollideBits(prm.prim_geom, 0); | 2533 | foreach (OdePrim prm in childrenPrim) |
2534 | } | 2534 | { |
2535 | else | 2535 | prm.m_collisionCategories = m_collisionCategories; |
2536 | { | 2536 | prm.m_collisionFlags = m_collisionFlags; |
2537 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); | 2537 | |
2538 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); | 2538 | if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero) |
2539 | } | 2539 | { |
2540 | d.GeomEnable(prm.prim_geom); | 2540 | if (prm.m_NoColide) |
2541 | } | 2541 | { |
2542 | prm.m_delaySelect = false; | 2542 | d.GeomSetCategoryBits(prm.prim_geom, 0); |
2543 | prm.m_softcolide = true; | 2543 | if (m_isphysical) |
2544 | } | 2544 | d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); |
2545 | } | 2545 | else |
2546 | 2546 | d.GeomSetCollideBits(prm.prim_geom, 0); | |
2547 | if (!m_disabled && prim_geom != IntPtr.Zero) | 2547 | } |
2548 | { | 2548 | else |
2549 | if (m_NoColide) | 2549 | { |
2550 | { | 2550 | d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); |
2551 | d.GeomSetCategoryBits(prim_geom, 0); | 2551 | d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); |
2552 | if (m_isphysical) | 2552 | } |
2553 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); | 2553 | d.GeomEnable(prm.prim_geom); |
2554 | else | 2554 | } |
2555 | d.GeomSetCollideBits(prim_geom, 0); | 2555 | prm.m_delaySelect = false; |
2556 | } | 2556 | prm.m_softcolide = true; |
2557 | else | 2557 | } |
2558 | { | 2558 | } |
2559 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2559 | |
2560 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2560 | if (!m_disabled && prim_geom != IntPtr.Zero) |
2561 | } | 2561 | { |
2562 | d.GeomEnable(prim_geom); | 2562 | if (m_NoColide) |
2563 | } | 2563 | { |
2564 | 2564 | d.GeomSetCategoryBits(prim_geom, 0); | |
2565 | m_delaySelect = false; | 2565 | if (m_isphysical) |
2566 | m_softcolide = true; | 2566 | d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); |
2567 | } | 2567 | else |
2568 | 2568 | d.GeomSetCollideBits(prim_geom, 0); | |
2569 | resetCollisionAccounting(); | 2569 | } |
2570 | } | 2570 | else |
2571 | 2571 | { | |
2572 | private void changePosition(Vector3 newPos) | 2572 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
2573 | { | 2573 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
2574 | CheckDelaySelect(); | 2574 | } |
2575 | if (m_isphysical) | 2575 | d.GeomEnable(prim_geom); |
2576 | { | 2576 | } |
2577 | if (childPrim) // inertia is messed, must rebuild | 2577 | |
2578 | { | 2578 | m_delaySelect = false; |
2579 | if (m_building) | 2579 | m_softcolide = true; |
2580 | { | 2580 | } |
2581 | _position = newPos; | 2581 | |
2582 | } | 2582 | resetCollisionAccounting(); |
2583 | } | 2583 | } |
2584 | else | 2584 | |
2585 | { | 2585 | private void changePosition(Vector3 newPos) |
2586 | if (_position != newPos) | 2586 | { |
2587 | { | 2587 | CheckDelaySelect(); |
2588 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); | 2588 | if (m_isphysical) |
2589 | _position = newPos; | 2589 | { |
2590 | } | 2590 | if (childPrim) // inertia is messed, must rebuild |
2591 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | 2591 | { |
2592 | d.BodyEnable(Body); | 2592 | if (m_building) |
2593 | } | 2593 | { |
2594 | } | 2594 | _position = newPos; |
2595 | else | 2595 | } |
2596 | { | 2596 | } |
2597 | if (prim_geom != IntPtr.Zero) | 2597 | else |
2598 | { | 2598 | { |
2599 | if (newPos != _position) | 2599 | if (_position != newPos) |
2600 | { | 2600 | { |
2601 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); | 2601 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); |
2602 | _position = newPos; | 2602 | _position = newPos; |
2603 | 2603 | } | |
2604 | m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace); | 2604 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) |
2605 | } | 2605 | d.BodyEnable(Body); |
2606 | } | 2606 | } |
2607 | } | 2607 | } |
2608 | givefakepos--; | 2608 | else |
2609 | if (givefakepos < 0) | 2609 | { |
2610 | givefakepos = 0; | 2610 | if (prim_geom != IntPtr.Zero) |
2611 | // changeSelectedStatus(); | 2611 | { |
2612 | m_softcolide = true; | 2612 | if (newPos != _position) |
2613 | resetCollisionAccounting(); | 2613 | { |
2614 | } | 2614 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); |
2615 | 2615 | _position = newPos; | |
2616 | private void changeOrientation(Quaternion newOri) | 2616 | |
2617 | { | 2617 | m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace); |
2618 | CheckDelaySelect(); | 2618 | } |
2619 | if (m_isphysical) | 2619 | } |
2620 | { | 2620 | } |
2621 | if (childPrim) // inertia is messed, must rebuild | 2621 | givefakepos--; |
2622 | { | 2622 | if (givefakepos < 0) |
2623 | if (m_building) | 2623 | givefakepos = 0; |
2624 | { | 2624 | // changeSelectedStatus(); |
2625 | _orientation = newOri; | 2625 | m_softcolide = true; |
2626 | } | 2626 | resetCollisionAccounting(); |
2627 | } | 2627 | } |
2628 | else | 2628 | |
2629 | { | 2629 | private void changeOrientation(Quaternion newOri) |
2630 | if (newOri != _orientation) | 2630 | { |
2631 | { | 2631 | CheckDelaySelect(); |
2632 | d.Quaternion myrot = new d.Quaternion(); | 2632 | if (m_isphysical) |
2633 | myrot.X = newOri.X; | 2633 | { |
2634 | myrot.Y = newOri.Y; | 2634 | if (childPrim) // inertia is messed, must rebuild |
2635 | myrot.Z = newOri.Z; | 2635 | { |
2636 | myrot.W = newOri.W; | 2636 | if (m_building) |
2637 | d.GeomSetQuaternion(prim_geom, ref myrot); | 2637 | { |
2638 | _orientation = newOri; | 2638 | _orientation = newOri; |
2639 | if (Body != IntPtr.Zero && !m_angularlock.ApproxEquals(Vector3.One, 0f)) | 2639 | } |
2640 | createAMotor(m_angularlock); | 2640 | } |
2641 | } | 2641 | else |
2642 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | 2642 | { |
2643 | d.BodyEnable(Body); | 2643 | if (newOri != _orientation) |
2644 | } | 2644 | { |
2645 | } | 2645 | d.Quaternion myrot = new d.Quaternion(); |
2646 | else | 2646 | myrot.X = newOri.X; |
2647 | { | 2647 | myrot.Y = newOri.Y; |
2648 | if (prim_geom != IntPtr.Zero) | 2648 | myrot.Z = newOri.Z; |
2649 | { | 2649 | myrot.W = newOri.W; |
2650 | if (newOri != _orientation) | 2650 | d.GeomSetQuaternion(prim_geom, ref myrot); |
2651 | { | 2651 | _orientation = newOri; |
2652 | d.Quaternion myrot = new d.Quaternion(); | 2652 | if (Body != IntPtr.Zero && !m_angularlock.ApproxEquals(Vector3.One, 0f)) |
2653 | myrot.X = newOri.X; | 2653 | createAMotor(m_angularlock); |
2654 | myrot.Y = newOri.Y; | 2654 | } |
2655 | myrot.Z = newOri.Z; | 2655 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) |
2656 | myrot.W = newOri.W; | 2656 | d.BodyEnable(Body); |
2657 | d.GeomSetQuaternion(prim_geom, ref myrot); | 2657 | } |
2658 | _orientation = newOri; | 2658 | } |
2659 | } | 2659 | else |
2660 | } | 2660 | { |
2661 | } | 2661 | if (prim_geom != IntPtr.Zero) |
2662 | givefakeori--; | 2662 | { |
2663 | if (givefakeori < 0) | 2663 | if (newOri != _orientation) |
2664 | givefakeori = 0; | 2664 | { |
2665 | m_softcolide = true; | 2665 | d.Quaternion myrot = new d.Quaternion(); |
2666 | resetCollisionAccounting(); | 2666 | myrot.X = newOri.X; |
2667 | } | 2667 | myrot.Y = newOri.Y; |
2668 | 2668 | myrot.Z = newOri.Z; | |
2669 | private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) | 2669 | myrot.W = newOri.W; |
2670 | { | 2670 | d.GeomSetQuaternion(prim_geom, ref myrot); |
2671 | CheckDelaySelect(); | 2671 | _orientation = newOri; |
2672 | if (m_isphysical) | 2672 | } |
2673 | { | 2673 | } |
2674 | if (childPrim && m_building) // inertia is messed, must rebuild | 2674 | } |
2675 | { | 2675 | givefakeori--; |
2676 | _position = newPos; | 2676 | if (givefakeori < 0) |
2677 | _orientation = newOri; | 2677 | givefakeori = 0; |
2678 | } | 2678 | m_softcolide = true; |
2679 | else | 2679 | resetCollisionAccounting(); |
2680 | { | 2680 | } |
2681 | if (newOri != _orientation) | 2681 | |
2682 | { | 2682 | private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) |
2683 | d.Quaternion myrot = new d.Quaternion(); | 2683 | { |
2684 | myrot.X = newOri.X; | 2684 | CheckDelaySelect(); |
2685 | myrot.Y = newOri.Y; | 2685 | if (m_isphysical) |
2686 | myrot.Z = newOri.Z; | 2686 | { |
2687 | myrot.W = newOri.W; | 2687 | if (childPrim && m_building) // inertia is messed, must rebuild |
2688 | d.GeomSetQuaternion(prim_geom, ref myrot); | 2688 | { |
2689 | _orientation = newOri; | 2689 | _position = newPos; |
2690 | if (Body != IntPtr.Zero && !m_angularlock.ApproxEquals(Vector3.One, 0f)) | 2690 | _orientation = newOri; |
2691 | createAMotor(m_angularlock); | 2691 | } |
2692 | } | 2692 | else |
2693 | if (_position != newPos) | 2693 | { |
2694 | { | 2694 | if (newOri != _orientation) |
2695 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); | 2695 | { |
2696 | _position = newPos; | 2696 | d.Quaternion myrot = new d.Quaternion(); |
2697 | } | 2697 | myrot.X = newOri.X; |
2698 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | 2698 | myrot.Y = newOri.Y; |
2699 | d.BodyEnable(Body); | 2699 | myrot.Z = newOri.Z; |
2700 | } | 2700 | myrot.W = newOri.W; |
2701 | } | 2701 | d.GeomSetQuaternion(prim_geom, ref myrot); |
2702 | else | 2702 | _orientation = newOri; |
2703 | { | 2703 | if (Body != IntPtr.Zero && !m_angularlock.ApproxEquals(Vector3.One, 0f)) |
2704 | // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); | 2704 | createAMotor(m_angularlock); |
2705 | // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); | 2705 | } |
2706 | 2706 | if (_position != newPos) | |
2707 | if (prim_geom != IntPtr.Zero) | 2707 | { |
2708 | { | 2708 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); |
2709 | if (newOri != _orientation) | 2709 | _position = newPos; |
2710 | { | 2710 | } |
2711 | d.Quaternion myrot = new d.Quaternion(); | 2711 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) |
2712 | myrot.X = newOri.X; | 2712 | d.BodyEnable(Body); |
2713 | myrot.Y = newOri.Y; | 2713 | } |
2714 | myrot.Z = newOri.Z; | 2714 | } |
2715 | myrot.W = newOri.W; | 2715 | else |
2716 | d.GeomSetQuaternion(prim_geom, ref myrot); | 2716 | { |
2717 | _orientation = newOri; | 2717 | // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); |
2718 | } | 2718 | // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); |
2719 | 2719 | ||
2720 | if (newPos != _position) | 2720 | if (prim_geom != IntPtr.Zero) |
2721 | { | 2721 | { |
2722 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); | 2722 | if (newOri != _orientation) |
2723 | _position = newPos; | 2723 | { |
2724 | 2724 | d.Quaternion myrot = new d.Quaternion(); | |
2725 | m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace); | 2725 | myrot.X = newOri.X; |
2726 | } | 2726 | myrot.Y = newOri.Y; |
2727 | } | 2727 | myrot.Z = newOri.Z; |
2728 | } | 2728 | myrot.W = newOri.W; |
2729 | givefakepos--; | 2729 | d.GeomSetQuaternion(prim_geom, ref myrot); |
2730 | if (givefakepos < 0) | 2730 | _orientation = newOri; |
2731 | givefakepos = 0; | 2731 | } |
2732 | givefakeori--; | 2732 | |
2733 | if (givefakeori < 0) | 2733 | if (newPos != _position) |
2734 | givefakeori = 0; | 2734 | { |
2735 | 2735 | d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); | |
2736 | m_softcolide = true; | 2736 | _position = newPos; |
2737 | resetCollisionAccounting(); | 2737 | |
2738 | } | 2738 | m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace); |
2739 | 2739 | } | |
2740 | 2740 | } | |
2741 | private void changeDisable(bool disable) | 2741 | } |
2742 | { | 2742 | givefakepos--; |
2743 | if (disable) | 2743 | if (givefakepos < 0) |
2744 | { | 2744 | givefakepos = 0; |
2745 | if (!m_disabled) | 2745 | givefakeori--; |
2746 | disableBodySoft(); | 2746 | if (givefakeori < 0) |
2747 | } | 2747 | givefakeori = 0; |
2748 | else | 2748 | |
2749 | { | 2749 | m_softcolide = true; |
2750 | if (m_disabled) | 2750 | resetCollisionAccounting(); |
2751 | enableBodySoft(); | 2751 | } |
2752 | } | 2752 | |
2753 | } | 2753 | |
2754 | 2754 | private void changeDisable(bool disable) | |
2755 | private void changePhysicsStatus(bool NewStatus) | 2755 | { |
2756 | { | 2756 | if (disable) |
2757 | CheckDelaySelect(); | 2757 | { |
2758 | 2758 | if (!m_disabled) | |
2759 | m_isphysical = NewStatus; | 2759 | disableBodySoft(); |
2760 | 2760 | } | |
2761 | if (!childPrim) | 2761 | else |
2762 | { | 2762 | { |
2763 | if (NewStatus) | 2763 | if (m_disabled) |
2764 | { | 2764 | enableBodySoft(); |
2765 | if (Body == IntPtr.Zero) | 2765 | } |
2766 | MakeBody(); | 2766 | } |
2767 | } | 2767 | |
2768 | else | 2768 | private void changePhysicsStatus(bool NewStatus) |
2769 | { | 2769 | { |
2770 | if (Body != IntPtr.Zero) | 2770 | CheckDelaySelect(); |
2771 | { | 2771 | |
2772 | DestroyBody(); | 2772 | m_isphysical = NewStatus; |
2773 | } | 2773 | |
2774 | Stop(); | 2774 | if (!childPrim) |
2775 | } | 2775 | { |
2776 | } | 2776 | if (NewStatus) |
2777 | 2777 | { | |
2778 | resetCollisionAccounting(); | 2778 | if (Body == IntPtr.Zero) |
2779 | } | 2779 | MakeBody(); |
2780 | 2780 | } | |
2781 | private void changeprimsizeshape() | 2781 | else |
2782 | { | 2782 | { |
2783 | CheckDelaySelect(); | 2783 | if (Body != IntPtr.Zero) |
2784 | 2784 | { | |
2785 | OdePrim parent = (OdePrim)_parent; | 2785 | DestroyBody(); |
2786 | 2786 | } | |
2787 | bool chp = childPrim; | 2787 | Stop(); |
2788 | 2788 | } | |
2789 | if (chp) | 2789 | } |
2790 | { | 2790 | |
2791 | if (parent != null) | 2791 | resetCollisionAccounting(); |
2792 | { | 2792 | } |
2793 | parent.DestroyBody(); | 2793 | |
2794 | } | 2794 | private void changeprimsizeshape() |
2795 | } | 2795 | { |
2796 | else | 2796 | CheckDelaySelect(); |
2797 | { | 2797 | |
2798 | DestroyBody(); | 2798 | OdePrim parent = (OdePrim)_parent; |
2799 | } | 2799 | |
2800 | 2800 | bool chp = childPrim; | |
2801 | RemoveGeom(); | 2801 | |
2802 | 2802 | if (chp) | |
2803 | // we don't need to do space calculation because the client sends a position update also. | 2803 | { |
2804 | if (_size.X <= 0) | 2804 | if (parent != null) |
2805 | _size.X = 0.01f; | 2805 | { |
2806 | if (_size.Y <= 0) | 2806 | parent.DestroyBody(); |
2807 | _size.Y = 0.01f; | 2807 | } |
2808 | if (_size.Z <= 0) | 2808 | } |
2809 | _size.Z = 0.01f; | 2809 | else |
2810 | // Construction of new prim | 2810 | { |
2811 | 2811 | DestroyBody(); | |
2812 | CreateGeom(); | 2812 | } |
2813 | 2813 | ||
2814 | if (prim_geom != IntPtr.Zero) | 2814 | RemoveGeom(); |
2815 | { | 2815 | |
2816 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 2816 | // we don't need to do space calculation because the client sends a position update also. |
2817 | d.Quaternion myrot = new d.Quaternion(); | 2817 | if (_size.X <= 0) |
2818 | myrot.X = _orientation.X; | 2818 | _size.X = 0.01f; |
2819 | myrot.Y = _orientation.Y; | 2819 | if (_size.Y <= 0) |
2820 | myrot.Z = _orientation.Z; | 2820 | _size.Y = 0.01f; |
2821 | myrot.W = _orientation.W; | 2821 | if (_size.Z <= 0) |
2822 | d.GeomSetQuaternion(prim_geom, ref myrot); | 2822 | _size.Z = 0.01f; |
2823 | } | 2823 | // Construction of new prim |
2824 | 2824 | ||
2825 | if (chp) | 2825 | CreateGeom(); |
2826 | { | 2826 | |
2827 | if (parent != null) | 2827 | if (prim_geom != IntPtr.Zero) |
2828 | { | 2828 | { |
2829 | parent.MakeBody(); | 2829 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
2830 | } | 2830 | d.Quaternion myrot = new d.Quaternion(); |
2831 | } | 2831 | myrot.X = _orientation.X; |
2832 | else | 2832 | myrot.Y = _orientation.Y; |
2833 | MakeBody(); | 2833 | myrot.Z = _orientation.Z; |
2834 | 2834 | myrot.W = _orientation.W; | |
2835 | m_softcolide = true; | 2835 | d.GeomSetQuaternion(prim_geom, ref myrot); |
2836 | resetCollisionAccounting(); | 2836 | } |
2837 | } | 2837 | |
2838 | 2838 | if (chp) | |
2839 | private void changeSize(Vector3 newSize) | 2839 | { |
2840 | { | 2840 | if (parent != null) |
2841 | _size = newSize; | 2841 | { |
2842 | changeprimsizeshape(); | 2842 | parent.MakeBody(); |
2843 | } | 2843 | } |
2844 | 2844 | } | |
2845 | private void changeShape(PrimitiveBaseShape newShape) | 2845 | else |
2846 | { | 2846 | MakeBody(); |
2847 | _pbs = newShape; | 2847 | |
2848 | changeprimsizeshape(); | 2848 | m_softcolide = true; |
2849 | } | 2849 | resetCollisionAccounting(); |
2850 | 2850 | } | |
2851 | private void changeFloatOnWater(bool newval) | 2851 | |
2852 | { | 2852 | private void changeSize(Vector3 newSize) |
2853 | m_collidesWater = newval; | 2853 | { |
2854 | 2854 | _size = newSize; | |
2855 | if (prim_geom != IntPtr.Zero && !m_isphantom) | 2855 | changeprimsizeshape(); |
2856 | { | 2856 | } |
2857 | if (m_collidesWater) | 2857 | |
2858 | { | 2858 | private void changeShape(PrimitiveBaseShape newShape) |
2859 | m_collisionFlags |= CollisionCategories.Water; | 2859 | { |
2860 | } | 2860 | if(newShape != null) |
2861 | else | 2861 | _pbs = newShape; |
2862 | { | 2862 | changeprimsizeshape(); |
2863 | m_collisionFlags &= ~CollisionCategories.Water; | 2863 | } |
2864 | } | 2864 | |
2865 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2865 | private void changeFloatOnWater(bool newval) |
2866 | } | 2866 | { |
2867 | } | 2867 | m_collidesWater = newval; |
2868 | 2868 | ||
2869 | private void changeSetTorque(Vector3 newtorque) | 2869 | if (prim_geom != IntPtr.Zero && !m_isphantom) |
2870 | { | 2870 | { |
2871 | if (!m_isSelected) | 2871 | if (m_collidesWater) |
2872 | { | 2872 | { |
2873 | if (m_isphysical && Body != IntPtr.Zero) | 2873 | m_collisionFlags |= CollisionCategories.Water; |
2874 | { | 2874 | } |
2875 | if (m_disabled) | 2875 | else |
2876 | enableBodySoft(); | 2876 | { |
2877 | else if (!d.BodyIsEnabled(Body)) | 2877 | m_collisionFlags &= ~CollisionCategories.Water; |
2878 | d.BodyEnable(Body); | 2878 | } |
2879 | 2879 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | |
2880 | } | 2880 | } |
2881 | _torque = newtorque; | 2881 | } |
2882 | } | 2882 | |
2883 | } | 2883 | private void changeSetTorque(Vector3 newtorque) |
2884 | 2884 | { | |
2885 | private void changeForce(Vector3 force) | 2885 | if (!m_isSelected) |
2886 | { | 2886 | { |
2887 | m_force = force; | 2887 | if (m_isphysical && Body != IntPtr.Zero) |
2888 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | 2888 | { |
2889 | d.BodyEnable(Body); | 2889 | if (m_disabled) |
2890 | } | 2890 | enableBodySoft(); |
2891 | 2891 | else if (!d.BodyIsEnabled(Body)) | |
2892 | private void changeAddForce(Vector3 force) | 2892 | d.BodyEnable(Body); |
2893 | { | 2893 | |
2894 | m_forceacc += force; | 2894 | } |
2895 | if (!m_isSelected) | 2895 | _torque = newtorque; |
2896 | { | 2896 | } |
2897 | lock (this) | 2897 | } |
2898 | { | 2898 | |
2899 | //m_log.Info("[PHYSICS]: dequeing forcelist"); | 2899 | private void changeForce(Vector3 force) |
2900 | if (m_isphysical && Body != IntPtr.Zero) | 2900 | { |
2901 | { | 2901 | m_force = force; |
2902 | if (m_disabled) | 2902 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) |
2903 | enableBodySoft(); | 2903 | d.BodyEnable(Body); |
2904 | else if (!d.BodyIsEnabled(Body)) | 2904 | } |
2905 | d.BodyEnable(Body); | 2905 | |
2906 | } | 2906 | private void changeAddForce(Vector3 force) |
2907 | } | 2907 | { |
2908 | 2908 | m_forceacc += force; | |
2909 | m_collisionscore = 0; | 2909 | if (!m_isSelected) |
2910 | } | 2910 | { |
2911 | } | 2911 | lock (this) |
2912 | 2912 | { | |
2913 | private void changeAddAngularForce(Vector3 aforce) | 2913 | //m_log.Info("[PHYSICS]: dequeing forcelist"); |
2914 | { | 2914 | if (m_isphysical && Body != IntPtr.Zero) |
2915 | m_angularForceacc += aforce; | 2915 | { |
2916 | if (!m_isSelected) | 2916 | if (m_disabled) |
2917 | { | 2917 | enableBodySoft(); |
2918 | lock (this) | 2918 | else if (!d.BodyIsEnabled(Body)) |
2919 | { | 2919 | d.BodyEnable(Body); |
2920 | if (m_isphysical && Body != IntPtr.Zero) | 2920 | } |
2921 | { | 2921 | } |
2922 | if (m_disabled) | 2922 | |
2923 | enableBodySoft(); | 2923 | m_collisionscore = 0; |
2924 | else if (!d.BodyIsEnabled(Body)) | 2924 | } |
2925 | d.BodyEnable(Body); | 2925 | } |
2926 | } | 2926 | |
2927 | } | 2927 | private void changeAddAngularForce(Vector3 aforce) |
2928 | m_collisionscore = 0; | 2928 | { |
2929 | } | 2929 | m_angularForceacc += aforce; |
2930 | } | 2930 | if (!m_isSelected) |
2931 | 2931 | { | |
2932 | private void changevelocity(Vector3 newVel) | 2932 | lock (this) |
2933 | { | 2933 | { |
2934 | if (!m_isSelected) | 2934 | if (m_isphysical && Body != IntPtr.Zero) |
2935 | { | 2935 | { |
2936 | if (Body != IntPtr.Zero) | 2936 | if (m_disabled) |
2937 | { | 2937 | enableBodySoft(); |
2938 | if (m_disabled) | 2938 | else if (!d.BodyIsEnabled(Body)) |
2939 | enableBodySoft(); | 2939 | d.BodyEnable(Body); |
2940 | else if (!d.BodyIsEnabled(Body)) | 2940 | } |
2941 | d.BodyEnable(Body); | 2941 | } |
2942 | 2942 | m_collisionscore = 0; | |
2943 | d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); | 2943 | } |
2944 | } | 2944 | } |
2945 | //resetCollisionAccounting(); | 2945 | |
2946 | } | 2946 | private void changevelocity(Vector3 newVel) |
2947 | _velocity = newVel; | 2947 | { |
2948 | } | 2948 | if (!m_isSelected) |
2949 | 2949 | { | |
2950 | private void changeVolumedetetion(bool newVolDtc) | 2950 | if (Body != IntPtr.Zero) |
2951 | { | 2951 | { |
2952 | m_isVolumeDetect = newVolDtc; | 2952 | if (m_disabled) |
2953 | } | 2953 | enableBodySoft(); |
2954 | 2954 | else if (!d.BodyIsEnabled(Body)) | |
2955 | protected void changeBuilding(bool newbuilding) | 2955 | d.BodyEnable(Body); |
2956 | { | 2956 | |
2957 | if ((bool)newbuilding) | 2957 | d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); |
2958 | { | 2958 | } |
2959 | m_building = true; | 2959 | //resetCollisionAccounting(); |
2960 | if (!childPrim) | 2960 | } |
2961 | DestroyBody(); | 2961 | _velocity = newVel; |
2962 | } | 2962 | } |
2963 | else | 2963 | |
2964 | { | 2964 | private void changeVolumedetetion(bool newVolDtc) |
2965 | m_building = false; | 2965 | { |
2966 | CheckDelaySelect(); | 2966 | m_isVolumeDetect = newVolDtc; |
2967 | if (!childPrim) | 2967 | } |
2968 | MakeBody(); | 2968 | |
2969 | } | 2969 | protected void changeBuilding(bool newbuilding) |
2970 | if (!childPrim && childrenPrim.Count > 0) | 2970 | { |
2971 | { | 2971 | if ((bool)newbuilding) |
2972 | foreach (OdePrim prm in childrenPrim) | 2972 | { |
2973 | prm.changeBuilding(m_building); // call directly | 2973 | m_building = true; |
2974 | } | 2974 | if (!childPrim) |
2975 | } | 2975 | DestroyBody(); |
2976 | 2976 | } | |
2977 | public void changeSetVehicle(VehicleData vdata) | 2977 | else |
2978 | { | 2978 | { |
2979 | if (m_vehicle == null) | 2979 | m_building = false; |
2980 | m_vehicle = new ODEDynamics(this); | 2980 | CheckDelaySelect(); |
2981 | m_vehicle.DoSetVehicle(vdata); | 2981 | if (!childPrim) |
2982 | } | 2982 | MakeBody(); |
2983 | private void changeVehicleType(int value) | 2983 | } |
2984 | { | 2984 | if (!childPrim && childrenPrim.Count > 0) |
2985 | if (value == (int)Vehicle.TYPE_NONE) | 2985 | { |
2986 | { | 2986 | foreach (OdePrim prm in childrenPrim) |
2987 | if (m_vehicle != null) | 2987 | prm.changeBuilding(m_building); // call directly |
2988 | m_vehicle = null; | 2988 | } |
2989 | } | 2989 | } |
2990 | else | 2990 | |
2991 | { | 2991 | public void changeSetVehicle(VehicleData vdata) |
2992 | if (m_vehicle == null) | 2992 | { |
2993 | m_vehicle = new ODEDynamics(this); | 2993 | if (m_vehicle == null) |
2994 | 2994 | m_vehicle = new ODEDynamics(this); | |
2995 | m_vehicle.ProcessTypeChange((Vehicle)value); | 2995 | m_vehicle.DoSetVehicle(vdata); |
2996 | } | 2996 | } |
2997 | } | 2997 | private void changeVehicleType(int value) |
2998 | 2998 | { | |
2999 | private void changeVehicleFloatParam(strVehicleFloatParam fp) | 2999 | if (value == (int)Vehicle.TYPE_NONE) |
3000 | { | 3000 | { |
3001 | if (m_vehicle == null) | 3001 | if (m_vehicle != null) |
3002 | return; | 3002 | m_vehicle = null; |
3003 | 3003 | } | |
3004 | m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); | 3004 | else |
3005 | } | 3005 | { |
3006 | 3006 | if (m_vehicle == null) | |
3007 | private void changeVehicleVectorParam(strVehicleVectorParam vp) | 3007 | m_vehicle = new ODEDynamics(this); |
3008 | { | 3008 | |
3009 | if (m_vehicle == null) | 3009 | m_vehicle.ProcessTypeChange((Vehicle)value); |
3010 | return; | 3010 | } |
3011 | m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); | 3011 | } |
3012 | } | 3012 | |
3013 | 3013 | private void changeVehicleFloatParam(strVehicleFloatParam fp) | |
3014 | private void changeVehicleRotationParam(strVehicleQuatParam qp) | 3014 | { |
3015 | { | 3015 | if (m_vehicle == null) |
3016 | if (m_vehicle == null) | 3016 | return; |
3017 | return; | 3017 | |
3018 | m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); | 3018 | m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); |
3019 | } | 3019 | } |
3020 | 3020 | ||
3021 | private void changeVehicleFlags(strVehicleBoolParam bp) | 3021 | private void changeVehicleVectorParam(strVehicleVectorParam vp) |
3022 | { | 3022 | { |
3023 | if (m_vehicle == null) | 3023 | if (m_vehicle == null) |
3024 | return; | 3024 | return; |
3025 | m_vehicle.ProcessVehicleFlags(bp.param, bp.value); | 3025 | m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); |
3026 | } | 3026 | } |
3027 | 3027 | ||
3028 | #endregion | 3028 | private void changeVehicleRotationParam(strVehicleQuatParam qp) |
3029 | 3029 | { | |
3030 | public void Move() | 3030 | if (m_vehicle == null) |
3031 | { | 3031 | return; |
3032 | if (!childPrim && m_isphysical && Body != IntPtr.Zero && | 3032 | m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); |
3033 | !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds) | 3033 | } |
3034 | // !m_disabled && !m_isSelected && !m_building && !m_outbounds) | 3034 | |
3035 | { | 3035 | private void changeVehicleFlags(strVehicleBoolParam bp) |
3036 | // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 | 3036 | { |
3037 | 3037 | if (m_vehicle == null) | |
3038 | float timestep = _parent_scene.ODE_STEPSIZE; | 3038 | return; |
3039 | 3039 | m_vehicle.ProcessVehicleFlags(bp.param, bp.value); | |
3040 | // check outside region | 3040 | } |
3041 | d.Vector3 lpos; | 3041 | |
3042 | d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator | 3042 | #endregion |
3043 | 3043 | ||
3044 | if (lpos.Z < -100 || lpos.Z > 100000f) | 3044 | public void Move() |
3045 | { | 3045 | { |
3046 | m_outbounds = true; | 3046 | if (!childPrim && m_isphysical && Body != IntPtr.Zero && |
3047 | 3047 | !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds) | |
3048 | lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); | 3048 | // !m_disabled && !m_isSelected && !m_building && !m_outbounds) |
3049 | _acceleration.X = 0; | 3049 | { |
3050 | _acceleration.Y = 0; | 3050 | // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 |
3051 | _acceleration.Z = 0; | 3051 | |
3052 | 3052 | float timestep = _parent_scene.ODE_STEPSIZE; | |
3053 | _velocity.X = 0; | 3053 | |
3054 | _velocity.Y = 0; | 3054 | // check outside region |
3055 | _velocity.Z = 0; | 3055 | d.Vector3 lpos; |
3056 | m_rotationalVelocity.X = 0; | 3056 | d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator |
3057 | m_rotationalVelocity.Y = 0; | 3057 | |
3058 | m_rotationalVelocity.Z = 0; | 3058 | if (lpos.Z < -100 || lpos.Z > 100000f) |
3059 | 3059 | { | |
3060 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | 3060 | m_outbounds = true; |
3061 | d.BodySetAngularVel(Body, 0, 0, 0); // stop it | 3061 | |
3062 | d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere | 3062 | lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); |
3063 | m_lastposition = _position; | 3063 | _acceleration.X = 0; |
3064 | m_lastorientation = _orientation; | 3064 | _acceleration.Y = 0; |
3065 | 3065 | _acceleration.Z = 0; | |
3066 | base.RequestPhysicsterseUpdate(); | 3066 | |
3067 | 3067 | _velocity.X = 0; | |
3068 | m_throttleUpdates = false; | 3068 | _velocity.Y = 0; |
3069 | throttleCounter = 0; | 3069 | _velocity.Z = 0; |
3070 | _zeroFlag = true; | 3070 | m_rotationalVelocity.X = 0; |
3071 | 3071 | m_rotationalVelocity.Y = 0; | |
3072 | disableBodySoft(); // disable it and colisions | 3072 | m_rotationalVelocity.Z = 0; |
3073 | base.RaiseOutOfBounds(_position); | 3073 | |
3074 | return; | 3074 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it |
3075 | } | 3075 | d.BodySetAngularVel(Body, 0, 0, 0); // stop it |
3076 | 3076 | d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere | |
3077 | if (lpos.X < 0f) | 3077 | m_lastposition = _position; |
3078 | { | 3078 | m_lastorientation = _orientation; |
3079 | _position.X = Util.Clip(lpos.X, -2f, -0.1f); | 3079 | |
3080 | m_outbounds = true; | 3080 | base.RequestPhysicsterseUpdate(); |
3081 | } | 3081 | |
3082 | else if(lpos.X > _parent_scene.WorldExtents.X) | 3082 | m_throttleUpdates = false; |
3083 | { | 3083 | throttleCounter = 0; |
3084 | _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f); | 3084 | _zeroFlag = true; |
3085 | m_outbounds = true; | 3085 | |
3086 | } | 3086 | disableBodySoft(); // disable it and colisions |
3087 | if (lpos.Y < 0f) | 3087 | base.RaiseOutOfBounds(_position); |
3088 | { | 3088 | return; |
3089 | _position.Y = Util.Clip(lpos.Y, -2f, -0.1f); | 3089 | } |
3090 | m_outbounds = true; | 3090 | |
3091 | } | 3091 | if (lpos.X < 0f) |
3092 | else if(lpos.Y > _parent_scene.WorldExtents.Y) | 3092 | { |
3093 | { | 3093 | _position.X = Util.Clip(lpos.X, -2f, -0.1f); |
3094 | _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); | 3094 | m_outbounds = true; |
3095 | m_outbounds = true; | 3095 | } |
3096 | } | 3096 | else if(lpos.X > _parent_scene.WorldExtents.X) |
3097 | 3097 | { | |
3098 | if(m_outbounds) | 3098 | _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f); |
3099 | { | 3099 | m_outbounds = true; |
3100 | m_lastposition = _position; | 3100 | } |
3101 | m_lastorientation = _orientation; | 3101 | if (lpos.Y < 0f) |
3102 | 3102 | { | |
3103 | d.Vector3 dtmp = d.BodyGetAngularVel(Body); | 3103 | _position.Y = Util.Clip(lpos.Y, -2f, -0.1f); |
3104 | m_rotationalVelocity.X = dtmp.X; | 3104 | m_outbounds = true; |
3105 | m_rotationalVelocity.Y = dtmp.Y; | 3105 | } |
3106 | m_rotationalVelocity.Z = dtmp.Z; | 3106 | else if(lpos.Y > _parent_scene.WorldExtents.Y) |
3107 | 3107 | { | |
3108 | dtmp = d.BodyGetLinearVel(Body); | 3108 | _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); |
3109 | _velocity.X = dtmp.X; | 3109 | m_outbounds = true; |
3110 | _velocity.Y = dtmp.Y; | 3110 | } |
3111 | _velocity.Z = dtmp.Z; | 3111 | |
3112 | 3112 | if(m_outbounds) | |
3113 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | 3113 | { |
3114 | d.BodySetAngularVel(Body, 0, 0, 0); | 3114 | m_lastposition = _position; |
3115 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 3115 | m_lastorientation = _orientation; |
3116 | disableBodySoft(); // stop collisions | 3116 | |
3117 | base.RequestPhysicsterseUpdate(); | 3117 | d.Vector3 dtmp = d.BodyGetAngularVel(Body); |
3118 | return; | 3118 | m_rotationalVelocity.X = dtmp.X; |
3119 | } | 3119 | m_rotationalVelocity.Y = dtmp.Y; |
3120 | 3120 | m_rotationalVelocity.Z = dtmp.Z; | |
3121 | 3121 | ||
3122 | float fx = 0; | 3122 | dtmp = d.BodyGetLinearVel(Body); |
3123 | float fy = 0; | 3123 | _velocity.X = dtmp.X; |
3124 | float fz = 0; | 3124 | _velocity.Y = dtmp.Y; |
3125 | 3125 | _velocity.Z = dtmp.Z; | |
3126 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | 3126 | |
3127 | { | 3127 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it |
3128 | // 'VEHICLES' are dealt with in ODEDynamics.cs | 3128 | d.BodySetAngularVel(Body, 0, 0, 0); |
3129 | m_vehicle.Step(); | 3129 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
3130 | } | 3130 | disableBodySoft(); // stop collisions |
3131 | else | 3131 | base.RequestPhysicsterseUpdate(); |
3132 | { | 3132 | return; |
3133 | float m_mass = _mass; | 3133 | } |
3134 | 3134 | ||
3135 | // fz = 0f; | 3135 | |
3136 | //m_log.Info(m_collisionFlags.ToString()); | 3136 | float fx = 0; |
3137 | if (m_usePID) | 3137 | float fy = 0; |
3138 | { | 3138 | float fz = 0; |
3139 | 3139 | ||
3140 | // If the PID Controller isn't active then we set our force | 3140 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) |
3141 | // calculating base velocity to the current position | 3141 | { |
3142 | 3142 | // 'VEHICLES' are dealt with in ODEDynamics.cs | |
3143 | if ((m_PIDTau < 1) && (m_PIDTau != 0)) | 3143 | m_vehicle.Step(); |
3144 | { | 3144 | } |
3145 | //PID_G = PID_G / m_PIDTau; | 3145 | else |
3146 | m_PIDTau = 1; | 3146 | { |
3147 | } | 3147 | float m_mass = _mass; |
3148 | 3148 | ||
3149 | if ((PID_G - m_PIDTau) <= 0) | 3149 | // fz = 0f; |
3150 | { | 3150 | //m_log.Info(m_collisionFlags.ToString()); |
3151 | PID_G = m_PIDTau + 1; | 3151 | if (m_usePID) |
3152 | } | 3152 | { |
3153 | 3153 | ||
3154 | d.Vector3 vel = d.BodyGetLinearVel(Body); | 3154 | // If the PID Controller isn't active then we set our force |
3155 | d.Vector3 pos = d.BodyGetPosition(Body); | 3155 | // calculating base velocity to the current position |
3156 | _target_velocity = | 3156 | |
3157 | new Vector3( | 3157 | if ((m_PIDTau < 1) && (m_PIDTau != 0)) |
3158 | (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), | 3158 | { |
3159 | (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), | 3159 | //PID_G = PID_G / m_PIDTau; |
3160 | (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) | 3160 | m_PIDTau = 1; |
3161 | ); | 3161 | } |
3162 | 3162 | ||
3163 | // if velocity is zero, use position control; otherwise, velocity control | 3163 | if ((PID_G - m_PIDTau) <= 0) |
3164 | 3164 | { | |
3165 | if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) | 3165 | PID_G = m_PIDTau + 1; |
3166 | { | 3166 | } |
3167 | // keep track of where we stopped. No more slippin' & slidin' | 3167 | |
3168 | 3168 | d.Vector3 vel = d.BodyGetLinearVel(Body); | |
3169 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | 3169 | d.Vector3 pos = d.BodyGetPosition(Body); |
3170 | // react to the physics scene by moving it's position. | 3170 | _target_velocity = |
3171 | // Avatar to Avatar collisions | 3171 | new Vector3( |
3172 | // Prim to avatar collisions | 3172 | (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), |
3173 | 3173 | (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), | |
3174 | //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); | 3174 | (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) |
3175 | //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); | 3175 | ); |
3176 | //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; | 3176 | |
3177 | d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); | 3177 | // if velocity is zero, use position control; otherwise, velocity control |
3178 | d.BodySetLinearVel(Body, 0, 0, 0); | 3178 | |
3179 | d.BodyAddForce(Body, 0, 0, fz); | 3179 | if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) |
3180 | return; | 3180 | { |
3181 | } | 3181 | // keep track of where we stopped. No more slippin' & slidin' |
3182 | else | 3182 | |
3183 | { | 3183 | // We only want to deactivate the PID Controller if we think we want to have our surrogate |
3184 | _zeroFlag = false; | 3184 | // react to the physics scene by moving it's position. |
3185 | 3185 | // Avatar to Avatar collisions | |
3186 | // We're flying and colliding with something | 3186 | // Prim to avatar collisions |
3187 | fx = ((_target_velocity.X) - vel.X) * (PID_D); | 3187 | |
3188 | fy = ((_target_velocity.Y) - vel.Y) * (PID_D); | 3188 | //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); |
3189 | 3189 | //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); | |
3190 | // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; | 3190 | //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; |
3191 | 3191 | d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); | |
3192 | fz = ((_target_velocity.Z - vel.Z) * (PID_D)); | 3192 | d.BodySetLinearVel(Body, 0, 0, 0); |
3193 | } | 3193 | d.BodyAddForce(Body, 0, 0, fz); |
3194 | } // end if (m_usePID) | 3194 | return; |
3195 | 3195 | } | |
3196 | // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller | 3196 | else |
3197 | else if (m_useHoverPID) | 3197 | { |
3198 | { | 3198 | _zeroFlag = false; |
3199 | //Console.WriteLine("Hover " + Name); | 3199 | |
3200 | 3200 | // We're flying and colliding with something | |
3201 | // If we're using the PID controller, then we have no gravity | 3201 | fx = ((_target_velocity.X) - vel.X) * (PID_D); |
3202 | 3202 | fy = ((_target_velocity.Y) - vel.Y) * (PID_D); | |
3203 | // no lock; for now it's only called from within Simulate() | 3203 | |
3204 | 3204 | // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; | |
3205 | // If the PID Controller isn't active then we set our force | 3205 | |
3206 | // calculating base velocity to the current position | 3206 | fz = ((_target_velocity.Z - vel.Z) * (PID_D)); |
3207 | 3207 | } | |
3208 | if ((m_PIDTau < 1)) | 3208 | } // end if (m_usePID) |
3209 | { | 3209 | |
3210 | PID_G = PID_G / m_PIDTau; | 3210 | // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller |
3211 | } | 3211 | else if (m_useHoverPID) |
3212 | 3212 | { | |
3213 | if ((PID_G - m_PIDTau) <= 0) | 3213 | //Console.WriteLine("Hover " + Name); |
3214 | { | 3214 | |
3215 | PID_G = m_PIDTau + 1; | 3215 | // If we're using the PID controller, then we have no gravity |
3216 | } | 3216 | |
3217 | 3217 | // no lock; for now it's only called from within Simulate() | |
3218 | // Where are we, and where are we headed? | 3218 | |
3219 | d.Vector3 pos = d.BodyGetPosition(Body); | 3219 | // If the PID Controller isn't active then we set our force |
3220 | d.Vector3 vel = d.BodyGetLinearVel(Body); | 3220 | // calculating base velocity to the current position |
3221 | 3221 | ||
3222 | // Non-Vehicles have a limited set of Hover options. | 3222 | if ((m_PIDTau < 1)) |
3223 | // determine what our target height really is based on HoverType | 3223 | { |
3224 | switch (m_PIDHoverType) | 3224 | PID_G = PID_G / m_PIDTau; |
3225 | { | 3225 | } |
3226 | case PIDHoverType.Ground: | 3226 | |
3227 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | 3227 | if ((PID_G - m_PIDTau) <= 0) |
3228 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | 3228 | { |
3229 | break; | 3229 | PID_G = m_PIDTau + 1; |
3230 | case PIDHoverType.GroundAndWater: | 3230 | } |
3231 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | 3231 | |
3232 | m_waterHeight = _parent_scene.GetWaterLevel(); | 3232 | // Where are we, and where are we headed? |
3233 | if (m_groundHeight > m_waterHeight) | 3233 | d.Vector3 pos = d.BodyGetPosition(Body); |
3234 | { | 3234 | d.Vector3 vel = d.BodyGetLinearVel(Body); |
3235 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | 3235 | |
3236 | } | 3236 | // Non-Vehicles have a limited set of Hover options. |
3237 | else | 3237 | // determine what our target height really is based on HoverType |
3238 | { | 3238 | switch (m_PIDHoverType) |
3239 | m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; | 3239 | { |
3240 | } | 3240 | case PIDHoverType.Ground: |
3241 | break; | 3241 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); |
3242 | 3242 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; | |
3243 | } // end switch (m_PIDHoverType) | 3243 | break; |
3244 | 3244 | case PIDHoverType.GroundAndWater: | |
3245 | 3245 | m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); | |
3246 | _target_velocity = | 3246 | m_waterHeight = _parent_scene.GetWaterLevel(); |
3247 | new Vector3(0.0f, 0.0f, | 3247 | if (m_groundHeight > m_waterHeight) |
3248 | (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) | 3248 | { |
3249 | ); | 3249 | m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; |
3250 | 3250 | } | |
3251 | // if velocity is zero, use position control; otherwise, velocity control | 3251 | else |
3252 | 3252 | { | |
3253 | if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) | 3253 | m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; |
3254 | { | 3254 | } |
3255 | // keep track of where we stopped. No more slippin' & slidin' | 3255 | break; |
3256 | 3256 | ||
3257 | // We only want to deactivate the PID Controller if we think we want to have our surrogate | 3257 | } // end switch (m_PIDHoverType) |
3258 | // react to the physics scene by moving it's position. | 3258 | |
3259 | // Avatar to Avatar collisions | 3259 | |
3260 | // Prim to avatar collisions | 3260 | _target_velocity = |
3261 | 3261 | new Vector3(0.0f, 0.0f, | |
3262 | d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); | 3262 | (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) |
3263 | d.BodySetLinearVel(Body, vel.X, vel.Y, 0); | 3263 | ); |
3264 | // ? d.BodyAddForce(Body, 0, 0, fz); | 3264 | |
3265 | return; | 3265 | // if velocity is zero, use position control; otherwise, velocity control |
3266 | } | 3266 | |
3267 | else | 3267 | if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) |
3268 | { | 3268 | { |
3269 | _zeroFlag = false; | 3269 | // keep track of where we stopped. No more slippin' & slidin' |
3270 | 3270 | ||
3271 | // We're flying and colliding with something | 3271 | // We only want to deactivate the PID Controller if we think we want to have our surrogate |
3272 | fz = ((_target_velocity.Z - vel.Z) * (PID_D)); | 3272 | // react to the physics scene by moving it's position. |
3273 | } | 3273 | // Avatar to Avatar collisions |
3274 | } | 3274 | // Prim to avatar collisions |
3275 | else | 3275 | |
3276 | { | 3276 | d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); |
3277 | float b = (1.0f - m_buoyancy); | 3277 | d.BodySetLinearVel(Body, vel.X, vel.Y, 0); |
3278 | fx = _parent_scene.gravityx * b; | 3278 | // ? d.BodyAddForce(Body, 0, 0, fz); |
3279 | fy = _parent_scene.gravityy * b; | 3279 | return; |
3280 | fz = _parent_scene.gravityz * b; | 3280 | } |
3281 | } | 3281 | else |
3282 | 3282 | { | |
3283 | fx *= m_mass; | 3283 | _zeroFlag = false; |
3284 | fy *= m_mass; | 3284 | |
3285 | fz *= m_mass; | 3285 | // We're flying and colliding with something |
3286 | 3286 | fz = ((_target_velocity.Z - vel.Z) * (PID_D)); | |
3287 | // constant force | 3287 | } |
3288 | fx += m_force.X; | 3288 | } |
3289 | fy += m_force.Y; | 3289 | else |
3290 | fz += m_force.Z; | 3290 | { |
3291 | 3291 | float b = (1.0f - m_buoyancy); | |
3292 | fx += m_forceacc.X; | 3292 | fx = _parent_scene.gravityx * b; |
3293 | fy += m_forceacc.Y; | 3293 | fy = _parent_scene.gravityy * b; |
3294 | fz += m_forceacc.Z; | 3294 | fz = _parent_scene.gravityz * b; |
3295 | 3295 | } | |
3296 | m_forceacc = Vector3.Zero; | 3296 | |
3297 | 3297 | fx *= m_mass; | |
3298 | //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); | 3298 | fy *= m_mass; |
3299 | if (fx != 0 || fy != 0 || fz != 0) | 3299 | fz *= m_mass; |
3300 | { | 3300 | |
3301 | d.BodyAddForce(Body, fx, fy, fz); | 3301 | // constant force |
3302 | //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); | 3302 | fx += m_force.X; |
3303 | } | 3303 | fy += m_force.Y; |
3304 | 3304 | fz += m_force.Z; | |
3305 | Vector3 trq; | 3305 | |
3306 | 3306 | fx += m_forceacc.X; | |
3307 | trq = _torque; | 3307 | fy += m_forceacc.Y; |
3308 | trq += m_angularForceacc; | 3308 | fz += m_forceacc.Z; |
3309 | m_angularForceacc = Vector3.Zero; | 3309 | |
3310 | if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) | 3310 | m_forceacc = Vector3.Zero; |
3311 | { | 3311 | |
3312 | d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z); | 3312 | //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); |
3313 | } | 3313 | if (fx != 0 || fy != 0 || fz != 0) |
3314 | 3314 | { | |
3315 | } | 3315 | d.BodyAddForce(Body, fx, fy, fz); |
3316 | } | 3316 | //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); |
3317 | else | 3317 | } |
3318 | { // is not physical, or is not a body or is selected | 3318 | |
3319 | // _zeroPosition = d.BodyGetPosition(Body); | 3319 | Vector3 trq; |
3320 | return; | 3320 | |
3321 | //Console.WriteLine("Nothing " + Name); | 3321 | trq = _torque; |
3322 | 3322 | trq += m_angularForceacc; | |
3323 | } | 3323 | m_angularForceacc = Vector3.Zero; |
3324 | } | 3324 | if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) |
3325 | 3325 | { | |
3326 | 3326 | d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z); | |
3327 | public void UpdatePositionAndVelocity(float simulatedtime) | 3327 | } |
3328 | { | 3328 | |
3329 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! | 3329 | } |
3330 | if (_parent == null && !m_disabled && !m_building && !m_outbounds) | 3330 | } |
3331 | { | 3331 | else |
3332 | if (Body != IntPtr.Zero) | 3332 | { // is not physical, or is not a body or is selected |
3333 | { | 3333 | // _zeroPosition = d.BodyGetPosition(Body); |
3334 | Vector3 pv = Vector3.Zero; | 3334 | return; |
3335 | bool lastZeroFlag = _zeroFlag; | 3335 | //Console.WriteLine("Nothing " + Name); |
3336 | 3336 | ||
3337 | d.Vector3 lpos; | 3337 | } |
3338 | d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator | 3338 | } |
3339 | 3339 | ||
3340 | 3340 | ||
3341 | d.Quaternion ori; | 3341 | public void UpdatePositionAndVelocity(float simulatedtime) |
3342 | d.GeomCopyQuaternion(prim_geom, out ori); | 3342 | { |
3343 | d.Vector3 vel = d.BodyGetLinearVel(Body); | 3343 | // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! |
3344 | d.Vector3 rotvel = d.BodyGetAngularVel(Body); | 3344 | if (_parent == null && !m_disabled && !m_building && !m_outbounds) |
3345 | 3345 | { | |
3346 | if ((Math.Abs(m_lastposition.X - lpos.X) < 0.01) | 3346 | if (Body != IntPtr.Zero) |
3347 | && (Math.Abs(m_lastposition.Y - lpos.Y) < 0.01) | 3347 | { |
3348 | && (Math.Abs(m_lastposition.Z - lpos.Z) < 0.01) | 3348 | Vector3 pv = Vector3.Zero; |
3349 | && (Math.Abs(m_lastorientation.X - ori.X) < 0.0001) | 3349 | bool lastZeroFlag = _zeroFlag; |
3350 | && (Math.Abs(m_lastorientation.Y - ori.Y) < 0.0001) | 3350 | |
3351 | && (Math.Abs(m_lastorientation.Z - ori.Z) < 0.0001) | 3351 | d.Vector3 lpos; |
3352 | ) | 3352 | d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator |
3353 | { | 3353 | |
3354 | _zeroFlag = true; | 3354 | |
3355 | //Console.WriteLine("ZFT 2"); | 3355 | d.Quaternion ori; |
3356 | m_throttleUpdates = false; | 3356 | d.GeomCopyQuaternion(prim_geom, out ori); |
3357 | } | 3357 | d.Vector3 vel = d.BodyGetLinearVel(Body); |
3358 | else | 3358 | d.Vector3 rotvel = d.BodyGetAngularVel(Body); |
3359 | { | 3359 | |
3360 | //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); | 3360 | if ((Math.Abs(m_lastposition.X - lpos.X) < 0.01) |
3361 | _zeroFlag = false; | 3361 | && (Math.Abs(m_lastposition.Y - lpos.Y) < 0.01) |
3362 | m_lastUpdateSent = false; | 3362 | && (Math.Abs(m_lastposition.Z - lpos.Z) < 0.01) |
3363 | //m_throttleUpdates = false; | 3363 | && (Math.Abs(m_lastorientation.X - ori.X) < 0.0001) |
3364 | } | 3364 | && (Math.Abs(m_lastorientation.Y - ori.Y) < 0.0001) |
3365 | 3365 | && (Math.Abs(m_lastorientation.Z - ori.Z) < 0.0001) | |
3366 | if (_zeroFlag) | 3366 | ) |
3367 | { | 3367 | { |
3368 | m_lastposition = _position; | 3368 | _zeroFlag = true; |
3369 | m_lastorientation = _orientation; | 3369 | //Console.WriteLine("ZFT 2"); |
3370 | 3370 | m_throttleUpdates = false; | |
3371 | _velocity.X = 0.0f; | 3371 | } |
3372 | _velocity.Y = 0.0f; | 3372 | else |
3373 | _velocity.Z = 0.0f; | 3373 | { |
3374 | 3374 | //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); | |
3375 | _acceleration.X = 0; | 3375 | _zeroFlag = false; |
3376 | _acceleration.Y = 0; | 3376 | m_lastUpdateSent = false; |
3377 | _acceleration.Z = 0; | 3377 | //m_throttleUpdates = false; |
3378 | 3378 | } | |
3379 | m_rotationalVelocity.X = 0; | 3379 | |
3380 | m_rotationalVelocity.Y = 0; | 3380 | if (_zeroFlag) |
3381 | m_rotationalVelocity.Z = 0; | 3381 | { |
3382 | if (!m_lastUpdateSent) | 3382 | m_lastposition = _position; |
3383 | { | 3383 | m_lastorientation = _orientation; |
3384 | m_throttleUpdates = false; | 3384 | |
3385 | throttleCounter = 0; | 3385 | _velocity.X = 0.0f; |
3386 | m_rotationalVelocity = pv; | 3386 | _velocity.Y = 0.0f; |
3387 | 3387 | _velocity.Z = 0.0f; | |
3388 | base.RequestPhysicsterseUpdate(); | 3388 | |
3389 | 3389 | _acceleration.X = 0; | |
3390 | m_lastUpdateSent = true; | 3390 | _acceleration.Y = 0; |
3391 | } | 3391 | _acceleration.Z = 0; |
3392 | } | 3392 | |
3393 | else | 3393 | m_rotationalVelocity.X = 0; |
3394 | { | 3394 | m_rotationalVelocity.Y = 0; |
3395 | if (lastZeroFlag != _zeroFlag) | 3395 | m_rotationalVelocity.Z = 0; |
3396 | { | 3396 | if (!m_lastUpdateSent) |
3397 | base.RequestPhysicsterseUpdate(); | 3397 | { |
3398 | } | 3398 | m_throttleUpdates = false; |
3399 | 3399 | throttleCounter = 0; | |
3400 | m_lastVelocity = _velocity; | 3400 | m_rotationalVelocity = pv; |
3401 | 3401 | ||
3402 | _position.X = lpos.X; | 3402 | base.RequestPhysicsterseUpdate(); |
3403 | _position.Y = lpos.Y; | 3403 | |
3404 | _position.Z = lpos.Z; | 3404 | m_lastUpdateSent = true; |
3405 | 3405 | } | |
3406 | _velocity.X = vel.X; | 3406 | } |
3407 | _velocity.Y = vel.Y; | 3407 | else |
3408 | _velocity.Z = vel.Z; | 3408 | { |
3409 | 3409 | if (lastZeroFlag != _zeroFlag) | |
3410 | _orientation.X = ori.X; | 3410 | { |
3411 | _orientation.Y = ori.Y; | 3411 | base.RequestPhysicsterseUpdate(); |
3412 | _orientation.Z = ori.Z; | 3412 | } |
3413 | _orientation.W = ori.W; | 3413 | |
3414 | 3414 | m_lastVelocity = _velocity; | |
3415 | _acceleration = ((_velocity - m_lastVelocity) / simulatedtime); | 3415 | |
3416 | 3416 | _position.X = lpos.X; | |
3417 | if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f)) | 3417 | _position.Y = lpos.Y; |
3418 | { | 3418 | _position.Z = lpos.Z; |
3419 | m_rotationalVelocity = pv; | 3419 | |
3420 | } | 3420 | _velocity.X = vel.X; |
3421 | else | 3421 | _velocity.Y = vel.Y; |
3422 | { | 3422 | _velocity.Z = vel.Z; |
3423 | m_rotationalVelocity.X = rotvel.X; | 3423 | |
3424 | m_rotationalVelocity.Y = rotvel.Y; | 3424 | _orientation.X = ori.X; |
3425 | m_rotationalVelocity.Z = rotvel.Z; | 3425 | _orientation.Y = ori.Y; |
3426 | } | 3426 | _orientation.Z = ori.Z; |
3427 | 3427 | _orientation.W = ori.W; | |
3428 | m_lastUpdateSent = false; | 3428 | |
3429 | if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) | 3429 | _acceleration = ((_velocity - m_lastVelocity) / simulatedtime); |
3430 | { | 3430 | |
3431 | m_lastposition = _position; | 3431 | if (m_rotationalVelocity.ApproxEquals(pv, 0.0001f)) |
3432 | m_lastorientation = _orientation; | 3432 | { |
3433 | base.RequestPhysicsterseUpdate(); | 3433 | m_rotationalVelocity = pv; |
3434 | } | 3434 | } |
3435 | else | 3435 | else |
3436 | { | 3436 | { |
3437 | throttleCounter++; | 3437 | m_rotationalVelocity.X = rotvel.X; |
3438 | } | 3438 | m_rotationalVelocity.Y = rotvel.Y; |
3439 | } | 3439 | m_rotationalVelocity.Z = rotvel.Z; |
3440 | } | 3440 | } |
3441 | else if (!m_lastUpdateSent || !_zeroFlag) | 3441 | |
3442 | { | 3442 | m_lastUpdateSent = false; |
3443 | // Not a body.. so Make sure the client isn't interpolating | 3443 | if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) |
3444 | _velocity.X = 0; | 3444 | { |
3445 | _velocity.Y = 0; | 3445 | m_lastposition = _position; |
3446 | _velocity.Z = 0; | 3446 | m_lastorientation = _orientation; |
3447 | 3447 | base.RequestPhysicsterseUpdate(); | |
3448 | _acceleration.X = 0; | 3448 | } |
3449 | _acceleration.Y = 0; | 3449 | else |
3450 | _acceleration.Z = 0; | 3450 | { |
3451 | 3451 | throttleCounter++; | |
3452 | m_rotationalVelocity.X = 0; | 3452 | } |
3453 | m_rotationalVelocity.Y = 0; | 3453 | } |
3454 | m_rotationalVelocity.Z = 0; | 3454 | } |
3455 | _zeroFlag = true; | 3455 | else if (!m_lastUpdateSent || !_zeroFlag) |
3456 | 3456 | { | |
3457 | if (!m_lastUpdateSent) | 3457 | // Not a body.. so Make sure the client isn't interpolating |
3458 | { | 3458 | _velocity.X = 0; |
3459 | m_throttleUpdates = false; | 3459 | _velocity.Y = 0; |
3460 | throttleCounter = 0; | 3460 | _velocity.Z = 0; |
3461 | 3461 | ||
3462 | base.RequestPhysicsterseUpdate(); | 3462 | _acceleration.X = 0; |
3463 | 3463 | _acceleration.Y = 0; | |
3464 | m_lastUpdateSent = true; | 3464 | _acceleration.Z = 0; |
3465 | } | 3465 | |
3466 | } | 3466 | m_rotationalVelocity.X = 0; |
3467 | } | 3467 | m_rotationalVelocity.Y = 0; |
3468 | } | 3468 | m_rotationalVelocity.Z = 0; |
3469 | 3469 | _zeroFlag = true; | |
3470 | internal static bool QuaternionIsFinite(Quaternion q) | 3470 | |
3471 | { | 3471 | if (!m_lastUpdateSent) |
3472 | if (Single.IsNaN(q.X) || Single.IsInfinity(q.X)) | 3472 | { |
3473 | return false; | 3473 | m_throttleUpdates = false; |
3474 | if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y)) | 3474 | throttleCounter = 0; |
3475 | return false; | 3475 | |
3476 | if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z)) | 3476 | base.RequestPhysicsterseUpdate(); |
3477 | return false; | 3477 | |
3478 | if (Single.IsNaN(q.W) || Single.IsInfinity(q.W)) | 3478 | m_lastUpdateSent = true; |
3479 | return false; | 3479 | } |
3480 | return true; | 3480 | } |
3481 | } | 3481 | } |
3482 | 3482 | } | |
3483 | internal static void DMassCopy(ref d.Mass src, ref d.Mass dst) | 3483 | |
3484 | { | 3484 | internal static bool QuaternionIsFinite(Quaternion q) |
3485 | dst.c.W = src.c.W; | 3485 | { |
3486 | dst.c.X = src.c.X; | 3486 | if (Single.IsNaN(q.X) || Single.IsInfinity(q.X)) |
3487 | dst.c.Y = src.c.Y; | 3487 | return false; |
3488 | dst.c.Z = src.c.Z; | 3488 | if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y)) |
3489 | dst.mass = src.mass; | 3489 | return false; |
3490 | dst.I.M00 = src.I.M00; | 3490 | if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z)) |
3491 | dst.I.M01 = src.I.M01; | 3491 | return false; |
3492 | dst.I.M02 = src.I.M02; | 3492 | if (Single.IsNaN(q.W) || Single.IsInfinity(q.W)) |
3493 | dst.I.M10 = src.I.M10; | 3493 | return false; |
3494 | dst.I.M11 = src.I.M11; | 3494 | return true; |
3495 | dst.I.M12 = src.I.M12; | 3495 | } |
3496 | dst.I.M20 = src.I.M20; | 3496 | |
3497 | dst.I.M21 = src.I.M21; | 3497 | internal static void DMassCopy(ref d.Mass src, ref d.Mass dst) |
3498 | dst.I.M22 = src.I.M22; | 3498 | { |
3499 | } | 3499 | dst.c.W = src.c.W; |
3500 | 3500 | dst.c.X = src.c.X; | |
3501 | private static void DMassDup(ref d.Mass src, out d.Mass dst) | 3501 | dst.c.Y = src.c.Y; |
3502 | { | 3502 | dst.c.Z = src.c.Z; |
3503 | dst = new d.Mass { }; | 3503 | dst.mass = src.mass; |
3504 | 3504 | dst.I.M00 = src.I.M00; | |
3505 | dst.c.W = src.c.W; | 3505 | dst.I.M01 = src.I.M01; |
3506 | dst.c.X = src.c.X; | 3506 | dst.I.M02 = src.I.M02; |
3507 | dst.c.Y = src.c.Y; | 3507 | dst.I.M10 = src.I.M10; |
3508 | dst.c.Z = src.c.Z; | 3508 | dst.I.M11 = src.I.M11; |
3509 | dst.mass = src.mass; | 3509 | dst.I.M12 = src.I.M12; |
3510 | dst.I.M00 = src.I.M00; | 3510 | dst.I.M20 = src.I.M20; |
3511 | dst.I.M01 = src.I.M01; | 3511 | dst.I.M21 = src.I.M21; |
3512 | dst.I.M02 = src.I.M02; | 3512 | dst.I.M22 = src.I.M22; |
3513 | dst.I.M10 = src.I.M10; | 3513 | } |
3514 | dst.I.M11 = src.I.M11; | 3514 | |
3515 | dst.I.M12 = src.I.M12; | 3515 | private static void DMassDup(ref d.Mass src, out d.Mass dst) |
3516 | dst.I.M20 = src.I.M20; | 3516 | { |
3517 | dst.I.M21 = src.I.M21; | 3517 | dst = new d.Mass { }; |
3518 | dst.I.M22 = src.I.M22; | 3518 | |
3519 | } | 3519 | dst.c.W = src.c.W; |
3520 | private void donullchange() | 3520 | dst.c.X = src.c.X; |
3521 | { | 3521 | dst.c.Y = src.c.Y; |
3522 | } | 3522 | dst.c.Z = src.c.Z; |
3523 | 3523 | dst.mass = src.mass; | |
3524 | public bool DoAChange(changes what, object arg) | 3524 | dst.I.M00 = src.I.M00; |
3525 | { | 3525 | dst.I.M01 = src.I.M01; |
3526 | if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.Remove) | 3526 | dst.I.M02 = src.I.M02; |
3527 | { | 3527 | dst.I.M10 = src.I.M10; |
3528 | return false; | 3528 | dst.I.M11 = src.I.M11; |
3529 | } | 3529 | dst.I.M12 = src.I.M12; |
3530 | 3530 | dst.I.M20 = src.I.M20; | |
3531 | // nasty switch | 3531 | dst.I.M21 = src.I.M21; |
3532 | switch (what) | 3532 | dst.I.M22 = src.I.M22; |
3533 | { | 3533 | } |
3534 | case changes.Add: | 3534 | private void donullchange() |
3535 | changeadd(); | 3535 | { |
3536 | break; | 3536 | } |
3537 | case changes.Remove: | 3537 | |
3538 | //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff... | 3538 | public bool DoAChange(changes what, object arg) |
3539 | //When we return true, it destroys all of the prims in the linkset anyway | 3539 | { |
3540 | if (_parent != null) | 3540 | if (prim_geom == IntPtr.Zero && what != changes.Add && what != changes.Remove) |
3541 | { | 3541 | { |
3542 | OdePrim parent = (OdePrim)_parent; | 3542 | return false; |
3543 | parent.ChildRemove(this, false); | 3543 | } |
3544 | } | 3544 | |
3545 | else | 3545 | // nasty switch |
3546 | ChildRemove(this, false); | 3546 | switch (what) |
3547 | 3547 | { | |
3548 | m_vehicle = null; | 3548 | case changes.Add: |
3549 | RemoveGeom(); | 3549 | changeadd(); |
3550 | m_targetSpace = IntPtr.Zero; | 3550 | break; |
3551 | if (m_eventsubscription > 0) | 3551 | case changes.Remove: |
3552 | UnSubscribeEvents(); | 3552 | //If its being removed, we don't want to rebuild the physical rep at all, so ignore this stuff... |
3553 | return true; | 3553 | //When we return true, it destroys all of the prims in the linkset anyway |
3554 | 3554 | if (_parent != null) | |
3555 | case changes.Link: | 3555 | { |
3556 | OdePrim tmp = (OdePrim)arg; | 3556 | OdePrim parent = (OdePrim)_parent; |
3557 | changeLink(tmp); | 3557 | parent.ChildRemove(this, false); |
3558 | break; | 3558 | } |
3559 | 3559 | else | |
3560 | case changes.DeLink: | 3560 | ChildRemove(this, false); |
3561 | changeLink(null); | 3561 | |
3562 | break; | 3562 | m_vehicle = null; |
3563 | 3563 | RemoveGeom(); | |
3564 | case changes.Position: | 3564 | m_targetSpace = IntPtr.Zero; |
3565 | changePosition((Vector3)arg); | 3565 | if (m_eventsubscription > 0) |
3566 | break; | 3566 | UnSubscribeEvents(); |
3567 | 3567 | return true; | |
3568 | case changes.Orientation: | 3568 | |
3569 | changeOrientation((Quaternion)arg); | 3569 | case changes.Link: |
3570 | break; | 3570 | OdePrim tmp = (OdePrim)arg; |
3571 | 3571 | changeLink(tmp); | |
3572 | case changes.PosOffset: | 3572 | break; |
3573 | donullchange(); | 3573 | |
3574 | break; | 3574 | case changes.DeLink: |
3575 | 3575 | changeLink(null); | |
3576 | case changes.OriOffset: | 3576 | break; |
3577 | donullchange(); | 3577 | |
3578 | break; | 3578 | case changes.Position: |
3579 | 3579 | changePosition((Vector3)arg); | |
3580 | case changes.Velocity: | 3580 | break; |
3581 | changevelocity((Vector3)arg); | 3581 | |
3582 | break; | 3582 | case changes.Orientation: |
3583 | 3583 | changeOrientation((Quaternion)arg); | |
3584 | // case changes.Acceleration: | 3584 | break; |
3585 | // changeacceleration((Vector3)arg); | 3585 | |
3586 | // break; | 3586 | case changes.PosOffset: |
3587 | // case changes.AngVelocity: | 3587 | donullchange(); |
3588 | // changeangvelocity((Vector3)arg); | 3588 | break; |
3589 | // break; | 3589 | |
3590 | 3590 | case changes.OriOffset: | |
3591 | case changes.Force: | 3591 | donullchange(); |
3592 | changeForce((Vector3)arg); | 3592 | break; |
3593 | break; | 3593 | |
3594 | 3594 | case changes.Velocity: | |
3595 | case changes.Torque: | 3595 | changevelocity((Vector3)arg); |
3596 | changeSetTorque((Vector3)arg); | 3596 | break; |
3597 | break; | 3597 | |
3598 | 3598 | // case changes.Acceleration: | |
3599 | case changes.AddForce: | 3599 | // changeacceleration((Vector3)arg); |
3600 | changeAddForce((Vector3)arg); | 3600 | // break; |
3601 | break; | 3601 | // case changes.AngVelocity: |
3602 | 3602 | // changeangvelocity((Vector3)arg); | |
3603 | case changes.AddAngForce: | 3603 | // break; |
3604 | changeAddAngularForce((Vector3)arg); | 3604 | |
3605 | break; | 3605 | case changes.Force: |
3606 | 3606 | changeForce((Vector3)arg); | |
3607 | case changes.AngLock: | 3607 | break; |
3608 | changeAngularLock((Vector3)arg); | 3608 | |
3609 | break; | 3609 | case changes.Torque: |
3610 | 3610 | changeSetTorque((Vector3)arg); | |
3611 | case changes.Size: | 3611 | break; |
3612 | changeSize((Vector3)arg); | 3612 | |
3613 | break; | 3613 | case changes.AddForce: |
3614 | 3614 | changeAddForce((Vector3)arg); | |
3615 | case changes.Shape: | 3615 | break; |
3616 | changeShape((PrimitiveBaseShape)arg); | 3616 | |
3617 | break; | 3617 | case changes.AddAngForce: |
3618 | 3618 | changeAddAngularForce((Vector3)arg); | |
3619 | case changes.CollidesWater: | 3619 | break; |
3620 | changeFloatOnWater((bool)arg); | 3620 | |
3621 | break; | 3621 | case changes.AngLock: |
3622 | 3622 | changeAngularLock((Vector3)arg); | |
3623 | case changes.VolumeDtc: | 3623 | break; |
3624 | changeVolumedetetion((bool)arg); | 3624 | |
3625 | break; | 3625 | case changes.Size: |
3626 | 3626 | changeSize((Vector3)arg); | |
3627 | case changes.Phantom: | 3627 | break; |
3628 | changePhantomStatus((bool)arg); | 3628 | |
3629 | break; | 3629 | case changes.Shape: |
3630 | 3630 | changeShape((PrimitiveBaseShape)arg); | |
3631 | case changes.Physical: | 3631 | break; |
3632 | changePhysicsStatus((bool)arg); | 3632 | |
3633 | break; | 3633 | case changes.CollidesWater: |
3634 | 3634 | changeFloatOnWater((bool)arg); | |
3635 | case changes.Selected: | 3635 | break; |
3636 | changeSelectedStatus((bool)arg); | 3636 | |
3637 | break; | 3637 | case changes.VolumeDtc: |
3638 | 3638 | changeVolumedetetion((bool)arg); | |
3639 | case changes.disabled: | 3639 | break; |
3640 | changeDisable((bool)arg); | 3640 | |
3641 | break; | 3641 | case changes.Phantom: |
3642 | 3642 | changePhantomStatus((bool)arg); | |
3643 | case changes.building: | 3643 | break; |
3644 | changeBuilding((bool)arg); | 3644 | |
3645 | break; | 3645 | case changes.Physical: |
3646 | 3646 | changePhysicsStatus((bool)arg); | |
3647 | case changes.VehicleType: | 3647 | break; |
3648 | changeVehicleType((int)arg); | 3648 | |
3649 | break; | 3649 | case changes.Selected: |
3650 | 3650 | changeSelectedStatus((bool)arg); | |
3651 | case changes.VehicleFlags: | 3651 | break; |
3652 | changeVehicleFlags((strVehicleBoolParam) arg); | 3652 | |
3653 | break; | 3653 | case changes.disabled: |
3654 | 3654 | changeDisable((bool)arg); | |
3655 | case changes.VehicleFloatParam: | 3655 | break; |
3656 | changeVehicleFloatParam((strVehicleFloatParam) arg); | 3656 | |
3657 | break; | 3657 | case changes.building: |
3658 | 3658 | changeBuilding((bool)arg); | |
3659 | case changes.VehicleVectorParam: | 3659 | break; |
3660 | changeVehicleVectorParam((strVehicleVectorParam) arg); | 3660 | |
3661 | break; | 3661 | case changes.VehicleType: |
3662 | 3662 | changeVehicleType((int)arg); | |
3663 | case changes.VehicleRotationParam: | 3663 | break; |
3664 | changeVehicleRotationParam((strVehicleQuatParam) arg); | 3664 | |
3665 | break; | 3665 | case changes.VehicleFlags: |
3666 | 3666 | changeVehicleFlags((strVehicleBoolParam) arg); | |
3667 | case changes.SetVehicle: | 3667 | break; |
3668 | changeSetVehicle((VehicleData) arg); | 3668 | |
3669 | break; | 3669 | case changes.VehicleFloatParam: |
3670 | case changes.Null: | 3670 | changeVehicleFloatParam((strVehicleFloatParam) arg); |
3671 | donullchange(); | 3671 | break; |
3672 | break; | 3672 | |
3673 | 3673 | case changes.VehicleVectorParam: | |
3674 | default: | 3674 | changeVehicleVectorParam((strVehicleVectorParam) arg); |
3675 | donullchange(); | 3675 | break; |
3676 | break; | 3676 | |
3677 | } | 3677 | case changes.VehicleRotationParam: |
3678 | return false; | 3678 | changeVehicleRotationParam((strVehicleQuatParam) arg); |
3679 | } | 3679 | break; |
3680 | 3680 | ||
3681 | public void AddChange(changes what, object arg) | 3681 | case changes.SetVehicle: |
3682 | { | 3682 | changeSetVehicle((VehicleData) arg); |
3683 | _parent_scene.AddChange((PhysicsActor) this, what, arg); | 3683 | break; |
3684 | } | 3684 | case changes.Null: |
3685 | 3685 | donullchange(); | |
3686 | 3686 | break; | |
3687 | private struct strVehicleBoolParam | 3687 | |
3688 | { | 3688 | default: |
3689 | public int param; | 3689 | donullchange(); |
3690 | public bool value; | 3690 | break; |
3691 | } | 3691 | } |
3692 | 3692 | return false; | |
3693 | private struct strVehicleFloatParam | 3693 | } |
3694 | { | 3694 | |
3695 | public int param; | 3695 | public void AddChange(changes what, object arg) |
3696 | public float value; | 3696 | { |
3697 | } | 3697 | _parent_scene.AddChange((PhysicsActor) this, what, arg); |
3698 | 3698 | } | |
3699 | private struct strVehicleQuatParam | 3699 | |
3700 | { | 3700 | |
3701 | public int param; | 3701 | private struct strVehicleBoolParam |
3702 | public Quaternion value; | 3702 | { |
3703 | } | 3703 | public int param; |
3704 | 3704 | public bool value; | |
3705 | private struct strVehicleVectorParam | 3705 | } |
3706 | { | 3706 | |
3707 | public int param; | 3707 | private struct strVehicleFloatParam |
3708 | public Vector3 value; | 3708 | { |
3709 | } | 3709 | public int param; |
3710 | } | 3710 | public float value; |
3711 | } | ||
3712 | |||
3713 | private struct strVehicleQuatParam | ||
3714 | { | ||
3715 | public int param; | ||
3716 | public Quaternion value; | ||
3717 | } | ||
3718 | |||
3719 | private struct strVehicleVectorParam | ||
3720 | { | ||
3721 | public int param; | ||
3722 | public Vector3 value; | ||
3723 | } | ||
3724 | } | ||
3711 | } \ No newline at end of file | 3725 | } \ No newline at end of file |