ODEPrim.cs 81 KB

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