ODEPrim.cs 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728
  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 log4net;
  33. using OpenMetaverse;
  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 _torque = new PhysicsVector(0,0,0);
  48. private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f, 0.0f, 0.0f);
  49. private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f);
  50. private Quaternion m_lastorientation = new Quaternion();
  51. private PhysicsVector m_rotationalVelocity;
  52. private PhysicsVector _size;
  53. private PhysicsVector _acceleration;
  54. // private d.Vector3 _zeroPosition = new d.Vector3(0.0f, 0.0f, 0.0f);
  55. private Quaternion _orientation;
  56. private PhysicsVector m_taintposition;
  57. private PhysicsVector m_taintsize;
  58. private PhysicsVector m_taintVelocity = new PhysicsVector(0, 0, 0);
  59. private PhysicsVector m_taintTorque = new PhysicsVector(0, 0, 0);
  60. private Quaternion m_taintrot;
  61. private PhysicsVector m_angularlock = new PhysicsVector(1f, 1f, 1f);
  62. private PhysicsVector m_taintAngularLock = new PhysicsVector(1f, 1f, 1f);
  63. private IntPtr Amotor = IntPtr.Zero;
  64. private PhysicsVector m_PIDTarget = new PhysicsVector(0, 0, 0);
  65. private float m_PIDTau = 0f;
  66. private float PID_D = 35f;
  67. private float PID_G = 25f;
  68. private float m_tensor = 5f;
  69. private int body_autodisable_frames = 20;
  70. private IMesh primMesh = null;
  71. private bool m_usePID = false;
  72. private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
  73. | CollisionCategories.Space
  74. | CollisionCategories.Body
  75. | CollisionCategories.Character
  76. );
  77. private bool m_taintshape = false;
  78. private bool m_taintPhysics = false;
  79. private bool m_collidesLand = true;
  80. private bool m_collidesWater = false;
  81. public bool m_returnCollisions = false;
  82. // Default we're a Geometry
  83. private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
  84. // Default, Collide with Other Geometries, spaces and Bodies
  85. private CollisionCategories m_collisionFlags = m_default_collisionFlags;
  86. public bool m_taintremove = false;
  87. public bool m_taintdisable = false;
  88. public bool m_disabled = false;
  89. public bool m_taintadd = false;
  90. public bool m_taintselected = false;
  91. public bool m_taintCollidesWater = false;
  92. public uint m_localID = 0;
  93. //public GCHandle gc;
  94. private CollisionLocker ode;
  95. private bool m_taintforce = false;
  96. private bool m_taintaddangularforce = false;
  97. private PhysicsVector m_force = new PhysicsVector(0.0f, 0.0f, 0.0f);
  98. private List<PhysicsVector> m_forcelist = new List<PhysicsVector>();
  99. private List<PhysicsVector> m_angularforcelist = new List<PhysicsVector>();
  100. private IMesh _mesh;
  101. private PrimitiveBaseShape _pbs;
  102. private OdeScene _parent_scene;
  103. public IntPtr m_targetSpace = (IntPtr) 0;
  104. public IntPtr prim_geom;
  105. public IntPtr prev_geom;
  106. public IntPtr _triMeshData;
  107. private IntPtr _linkJointGroup = (IntPtr)0;
  108. private PhysicsActor _parent = null;
  109. private PhysicsActor m_taintparent = null;
  110. private List<OdePrim> childrenPrim = new List<OdePrim>();
  111. private bool iscolliding = false;
  112. private bool m_isphysical = false;
  113. private bool m_isSelected = false;
  114. internal bool m_isVolumeDetect = false; // If true, this prim only detects collisions but doesn't collide actively
  115. private bool m_throttleUpdates = false;
  116. private int throttleCounter = 0;
  117. public int m_interpenetrationcount = 0;
  118. public float m_collisionscore = 0;
  119. public int m_roundsUnderMotionThreshold = 0;
  120. private int m_crossingfailures = 0;
  121. public float m_buoyancy = 0f;
  122. public bool outofBounds = false;
  123. private float m_density = 10.000006836f; // Aluminum g/cm3;
  124. public bool _zeroFlag = false;
  125. private bool m_lastUpdateSent = false;
  126. public IntPtr Body = (IntPtr) 0;
  127. private String m_primName;
  128. private PhysicsVector _target_velocity;
  129. public d.Mass pMass;
  130. public int m_eventsubscription = 0;
  131. private CollisionEventUpdate CollisionEventsThisFrame = null;
  132. private IntPtr m_linkJoint = (IntPtr)0;
  133. public volatile bool childPrim = false;
  134. public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size,
  135. Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
  136. {
  137. _target_velocity = new PhysicsVector(0, 0, 0);
  138. //gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned);
  139. ode = dode;
  140. _velocity = new PhysicsVector();
  141. _position = pos;
  142. m_taintposition = pos;
  143. PID_D = parent_scene.bodyPIDD;
  144. PID_G = parent_scene.bodyPIDG;
  145. m_density = parent_scene.geomDefaultDensity;
  146. m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
  147. body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
  148. prim_geom = IntPtr.Zero;
  149. prev_geom = IntPtr.Zero;
  150. if (size.X <= 0) size.X = 0.01f;
  151. if (size.Y <= 0) size.Y = 0.01f;
  152. if (size.Z <= 0) size.Z = 0.01f;
  153. _size = size;
  154. m_taintsize = _size;
  155. _acceleration = new PhysicsVector();
  156. m_rotationalVelocity = PhysicsVector.Zero;
  157. _orientation = rotation;
  158. m_taintrot = _orientation;
  159. _mesh = mesh;
  160. _pbs = pbs;
  161. _parent_scene = parent_scene;
  162. m_targetSpace = (IntPtr)0;
  163. if (pos.Z < 0)
  164. m_isphysical = false;
  165. else
  166. {
  167. m_isphysical = pisPhysical;
  168. // If we're physical, we need to be in the master space for now.
  169. // linksets *should* be in a space together.. but are not currently
  170. if (m_isphysical)
  171. m_targetSpace = _parent_scene.space;
  172. }
  173. m_primName = primName;
  174. m_taintadd = true;
  175. _parent_scene.AddPhysicsActorTaint(this);
  176. // don't do .add() here; old geoms get recycled with the same hash
  177. }
  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. m_collisionscore = 0;
  206. if ((m_isphysical && !_zeroFlag) || !value)
  207. {
  208. m_taintselected = value;
  209. _parent_scene.AddPhysicsActorTaint(this);
  210. }
  211. else
  212. {
  213. m_taintselected = value;
  214. m_isSelected = value;
  215. }
  216. }
  217. }
  218. public void SetGeom(IntPtr geom)
  219. {
  220. prev_geom = prim_geom;
  221. prim_geom = geom;
  222. if (prim_geom != IntPtr.Zero)
  223. {
  224. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  225. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  226. }
  227. if (childPrim)
  228. {
  229. if (_parent != null && _parent is OdePrim)
  230. {
  231. OdePrim parent = (OdePrim)_parent;
  232. parent.ChildSetGeom(this);
  233. }
  234. }
  235. //m_log.Warn("Setting Geom to: " + prim_geom);
  236. }
  237. public void enableBodySoft()
  238. {
  239. if (!childPrim)
  240. {
  241. if (m_isphysical && Body != IntPtr.Zero)
  242. d.BodyEnable(Body);
  243. m_disabled = false;
  244. }
  245. }
  246. public void disableBodySoft()
  247. {
  248. m_disabled = true;
  249. if (m_isphysical && Body != IntPtr.Zero)
  250. d.BodyDisable(Body);
  251. }
  252. public void enableBody()
  253. {
  254. // Don't enable this body if we're a child prim
  255. // this should be taken care of in the parent function not here
  256. if (!childPrim)
  257. {
  258. // Sets the geom to a body
  259. Body = d.BodyCreate(_parent_scene.world);
  260. setMass();
  261. d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
  262. d.Quaternion myrot = new d.Quaternion();
  263. myrot.X = _orientation.X;
  264. myrot.Y = _orientation.Y;
  265. myrot.Z = _orientation.Z;
  266. myrot.W = _orientation.W;
  267. d.BodySetQuaternion(Body, ref myrot);
  268. d.GeomSetBody(prim_geom, Body);
  269. m_collisionCategories |= CollisionCategories.Body;
  270. m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
  271. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  272. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  273. d.BodySetAutoDisableFlag(Body, true);
  274. d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
  275. m_interpenetrationcount = 0;
  276. m_collisionscore = 0;
  277. m_disabled = false;
  278. // The body doesn't already have a finite rotation mode set here
  279. if ((!m_angularlock.IsIdentical(PhysicsVector.Zero, 0)) && _parent == null)
  280. {
  281. createAMotor(m_angularlock);
  282. }
  283. _parent_scene.addActivePrim(this);
  284. }
  285. }
  286. #region Mass Calculation
  287. private float CalculateMass()
  288. {
  289. float volume = 0;
  290. // No material is passed to the physics engines yet.. soo..
  291. // we're using the m_density constant in the class definition
  292. float returnMass = 0;
  293. switch (_pbs.ProfileShape)
  294. {
  295. case ProfileShape.Square:
  296. // Profile Volume
  297. volume = _size.X*_size.Y*_size.Z;
  298. // If the user has 'hollowed out'
  299. // ProfileHollow is one of those 0 to 50000 values :P
  300. // we like percentages better.. so turning into a percentage
  301. if (((float) _pbs.ProfileHollow/50000f) > 0.0)
  302. {
  303. float hollowAmount = (float) _pbs.ProfileHollow/50000f;
  304. // calculate the hollow volume by it's shape compared to the prim shape
  305. float hollowVolume = 0;
  306. switch (_pbs.HollowShape)
  307. {
  308. case HollowShape.Square:
  309. case HollowShape.Same:
  310. // Cube Hollow volume calculation
  311. float hollowsizex = _size.X*hollowAmount;
  312. float hollowsizey = _size.Y*hollowAmount;
  313. float hollowsizez = _size.Z*hollowAmount;
  314. hollowVolume = hollowsizex*hollowsizey*hollowsizez;
  315. break;
  316. case HollowShape.Circle:
  317. // Hollow shape is a perfect cyllinder in respect to the cube's scale
  318. // Cyllinder hollow volume calculation
  319. float hRadius = _size.X/2;
  320. float hLength = _size.Z;
  321. // pi * r2 * h
  322. hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount);
  323. break;
  324. case HollowShape.Triangle:
  325. // Equilateral Triangular Prism volume hollow calculation
  326. // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
  327. float aLength = _size.Y;
  328. // 1/2 abh
  329. hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount);
  330. break;
  331. default:
  332. hollowVolume = 0;
  333. break;
  334. }
  335. volume = volume - hollowVolume;
  336. }
  337. break;
  338. case ProfileShape.Circle:
  339. if (_pbs.PathCurve == (byte)Extrusion.Straight)
  340. {
  341. // Cylinder
  342. float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z);
  343. float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z);
  344. // Approximating the cylinder's irregularity.
  345. if (volume1 > volume2)
  346. {
  347. volume = (float)volume1 - (volume1 - volume2);
  348. }
  349. else if (volume2 > volume1)
  350. {
  351. volume = (float)volume2 - (volume2 - volume1);
  352. }
  353. else
  354. {
  355. // Regular cylinder
  356. volume = volume1;
  357. }
  358. }
  359. else
  360. {
  361. // We don't know what the shape is yet, so use default
  362. volume = _size.X * _size.Y * _size.Z;
  363. }
  364. // If the user has 'hollowed out'
  365. // ProfileHollow is one of those 0 to 50000 values :P
  366. // we like percentages better.. so turning into a percentage
  367. if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
  368. {
  369. float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
  370. // calculate the hollow volume by it's shape compared to the prim shape
  371. float hollowVolume = 0;
  372. switch (_pbs.HollowShape)
  373. {
  374. case HollowShape.Same:
  375. case HollowShape.Circle:
  376. // Hollow shape is a perfect cyllinder in respect to the cube's scale
  377. // Cyllinder hollow volume calculation
  378. float hRadius = _size.X / 2;
  379. float hLength = _size.Z;
  380. // pi * r2 * h
  381. hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
  382. break;
  383. case HollowShape.Square:
  384. // Cube Hollow volume calculation
  385. float hollowsizex = _size.X * hollowAmount;
  386. float hollowsizey = _size.Y * hollowAmount;
  387. float hollowsizez = _size.Z * hollowAmount;
  388. hollowVolume = hollowsizex * hollowsizey * hollowsizez;
  389. break;
  390. case HollowShape.Triangle:
  391. // Equilateral Triangular Prism volume hollow calculation
  392. // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
  393. float aLength = _size.Y;
  394. // 1/2 abh
  395. hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
  396. break;
  397. default:
  398. hollowVolume = 0;
  399. break;
  400. }
  401. volume = volume - hollowVolume;
  402. }
  403. break;
  404. case ProfileShape.HalfCircle:
  405. if (_pbs.PathCurve == (byte)Extrusion.Curve1)
  406. {
  407. if (_size.X == _size.Z && _size.Z == _size.X)
  408. {
  409. // regular sphere
  410. // v = 4/3 * pi * r^3
  411. float sradius3 = (float)Math.Pow((_size.X / 2), 3);
  412. volume = (float)((4 / 3) * Math.PI * sradius3);
  413. }
  414. else
  415. {
  416. // we treat this as a box currently
  417. volume = _size.X * _size.Y * _size.Z;
  418. }
  419. }
  420. else
  421. {
  422. // We don't know what the shape is yet, so use default
  423. volume = _size.X * _size.Y * _size.Z;
  424. }
  425. break;
  426. case ProfileShape.EquilateralTriangle:
  427. /*
  428. v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
  429. // seed mesh
  430. Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
  431. Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
  432. Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
  433. */
  434. float xA = -0.25f * _size.X;
  435. float yA = -0.45f * _size.Y;
  436. float xB = 0.5f * _size.X;
  437. float yB = 0;
  438. float xC = -0.25f * _size.X;
  439. float yC = 0.45f * _size.Y;
  440. volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z);
  441. // If the user has 'hollowed out'
  442. // ProfileHollow is one of those 0 to 50000 values :P
  443. // we like percentages better.. so turning into a percentage
  444. float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
  445. if (((float)fhollowFactor / 50000f) > 0.0)
  446. {
  447. float hollowAmount = (float)fhollowFactor / 50000f;
  448. // calculate the hollow volume by it's shape compared to the prim shape
  449. float hollowVolume = 0;
  450. switch (_pbs.HollowShape)
  451. {
  452. case HollowShape.Same:
  453. case HollowShape.Triangle:
  454. // Equilateral Triangular Prism volume hollow calculation
  455. // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
  456. float aLength = _size.Y;
  457. // 1/2 abh
  458. hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
  459. break;
  460. case HollowShape.Square:
  461. // Cube Hollow volume calculation
  462. float hollowsizex = _size.X * hollowAmount;
  463. float hollowsizey = _size.Y * hollowAmount;
  464. float hollowsizez = _size.Z * hollowAmount;
  465. hollowVolume = hollowsizex * hollowsizey * hollowsizez;
  466. break;
  467. case HollowShape.Circle:
  468. // Hollow shape is a perfect cyllinder in respect to the cube's scale
  469. // Cyllinder hollow volume calculation
  470. float hRadius = _size.X / 2;
  471. float hLength = _size.Z;
  472. // pi * r2 * h
  473. hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount);
  474. break;
  475. default:
  476. hollowVolume = 0;
  477. break;
  478. }
  479. volume = volume - hollowVolume;
  480. }
  481. break;
  482. default:
  483. // we don't have all of the volume formulas yet so
  484. // use the common volume formula for all
  485. volume = _size.X*_size.Y*_size.Z;
  486. break;
  487. }
  488. // Calculate Path cut effect on volume
  489. // Not exact, in the triangle hollow example
  490. // They should never be zero or less then zero..
  491. // we'll ignore it if it's less then zero
  492. // ProfileEnd and ProfileBegin are values
  493. // from 0 to 50000
  494. // Turning them back into percentages so that I can cut that percentage off the volume
  495. float PathCutEndAmount = _pbs.ProfileEnd;
  496. float PathCutStartAmount = _pbs.ProfileBegin;
  497. if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f)
  498. {
  499. float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f);
  500. // Check the return amount for sanity
  501. if (pathCutAmount >= 0.99f)
  502. pathCutAmount = 0.99f;
  503. volume = volume - (volume*pathCutAmount);
  504. }
  505. UInt16 taperX = _pbs.PathScaleX;
  506. UInt16 taperY = _pbs.PathScaleY;
  507. float taperFactorX = 0;
  508. float taperFactorY = 0;
  509. // Mass = density * volume
  510. if (taperX != 100)
  511. {
  512. if (taperX > 100)
  513. {
  514. taperFactorX = 1.0f - ((float)taperX / 200);
  515. //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
  516. }
  517. else
  518. {
  519. taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
  520. //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
  521. }
  522. volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
  523. }
  524. if (taperY != 100)
  525. {
  526. if (taperY > 100)
  527. {
  528. taperFactorY = 1.0f - ((float)taperY / 200);
  529. //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
  530. }
  531. else
  532. {
  533. taperFactorY = 1.0f - ((100 - (float)taperY) / 100);
  534. //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
  535. }
  536. volume = (float)volume * ((taperFactorY / 3f) + 0.001f);
  537. }
  538. returnMass = m_density*volume;
  539. if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero.
  540. // Recursively calculate mass
  541. bool HasChildPrim = false;
  542. lock (childrenPrim)
  543. {
  544. if (childrenPrim.Count > 0)
  545. {
  546. HasChildPrim = true;
  547. }
  548. }
  549. if (HasChildPrim)
  550. {
  551. OdePrim[] childPrimArr = new OdePrim[0];
  552. lock (childrenPrim)
  553. childPrimArr = childrenPrim.ToArray();
  554. for (int i = 0; i < childPrimArr.Length; i++)
  555. {
  556. if (childPrimArr[i] != null && !childPrimArr[i].m_taintremove)
  557. returnMass += childPrimArr[i].CalculateMass();
  558. // failsafe, this shouldn't happen but with OpenSim, you never know :)
  559. if (i > 256)
  560. break;
  561. }
  562. }
  563. return returnMass;
  564. }
  565. #endregion
  566. public void setMass()
  567. {
  568. if (Body != (IntPtr) 0)
  569. {
  570. float newmass = CalculateMass();
  571. //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString());
  572. d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z);
  573. d.BodySetMass(Body, ref pMass);
  574. }
  575. }
  576. public void disableBody()
  577. {
  578. //this kills the body so things like 'mesh' can re-create it.
  579. lock (this)
  580. {
  581. if (!childPrim)
  582. {
  583. if (Body != IntPtr.Zero)
  584. {
  585. _parent_scene.remActivePrim(this);
  586. m_collisionCategories &= ~CollisionCategories.Body;
  587. m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
  588. if (prim_geom != IntPtr.Zero)
  589. {
  590. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  591. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  592. }
  593. d.BodyDestroy(Body);
  594. lock (childrenPrim)
  595. {
  596. if (childrenPrim.Count > 0)
  597. {
  598. foreach (OdePrim prm in childrenPrim)
  599. {
  600. _parent_scene.remActivePrim(prm);
  601. prm.Body = IntPtr.Zero;
  602. }
  603. }
  604. }
  605. Body = IntPtr.Zero;
  606. }
  607. }
  608. else
  609. {
  610. _parent_scene.remActivePrim(this);
  611. m_collisionCategories &= ~CollisionCategories.Body;
  612. m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
  613. if (prim_geom != IntPtr.Zero)
  614. {
  615. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  616. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  617. }
  618. Body = IntPtr.Zero;
  619. }
  620. }
  621. m_disabled = true;
  622. m_collisionscore = 0;
  623. }
  624. public void setMesh(OdeScene parent_scene, IMesh mesh)
  625. {
  626. // This sleeper is there to moderate how long it takes between
  627. // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
  628. Thread.Sleep(10);
  629. //Kill Body so that mesh can re-make the geom
  630. if (IsPhysical && Body != IntPtr.Zero)
  631. {
  632. if (childPrim)
  633. {
  634. if (_parent != null)
  635. {
  636. OdePrim parent = (OdePrim)_parent;
  637. parent.ChildDelink(this);
  638. }
  639. }
  640. else
  641. {
  642. disableBody();
  643. }
  644. }
  645. IMesh oldMesh = primMesh;
  646. primMesh = mesh;
  647. float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
  648. int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
  649. primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
  650. int VertexCount = vertexList.GetLength(0)/3;
  651. int IndexCount = indexList.GetLength(0);
  652. _triMeshData = d.GeomTriMeshDataCreate();
  653. d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount,
  654. 3*sizeof (int));
  655. d.GeomTriMeshDataPreprocess(_triMeshData);
  656. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  657. try
  658. {
  659. if (prim_geom == IntPtr.Zero)
  660. {
  661. SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
  662. }
  663. }
  664. catch (AccessViolationException)
  665. {
  666. m_log.Error("[PHYSICS]: MESH LOCKED");
  667. return;
  668. }
  669. if (oldMesh != null)
  670. {
  671. oldMesh.releasePinned();
  672. oldMesh = null;
  673. }
  674. // if (IsPhysical && Body == (IntPtr) 0)
  675. // {
  676. // Recreate the body
  677. // m_interpenetrationcount = 0;
  678. // m_collisionscore = 0;
  679. // enableBody();
  680. // }
  681. }
  682. public void ProcessTaints(float timestep)
  683. {
  684. if (m_taintadd)
  685. {
  686. changeadd(timestep);
  687. }
  688. if (prim_geom != IntPtr.Zero)
  689. {
  690. if (!_position.IsIdentical(m_taintposition,0f))
  691. changemove(timestep);
  692. if (m_taintrot != _orientation)
  693. rotate(timestep);
  694. //
  695. if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent))
  696. changePhysicsStatus(timestep);
  697. //
  698. if (!_size.IsIdentical(m_taintsize,0))
  699. changesize(timestep);
  700. //
  701. if (m_taintshape)
  702. changeshape(timestep);
  703. //
  704. if (m_taintforce)
  705. changeAddForce(timestep);
  706. if (m_taintaddangularforce)
  707. changeAddAngularForce(timestep);
  708. if (!m_taintTorque.IsIdentical(PhysicsVector.Zero, 0.001f))
  709. changeSetTorque(timestep);
  710. if (m_taintdisable)
  711. changedisable(timestep);
  712. if (m_taintselected != m_isSelected)
  713. changeSelectedStatus(timestep);
  714. if (!m_taintVelocity.IsIdentical(PhysicsVector.Zero, 0.001f))
  715. changevelocity(timestep);
  716. if (m_taintparent != _parent)
  717. changelink(timestep);
  718. if (m_taintCollidesWater != m_collidesWater)
  719. changefloatonwater(timestep);
  720. if (!m_angularlock.IsIdentical(m_taintAngularLock,0))
  721. changeAngularLock(timestep);
  722. }
  723. else
  724. {
  725. m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)");
  726. }
  727. }
  728. private void changeAngularLock(float timestep)
  729. {
  730. // do we have a Physical object?
  731. if (Body != IntPtr.Zero)
  732. {
  733. //Check that we have a Parent
  734. //If we have a parent then we're not authorative here
  735. if (_parent == null)
  736. {
  737. if (!m_taintAngularLock.IsIdentical(new PhysicsVector(1f,1f,1f), 0))
  738. {
  739. //d.BodySetFiniteRotationMode(Body, 0);
  740. //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z);
  741. createAMotor(m_taintAngularLock);
  742. }
  743. else
  744. {
  745. if (Amotor != IntPtr.Zero)
  746. {
  747. d.JointDestroy(Amotor);
  748. Amotor = IntPtr.Zero;
  749. }
  750. }
  751. }
  752. }
  753. // Store this for later in case we get turned into a separate body
  754. m_angularlock = new PhysicsVector(m_taintAngularLock.X, m_taintAngularLock.Y, m_taintAngularLock.Z);
  755. }
  756. private void changelink(float timestep)
  757. {
  758. // If the newly set parent is not null
  759. // create link
  760. if (_parent == null && m_taintparent != null)
  761. {
  762. if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim)
  763. {
  764. OdePrim obj = (OdePrim)m_taintparent;
  765. //obj.disableBody();
  766. obj.ParentPrim(this);
  767. /*
  768. if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body)
  769. {
  770. _linkJointGroup = d.JointGroupCreate(0);
  771. m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
  772. d.JointAttach(m_linkJoint, obj.Body, Body);
  773. d.JointSetFixed(m_linkJoint);
  774. }
  775. */
  776. }
  777. }
  778. // If the newly set parent is null
  779. // destroy link
  780. else if (_parent != null && m_taintparent == null)
  781. {
  782. if (_parent is OdePrim)
  783. {
  784. OdePrim obj = (OdePrim)_parent;
  785. obj.ChildDelink(this);
  786. childPrim = false;
  787. //_parent = null;
  788. }
  789. /*
  790. if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0)
  791. d.JointGroupDestroy(_linkJointGroup);
  792. _linkJointGroup = (IntPtr)0;
  793. m_linkJoint = (IntPtr)0;
  794. */
  795. }
  796. _parent = m_taintparent;
  797. m_taintPhysics = m_isphysical;
  798. }
  799. // I'm the parent
  800. // prim is the child
  801. public void ParentPrim(OdePrim prim)
  802. {
  803. if (this.m_localID != prim.m_localID)
  804. {
  805. if (Body == IntPtr.Zero)
  806. {
  807. Body = d.BodyCreate(_parent_scene.world);
  808. }
  809. if (Body != IntPtr.Zero)
  810. {
  811. lock (childrenPrim)
  812. {
  813. if (!childrenPrim.Contains(prim))
  814. {
  815. childrenPrim.Add(prim);
  816. foreach (OdePrim prm in childrenPrim)
  817. {
  818. d.Mass m2;
  819. d.MassSetZero(out m2);
  820. d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
  821. d.Quaternion quat = new d.Quaternion();
  822. quat.W = prm._orientation.W;
  823. quat.X = prm._orientation.X;
  824. quat.Y = prm._orientation.Y;
  825. quat.Z = prm._orientation.Z;
  826. d.Matrix3 mat = new d.Matrix3();
  827. d.RfromQ(out mat, ref quat);
  828. d.MassRotate(out m2, ref mat);
  829. d.MassTranslate(out m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
  830. d.MassAdd(ref pMass, ref m2);
  831. }
  832. foreach (OdePrim prm in childrenPrim)
  833. {
  834. prm.m_collisionCategories |= CollisionCategories.Body;
  835. prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
  836. if (prm.prim_geom == IntPtr.Zero)
  837. {
  838. m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet");
  839. continue;
  840. }
  841. d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
  842. d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
  843. d.Quaternion quat = new d.Quaternion();
  844. quat.W = prm._orientation.W;
  845. quat.X = prm._orientation.X;
  846. quat.Y = prm._orientation.Y;
  847. quat.Z = prm._orientation.Z;
  848. d.Matrix3 mat = new d.Matrix3();
  849. d.RfromQ(out mat, ref quat);
  850. if (Body != IntPtr.Zero)
  851. {
  852. d.GeomSetBody(prm.prim_geom, Body);
  853. prm.childPrim = true;
  854. d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z);
  855. //d.GeomSetOffsetPosition(prim.prim_geom,
  856. // (Position.X - prm.Position.X) - pMass.c.X,
  857. // (Position.Y - prm.Position.Y) - pMass.c.Y,
  858. // (Position.Z - prm.Position.Z) - pMass.c.Z);
  859. d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat);
  860. //d.GeomSetOffsetRotation(prm.prim_geom, ref mat);
  861. d.MassTranslate(out pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
  862. d.BodySetMass(Body, ref pMass);
  863. }
  864. else
  865. {
  866. m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body");
  867. }
  868. prm.m_interpenetrationcount = 0;
  869. prm.m_collisionscore = 0;
  870. prm.m_disabled = false;
  871. // The body doesn't already have a finite rotation mode set here
  872. if ((!m_angularlock.IsIdentical(PhysicsVector.Zero, 0)) && _parent == null)
  873. {
  874. prm.createAMotor(m_angularlock);
  875. }
  876. prm.Body = Body;
  877. _parent_scene.addActivePrim(prm);
  878. }
  879. m_collisionCategories |= CollisionCategories.Body;
  880. m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
  881. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  882. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  883. d.Quaternion quat2 = new d.Quaternion();
  884. quat2.W = _orientation.W;
  885. quat2.X = _orientation.X;
  886. quat2.Y = _orientation.Y;
  887. quat2.Z = _orientation.Z;
  888. d.Matrix3 mat2 = new d.Matrix3();
  889. d.RfromQ(out mat2, ref quat2);
  890. d.GeomSetBody(prim_geom, Body);
  891. d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
  892. //d.GeomSetOffsetPosition(prim.prim_geom,
  893. // (Position.X - prm.Position.X) - pMass.c.X,
  894. // (Position.Y - prm.Position.Y) - pMass.c.Y,
  895. // (Position.Z - prm.Position.Z) - pMass.c.Z);
  896. //d.GeomSetOffsetRotation(prim_geom, ref mat2);
  897. d.MassTranslate(out pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
  898. d.BodySetMass(Body, ref pMass);
  899. d.BodySetAutoDisableFlag(Body, true);
  900. d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
  901. m_interpenetrationcount = 0;
  902. m_collisionscore = 0;
  903. m_disabled = false;
  904. // The body doesn't already have a finite rotation mode set here
  905. if ((!m_angularlock.IsIdentical(PhysicsVector.Zero, 0)) && _parent == null)
  906. {
  907. createAMotor(m_angularlock);
  908. }
  909. d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
  910. _parent_scene.addActivePrim(this);
  911. }
  912. }
  913. }
  914. }
  915. }
  916. private void ChildSetGeom(OdePrim odePrim)
  917. {
  918. //if (m_isphysical && Body != IntPtr.Zero)
  919. lock (childrenPrim)
  920. {
  921. foreach (OdePrim prm in childrenPrim)
  922. {
  923. //prm.childPrim = true;
  924. prm.disableBody();
  925. //prm.m_taintparent = null;
  926. //prm._parent = null;
  927. //prm.m_taintPhysics = false;
  928. //prm.m_disabled = true;
  929. //prm.childPrim = false;
  930. }
  931. }
  932. disableBody();
  933. if (Body != IntPtr.Zero)
  934. {
  935. _parent_scene.remActivePrim(this);
  936. }
  937. lock (childrenPrim)
  938. {
  939. foreach (OdePrim prm in childrenPrim)
  940. {
  941. ParentPrim(prm);
  942. }
  943. }
  944. }
  945. private void ChildDelink(OdePrim odePrim)
  946. {
  947. // Okay, we have a delinked child.. need to rebuild the body.
  948. lock (childrenPrim)
  949. {
  950. foreach (OdePrim prm in childrenPrim)
  951. {
  952. prm.childPrim = true;
  953. prm.disableBody();
  954. //prm.m_taintparent = null;
  955. //prm._parent = null;
  956. //prm.m_taintPhysics = false;
  957. //prm.m_disabled = true;
  958. //prm.childPrim = false;
  959. }
  960. }
  961. disableBody();
  962. lock (childrenPrim)
  963. {
  964. childrenPrim.Remove(odePrim);
  965. }
  966. if (Body != IntPtr.Zero)
  967. {
  968. _parent_scene.remActivePrim(this);
  969. }
  970. lock (childrenPrim)
  971. {
  972. foreach (OdePrim prm in childrenPrim)
  973. {
  974. ParentPrim(prm);
  975. }
  976. }
  977. }
  978. private void changeSelectedStatus(float timestep)
  979. {
  980. if (m_taintselected)
  981. {
  982. m_collisionCategories = CollisionCategories.Selected;
  983. m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
  984. // We do the body disable soft twice because 'in theory' a collision could have happened
  985. // in between the disabling and the collision properties setting
  986. // which would wake the physical body up from a soft disabling and potentially cause it to fall
  987. // through the ground.
  988. // NOTE FOR JOINTS: this doesn't always work for jointed assemblies because if you select
  989. // just one part of the assembly, the rest of the assembly is non-selected and still simulating,
  990. // so that causes the selected part to wake up and continue moving.
  991. // even if you select all parts of a jointed assembly, it is not guaranteed that the entire
  992. // assembly will stop simulating during the selection, because of the lack of atomicity
  993. // of select operations (their processing could be interrupted by a thread switch, causing
  994. // simulation to continue before all of the selected object notifications trickle down to
  995. // the physics engine).
  996. // e.g. we select 100 prims that are connected by joints. non-atomically, the first 50 are
  997. // selected and disabled. then, due to a thread switch, the selection processing is
  998. // interrupted and the physics engine continues to simulate, so the last 50 items, whose
  999. // selection was not yet processed, continues to simulate. this wakes up ALL of the
  1000. // first 50 again. then the last 50 are disabled. then the first 50, which were just woken
  1001. // up, start simulating again, which in turn wakes up the last 50.
  1002. if (m_isphysical)
  1003. {
  1004. disableBodySoft();
  1005. }
  1006. if (prim_geom != IntPtr.Zero)
  1007. {
  1008. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  1009. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  1010. }
  1011. if (m_isphysical)
  1012. {
  1013. disableBodySoft();
  1014. }
  1015. }
  1016. else
  1017. {
  1018. m_collisionCategories = CollisionCategories.Geom;
  1019. if (m_isphysical)
  1020. m_collisionCategories |= CollisionCategories.Body;
  1021. m_collisionFlags = m_default_collisionFlags;
  1022. if (m_collidesLand)
  1023. m_collisionFlags |= CollisionCategories.Land;
  1024. if (m_collidesWater)
  1025. m_collisionFlags |= CollisionCategories.Water;
  1026. if (prim_geom != IntPtr.Zero)
  1027. {
  1028. d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
  1029. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  1030. }
  1031. if (m_isphysical)
  1032. {
  1033. if (Body != IntPtr.Zero)
  1034. {
  1035. d.BodySetLinearVel(Body, 0f, 0f, 0f);
  1036. d.BodySetForce(Body, 0, 0, 0);
  1037. enableBodySoft();
  1038. }
  1039. }
  1040. }
  1041. resetCollisionAccounting();
  1042. m_isSelected = m_taintselected;
  1043. }
  1044. public void ResetTaints()
  1045. {
  1046. m_taintposition = _position;
  1047. m_taintrot = _orientation;
  1048. m_taintPhysics = m_isphysical;
  1049. m_taintselected = m_isSelected;
  1050. m_taintsize = _size;
  1051. m_taintshape = false;
  1052. m_taintforce = false;
  1053. m_taintdisable = false;
  1054. m_taintVelocity = PhysicsVector.Zero;
  1055. }
  1056. public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh)
  1057. {
  1058. if (_mesh != null)
  1059. {
  1060. setMesh(_parent_scene, _mesh);
  1061. }
  1062. else
  1063. {
  1064. if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1065. {
  1066. if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1067. {
  1068. if (((_size.X / 2f) > 0f))
  1069. {
  1070. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1071. try
  1072. {
  1073. SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1074. }
  1075. catch (AccessViolationException)
  1076. {
  1077. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  1078. ode.dunlock(_parent_scene.world);
  1079. return;
  1080. }
  1081. }
  1082. else
  1083. {
  1084. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1085. try
  1086. {
  1087. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1088. }
  1089. catch (AccessViolationException)
  1090. {
  1091. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  1092. ode.dunlock(_parent_scene.world);
  1093. return;
  1094. }
  1095. }
  1096. }
  1097. else
  1098. {
  1099. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1100. try
  1101. {
  1102. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1103. }
  1104. catch (AccessViolationException)
  1105. {
  1106. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  1107. ode.dunlock(_parent_scene.world);
  1108. return;
  1109. }
  1110. }
  1111. }
  1112. else
  1113. {
  1114. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1115. try
  1116. {
  1117. SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1118. }
  1119. catch (AccessViolationException)
  1120. {
  1121. m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
  1122. ode.dunlock(_parent_scene.world);
  1123. return;
  1124. }
  1125. }
  1126. }
  1127. }
  1128. public void changeadd(float timestep)
  1129. {
  1130. int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
  1131. IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
  1132. if (targetspace == IntPtr.Zero)
  1133. targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
  1134. m_targetSpace = targetspace;
  1135. if (_mesh == null)
  1136. {
  1137. if (_parent_scene.needsMeshing(_pbs))
  1138. {
  1139. // Don't need to re-enable body.. it's done in SetMesh
  1140. _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
  1141. // createmesh returns null when it's a shape that isn't a cube.
  1142. }
  1143. }
  1144. lock (_parent_scene.OdeLock)
  1145. {
  1146. CreateGeom(m_targetSpace, _mesh);
  1147. if (prim_geom != IntPtr.Zero)
  1148. {
  1149. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1150. d.Quaternion myrot = new d.Quaternion();
  1151. myrot.X = _orientation.X;
  1152. myrot.Y = _orientation.Y;
  1153. myrot.Z = _orientation.Z;
  1154. myrot.W = _orientation.W;
  1155. d.GeomSetQuaternion(prim_geom, ref myrot);
  1156. }
  1157. if (m_isphysical && Body == IntPtr.Zero)
  1158. {
  1159. enableBody();
  1160. }
  1161. }
  1162. _parent_scene.geom_name_map[prim_geom] = this.m_primName;
  1163. _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
  1164. changeSelectedStatus(timestep);
  1165. m_taintadd = false;
  1166. }
  1167. public void changemove(float timestep)
  1168. {
  1169. if (m_isphysical)
  1170. {
  1171. if (!m_disabled && !m_taintremove && !childPrim)
  1172. {
  1173. if (Body == IntPtr.Zero)
  1174. enableBody();
  1175. //Prim auto disable after 20 frames,
  1176. //if you move it, re-enable the prim manually.
  1177. if (_parent != null)
  1178. {
  1179. if (m_linkJoint != IntPtr.Zero)
  1180. {
  1181. d.JointDestroy(m_linkJoint);
  1182. m_linkJoint = IntPtr.Zero;
  1183. }
  1184. }
  1185. if (Body != IntPtr.Zero)
  1186. {
  1187. d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
  1188. if (_parent != null)
  1189. {
  1190. OdePrim odParent = (OdePrim)_parent;
  1191. if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body)
  1192. {
  1193. m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
  1194. d.JointAttach(m_linkJoint, Body, odParent.Body);
  1195. d.JointSetFixed(m_linkJoint);
  1196. }
  1197. }
  1198. d.BodyEnable(Body);
  1199. }
  1200. else
  1201. {
  1202. m_log.Warn("[PHYSICS]: Body Still null after enableBody(). This is a crash scenario.");
  1203. }
  1204. }
  1205. //else
  1206. // {
  1207. //m_log.Debug("[BUG]: race!");
  1208. //}
  1209. }
  1210. else
  1211. {
  1212. // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
  1213. // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
  1214. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1215. IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
  1216. m_targetSpace = tempspace;
  1217. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1218. if (prim_geom != IntPtr.Zero)
  1219. {
  1220. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1221. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1222. d.SpaceAdd(m_targetSpace, prim_geom);
  1223. }
  1224. }
  1225. changeSelectedStatus(timestep);
  1226. resetCollisionAccounting();
  1227. m_taintposition = _position;
  1228. }
  1229. public void Move(float timestep)
  1230. {
  1231. float fx = 0;
  1232. float fy = 0;
  1233. float fz = 0;
  1234. if (IsPhysical && Body != IntPtr.Zero && !m_isSelected)
  1235. {
  1236. //float PID_P = 900.0f;
  1237. float m_mass = CalculateMass();
  1238. fz = 0f;
  1239. //m_log.Info(m_collisionFlags.ToString());
  1240. if (m_buoyancy != 0)
  1241. {
  1242. if (m_buoyancy > 0)
  1243. {
  1244. fz = (((-1 * _parent_scene.gravityz) * m_buoyancy) * m_mass);
  1245. //d.Vector3 l_velocity = d.BodyGetLinearVel(Body);
  1246. //m_log.Info("Using Buoyancy: " + buoyancy + " G: " + (_parent_scene.gravityz * m_buoyancy) + "mass:" + m_mass + " Pos: " + Position.ToString());
  1247. }
  1248. else
  1249. {
  1250. fz = (-1 * (((-1 * _parent_scene.gravityz) * (-1 * m_buoyancy)) * m_mass));
  1251. }
  1252. }
  1253. if (m_usePID)
  1254. {
  1255. // If we're using the PID controller, then we have no gravity
  1256. fz = (-1 * _parent_scene.gravityz) * m_mass;
  1257. // no lock; for now it's only called from within Simulate()
  1258. // If the PID Controller isn't active then we set our force
  1259. // calculating base velocity to the current position
  1260. if ((m_PIDTau < 1))
  1261. {
  1262. PID_G = PID_G / m_PIDTau;
  1263. }
  1264. if ((PID_G - m_PIDTau) <= 0)
  1265. {
  1266. PID_G = m_PIDTau + 1;
  1267. }
  1268. //PidStatus = true;
  1269. // PhysicsVector vec = new PhysicsVector();
  1270. d.Vector3 vel = d.BodyGetLinearVel(Body);
  1271. d.Vector3 pos = d.BodyGetPosition(Body);
  1272. _target_velocity =
  1273. new PhysicsVector(
  1274. (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
  1275. (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
  1276. (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
  1277. );
  1278. // if velocity is zero, use position control; otherwise, velocity control
  1279. if (_target_velocity.IsIdentical(PhysicsVector.Zero,0.1f))
  1280. {
  1281. // keep track of where we stopped. No more slippin' & slidin'
  1282. // We only want to deactivate the PID Controller if we think we want to have our surrogate
  1283. // react to the physics scene by moving it's position.
  1284. // Avatar to Avatar collisions
  1285. // Prim to avatar collisions
  1286. //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
  1287. //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2);
  1288. //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
  1289. d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
  1290. d.BodySetLinearVel(Body, 0, 0, 0);
  1291. d.BodyAddForce(Body, 0, 0, fz);
  1292. return;
  1293. }
  1294. else
  1295. {
  1296. _zeroFlag = false;
  1297. // We're flying and colliding with something
  1298. fx = ((_target_velocity.X) - vel.X) * (PID_D);
  1299. fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
  1300. // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
  1301. fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
  1302. }
  1303. }
  1304. fx *= m_mass;
  1305. fy *= m_mass;
  1306. //fz *= m_mass;
  1307. fx += m_force.X;
  1308. fy += m_force.Y;
  1309. fz += m_force.Z;
  1310. //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
  1311. if (fx != 0 || fy != 0 || fz != 0)
  1312. {
  1313. //m_taintdisable = true;
  1314. //base.RaiseOutOfBounds(Position);
  1315. //d.BodySetLinearVel(Body, fx, fy, 0f);
  1316. if (!d.BodyIsEnabled(Body))
  1317. {
  1318. d.BodySetLinearVel(Body, 0f, 0f, 0f);
  1319. d.BodySetForce(Body, 0, 0, 0);
  1320. enableBodySoft();
  1321. }
  1322. d.BodyAddForce(Body, fx, fy, fz);
  1323. }
  1324. }
  1325. else
  1326. {
  1327. // _zeroPosition = d.BodyGetPosition(Body);
  1328. return;
  1329. }
  1330. }
  1331. public void rotate(float timestep)
  1332. {
  1333. d.Quaternion myrot = new d.Quaternion();
  1334. myrot.X = _orientation.X;
  1335. myrot.Y = _orientation.Y;
  1336. myrot.Z = _orientation.Z;
  1337. myrot.W = _orientation.W;
  1338. d.GeomSetQuaternion(prim_geom, ref myrot);
  1339. if (m_isphysical && Body != IntPtr.Zero)
  1340. {
  1341. d.BodySetQuaternion(Body, ref myrot);
  1342. if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0))
  1343. createAMotor(m_angularlock);
  1344. }
  1345. resetCollisionAccounting();
  1346. m_taintrot = _orientation;
  1347. }
  1348. private void resetCollisionAccounting()
  1349. {
  1350. m_collisionscore = 0;
  1351. m_interpenetrationcount = 0;
  1352. m_disabled = false;
  1353. }
  1354. public void changedisable(float timestep)
  1355. {
  1356. m_disabled = true;
  1357. if (Body != IntPtr.Zero)
  1358. {
  1359. d.BodyDisable(Body);
  1360. Body = IntPtr.Zero;
  1361. }
  1362. m_taintdisable = false;
  1363. }
  1364. public void changePhysicsStatus(float timestep)
  1365. {
  1366. if (m_isphysical == true)
  1367. {
  1368. if (Body == IntPtr.Zero)
  1369. {
  1370. if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
  1371. {
  1372. changeshape(2f);
  1373. }
  1374. else
  1375. {
  1376. enableBody();
  1377. }
  1378. }
  1379. }
  1380. else
  1381. {
  1382. if (Body != IntPtr.Zero)
  1383. {
  1384. if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
  1385. {
  1386. if (prim_geom != IntPtr.Zero)
  1387. {
  1388. try
  1389. {
  1390. d.GeomDestroy(prim_geom);
  1391. prim_geom = IntPtr.Zero;
  1392. _mesh = null;
  1393. }
  1394. catch (System.AccessViolationException)
  1395. {
  1396. prim_geom = IntPtr.Zero;
  1397. m_log.Error("[PHYSICS]: PrimGeom dead");
  1398. }
  1399. }
  1400. changeadd(2f);
  1401. }
  1402. if (childPrim)
  1403. {
  1404. if (_parent != null)
  1405. {
  1406. OdePrim parent = (OdePrim)_parent;
  1407. parent.ChildDelink(this);
  1408. }
  1409. }
  1410. else
  1411. {
  1412. disableBody();
  1413. }
  1414. }
  1415. }
  1416. changeSelectedStatus(timestep);
  1417. resetCollisionAccounting();
  1418. m_taintPhysics = m_isphysical;
  1419. }
  1420. public void changesize(float timestamp)
  1421. {
  1422. //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom))
  1423. //{
  1424. // m_taintsize = _size;
  1425. //return;
  1426. //}
  1427. string oldname = _parent_scene.geom_name_map[prim_geom];
  1428. if (_size.X <= 0) _size.X = 0.01f;
  1429. if (_size.Y <= 0) _size.Y = 0.01f;
  1430. if (_size.Z <= 0) _size.Z = 0.01f;
  1431. // Cleanup of old prim geometry
  1432. if (_mesh != null)
  1433. {
  1434. // Cleanup meshing here
  1435. }
  1436. //kill body to rebuild
  1437. if (IsPhysical && Body != IntPtr.Zero)
  1438. {
  1439. if (childPrim)
  1440. {
  1441. if (_parent != null)
  1442. {
  1443. OdePrim parent = (OdePrim)_parent;
  1444. parent.ChildDelink(this);
  1445. }
  1446. }
  1447. else
  1448. {
  1449. disableBody();
  1450. }
  1451. }
  1452. if (d.SpaceQuery(m_targetSpace, prim_geom))
  1453. {
  1454. _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1455. d.SpaceRemove(m_targetSpace, prim_geom);
  1456. }
  1457. d.GeomDestroy(prim_geom);
  1458. prim_geom = IntPtr.Zero;
  1459. // we don't need to do space calculation because the client sends a position update also.
  1460. // Construction of new prim
  1461. if (_parent_scene.needsMeshing(_pbs))
  1462. {
  1463. float meshlod = _parent_scene.meshSculptLOD;
  1464. if (IsPhysical)
  1465. meshlod = _parent_scene.MeshSculptphysicalLOD;
  1466. // Don't need to re-enable body.. it's done in SetMesh
  1467. IMesh mesh = null;
  1468. if (_parent_scene.needsMeshing(_pbs))
  1469. mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
  1470. //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
  1471. CreateGeom(m_targetSpace, mesh);
  1472. }
  1473. else
  1474. {
  1475. _mesh = null;
  1476. CreateGeom(m_targetSpace, _mesh);
  1477. }
  1478. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1479. d.Quaternion myrot = new d.Quaternion();
  1480. myrot.X = _orientation.X;
  1481. myrot.Y = _orientation.Y;
  1482. myrot.Z = _orientation.Z;
  1483. myrot.W = _orientation.W;
  1484. d.GeomSetQuaternion(prim_geom, ref myrot);
  1485. //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1486. if (IsPhysical && Body == IntPtr.Zero && !childPrim)
  1487. {
  1488. // Re creates body on size.
  1489. // EnableBody also does setMass()
  1490. enableBody();
  1491. d.BodyEnable(Body);
  1492. }
  1493. _parent_scene.geom_name_map[prim_geom] = oldname;
  1494. changeSelectedStatus(timestamp);
  1495. if (childPrim)
  1496. {
  1497. if (_parent is OdePrim)
  1498. {
  1499. OdePrim parent = (OdePrim)_parent;
  1500. parent.ChildSetGeom(this);
  1501. }
  1502. }
  1503. resetCollisionAccounting();
  1504. m_taintsize = _size;
  1505. }
  1506. //public void changesize(float timestamp)
  1507. //{
  1508. // //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom))
  1509. // //{
  1510. // // m_taintsize = _size;
  1511. // //return;
  1512. // //}
  1513. // string oldname = _parent_scene.geom_name_map[prim_geom];
  1514. // if (_size.X <= 0) _size.X = 0.01f;
  1515. // if (_size.Y <= 0) _size.Y = 0.01f;
  1516. // if (_size.Z <= 0) _size.Z = 0.01f;
  1517. // // Cleanup of old prim geometry
  1518. // if (_mesh != null)
  1519. // {
  1520. // // Cleanup meshing here
  1521. // }
  1522. // //kill body to rebuild
  1523. // if (IsPhysical && Body != (IntPtr) 0)
  1524. // {
  1525. // disableBody();
  1526. // }
  1527. // if (d.SpaceQuery(m_targetSpace, prim_geom))
  1528. // {
  1529. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1530. // d.SpaceRemove(m_targetSpace, prim_geom);
  1531. // }
  1532. // d.GeomDestroy(prim_geom);
  1533. // prim_geom = (IntPtr)0;
  1534. // // we don't need to do space calculation because the client sends a position update also.
  1535. // // Construction of new prim
  1536. // if (_parent_scene.needsMeshing(_pbs))
  1537. // {
  1538. // float meshlod = _parent_scene.meshSculptLOD;
  1539. // if (IsPhysical)
  1540. // meshlod = _parent_scene.MeshSculptphysicalLOD;
  1541. // // Don't need to re-enable body.. it's done in SetMesh
  1542. // IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
  1543. // // createmesh returns null when it's a shape that isn't a cube.
  1544. // if (mesh != null)
  1545. // {
  1546. // setMesh(_parent_scene, mesh);
  1547. // d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1548. // d.Quaternion myrot = new d.Quaternion();
  1549. // myrot.W = _orientation.w;
  1550. // myrot.X = _orientation.X;
  1551. // myrot.Y = _orientation.Y;
  1552. // myrot.Z = _orientation.Z;
  1553. // d.GeomSetQuaternion(prim_geom, ref myrot);
  1554. // //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1555. // if (IsPhysical && Body == (IntPtr)0)
  1556. // {
  1557. // // Re creates body on size.
  1558. // // EnableBody also does setMass()
  1559. // enableBody();
  1560. // d.BodyEnable(Body);
  1561. // }
  1562. // }
  1563. // else
  1564. // {
  1565. // if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1566. // {
  1567. // if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1568. // {
  1569. // if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
  1570. // {
  1571. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1572. // SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1573. // }
  1574. // else
  1575. // {
  1576. // m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
  1577. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1578. // SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1579. // }
  1580. // }
  1581. // else
  1582. // {
  1583. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1584. // SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1585. // }
  1586. // }
  1587. // //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
  1588. // //{
  1589. // //Cyllinder
  1590. // //if (_size.X == _size.Y)
  1591. // //{
  1592. // // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  1593. // //}
  1594. // //else
  1595. // //{
  1596. // //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1597. // //}
  1598. // //}
  1599. // else
  1600. // {
  1601. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1602. // SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1603. // }
  1604. // //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1605. // d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1606. // d.Quaternion myrot = new d.Quaternion();
  1607. // myrot.W = _orientation.w;
  1608. // myrot.X = _orientation.X;
  1609. // myrot.Y = _orientation.Y;
  1610. // myrot.Z = _orientation.Z;
  1611. // d.GeomSetQuaternion(prim_geom, ref myrot);
  1612. // }
  1613. // }
  1614. // else
  1615. // {
  1616. // if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
  1617. // {
  1618. // if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
  1619. // {
  1620. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1621. // SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
  1622. // }
  1623. // else
  1624. // {
  1625. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1626. // SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1627. // }
  1628. // }
  1629. // //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
  1630. // //{
  1631. // //Cyllinder
  1632. // //if (_size.X == _size.Y)
  1633. // //{
  1634. // //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
  1635. // //}
  1636. // //else
  1637. // //{
  1638. // //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
  1639. // //}
  1640. // //}
  1641. // else
  1642. // {
  1643. // _parent_scene.waitForSpaceUnlock(m_targetSpace);
  1644. // SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
  1645. // }
  1646. // d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1647. // d.Quaternion myrot = new d.Quaternion();
  1648. // myrot.W = _orientation.w;
  1649. // myrot.X = _orientation.X;
  1650. // myrot.Y = _orientation.Y;
  1651. // myrot.Z = _orientation.Z;
  1652. // d.GeomSetQuaternion(prim_geom, ref myrot);
  1653. // //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1654. // if (IsPhysical && Body == (IntPtr) 0)
  1655. // {
  1656. // // Re creates body on size.
  1657. // // EnableBody also does setMass()
  1658. // enableBody();
  1659. // d.BodyEnable(Body);
  1660. // }
  1661. // }
  1662. // _parent_scene.geom_name_map[prim_geom] = oldname;
  1663. // changeSelectedStatus(timestamp);
  1664. // resetCollisionAccounting();
  1665. // m_taintsize = _size;
  1666. //}
  1667. public void changefloatonwater(float timestep)
  1668. {
  1669. m_collidesWater = m_taintCollidesWater;
  1670. if (prim_geom != IntPtr.Zero)
  1671. {
  1672. if (m_collidesWater)
  1673. {
  1674. m_collisionFlags |= CollisionCategories.Water;
  1675. }
  1676. else
  1677. {
  1678. m_collisionFlags &= ~CollisionCategories.Water;
  1679. }
  1680. d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
  1681. }
  1682. }
  1683. public void changeshape(float timestamp)
  1684. {
  1685. string oldname = _parent_scene.geom_name_map[prim_geom];
  1686. // Cleanup of old prim geometry and Bodies
  1687. if (IsPhysical && Body != IntPtr.Zero)
  1688. {
  1689. if (childPrim)
  1690. {
  1691. if (_parent != null)
  1692. {
  1693. OdePrim parent = (OdePrim)_parent;
  1694. parent.ChildDelink(this);
  1695. }
  1696. }
  1697. else
  1698. {
  1699. disableBody();
  1700. }
  1701. }
  1702. try
  1703. {
  1704. d.GeomDestroy(prim_geom);
  1705. }
  1706. catch (System.AccessViolationException)
  1707. {
  1708. prim_geom = IntPtr.Zero;
  1709. m_log.Error("[PHYSICS]: PrimGeom dead");
  1710. }
  1711. prim_geom = IntPtr.Zero;
  1712. // we don't need to do space calculation because the client sends a position update also.
  1713. if (_size.X <= 0) _size.X = 0.01f;
  1714. if (_size.Y <= 0) _size.Y = 0.01f;
  1715. if (_size.Z <= 0) _size.Z = 0.01f;
  1716. // Construction of new prim
  1717. if (_parent_scene.needsMeshing(_pbs))
  1718. {
  1719. // Don't need to re-enable body.. it's done in SetMesh
  1720. float meshlod = _parent_scene.meshSculptLOD;
  1721. if (IsPhysical)
  1722. meshlod = _parent_scene.MeshSculptphysicalLOD;
  1723. IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical);
  1724. // createmesh returns null when it doesn't mesh.
  1725. CreateGeom(m_targetSpace, mesh);
  1726. }
  1727. else
  1728. {
  1729. _mesh = null;
  1730. CreateGeom(m_targetSpace, null);
  1731. }
  1732. d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
  1733. d.Quaternion myrot = new d.Quaternion();
  1734. //myrot.W = _orientation.w;
  1735. myrot.W = _orientation.W;
  1736. myrot.X = _orientation.X;
  1737. myrot.Y = _orientation.Y;
  1738. myrot.Z = _orientation.Z;
  1739. d.GeomSetQuaternion(prim_geom, ref myrot);
  1740. //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
  1741. if (IsPhysical && Body == IntPtr.Zero)
  1742. {
  1743. // Re creates body on size.
  1744. // EnableBody also does setMass()
  1745. enableBody();
  1746. d.BodyEnable(Body);
  1747. }
  1748. _parent_scene.geom_name_map[prim_geom] = oldname;
  1749. changeSelectedStatus(timestamp);
  1750. if (childPrim)
  1751. {
  1752. if (_parent is OdePrim)
  1753. {
  1754. OdePrim parent = (OdePrim)_parent;
  1755. parent.ChildSetGeom(this);
  1756. }
  1757. }
  1758. resetCollisionAccounting();
  1759. m_taintshape = false;
  1760. }
  1761. public void changeAddForce(float timestamp)
  1762. {
  1763. if (!m_isSelected)
  1764. {
  1765. lock (m_forcelist)
  1766. {
  1767. //m_log.Info("[PHYSICS]: dequeing forcelist");
  1768. if (IsPhysical)
  1769. {
  1770. PhysicsVector iforce = new PhysicsVector();
  1771. for (int i = 0; i < m_forcelist.Count; i++)
  1772. {
  1773. iforce = iforce + (m_forcelist[i] * 100);
  1774. }
  1775. d.BodyEnable(Body);
  1776. d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z);
  1777. }
  1778. m_forcelist.Clear();
  1779. }
  1780. m_collisionscore = 0;
  1781. m_interpenetrationcount = 0;
  1782. }
  1783. m_taintforce = false;
  1784. }
  1785. public void changeSetTorque(float timestamp)
  1786. {
  1787. if (!m_isSelected)
  1788. {
  1789. if (IsPhysical && Body != IntPtr.Zero)
  1790. {
  1791. d.BodySetTorque(Body, m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z);
  1792. }
  1793. }
  1794. m_taintTorque = new PhysicsVector(0, 0, 0);
  1795. }
  1796. public void changeAddAngularForce(float timestamp)
  1797. {
  1798. if (!m_isSelected)
  1799. {
  1800. lock (m_angularforcelist)
  1801. {
  1802. //m_log.Info("[PHYSICS]: dequeing forcelist");
  1803. if (IsPhysical)
  1804. {
  1805. PhysicsVector iforce = new PhysicsVector();
  1806. for (int i = 0; i < m_angularforcelist.Count; i++)
  1807. {
  1808. iforce = iforce + (m_angularforcelist[i] * 100);
  1809. }
  1810. d.BodyEnable(Body);
  1811. d.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z);
  1812. }
  1813. m_angularforcelist.Clear();
  1814. }
  1815. m_collisionscore = 0;
  1816. m_interpenetrationcount = 0;
  1817. }
  1818. m_taintaddangularforce = false;
  1819. }
  1820. private void changevelocity(float timestep)
  1821. {
  1822. if (!m_isSelected)
  1823. {
  1824. Thread.Sleep(20);
  1825. if (IsPhysical)
  1826. {
  1827. if (Body != IntPtr.Zero)
  1828. {
  1829. d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
  1830. }
  1831. }
  1832. //resetCollisionAccounting();
  1833. }
  1834. m_taintVelocity = PhysicsVector.Zero;
  1835. }
  1836. public override bool IsPhysical
  1837. {
  1838. get { return m_isphysical; }
  1839. set { m_isphysical = value; }
  1840. }
  1841. public void setPrimForRemoval()
  1842. {
  1843. m_taintremove = true;
  1844. }
  1845. public override bool Flying
  1846. {
  1847. // no flying prims for you
  1848. get { return false; }
  1849. set { }
  1850. }
  1851. public override bool IsColliding
  1852. {
  1853. get { return iscolliding; }
  1854. set { iscolliding = value; }
  1855. }
  1856. public override bool CollidingGround
  1857. {
  1858. get { return false; }
  1859. set { return; }
  1860. }
  1861. public override bool CollidingObj
  1862. {
  1863. get { return false; }
  1864. set { return; }
  1865. }
  1866. public override bool ThrottleUpdates
  1867. {
  1868. get { return m_throttleUpdates; }
  1869. set { m_throttleUpdates = value; }
  1870. }
  1871. public override bool Stopped
  1872. {
  1873. get { return _zeroFlag; }
  1874. }
  1875. public override PhysicsVector Position
  1876. {
  1877. get { return _position; }
  1878. set { _position = value;
  1879. //m_log.Info("[PHYSICS]: " + _position.ToString());
  1880. }
  1881. }
  1882. public override PhysicsVector Size
  1883. {
  1884. get { return _size; }
  1885. set { _size = value; }
  1886. }
  1887. public override float Mass
  1888. {
  1889. get { return CalculateMass(); }
  1890. }
  1891. public override PhysicsVector Force
  1892. {
  1893. //get { return PhysicsVector.Zero; }
  1894. get { return m_force; }
  1895. set { m_force = value; }
  1896. }
  1897. public override int VehicleType
  1898. {
  1899. get { return 0; }
  1900. set { return; }
  1901. }
  1902. public override void VehicleFloatParam(int param, float value)
  1903. {
  1904. }
  1905. public override void VehicleVectorParam(int param, PhysicsVector value)
  1906. {
  1907. }
  1908. public override void VehicleRotationParam(int param, Quaternion rotation)
  1909. {
  1910. }
  1911. public override void SetVolumeDetect(int param)
  1912. {
  1913. lock (_parent_scene.OdeLock)
  1914. {
  1915. m_isVolumeDetect = (param!=0);
  1916. }
  1917. }
  1918. public override PhysicsVector CenterOfMass
  1919. {
  1920. get { return PhysicsVector.Zero; }
  1921. }
  1922. public override PhysicsVector GeometricCenter
  1923. {
  1924. get { return PhysicsVector.Zero; }
  1925. }
  1926. public override PrimitiveBaseShape Shape
  1927. {
  1928. set
  1929. {
  1930. _pbs = value;
  1931. m_taintshape = true;
  1932. }
  1933. }
  1934. public override PhysicsVector Velocity
  1935. {
  1936. get
  1937. {
  1938. // Averate previous velocity with the new one so
  1939. // client object interpolation works a 'little' better
  1940. PhysicsVector returnVelocity = new PhysicsVector();
  1941. returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2;
  1942. returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2;
  1943. returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2;
  1944. return returnVelocity;
  1945. }
  1946. set
  1947. {
  1948. _velocity = value;
  1949. m_taintVelocity = value;
  1950. _parent_scene.AddPhysicsActorTaint(this);
  1951. }
  1952. }
  1953. public override PhysicsVector Torque
  1954. {
  1955. get
  1956. {
  1957. if (!m_isphysical || Body == IntPtr.Zero)
  1958. return new PhysicsVector(0,0,0);
  1959. return _torque;
  1960. }
  1961. set
  1962. {
  1963. m_taintTorque = value;
  1964. _parent_scene.AddPhysicsActorTaint(this);
  1965. }
  1966. }
  1967. public override float CollisionScore
  1968. {
  1969. get { return m_collisionscore; }
  1970. set { m_collisionscore = value; }
  1971. }
  1972. public override bool Kinematic
  1973. {
  1974. get { return false; }
  1975. set { }
  1976. }
  1977. public override Quaternion Orientation
  1978. {
  1979. get { return _orientation; }
  1980. set { _orientation = value; }
  1981. }
  1982. public override PhysicsVector Acceleration
  1983. {
  1984. get { return _acceleration; }
  1985. }
  1986. public void SetAcceleration(PhysicsVector accel)
  1987. {
  1988. _acceleration = accel;
  1989. }
  1990. public override void AddForce(PhysicsVector force, bool pushforce)
  1991. {
  1992. m_forcelist.Add(force);
  1993. m_taintforce = true;
  1994. //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
  1995. }
  1996. public override void AddAngularForce(PhysicsVector force, bool pushforce)
  1997. {
  1998. m_angularforcelist.Add(force);
  1999. m_taintaddangularforce = true;
  2000. }
  2001. public override PhysicsVector RotationalVelocity
  2002. {
  2003. get
  2004. {
  2005. PhysicsVector pv = new PhysicsVector(0, 0, 0);
  2006. if (_zeroFlag)
  2007. return pv;
  2008. m_lastUpdateSent = false;
  2009. if (m_rotationalVelocity.IsIdentical(pv, 0.2f))
  2010. return pv;
  2011. return m_rotationalVelocity;
  2012. }
  2013. set { m_rotationalVelocity = value; }
  2014. }
  2015. public override void CrossingFailure()
  2016. {
  2017. m_crossingfailures++;
  2018. if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds)
  2019. {
  2020. base.RaiseOutOfBounds(_position);
  2021. return;
  2022. }
  2023. else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds)
  2024. {
  2025. m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
  2026. }
  2027. }
  2028. public override float Buoyancy
  2029. {
  2030. get { return m_buoyancy; }
  2031. set { m_buoyancy = value; }
  2032. }
  2033. public override void link(PhysicsActor obj)
  2034. {
  2035. m_taintparent = obj;
  2036. }
  2037. public override void delink()
  2038. {
  2039. m_taintparent = null;
  2040. }
  2041. public override void LockAngularMotion(PhysicsVector axis)
  2042. {
  2043. // reverse the zero/non zero values for ODE.
  2044. axis.X = (axis.X > 0) ? 1f : 0f;
  2045. axis.Y = (axis.Y > 0) ? 1f : 0f;
  2046. axis.Z = (axis.Z > 0) ? 1f : 0f;
  2047. m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
  2048. m_taintAngularLock = new PhysicsVector(axis.X, axis.Y, axis.Z); ;
  2049. }
  2050. public void UpdatePositionAndVelocity()
  2051. {
  2052. // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
  2053. if (_parent == null)
  2054. {
  2055. PhysicsVector pv = new PhysicsVector(0, 0, 0);
  2056. bool lastZeroFlag = _zeroFlag;
  2057. if (Body != (IntPtr)0) // FIXME -> or if it is a joint
  2058. {
  2059. d.Vector3 vec = d.BodyGetPosition(Body);
  2060. d.Quaternion ori = d.BodyGetQuaternion(Body);
  2061. d.Vector3 vel = d.BodyGetLinearVel(Body);
  2062. d.Vector3 rotvel = d.BodyGetAngularVel(Body);
  2063. d.Vector3 torque = d.BodyGetTorque(Body);
  2064. _torque.setValues(torque.X, torque.Y, torque.Z);
  2065. PhysicsVector l_position = new PhysicsVector();
  2066. Quaternion l_orientation = new Quaternion();
  2067. // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
  2068. //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  2069. //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  2070. //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  2071. //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
  2072. m_lastposition = _position;
  2073. m_lastorientation = _orientation;
  2074. l_position.X = vec.X;
  2075. l_position.Y = vec.Y;
  2076. l_position.Z = vec.Z;
  2077. l_orientation.X = ori.X;
  2078. l_orientation.Y = ori.Y;
  2079. l_orientation.Z = ori.Z;
  2080. l_orientation.W = ori.W;
  2081. if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f)
  2082. {
  2083. //base.RaiseOutOfBounds(l_position);
  2084. if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds)
  2085. {
  2086. _position = l_position;
  2087. //_parent_scene.remActivePrim(this);
  2088. if (_parent == null)
  2089. base.RequestPhysicsterseUpdate();
  2090. return;
  2091. }
  2092. else
  2093. {
  2094. if (_parent == null)
  2095. base.RaiseOutOfBounds(l_position);
  2096. return;
  2097. }
  2098. }
  2099. if (l_position.Z < 0)
  2100. {
  2101. // This is so prim that get lost underground don't fall forever and suck up
  2102. //
  2103. // Sim resources and memory.
  2104. // Disables the prim's movement physics....
  2105. // It's a hack and will generate a console message if it fails.
  2106. //IsPhysical = false;
  2107. if (_parent == null)
  2108. base.RaiseOutOfBounds(_position);
  2109. _acceleration.X = 0;
  2110. _acceleration.Y = 0;
  2111. _acceleration.Z = 0;
  2112. _velocity.X = 0;
  2113. _velocity.Y = 0;
  2114. _velocity.Z = 0;
  2115. m_rotationalVelocity.X = 0;
  2116. m_rotationalVelocity.Y = 0;
  2117. m_rotationalVelocity.Z = 0;
  2118. if (_parent == null)
  2119. base.RequestPhysicsterseUpdate();
  2120. m_throttleUpdates = false;
  2121. throttleCounter = 0;
  2122. _zeroFlag = true;
  2123. //outofBounds = true;
  2124. }
  2125. if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
  2126. && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
  2127. && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)
  2128. && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01 ))
  2129. {
  2130. _zeroFlag = true;
  2131. m_throttleUpdates = false;
  2132. }
  2133. else
  2134. {
  2135. //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
  2136. _zeroFlag = false;
  2137. }
  2138. if (_zeroFlag)
  2139. {
  2140. _velocity.X = 0.0f;
  2141. _velocity.Y = 0.0f;
  2142. _velocity.Z = 0.0f;
  2143. _acceleration.X = 0;
  2144. _acceleration.Y = 0;
  2145. _acceleration.Z = 0;
  2146. //_orientation.w = 0f;
  2147. //_orientation.X = 0f;
  2148. //_orientation.Y = 0f;
  2149. //_orientation.Z = 0f;
  2150. m_rotationalVelocity.X = 0;
  2151. m_rotationalVelocity.Y = 0;
  2152. m_rotationalVelocity.Z = 0;
  2153. if (!m_lastUpdateSent)
  2154. {
  2155. m_throttleUpdates = false;
  2156. throttleCounter = 0;
  2157. m_rotationalVelocity = pv;
  2158. if (_parent == null)
  2159. base.RequestPhysicsterseUpdate();
  2160. m_lastUpdateSent = true;
  2161. }
  2162. }
  2163. else
  2164. {
  2165. if (lastZeroFlag != _zeroFlag)
  2166. {
  2167. if (_parent == null)
  2168. base.RequestPhysicsterseUpdate();
  2169. }
  2170. m_lastVelocity = _velocity;
  2171. _position = l_position;
  2172. _velocity.X = vel.X;
  2173. _velocity.Y = vel.Y;
  2174. _velocity.Z = vel.Z;
  2175. _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
  2176. _acceleration = new PhysicsVector(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f);
  2177. //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
  2178. if (_velocity.IsIdentical(pv, 0.5f))
  2179. {
  2180. m_rotationalVelocity = pv;
  2181. }
  2182. else
  2183. {
  2184. m_rotationalVelocity.setValues(rotvel.X, rotvel.Y, rotvel.Z);
  2185. }
  2186. //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString());
  2187. _orientation.X = ori.X;
  2188. _orientation.Y = ori.Y;
  2189. _orientation.Z = ori.Z;
  2190. _orientation.W = ori.W;
  2191. m_lastUpdateSent = false;
  2192. if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate)
  2193. {
  2194. if (_parent == null)
  2195. base.RequestPhysicsterseUpdate();
  2196. }
  2197. else
  2198. {
  2199. throttleCounter++;
  2200. }
  2201. }
  2202. m_lastposition = l_position;
  2203. }
  2204. else
  2205. {
  2206. // Not a body.. so Make sure the client isn't interpolating
  2207. _velocity.X = 0;
  2208. _velocity.Y = 0;
  2209. _velocity.Z = 0;
  2210. _acceleration.X = 0;
  2211. _acceleration.Y = 0;
  2212. _acceleration.Z = 0;
  2213. m_rotationalVelocity.X = 0;
  2214. m_rotationalVelocity.Y = 0;
  2215. m_rotationalVelocity.Z = 0;
  2216. _zeroFlag = true;
  2217. }
  2218. }
  2219. }
  2220. public override bool FloatOnWater
  2221. {
  2222. set {
  2223. m_taintCollidesWater = value;
  2224. _parent_scene.AddPhysicsActorTaint(this);
  2225. }
  2226. }
  2227. public override void SetMomentum(PhysicsVector momentum)
  2228. {
  2229. }
  2230. public override PhysicsVector PIDTarget { set { m_PIDTarget = value; ; } }
  2231. public override bool PIDActive { set { m_usePID = value; } }
  2232. public override float PIDTau { set { m_PIDTau = value; } }
  2233. private void createAMotor(PhysicsVector axis)
  2234. {
  2235. if (Body == IntPtr.Zero)
  2236. return;
  2237. if (Amotor != IntPtr.Zero)
  2238. {
  2239. d.JointDestroy(Amotor);
  2240. Amotor = IntPtr.Zero;
  2241. }
  2242. float axisnum = 3;
  2243. axisnum = (axisnum - (axis.X + axis.Y + axis.Z));
  2244. if (axisnum <= 0)
  2245. return;
  2246. int dAMotorEuler = 1;
  2247. Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
  2248. d.JointAttach(Amotor, Body, IntPtr.Zero);
  2249. d.JointSetAMotorMode(Amotor, dAMotorEuler);
  2250. d.JointSetAMotorNumAxes(Amotor,(int)axisnum);
  2251. int i = 0;
  2252. if (axis.X == 0)
  2253. {
  2254. d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0);
  2255. i++;
  2256. }
  2257. if (axis.Y == 0)
  2258. {
  2259. d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0);
  2260. i++;
  2261. }
  2262. if (axis.Z == 0)
  2263. {
  2264. d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1);
  2265. i++;
  2266. }
  2267. for (int j = 0; j < (int)axisnum; j++)
  2268. {
  2269. //d.JointSetAMotorAngle(Amotor, j, 0);
  2270. }
  2271. //d.JointSetAMotorAngle(Amotor, 1, 0);
  2272. //d.JointSetAMotorAngle(Amotor, 2, 0);
  2273. // These lowstops and high stops are effectively (no wiggle room)
  2274. d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
  2275. d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
  2276. d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
  2277. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
  2278. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
  2279. d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
  2280. d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
  2281. d.JointSetAMotorParam(Amotor, (int)dParam.FMax, m_tensor * 5);//
  2282. }
  2283. public override void SubscribeEvents(int ms)
  2284. {
  2285. m_eventsubscription = ms;
  2286. _parent_scene.addCollisionEventReporting(this);
  2287. }
  2288. public override void UnSubscribeEvents()
  2289. {
  2290. _parent_scene.remCollisionEventReporting(this);
  2291. m_eventsubscription = 0;
  2292. }
  2293. public void AddCollisionEvent(uint CollidedWith, float depth)
  2294. {
  2295. if (CollisionEventsThisFrame == null)
  2296. CollisionEventsThisFrame = new CollisionEventUpdate();
  2297. CollisionEventsThisFrame.addCollider(CollidedWith,depth);
  2298. }
  2299. public void SendCollisions()
  2300. {
  2301. if (CollisionEventsThisFrame == null)
  2302. return;
  2303. base.SendCollisionUpdate(CollisionEventsThisFrame);
  2304. if (CollisionEventsThisFrame.m_objCollisionList.Count == 0)
  2305. CollisionEventsThisFrame = null;
  2306. else
  2307. CollisionEventsThisFrame = new CollisionEventUpdate();
  2308. }
  2309. public override bool SubscribedEvents()
  2310. {
  2311. if (m_eventsubscription > 0)
  2312. return true;
  2313. return false;
  2314. }
  2315. }
  2316. }