ODEPrim.cs 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Runtime.InteropServices;
  31. using System.Threading;
  32. using Axiom.Math;
  33. using log4net;
  34. using Ode.NET;
  35. using OpenSim.Framework;
  36. using OpenSim.Region.Physics.Manager;
  37. namespace OpenSim.Region.Physics.OdePlugin
  38. {
  39. /// <summary>
  40. /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves.
  41. /// </summary>
  42. public class OdePrim : PhysicsActor
  43. {
  44. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  45. public PhysicsVector _position;
  46. private PhysicsVector _velocity;
  47. private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f, 0.0f, 0.0f);
  48. private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f);
  49. private PhysicsVector m_rotationalVelocity;
  50. private PhysicsVector _size;
  51. private PhysicsVector _acceleration;
  52. private d.Vector3 _zeroPosition = new d.Vector3(0.0f, 0.0f, 0.0f);
  53. private Quaternion _orientation;
  54. private PhysicsVector m_taintposition;
  55. private PhysicsVector m_taintsize;
  56. private PhysicsVector m_taintVelocity = PhysicsVector.Zero;
  57. private Quaternion m_taintrot;
  58. private PhysicsVector m_angularlock = new PhysicsVector(1f, 1f, 1f);
  59. private PhysicsVector m_taintAngularLock = new PhysicsVector(1f, 1f, 1f);
  60. private IntPtr Amotor = IntPtr.Zero;
  61. private PhysicsVector m_PIDTarget = new PhysicsVector(0, 0, 0);
  62. private float m_PIDTau = 0f;
  63. private float PID_D = 35f;
  64. private float PID_G = 25f;
  65. private float m_tensor = 5f;
  66. private int body_autodisable_frames = 20;
  67. private IMesh primMesh = null;
  68. private bool m_usePID = false;
  69. private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
  70. | CollisionCategories.Space
  71. | CollisionCategories.Body
  72. | CollisionCategories.Character
  73. );
  74. private bool m_taintshape = false;
  75. private bool m_taintPhysics = false;
  76. private bool m_collidesLand = true;
  77. private bool m_collidesWater = false;
  78. public bool m_returnCollisions = false;
  79. // Default we're a Geometry
  80. private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
  81. // Default, Collide with Other Geometries, spaces and Bodies
  82. private CollisionCategories m_collisionFlags = m_default_collisionFlags;
  83. public bool m_taintremove = false;
  84. public bool m_taintdisable = false;
  85. public bool m_disabled = false;
  86. public bool m_taintadd = false;
  87. public bool m_taintselected = false;
  88. public bool m_taintCollidesWater = false;
  89. public uint m_localID = 0;
  90. //public GCHandle gc;
  91. private CollisionLocker ode;
  92. private bool m_taintforce = false;
  93. private List<PhysicsVector> m_forcelist = new List<PhysicsVector>();
  94. private IMesh _mesh;
  95. private PrimitiveBaseShape _pbs;
  96. private OdeScene _parent_scene;
  97. public IntPtr m_targetSpace = (IntPtr) 0;
  98. public IntPtr prim_geom;
  99. public IntPtr prev_geom;
  100. public IntPtr _triMeshData;
  101. private IntPtr _linkJointGroup = (IntPtr)0;
  102. private PhysicsActor _parent = null;
  103. private PhysicsActor m_taintparent = null;
  104. private bool iscolliding = false;
  105. private bool m_isphysical = false;
  106. private bool m_isSelected = false;
  107. private bool m_throttleUpdates = false;
  108. private int throttleCounter = 0;
  109. public int m_interpenetrationcount = 0;
  110. public float m_collisionscore = 0;
  111. public int m_roundsUnderMotionThreshold = 0;
  112. private int m_crossingfailures = 0;
  113. public float m_buoyancy = 0f;
  114. public bool outofBounds = false;
  115. private float m_density = 10.000006836f; // Aluminum g/cm3;
  116. public bool _zeroFlag = false;
  117. private bool m_lastUpdateSent = false;
  118. public IntPtr Body = (IntPtr) 0;
  119. private String m_primName;
  120. private PhysicsVector _target_velocity;
  121. public d.Mass pMass;
  122. public int m_eventsubscription = 0;
  123. private CollisionEventUpdate CollisionEventsThisFrame = null;
  124. private IntPtr m_linkJoint = (IntPtr)0;
  125. public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size,
  126. Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
  127. {
  128. _target_velocity = new PhysicsVector(0, 0, 0);
  129. //gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned);
  130. ode = dode;
  131. _velocity = new PhysicsVector();
  132. _position = pos;
  133. m_taintposition = pos;
  134. PID_D = parent_scene.bodyPIDD;
  135. PID_G = parent_scene.bodyPIDG;
  136. m_density = parent_scene.geomDefaultDensity;
  137. m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
  138. body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
  139. //if (_position.X > 257)
  140. //{
  141. //_position.X = 257;
  142. //}
  143. //if (_position.X < 0)
  144. //{
  145. //_position.X = 0;
  146. //}
  147. //if (_position.Y > 257)
  148. //{
  149. //_position.Y = 257;
  150. //}
  151. //if (_position.Y < 0)
  152. //{
  153. // _position.Y = 0;
  154. //}
  155. prim_geom = (IntPtr)0;
  156. prev_geom = (IntPtr)0;
  157. if (size.X <= 0) size.X = 0.01f;
  158. if (size.Y <= 0) size.Y = 0.01f;
  159. if (size.Z <= 0) size.Z = 0.01f;
  160. _size = size;
  161. m_taintsize = _size;
  162. _acceleration = new PhysicsVector();
  163. m_rotationalVelocity = PhysicsVector.Zero;
  164. _orientation = rotation;
  165. m_taintrot = _orientation;
  166. _mesh = mesh;
  167. _pbs = pbs;
  168. _parent_scene = parent_scene;
  169. m_targetSpace = (IntPtr)0;
  170. if (pos.Z < 0)
  171. m_isphysical = false;
  172. else
  173. {
  174. m_isphysical = pisPhysical;
  175. // If we're physical, we need to be in the master space for now.
  176. // linksets *should* be in a space together.. but are not currently
  177. if (m_isphysical)
  178. m_targetSpace = _parent_scene.space;
  179. }
  180. m_primName = primName;
  181. m_taintadd = true;
  182. _parent_scene.AddPhysicsActorTaint(this);
  183. // don't do .add() here; old geoms get recycled with the same hash
  184. }
  185. public override int PhysicsActorType
  186. {
  187. get { return (int) ActorTypes.Prim; }
  188. set { return; }
  189. }
  190. public override bool SetAlwaysRun
  191. {
  192. get { return false; }
  193. set { return; }
  194. }
  195. public override uint LocalID
  196. {
  197. set {
  198. //m_log.Info("[PHYSICS]: Setting TrackerID: " + value);
  199. m_localID = value; }
  200. }
  201. public override bool Grabbed
  202. {
  203. set { return; }
  204. }
  205. public override bool Selected
  206. {
  207. set {
  208. // This only makes the object not collidable if the object
  209. // is physical or the object is modified somehow *IN THE FUTURE*
  210. // without this, if an avatar selects prim, they can walk right
  211. // through it while it's selected
  212. m_collisionscore = 0;
  213. if ((m_isphysical && !_zeroFlag) || !value)
  214. {
  215. m_taintselected = value;
  216. _parent_scene.AddPhysicsActorTaint(this);
  217. }
  218. else
  219. {
  220. m_taintselected = value;
  221. m_isSelected = value;
  222. }
  223. }
  224. }
  225. public void SetGeom(IntPtr geom)
  226. {
  227. prev_geom = prim_geom;
  228. prim_geom = geom;
  229. if (prim_geom != (IntPtr)0)
  230. {
  231. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  232. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  233. }
  234. //m_log.Warn("Setting Geom to: " + prim_geom);
  235. }
  236. public void enableBodySoft()
  237. {
  238. if (m_isphysical && Body != (IntPtr)0)
  239. d.BodyEnable(Body);
  240. m_disabled = false;
  241. }
  242. public void disableBodySoft()
  243. {
  244. m_disabled = true;
  245. if (m_isphysical && Body != (IntPtr)0)
  246. d.BodyDisable(Body);
  247. }
  248. public void enableBody()
  249. {
  250. // Sets the geom to a body
  251. Body = d.BodyCreate(_parent_scene.world);
  252. setMass();
  253. d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
  254. d.Quaternion myrot = new d.Quaternion();
  255. myrot.W = _orientation.w;
  256. myrot.X = _orientation.x;
  257. myrot.Y = _orientation.y;
  258. myrot.Z = _orientation.z;
  259. d.BodySetQuaternion(Body, ref myrot);
  260. d.GeomSetBody(prim_geom, Body);
  261. m_collisionCategories |= CollisionCategories.Body;
  262. m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
  263. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  264. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  265. d.BodySetAutoDisableFlag(Body, true);
  266. d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
  267. m_interpenetrationcount = 0;
  268. m_collisionscore = 0;
  269. m_disabled = false;
  270. // The body doesn't already have a finite rotation mode set here
  271. if ((!m_angularlock.IsIdentical(PhysicsVector.Zero, 0)) && _parent == null)
  272. {
  273. createAMotor(m_angularlock);
  274. }
  275. _parent_scene.addActivePrim(this);
  276. }
  277. #region Mass Calculation
  278. private float CalculateMass()
  279. {
  280. float volume = 0;
  281. // No material is passed to the physics engines yet.. soo..
  282. // we're using the m_density constant in the class definition
  283. float returnMass = 0;
  284. switch (_pbs.ProfileShape)
  285. {
  286. case ProfileShape.Square:
  287. // Profile Volume
  288. volume = _size.X*_size.Y*_size.Z;
  289. // If the user has 'hollowed out'
  290. // ProfileHollow is one of those 0 to 50000 values :P
  291. // we like percentages better.. so turning into a percentage
  292. if (((float) _pbs.ProfileHollow/50000f) > 0.0)
  293. {
  294. float hollowAmount = (float) _pbs.ProfileHollow/50000f;
  295. // calculate the hollow volume by it's shape compared to the prim shape
  296. float hollowVolume = 0;
  297. switch (_pbs.HollowShape)
  298. {
  299. case HollowShape.Square:
  300. case HollowShape.Same:
  301. // Cube Hollow volume calculation
  302. float hollowsizex = _size.X*hollowAmount;
  303. float hollowsizey = _size.Y*hollowAmount;
  304. float hollowsizez = _size.Z*hollowAmount;
  305. hollowVolume = hollowsizex*hollowsizey*hollowsizez;
  306. break;
  307. case HollowShape.Circle:
  308. // Hollow shape is a perfect cyllinder in respect to the cube's scale
  309. // Cyllinder hollow volume calculation
  310. float hRadius = _size.X/2;
  311. float hLength = _size.Z;
  312. // pi * r2 * h
  313. hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount);
  314. break;
  315. case HollowShape.Triangle:
  316. // Equilateral Triangular Prism volume hollow calculation
  317. // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
  318. float aLength = _size.Y;
  319. // 1/2 abh
  320. hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount);
  321. break;
  322. default:
  323. hollowVolume = 0;
  324. break;
  325. }
  326. volume = volume - hollowVolume;
  327. }
  328. break;
  329. case ProfileShape.Circle:
  330. if (_pbs.PathCurve == (byte)Extrusion.Straight)
  331. {
  332. // Cylinder
  333. float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z);
  334. float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z);
  335. // Approximating the cylinder's irregularity.
  336. if (volume1 > volume2)
  337. {
  338. volume = (float)volume1 - (volume1 - volume2);
  339. }
  340. else if (volume2 > volume1)
  341. {
  342. volume = (float)volume2 - (volume2 - volume1);
  343. }
  344. else
  345. {
  346. // Regular cylinder
  347. volume = volume1;
  348. }
  349. }
  350. else
  351. {
  352. // We don't know what the shape is yet, so use default
  353. volume = _size.X * _size.Y * _size.Z;
  354. }
  355. // If the user has 'hollowed out'
  356. // ProfileHollow is one of those 0 to 50000 values :P
  357. // we like percentages better.. so turning into a percentage
  358. if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
  359. {
  360. float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
  361. // calculate the hollow volume by it's shape compared to the prim shape
  362. float hollowVolume = 0;
  363. switch (_pbs.HollowShape)
  364. {
  365. case HollowShape.Same:
  366. case HollowShape.Circle:
  367. // Hollow shape is a perfect cyllinder in respect to the cube's scale
  368. // Cyllinder hollow volume calculation
  369. float hRadius = _size.X / 2;
  370. float hLength = _size.Z;
  371. // pi * r2 * h
  372. hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
  373. break;
  374. case HollowShape.Square:
  375. // Cube Hollow volume calculation
  376. float hollowsizex = _size.X * hollowAmount;
  377. float hollowsizey = _size.Y * hollowAmount;
  378. float hollowsizez = _size.Z * hollowAmount;
  379. hollowVolume = hollowsizex * hollowsizey * hollowsizez;
  380. break;
  381. case HollowShape.Triangle:
  382. // Equilateral Triangular Prism volume hollow calculation
  383. // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
  384. float aLength = _size.Y;
  385. // 1/2 abh
  386. hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
  387. break;
  388. default:
  389. hollowVolume = 0;
  390. break;
  391. }
  392. volume = volume - hollowVolume;
  393. }
  394. break;
  395. case ProfileShape.HalfCircle:
  396. if (_pbs.PathCurve == (byte)Extrusion.Curve1)
  397. {
  398. if (_size.X == _size.Z && _size.Z == _size.X)
  399. {
  400. // regular sphere
  401. // v = 4/3 * pi * r^3
  402. float sradius3 = (float)Math.Pow((_size.X / 2), 3);
  403. volume = (float)((4 / 3) * Math.PI * sradius3);
  404. }
  405. else
  406. {
  407. // we treat this as a box currently
  408. volume = _size.X * _size.Y * _size.Z;
  409. }
  410. }
  411. else
  412. {
  413. // We don't know what the shape is yet, so use default
  414. volume = _size.X * _size.Y * _size.Z;
  415. }
  416. break;
  417. case ProfileShape.EquilateralTriangle:
  418. /*
  419. v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
  420. // seed mesh
  421. Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
  422. Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
  423. Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
  424. */
  425. float xA = -0.25f * _size.X;
  426. float yA = -0.45f * _size.Y;
  427. float xB = 0.5f * _size.X;
  428. float yB = 0;
  429. float xC = -0.25f * _size.X;
  430. float yC = 0.45f * _size.Y;
  431. volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z);
  432. // If the user has 'hollowed out'
  433. // ProfileHollow is one of those 0 to 50000 values :P
  434. // we like percentages better.. so turning into a percentage
  435. float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
  436. if (((float)fhollowFactor / 50000f) > 0.0)
  437. {
  438. float hollowAmount = (float)fhollowFactor / 50000f;
  439. // calculate the hollow volume by it's shape compared to the prim shape
  440. float hollowVolume = 0;
  441. switch (_pbs.HollowShape)
  442. {
  443. case HollowShape.Same:
  444. case HollowShape.Triangle:
  445. // Equilateral Triangular Prism volume hollow calculation
  446. // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
  447. float aLength = _size.Y;
  448. // 1/2 abh
  449. hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
  450. break;
  451. case HollowShape.Square:
  452. // Cube Hollow volume calculation
  453. float hollowsizex = _size.X * hollowAmount;
  454. float hollowsizey = _size.Y * hollowAmount;
  455. float hollowsizez = _size.Z * hollowAmount;
  456. hollowVolume = hollowsizex * hollowsizey * hollowsizez;
  457. break;
  458. case HollowShape.Circle:
  459. // Hollow shape is a perfect cyllinder in respect to the cube's scale
  460. // Cyllinder hollow volume calculation
  461. float hRadius = _size.X / 2;
  462. float hLength = _size.Z;
  463. // pi * r2 * h
  464. hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount);
  465. break;
  466. default:
  467. hollowVolume = 0;
  468. break;
  469. }
  470. volume = volume - hollowVolume;
  471. }
  472. break;
  473. default:
  474. // we don't have all of the volume formulas yet so
  475. // use the common volume formula for all
  476. volume = _size.X*_size.Y*_size.Z;
  477. break;
  478. }
  479. // Calculate Path cut effect on volume
  480. // Not exact, in the triangle hollow example
  481. // They should never be zero or less then zero..
  482. // we'll ignore it if it's less then zero
  483. // ProfileEnd and ProfileBegin are values
  484. // from 0 to 50000
  485. // Turning them back into percentages so that I can cut that percentage off the volume
  486. float PathCutEndAmount = _pbs.ProfileEnd;
  487. float PathCutStartAmount = _pbs.ProfileBegin;
  488. if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f)
  489. {
  490. float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f);
  491. // Check the return amount for sanity
  492. if (pathCutAmount >= 0.99f)
  493. pathCutAmount = 0.99f;
  494. volume = volume - (volume*pathCutAmount);
  495. }
  496. UInt16 taperX = _pbs.PathScaleX;
  497. UInt16 taperY = _pbs.PathScaleY;
  498. float taperFactorX = 0;
  499. float taperFactorY = 0;
  500. // Mass = density * volume
  501. if (taperX != 100)
  502. {
  503. if (taperX > 100)
  504. {
  505. taperFactorX = 1.0f - ((float)taperX / 200);
  506. //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
  507. }
  508. else
  509. {
  510. taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
  511. //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
  512. }
  513. volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
  514. }
  515. if (taperY != 100)
  516. {
  517. if (taperY > 100)
  518. {
  519. taperFactorY = 1.0f - ((float)taperY / 200);
  520. //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
  521. }
  522. else
  523. {
  524. taperFactorY = 1.0f - ((100 - (float)taperY) / 100);
  525. //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
  526. }
  527. volume = (float)volume * ((taperFactorY / 3f) + 0.001f);
  528. }
  529. returnMass = m_density*volume;
  530. return returnMass;
  531. }
  532. #endregion
  533. public void setMass()
  534. {
  535. if (Body != (IntPtr) 0)
  536. {
  537. float newmass = CalculateMass();
  538. //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString());
  539. if (newmass <= 0) newmass = 0.0001f;
  540. d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z);
  541. d.BodySetMass(Body, ref pMass);
  542. }
  543. }
  544. public void disableBody()
  545. {
  546. //this kills the body so things like 'mesh' can re-create it.
  547. lock (this)
  548. {
  549. if (Body != (IntPtr)0)
  550. {
  551. m_collisionCategories &= ~CollisionCategories.Body;
  552. m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
  553. if (prim_geom != (IntPtr)0)
  554. {
  555. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  556. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  557. }
  558. _parent_scene.remActivePrim(this);
  559. d.BodyDestroy(Body);
  560. Body = (IntPtr)0;
  561. }
  562. }
  563. m_disabled = true;
  564. m_collisionscore = 0;
  565. }
  566. public void setMesh(OdeScene parent_scene, IMesh mesh)
  567. {
  568. // This sleeper is there to moderate how long it takes between
  569. // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
  570. Thread.Sleep(10);
  571. //Kill Body so that mesh can re-make the geom
  572. if (IsPhysical && Body != (IntPtr) 0)
  573. {
  574. disableBody();
  575. }
  576. IMesh oldMesh = primMesh;
  577. primMesh = mesh;
  578. float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
  579. int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
  580. int VertexCount = vertexList.GetLength(0)/3;
  581. int IndexCount = indexList.GetLength(0);
  582. _triMeshData = d.GeomTriMeshDataCreate();
  583. d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount,
  584. 3*sizeof (int));
  585. d.GeomTriMeshDataPreprocess(_triMeshData);
  586. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  587. try
  588. {
  589. if (prim_geom == (IntPtr)0)
  590. {
  591. SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
  592. }
  593. }
  594. catch (AccessViolationException)
  595. {
  596. m_log.Error("[PHYSICS]: MESH LOCKED");
  597. return;
  598. }
  599. if (oldMesh != null)
  600. {
  601. oldMesh.releasePinned();
  602. oldMesh = null;
  603. }
  604. if (IsPhysical && Body == (IntPtr) 0)
  605. {
  606. // Recreate the body
  607. m_interpenetrationcount = 0;
  608. m_collisionscore = 0;
  609. enableBody();
  610. }
  611. }
  612. public void ProcessTaints(float timestep)
  613. {
  614. if (m_taintadd)
  615. {
  616. changeadd(timestep);
  617. }
  618. if (prim_geom != (IntPtr)0)
  619. {
  620. if (!_position.IsIdentical(m_taintposition,0f))
  621. changemove(timestep);
  622. if (m_taintrot != _orientation)
  623. rotate(timestep);
  624. //
  625. if (m_taintPhysics != m_isphysical)
  626. changePhysicsStatus(timestep);
  627. //
  628. if (!_size.IsIdentical(m_taintsize,0))
  629. changesize(timestep);
  630. //
  631. if (m_taintshape)
  632. changeshape(timestep);
  633. //
  634. if (m_taintforce)
  635. changeAddForce(timestep);
  636. if (m_taintdisable)
  637. changedisable(timestep);
  638. if (m_taintselected != m_isSelected)
  639. changeSelectedStatus(timestep);
  640. if (!m_taintVelocity.IsIdentical(PhysicsVector.Zero,0))
  641. changevelocity(timestep);
  642. if (m_taintparent != _parent)
  643. changelink(timestep);
  644. if (m_taintCollidesWater != m_collidesWater)
  645. changefloatonwater(timestep);
  646. if (!m_angularlock.IsIdentical(m_taintAngularLock,0))
  647. changeAngularLock(timestep);
  648. }
  649. else
  650. {
  651. m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil.");
  652. }
  653. }
  654. private void changeAngularLock(float timestep)
  655. {
  656. // do we have a Physical object?
  657. if (Body != IntPtr.Zero)
  658. {
  659. //Check that we have a Parent
  660. //If we have a parent then we're not authorative here
  661. if (_parent == null)
  662. {
  663. if (!m_taintAngularLock.IsIdentical(new PhysicsVector(1f,1f,1f), 0))
  664. {
  665. //d.BodySetFiniteRotationMode(Body, 0);
  666. //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z);
  667. createAMotor(m_taintAngularLock);
  668. }
  669. else
  670. {
  671. if (Amotor != IntPtr.Zero)
  672. {
  673. d.JointDestroy(Amotor);
  674. Amotor = (IntPtr)0;
  675. }
  676. }
  677. }
  678. }
  679. // Store this for later in case we get turned into a separate body
  680. m_angularlock = new PhysicsVector(m_taintAngularLock.X,m_angularlock.Y,m_angularlock.Z);
  681. }
  682. private void changelink(float timestep)
  683. {
  684. if (_parent == null && m_taintparent != null)
  685. {
  686. if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim)
  687. {
  688. OdePrim obj = (OdePrim)m_taintparent;
  689. if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body)
  690. {
  691. _linkJointGroup = d.JointGroupCreate(0);
  692. m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
  693. d.JointAttach(m_linkJoint, obj.Body, Body);
  694. d.JointSetFixed(m_linkJoint);
  695. }
  696. }
  697. }
  698. else if (_parent != null && m_taintparent == null)
  699. {
  700. if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0)
  701. d.JointGroupDestroy(_linkJointGroup);
  702. _linkJointGroup = (IntPtr)0;
  703. m_linkJoint = (IntPtr)0;
  704. }
  705. _parent = m_taintparent;
  706. }
  707. private void changeSelectedStatus(float timestep)
  708. {
  709. if (m_taintselected)
  710. {
  711. m_collisionCategories = CollisionCategories.Selected;
  712. m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
  713. // We do the body disable soft twice because 'in theory' a collision could have happened
  714. // in between the disabling and the collision properties setting
  715. // which would wake the physical body up from a soft disabling and potentially cause it to fall
  716. // through the ground.
  717. if (m_isphysical)
  718. {
  719. disableBodySoft();
  720. }
  721. if (prim_geom != (IntPtr)0)
  722. {
  723. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  724. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  725. }
  726. if (m_isphysical)
  727. {
  728. disableBodySoft();
  729. }
  730. }
  731. else
  732. {
  733. m_collisionCategories = CollisionCategories.Geom;
  734. if (m_isphysical)
  735. m_collisionCategories |= CollisionCategories.Body;
  736. m_collisionFlags = m_default_collisionFlags;
  737. if (m_collidesLand)
  738. m_collisionFlags |= CollisionCategories.Land;
  739. if (m_collidesWater)
  740. m_collisionFlags |= CollisionCategories.Water;
  741. if (prim_geom != (IntPtr)0)
  742. {
  743. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  744. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  745. }
  746. if (m_isphysical)
  747. {
  748. d.BodySetLinearVel(Body, 0f, 0f, 0f);
  749. enableBodySoft();
  750. }
  751. }
  752. resetCollisionAccounting();
  753. m_isSelected = m_taintselected;
  754. }
  755. public void ResetTaints()
  756. {
  757. m_taintposition = _position;
  758. m_taintrot = _orientation;
  759. m_taintPhysics = m_isphysical;
  760. m_taintselected = m_isSelected;
  761. m_taintsize = _size;
  762. m_taintshape = false;
  763. m_taintforce = false;
  764. m_taintdisable = false;
  765. m_taintVelocity = PhysicsVector.Zero;
  766. }
  767. public void changeadd(float timestep)
  768. {
  769. int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
  770. IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
  771. if (targetspace == IntPtr.Zero)
  772. targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
  773. m_targetSpace = targetspace;
  774. if (_mesh == null)
  775. {
  776. if (_parent_scene.needsMeshing(_pbs))
  777. {
  778. // Don't need to re-enable body.. it's done in SetMesh
  779. _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD);
  780. // createmesh returns null when it's a shape that isn't a cube.
  781. }
  782. }
  783. lock (OdeScene.OdeLock)
  784. {
  785. if (_mesh != null)
  786. {
  787. setMesh(_parent_scene, _mesh);
  788. }
  789. else
  790. {
  791. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  792. {
  793. if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  794. {
  795. if (((_size.X / 2f) > 0f))
  796. {
  797. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  798. try
  799. {
  800. SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  801. }
  802. catch (AccessViolationException)
  803. {
  804. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  805. ode.dunlock(_parent_scene.world);
  806. return;
  807. }
  808. }
  809. else
  810. {
  811. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  812. try
  813. {
  814. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  815. }
  816. catch (AccessViolationException)
  817. {
  818. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  819. ode.dunlock(_parent_scene.world);
  820. return;
  821. }
  822. }
  823. }
  824. else
  825. {
  826. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  827. try
  828. {
  829. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  830. }
  831. catch (AccessViolationException)
  832. {
  833. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  834. ode.dunlock(_parent_scene.world);
  835. return;
  836. }
  837. }
  838. }
  839. //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
  840. //{
  841. //Cyllinder
  842. //if (_size.X == _size.Y)
  843. //{
  844. //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  845. //}
  846. //else
  847. //{
  848. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  849. //}
  850. //}
  851. else
  852. {
  853. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  854. try
  855. {
  856. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  857. }
  858. catch (AccessViolationException)
  859. {
  860. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  861. ode.dunlock(_parent_scene.world);
  862. return;
  863. }
  864. }
  865. }
  866. if (prim_geom != (IntPtr) 0)
  867. {
  868. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  869. d.Quaternion myrot = new d.Quaternion();
  870. myrot.W = _orientation.w;
  871. myrot.X = _orientation.x;
  872. myrot.Y = _orientation.y;
  873. myrot.Z = _orientation.z;
  874. d.GeomSetQuaternion(prim_geom, ref myrot);
  875. }
  876. if (m_isphysical && Body == (IntPtr)0)
  877. {
  878. enableBody();
  879. }
  880. }
  881. _parent_scene.geom_name_map[prim_geom] = this.m_primName;
  882. _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
  883. changeSelectedStatus(timestep);
  884. m_taintadd = false;
  885. }
  886. public void changemove(float timestep)
  887. {
  888. if (m_isphysical)
  889. {
  890. // This is a fallback.. May no longer be necessary.
  891. if (Body == (IntPtr) 0)
  892. enableBody();
  893. //Prim auto disable after 20 frames,
  894. //if you move it, re-enable the prim manually.
  895. if (_parent != null)
  896. {
  897. if (m_linkJoint != (IntPtr)0)
  898. {
  899. d.JointDestroy(m_linkJoint);
  900. m_linkJoint = (IntPtr)0;
  901. }
  902. }
  903. d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
  904. if (_parent != null)
  905. {
  906. OdePrim odParent = (OdePrim)_parent;
  907. if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body)
  908. {
  909. m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
  910. d.JointAttach(m_linkJoint, Body, odParent.Body);
  911. d.JointSetFixed(m_linkJoint);
  912. }
  913. }
  914. d.BodyEnable(Body);
  915. }
  916. else
  917. {
  918. string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
  919. int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
  920. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  921. IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
  922. m_targetSpace = tempspace;
  923. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  924. if (prim_geom != (IntPtr) 0)
  925. {
  926. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  927. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  928. d.SpaceAdd(m_targetSpace, prim_geom);
  929. }
  930. }
  931. changeSelectedStatus(timestep);
  932. resetCollisionAccounting();
  933. m_taintposition = _position;
  934. }
  935. public void Move(float timestep)
  936. {
  937. float fx = 0;
  938. float fy = 0;
  939. float fz = 0;
  940. if (IsPhysical && Body != (IntPtr)0 && !m_isSelected)
  941. {
  942. //float PID_P = 900.0f;
  943. float m_mass = CalculateMass();
  944. fz = 0f;
  945. //m_log.Info(m_collisionFlags.ToString());
  946. if (m_buoyancy != 0)
  947. {
  948. if (m_buoyancy > 0)
  949. {
  950. fz = (((-1 * _parent_scene.gravityz) * m_buoyancy) * m_mass);
  951. //d.Vector3 l_velocity = d.BodyGetLinearVel(Body);
  952. //m_log.Info("Using Buoyancy: " + buoyancy + " G: " + (_parent_scene.gravityz * m_buoyancy) + "mass:" + m_mass + " Pos: " + Position.ToString());
  953. }
  954. else
  955. {
  956. fz = (-1 * (((-1 * _parent_scene.gravityz) * (-1 * m_buoyancy)) * m_mass));
  957. }
  958. }
  959. if (m_usePID)
  960. {
  961. // If we're using the PID controller, then we have no gravity
  962. fz = (-1 * _parent_scene.gravityz) * this.Mass;
  963. // no lock; for now it's only called from within Simulate()
  964. // If the PID Controller isn't active then we set our force
  965. // calculating base velocity to the current position
  966. if ((m_PIDTau < 1))
  967. {
  968. PID_G = PID_G / m_PIDTau;
  969. }
  970. if ((PID_G - m_PIDTau) <= 0)
  971. {
  972. PID_G = m_PIDTau + 1;
  973. }
  974. //PidStatus = true;
  975. PhysicsVector vec = new PhysicsVector();
  976. d.Vector3 vel = d.BodyGetLinearVel(Body);
  977. d.Vector3 pos = d.BodyGetPosition(Body);
  978. _target_velocity =
  979. new PhysicsVector(
  980. (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
  981. (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
  982. (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
  983. );
  984. // if velocity is zero, use position control; otherwise, velocity control
  985. if (_target_velocity.IsIdentical(PhysicsVector.Zero,0.1f))
  986. {
  987. // keep track of where we stopped. No more slippin' & slidin'
  988. // We only want to deactivate the PID Controller if we think we want to have our surrogate
  989. // react to the physics scene by moving it's position.
  990. // Avatar to Avatar collisions
  991. // Prim to avatar collisions
  992. //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
  993. //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
  994. //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
  995. d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
  996. d.BodySetLinearVel(Body, 0, 0, 0);
  997. d.BodyAddForce(Body, 0, 0, fz);
  998. return;
  999. }
  1000. else
  1001. {
  1002. _zeroFlag = false;
  1003. // We're flying and colliding with something
  1004. fx = ((_target_velocity.X) - vel.X) * (PID_D);
  1005. fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
  1006. // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
  1007. fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
  1008. }
  1009. }
  1010. fx *= m_mass;
  1011. fy *= m_mass;
  1012. //fz *= m_mass;
  1013. //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
  1014. if (fx != 0 || fy != 0 || fz != 0)
  1015. {
  1016. //m_taintdisable = true;
  1017. //base.RaiseOutOfBounds(Position);
  1018. //d.BodySetLinearVel(Body, fx, fy, 0f);
  1019. enableBodySoft();
  1020. d.BodyAddForce(Body, fx, fy, fz);
  1021. }
  1022. }
  1023. else
  1024. {
  1025. _zeroPosition = d.BodyGetPosition(Body);
  1026. return;
  1027. }
  1028. }
  1029. public void rotate(float timestep)
  1030. {
  1031. d.Quaternion myrot = new d.Quaternion();
  1032. myrot.W = _orientation.w;
  1033. myrot.X = _orientation.x;
  1034. myrot.Y = _orientation.y;
  1035. myrot.Z = _orientation.z;
  1036. d.GeomSetQuaternion(prim_geom, ref myrot);
  1037. if (m_isphysical && Body != (IntPtr) 0)
  1038. {
  1039. d.BodySetQuaternion(Body, ref myrot);
  1040. if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0))
  1041. createAMotor(m_angularlock);
  1042. }
  1043. resetCollisionAccounting();
  1044. m_taintrot = _orientation;
  1045. }
  1046. private void resetCollisionAccounting()
  1047. {
  1048. m_collisionscore = 0;
  1049. m_interpenetrationcount = 0;
  1050. m_disabled = false;
  1051. }
  1052. public void changedisable(float timestep)
  1053. {
  1054. m_disabled = true;
  1055. if (Body != (IntPtr)0)
  1056. {
  1057. d.BodyDisable(Body);
  1058. Body = (IntPtr)0;
  1059. }
  1060. m_taintdisable = false;
  1061. }
  1062. public void changePhysicsStatus(float timestep)
  1063. {
  1064. if (m_isphysical == true)
  1065. {
  1066. if (Body == (IntPtr)0)
  1067. {
  1068. if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
  1069. {
  1070. changeshape(2f);
  1071. }
  1072. else
  1073. {
  1074. enableBody();
  1075. }
  1076. }
  1077. }
  1078. else
  1079. {
  1080. if (Body != (IntPtr)0)
  1081. {
  1082. if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
  1083. {
  1084. if (prim_geom != IntPtr.Zero)
  1085. d.GeomDestroy(prim_geom);
  1086. changeadd(2f);
  1087. }
  1088. disableBody();
  1089. }
  1090. }
  1091. changeSelectedStatus(timestep);
  1092. resetCollisionAccounting();
  1093. m_taintPhysics = m_isphysical;
  1094. }
  1095. public void changesize(float timestamp)
  1096. {
  1097. //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom))
  1098. //{
  1099. // m_taintsize = _size;
  1100. //return;
  1101. //}
  1102. string oldname = _parent_scene.geom_name_map[prim_geom];
  1103. if (_size.X <= 0) _size.X = 0.01f;
  1104. if (_size.Y <= 0) _size.Y = 0.01f;
  1105. if (_size.Z <= 0) _size.Z = 0.01f;
  1106. // Cleanup of old prim geometry
  1107. if (_mesh != null)
  1108. {
  1109. // Cleanup meshing here
  1110. }
  1111. //kill body to rebuild
  1112. if (IsPhysical && Body != (IntPtr) 0)
  1113. {
  1114. disableBody();
  1115. }
  1116. if (d.SpaceQuery(m_targetSpace, prim_geom))
  1117. {
  1118. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1119. d.SpaceRemove(m_targetSpace, prim_geom);
  1120. }
  1121. d.GeomDestroy(prim_geom);
  1122. prim_geom = (IntPtr)0;
  1123. // we don't need to do space calculation because the client sends a position update also.
  1124. // Construction of new prim
  1125. if (_parent_scene.needsMeshing(_pbs))
  1126. {
  1127. float meshlod = _parent_scene.meshSculptLOD;
  1128. if (IsPhysical)
  1129. meshlod = _parent_scene.MeshSculptphysicalLOD;
  1130. // Don't need to re-enable body.. it's done in SetMesh
  1131. IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod);
  1132. // createmesh returns null when it's a shape that isn't a cube.
  1133. if (mesh != null)
  1134. {
  1135. setMesh(_parent_scene, mesh);
  1136. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1137. d.Quaternion myrot = new d.Quaternion();
  1138. myrot.W = _orientation.w;
  1139. myrot.X = _orientation.x;
  1140. myrot.Y = _orientation.y;
  1141. myrot.Z = _orientation.z;
  1142. d.GeomSetQuaternion(prim_geom, ref myrot);
  1143. //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1144. if (IsPhysical && Body == (IntPtr)0)
  1145. {
  1146. // Re creates body on size.
  1147. // EnableBody also does setMass()
  1148. enableBody();
  1149. d.BodyEnable(Body);
  1150. }
  1151. }
  1152. else
  1153. {
  1154. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1155. {
  1156. if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1157. {
  1158. if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
  1159. {
  1160. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1161. SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1162. }
  1163. else
  1164. {
  1165. m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
  1166. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1167. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1168. }
  1169. }
  1170. else
  1171. {
  1172. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1173. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1174. }
  1175. }
  1176. //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
  1177. //{
  1178. //Cyllinder
  1179. //if (_size.X == _size.Y)
  1180. //{
  1181. // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  1182. //}
  1183. //else
  1184. //{
  1185. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1186. //}
  1187. //}
  1188. else
  1189. {
  1190. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1191. SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1192. }
  1193. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1194. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1195. d.Quaternion myrot = new d.Quaternion();
  1196. myrot.W = _orientation.w;
  1197. myrot.X = _orientation.x;
  1198. myrot.Y = _orientation.y;
  1199. myrot.Z = _orientation.z;
  1200. d.GeomSetQuaternion(prim_geom, ref myrot);
  1201. }
  1202. }
  1203. else
  1204. {
  1205. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1206. {
  1207. if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1208. {
  1209. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1210. SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1211. }
  1212. else
  1213. {
  1214. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1215. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1216. }
  1217. }
  1218. //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
  1219. //{
  1220. //Cyllinder
  1221. //if (_size.X == _size.Y)
  1222. //{
  1223. //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  1224. //}
  1225. //else
  1226. //{
  1227. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1228. //}
  1229. //}
  1230. else
  1231. {
  1232. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1233. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1234. }
  1235. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1236. d.Quaternion myrot = new d.Quaternion();
  1237. myrot.W = _orientation.w;
  1238. myrot.X = _orientation.x;
  1239. myrot.Y = _orientation.y;
  1240. myrot.Z = _orientation.z;
  1241. d.GeomSetQuaternion(prim_geom, ref myrot);
  1242. //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1243. if (IsPhysical && Body == (IntPtr) 0)
  1244. {
  1245. // Re creates body on size.
  1246. // EnableBody also does setMass()
  1247. enableBody();
  1248. d.BodyEnable(Body);
  1249. }
  1250. }
  1251. _parent_scene.geom_name_map[prim_geom] = oldname;
  1252. changeSelectedStatus(timestamp);
  1253. resetCollisionAccounting();
  1254. m_taintsize = _size;
  1255. }
  1256. public void changefloatonwater(float timestep)
  1257. {
  1258. m_collidesWater = m_taintCollidesWater;
  1259. if (prim_geom != (IntPtr)0)
  1260. {
  1261. if (m_collidesWater)
  1262. {
  1263. m_collisionFlags |= CollisionCategories.Water;
  1264. }
  1265. else
  1266. {
  1267. m_collisionFlags &= ~CollisionCategories.Water;
  1268. }
  1269. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  1270. }
  1271. }
  1272. public void changeshape(float timestamp)
  1273. {
  1274. string oldname = _parent_scene.geom_name_map[prim_geom];
  1275. // Cleanup of old prim geometry and Bodies
  1276. if (IsPhysical && Body != (IntPtr) 0)
  1277. {
  1278. disableBody();
  1279. }
  1280. d.GeomDestroy(prim_geom);
  1281. prim_geom = (IntPtr) 0;
  1282. // we don't need to do space calculation because the client sends a position update also.
  1283. if (_size.X <= 0) _size.X = 0.01f;
  1284. if (_size.Y <= 0) _size.Y = 0.01f;
  1285. if (_size.Z <= 0) _size.Z = 0.01f;
  1286. // Construction of new prim
  1287. if (_parent_scene.needsMeshing(_pbs))
  1288. {
  1289. // Don't need to re-enable body.. it's done in SetMesh
  1290. float meshlod = _parent_scene.meshSculptLOD;
  1291. if (IsPhysical)
  1292. meshlod = _parent_scene.MeshSculptphysicalLOD;
  1293. IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod);
  1294. // createmesh returns null when it's a shape that isn't a cube.
  1295. if (mesh != null)
  1296. {
  1297. setMesh(_parent_scene, mesh);
  1298. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1299. d.Quaternion myrot = new d.Quaternion();
  1300. myrot.W = _orientation.w;
  1301. myrot.X = _orientation.x;
  1302. myrot.Y = _orientation.y;
  1303. myrot.Z = _orientation.z;
  1304. d.GeomSetQuaternion(prim_geom, ref myrot);
  1305. //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1306. if (IsPhysical && Body == (IntPtr)0)
  1307. {
  1308. // Re creates body on size.
  1309. // EnableBody also does setMass()
  1310. enableBody();
  1311. }
  1312. }
  1313. else
  1314. {
  1315. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1316. {
  1317. if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1318. {
  1319. if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
  1320. {
  1321. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1322. SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1323. }
  1324. else
  1325. {
  1326. m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
  1327. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1328. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1329. }
  1330. }
  1331. else
  1332. {
  1333. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1334. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1335. }
  1336. }
  1337. //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
  1338. //{
  1339. //Cyllinder
  1340. //if (_size.X == _size.Y)
  1341. //{
  1342. // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  1343. //}
  1344. //else
  1345. //{
  1346. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1347. //}
  1348. //}
  1349. else
  1350. {
  1351. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1352. SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1353. }
  1354. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1355. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1356. d.Quaternion myrot = new d.Quaternion();
  1357. myrot.W = _orientation.w;
  1358. myrot.X = _orientation.x;
  1359. myrot.Y = _orientation.y;
  1360. myrot.Z = _orientation.z;
  1361. d.GeomSetQuaternion(prim_geom, ref myrot);
  1362. }
  1363. }
  1364. else
  1365. {
  1366. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1367. {
  1368. if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1369. {
  1370. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1371. SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1372. }
  1373. else
  1374. {
  1375. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1376. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1377. }
  1378. }
  1379. //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
  1380. //{
  1381. //Cyllinder
  1382. //if (_size.X == _size.Y)
  1383. //{
  1384. //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  1385. //}
  1386. //else
  1387. //{
  1388. //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1389. //}
  1390. //}
  1391. else
  1392. {
  1393. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1394. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1395. }
  1396. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1397. d.Quaternion myrot = new d.Quaternion();
  1398. myrot.W = _orientation.w;
  1399. myrot.X = _orientation.x;
  1400. myrot.Y = _orientation.y;
  1401. myrot.Z = _orientation.z;
  1402. d.GeomSetQuaternion(prim_geom, ref myrot);
  1403. //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1404. if (IsPhysical && Body == (IntPtr)0)
  1405. {
  1406. // Re creates body on size.
  1407. // EnableBody also does setMass()
  1408. enableBody();
  1409. d.BodyEnable(Body);
  1410. }
  1411. }
  1412. _parent_scene.geom_name_map[prim_geom] = oldname;
  1413. changeSelectedStatus(timestamp);
  1414. resetCollisionAccounting();
  1415. m_taintshape = false;
  1416. }
  1417. public void changeAddForce(float timestamp)
  1418. {
  1419. if (!m_isSelected)
  1420. {
  1421. lock (m_forcelist)
  1422. {
  1423. //m_log.Info("[PHYSICS]: dequeing forcelist");
  1424. if (IsPhysical)
  1425. {
  1426. PhysicsVector iforce = new PhysicsVector();
  1427. for (int i = 0; i < m_forcelist.Count; i++)
  1428. {
  1429. iforce = iforce + (m_forcelist[i] * 100);
  1430. }
  1431. d.BodyEnable(Body);
  1432. d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z);
  1433. }
  1434. m_forcelist.Clear();
  1435. }
  1436. m_collisionscore = 0;
  1437. m_interpenetrationcount = 0;
  1438. }
  1439. m_taintforce = false;
  1440. }
  1441. private void changevelocity(float timestep)
  1442. {
  1443. if (!m_isSelected)
  1444. {
  1445. Thread.Sleep(20);
  1446. if (IsPhysical)
  1447. {
  1448. if (Body != (IntPtr)0)
  1449. {
  1450. d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
  1451. }
  1452. }
  1453. //resetCollisionAccounting();
  1454. }
  1455. m_taintVelocity = PhysicsVector.Zero;
  1456. }
  1457. public override bool IsPhysical
  1458. {
  1459. get { return m_isphysical; }
  1460. set { m_isphysical = value; }
  1461. }
  1462. public void setPrimForRemoval()
  1463. {
  1464. m_taintremove = true;
  1465. }
  1466. public override bool Flying
  1467. {
  1468. // no flying prims for you
  1469. get { return false; }
  1470. set { }
  1471. }
  1472. public override bool IsColliding
  1473. {
  1474. get { return iscolliding; }
  1475. set { iscolliding = value; }
  1476. }
  1477. public override bool CollidingGround
  1478. {
  1479. get { return false; }
  1480. set { return; }
  1481. }
  1482. public override bool CollidingObj
  1483. {
  1484. get { return false; }
  1485. set { return; }
  1486. }
  1487. public override bool ThrottleUpdates
  1488. {
  1489. get { return m_throttleUpdates; }
  1490. set { m_throttleUpdates = value; }
  1491. }
  1492. public override bool Stopped
  1493. {
  1494. get { return _zeroFlag; }
  1495. }
  1496. public override PhysicsVector Position
  1497. {
  1498. get { return _position; }
  1499. set { _position = value;
  1500. //m_log.Info("[PHYSICS]: " + _position.ToString());
  1501. }
  1502. }
  1503. public override PhysicsVector Size
  1504. {
  1505. get { return _size; }
  1506. set { _size = value; }
  1507. }
  1508. public override float Mass
  1509. {
  1510. get { return CalculateMass(); }
  1511. }
  1512. public override PhysicsVector Force
  1513. {
  1514. get { return PhysicsVector.Zero; }
  1515. }
  1516. public override PhysicsVector CenterOfMass
  1517. {
  1518. get { return PhysicsVector.Zero; }
  1519. }
  1520. public override PhysicsVector GeometricCenter
  1521. {
  1522. get { return PhysicsVector.Zero; }
  1523. }
  1524. public override PrimitiveBaseShape Shape
  1525. {
  1526. set
  1527. {
  1528. _pbs = value;
  1529. m_taintshape = true;
  1530. }
  1531. }
  1532. public override PhysicsVector Velocity
  1533. {
  1534. get
  1535. {
  1536. // Averate previous velocity with the new one so
  1537. // client object interpolation works a 'little' better
  1538. PhysicsVector returnVelocity = new PhysicsVector();
  1539. returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2;
  1540. returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2;
  1541. returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2;
  1542. return returnVelocity;
  1543. }
  1544. set
  1545. {
  1546. _velocity = value;
  1547. m_taintVelocity = value;
  1548. _parent_scene.AddPhysicsActorTaint(this);
  1549. }
  1550. }
  1551. public override float CollisionScore
  1552. {
  1553. get { return m_collisionscore; }
  1554. set { m_collisionscore = value; }
  1555. }
  1556. public override bool Kinematic
  1557. {
  1558. get { return false; }
  1559. set { }
  1560. }
  1561. public override Quaternion Orientation
  1562. {
  1563. get { return _orientation; }
  1564. set { _orientation = value; }
  1565. }
  1566. public override PhysicsVector Acceleration
  1567. {
  1568. get { return _acceleration; }
  1569. }
  1570. public void SetAcceleration(PhysicsVector accel)
  1571. {
  1572. _acceleration = accel;
  1573. }
  1574. public override void AddForce(PhysicsVector force, bool pushforce)
  1575. {
  1576. m_forcelist.Add(force);
  1577. m_taintforce = true;
  1578. //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
  1579. }
  1580. public override PhysicsVector RotationalVelocity
  1581. {
  1582. get
  1583. {
  1584. PhysicsVector pv = new PhysicsVector(0, 0, 0);
  1585. if (_zeroFlag)
  1586. return pv;
  1587. m_lastUpdateSent = false;
  1588. if (m_rotationalVelocity.IsIdentical(pv, 0.2f))
  1589. return pv;
  1590. return m_rotationalVelocity;
  1591. }
  1592. set { m_rotationalVelocity = value; }
  1593. }
  1594. public override void CrossingFailure()
  1595. {
  1596. m_crossingfailures++;
  1597. if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds)
  1598. {
  1599. base.RaiseOutOfBounds(_position);
  1600. return;
  1601. }
  1602. else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds)
  1603. {
  1604. m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
  1605. }
  1606. }
  1607. public override float Buoyancy
  1608. {
  1609. get { return m_buoyancy; }
  1610. set { m_buoyancy = value; }
  1611. }
  1612. public override void link(PhysicsActor obj)
  1613. {
  1614. m_taintparent = obj;
  1615. }
  1616. public override void delink()
  1617. {
  1618. m_taintparent = null;
  1619. }
  1620. public override void LockAngularMotion(PhysicsVector axis)
  1621. {
  1622. // reverse the zero/non zero values for ODE.
  1623. axis.X = (axis.X > 0) ? 1f : 0f;
  1624. axis.Y = (axis.Y > 0) ? 1f : 0f;
  1625. axis.Z = (axis.Z > 0) ? 1f : 0f;
  1626. m_taintAngularLock = new PhysicsVector(axis.X, axis.Y, axis.Z); ;
  1627. }
  1628. public void UpdatePositionAndVelocity()
  1629. {
  1630. // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
  1631. if (_parent == null)
  1632. {
  1633. PhysicsVector pv = new PhysicsVector(0, 0, 0);
  1634. bool lastZeroFlag = _zeroFlag;
  1635. if (Body != (IntPtr)0)
  1636. {
  1637. d.Vector3 vec = d.BodyGetPosition(Body);
  1638. d.Quaternion ori = d.BodyGetQuaternion(Body);
  1639. d.Vector3 vel = d.BodyGetLinearVel(Body);
  1640. d.Vector3 rotvel = d.BodyGetAngularVel(Body);
  1641. PhysicsVector l_position = new PhysicsVector();
  1642. // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
  1643. //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  1644. //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  1645. //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  1646. //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  1647. m_lastposition = _position;
  1648. l_position.X = vec.X;
  1649. l_position.Y = vec.Y;
  1650. l_position.Z = vec.Z;
  1651. if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f)
  1652. {
  1653. //base.RaiseOutOfBounds(l_position);
  1654. if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds)
  1655. {
  1656. _position = l_position;
  1657. //_parent_scene.remActivePrim(this);
  1658. if (_parent == null)
  1659. base.RequestPhysicsterseUpdate();
  1660. return;
  1661. }
  1662. else
  1663. {
  1664. if (_parent == null)
  1665. base.RaiseOutOfBounds(l_position);
  1666. return;
  1667. }
  1668. }
  1669. if (l_position.Z < 0)
  1670. {
  1671. // This is so prim that get lost underground don't fall forever and suck up
  1672. //
  1673. // Sim resources and memory.
  1674. // Disables the prim's movement physics....
  1675. // It's a hack and will generate a console message if it fails.
  1676. //IsPhysical = false;
  1677. if (_parent == null)
  1678. base.RaiseOutOfBounds(_position);
  1679. _acceleration.X = 0;
  1680. _acceleration.Y = 0;
  1681. _acceleration.Z = 0;
  1682. _velocity.X = 0;
  1683. _velocity.Y = 0;
  1684. _velocity.Z = 0;
  1685. m_rotationalVelocity.X = 0;
  1686. m_rotationalVelocity.Y = 0;
  1687. m_rotationalVelocity.Z = 0;
  1688. if (_parent == null)
  1689. base.RequestPhysicsterseUpdate();
  1690. m_throttleUpdates = false;
  1691. throttleCounter = 0;
  1692. _zeroFlag = true;
  1693. //outofBounds = true;
  1694. }
  1695. if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
  1696. && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
  1697. && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02))
  1698. {
  1699. _zeroFlag = true;
  1700. m_throttleUpdates = false;
  1701. }
  1702. else
  1703. {
  1704. //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
  1705. _zeroFlag = false;
  1706. }
  1707. if (_zeroFlag)
  1708. {
  1709. _velocity.X = 0.0f;
  1710. _velocity.Y = 0.0f;
  1711. _velocity.Z = 0.0f;
  1712. _acceleration.X = 0;
  1713. _acceleration.Y = 0;
  1714. _acceleration.Z = 0;
  1715. //_orientation.w = 0f;
  1716. //_orientation.x = 0f;
  1717. //_orientation.y = 0f;
  1718. //_orientation.z = 0f;
  1719. m_rotationalVelocity.X = 0;
  1720. m_rotationalVelocity.Y = 0;
  1721. m_rotationalVelocity.Z = 0;
  1722. if (!m_lastUpdateSent)
  1723. {
  1724. m_throttleUpdates = false;
  1725. throttleCounter = 0;
  1726. m_rotationalVelocity = pv;
  1727. if (_parent == null)
  1728. base.RequestPhysicsterseUpdate();
  1729. m_lastUpdateSent = true;
  1730. }
  1731. }
  1732. else
  1733. {
  1734. if (lastZeroFlag != _zeroFlag)
  1735. {
  1736. if (_parent == null)
  1737. base.RequestPhysicsterseUpdate();
  1738. }
  1739. m_lastVelocity = _velocity;
  1740. _position = l_position;
  1741. _velocity.X = vel.X;
  1742. _velocity.Y = vel.Y;
  1743. _velocity.Z = vel.Z;
  1744. _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
  1745. _acceleration = new PhysicsVector(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f);
  1746. //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
  1747. if (_velocity.IsIdentical(pv, 0.5f))
  1748. {
  1749. m_rotationalVelocity = pv;
  1750. }
  1751. else
  1752. {
  1753. m_rotationalVelocity.setValues(rotvel.X, rotvel.Y, rotvel.Z);
  1754. }
  1755. //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString());
  1756. _orientation.w = ori.W;
  1757. _orientation.x = ori.X;
  1758. _orientation.y = ori.Y;
  1759. _orientation.z = ori.Z;
  1760. m_lastUpdateSent = false;
  1761. if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate)
  1762. {
  1763. if (_parent == null)
  1764. base.RequestPhysicsterseUpdate();
  1765. }
  1766. else
  1767. {
  1768. throttleCounter++;
  1769. }
  1770. }
  1771. m_lastposition = l_position;
  1772. }
  1773. else
  1774. {
  1775. // Not a body.. so Make sure the client isn't interpolating
  1776. _velocity.X = 0;
  1777. _velocity.Y = 0;
  1778. _velocity.Z = 0;
  1779. _acceleration.X = 0;
  1780. _acceleration.Y = 0;
  1781. _acceleration.Z = 0;
  1782. m_rotationalVelocity.X = 0;
  1783. m_rotationalVelocity.Y = 0;
  1784. m_rotationalVelocity.Z = 0;
  1785. _zeroFlag = true;
  1786. }
  1787. }
  1788. }
  1789. public override bool FloatOnWater
  1790. {
  1791. set {
  1792. m_taintCollidesWater = value;
  1793. _parent_scene.AddPhysicsActorTaint(this);
  1794. }
  1795. }
  1796. public override void SetMomentum(PhysicsVector momentum)
  1797. {
  1798. }
  1799. public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } }
  1800. public override bool PIDActive { set { m_usePID = value; } }
  1801. public override float PIDTau { set { m_PIDTau = value; } }
  1802. private void createAMotor(PhysicsVector axis)
  1803. {
  1804. if (Body == IntPtr.Zero)
  1805. return;
  1806. if (Amotor != IntPtr.Zero)
  1807. {
  1808. d.JointDestroy(Amotor);
  1809. Amotor = IntPtr.Zero;
  1810. }
  1811. float axisnum = 3;
  1812. axisnum = (axisnum - (axis.X + axis.Y + axis.Z));
  1813. if (axisnum <= 0)
  1814. return;
  1815. int dAMotorEuler = 1;
  1816. Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
  1817. d.JointAttach(Amotor, Body, IntPtr.Zero);
  1818. d.JointSetAMotorMode(Amotor, dAMotorEuler);
  1819. d.JointSetAMotorNumAxes(Amotor,(int)axisnum);
  1820. int i = 0;
  1821. if (axis.X == 0)
  1822. {
  1823. d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0);
  1824. i++;
  1825. }
  1826. if (axis.Y == 0)
  1827. {
  1828. d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0);
  1829. i++;
  1830. }
  1831. if (axis.Z == 0)
  1832. {
  1833. d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1);
  1834. i++;
  1835. }
  1836. for (int j = 0; j < (int)axisnum; j++)
  1837. {
  1838. //d.JointSetAMotorAngle(Amotor, j, 0);
  1839. }
  1840. //d.JointSetAMotorAngle(Amotor, 1, 0);
  1841. //d.JointSetAMotorAngle(Amotor, 2, 0);
  1842. // These lowstops and high stops are effectively (no wiggle room)
  1843. d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
  1844. d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
  1845. d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
  1846. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
  1847. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
  1848. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
  1849. d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
  1850. d.JointSetAMotorParam(Amotor, (int)dParam.FMax, m_tensor);
  1851. }
  1852. public override void SubscribeEvents(int ms)
  1853. {
  1854. m_eventsubscription = ms;
  1855. _parent_scene.addCollisionEventReporting(this);
  1856. }
  1857. public override void UnSubscribeEvents()
  1858. {
  1859. _parent_scene.remCollisionEventReporting(this);
  1860. m_eventsubscription = 0;
  1861. }
  1862. public void AddCollisionEvent(uint CollidedWith, float depth)
  1863. {
  1864. if (CollisionEventsThisFrame == null)
  1865. CollisionEventsThisFrame = new CollisionEventUpdate();
  1866. CollisionEventsThisFrame.addCollider(CollidedWith,depth);
  1867. }
  1868. public void SendCollisions()
  1869. {
  1870. if (CollisionEventsThisFrame == null)
  1871. return;
  1872. //if (CollisionEventsThisFrame.m_objCollisionList == null)
  1873. // return;
  1874. if (CollisionEventsThisFrame.m_objCollisionList.Count > 0)
  1875. {
  1876. base.SendCollisionUpdate(CollisionEventsThisFrame);
  1877. CollisionEventsThisFrame = new CollisionEventUpdate();
  1878. }
  1879. }
  1880. public override bool SubscribedEvents()
  1881. {
  1882. if (m_eventsubscription > 0)
  1883. return true;
  1884. return false;
  1885. }
  1886. }
  1887. }