1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Threading;
- using log4net;
- using OpenMetaverse;
- using BulletDotNET;
- using OpenSim.Framework;
- using OpenSim.Region.Physics.Manager;
- namespace OpenSim.Region.Physics.BulletDotNETPlugin
- {
- public class BulletDotNETPrim : PhysicsActor
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private Vector3 _position;
- private Vector3 m_zeroPosition;
- private Vector3 _velocity;
- private Vector3 _torque;
- private Vector3 m_lastVelocity;
- private Vector3 m_lastposition;
- private Quaternion m_lastorientation = Quaternion.Identity;
- private Vector3 m_rotationalVelocity;
- private Vector3 _size;
- private Vector3 _acceleration;
- // private d.Vector3 _zeroPosition = new d.Vector3(0.0f, 0.0f, 0.0f);
- private Quaternion _orientation;
- private Vector3 m_taintposition;
- private Vector3 m_taintsize;
- private Vector3 m_taintVelocity;
- private Vector3 m_taintTorque;
- private Quaternion m_taintrot;
- private Vector3 m_angularlock = Vector3.One;
- private Vector3 m_taintAngularLock = Vector3.One;
- // private btGeneric6DofConstraint Amotor;
- private Vector3 m_PIDTarget;
- private float m_PIDTau;
- private float m_PIDHoverHeight;
- private float m_PIDHoverTau;
- private bool m_useHoverPID;
- private PIDHoverType m_PIDHoverType = PIDHoverType.Ground;
- private float m_targetHoverHeight;
- private float m_groundHeight;
- private float m_waterHeight;
- private float PID_D = 35f;
- private float PID_G = 25f;
- // private float m_tensor = 5f;
- // private int body_autodisable_frames = 20;
- private IMesh primMesh;
- private bool m_usePID;
- private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom
- | CollisionCategories.Space
- | CollisionCategories.Body
- | CollisionCategories.Character
- );
- private bool m_taintshape;
- private bool m_taintPhysics;
- // private bool m_collidesLand = true;
- private bool m_collidesWater;
- public bool m_returnCollisions;
- // Default we're a Geometry
- // private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
- // Default, Collide with Other Geometries, spaces and Bodies
- // private CollisionCategories m_collisionFlags = m_default_collisionFlags;
- public bool m_taintremove;
- public bool m_taintdisable;
- public bool m_disabled;
- public bool m_taintadd;
- public bool m_taintselected;
- public bool m_taintCollidesWater;
- public uint m_localID;
- //public GCHandle gc;
- // private CollisionLocker ode;
- private bool m_taintforce;
- private bool m_taintaddangularforce;
- private Vector3 m_force;
- private List<Vector3> m_forcelist = new List<Vector3>();
- private List<Vector3> m_angularforcelist = new List<Vector3>();
- private IMesh _mesh;
- private PrimitiveBaseShape _pbs;
- private BulletDotNETScene _parent_scene;
- public btCollisionShape prim_geom;
- public IntPtr _triMeshData;
- private PhysicsActor _parent;
- private PhysicsActor m_taintparent;
- private List<BulletDotNETPrim> childrenPrim = new List<BulletDotNETPrim>();
- private bool iscolliding;
- private bool m_isphysical;
- private bool m_isSelected;
- internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
- private bool m_throttleUpdates;
- // private int throttleCounter;
- public int m_interpenetrationcount;
- public float m_collisionscore;
- public int m_roundsUnderMotionThreshold;
- private int m_crossingfailures;
- public float m_buoyancy;
- public bool outofBounds;
- private float m_density = 10.000006836f; // Aluminum g/cm3;
- public bool _zeroFlag;
- private bool m_lastUpdateSent;
- private String m_primName;
- private Vector3 _target_velocity;
- public int m_eventsubscription;
- private int m_requestedUpdateFrequency = 0;
- private CollisionEventUpdate CollisionEventsThisFrame = null;
- public volatile bool childPrim;
- private btVector3 tempPosition1;
- private btVector3 tempPosition2;
- private btVector3 tempPosition3;
- private btVector3 tempSize1;
- private btVector3 tempSize2;
- private btVector3 tempLinearVelocity1;
- private btVector3 tempLinearVelocity2;
- private btVector3 tempAngularVelocity1;
- private btVector3 tempAngularVelocity2;
- private btVector3 tempInertia1;
- private btVector3 tempInertia2;
- private btVector3 tempAddForce;
- private btQuaternion tempOrientation1;
- private btQuaternion tempOrientation2;
- private btMotionState tempMotionState1;
- private btMotionState tempMotionState2;
- private btMotionState tempMotionState3;
- private btTransform tempTransform1;
- private btTransform tempTransform2;
- private btTransform tempTransform3;
- private btTransform tempTransform4;
- private btTriangleIndexVertexArray btshapeArray;
- private btVector3 AxisLockAngleHigh;
- private btVector3 AxisLockLinearLow;
- private btVector3 AxisLockLinearHigh;
- private bool forceenable = false;
- private btGeneric6DofConstraint m_aMotor;
- public btRigidBody Body;
- public BulletDotNETPrim(String primName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size,
- Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
- {
- tempPosition1 = new btVector3(0, 0, 0);
- tempPosition2 = new btVector3(0, 0, 0);
- tempPosition3 = new btVector3(0, 0, 0);
- tempSize1 = new btVector3(0, 0, 0);
- tempSize2 = new btVector3(0, 0, 0);
- tempLinearVelocity1 = new btVector3(0, 0, 0);
- tempLinearVelocity2 = new btVector3(0, 0, 0);
- tempAngularVelocity1 = new btVector3(0, 0, 0);
- tempAngularVelocity2 = new btVector3(0, 0, 0);
- tempInertia1 = new btVector3(0, 0, 0);
- tempInertia2 = new btVector3(0, 0, 0);
- tempOrientation1 = new btQuaternion(0, 0, 0, 1);
- tempOrientation2 = new btQuaternion(0, 0, 0, 1);
- _parent_scene = parent_scene;
- tempTransform1 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero);
- tempTransform2 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); ;
- tempTransform3 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); ;
- tempTransform4 = new btTransform(_parent_scene.QuatIdentity, _parent_scene.VectorZero); ;
- tempMotionState1 = new btDefaultMotionState(_parent_scene.TransZero);
- tempMotionState2 = new btDefaultMotionState(_parent_scene.TransZero);
- tempMotionState3 = new btDefaultMotionState(_parent_scene.TransZero);
- AxisLockLinearLow = new btVector3(-1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize, -1 * (int)Constants.RegionSize);
- int regionsize = (int)Constants.RegionSize;
- if (regionsize == 256)
- regionsize = 512;
- AxisLockLinearHigh = new btVector3((int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionSize);
- _target_velocity = Vector3.Zero;
- _velocity = Vector3.Zero;
- _position = pos;
- m_taintposition = pos;
- PID_D = parent_scene.bodyPIDD;
- PID_G = parent_scene.bodyPIDG;
- m_density = parent_scene.geomDefaultDensity;
- // m_tensor = parent_scene.bodyMotorJointMaxforceTensor;
- // body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
- prim_geom = null;
- Body = null;
- if (size.X <= 0) size.X = 0.01f;
- if (size.Y <= 0) size.Y = 0.01f;
- if (size.Z <= 0) size.Z = 0.01f;
- _size = size;
- m_taintsize = _size;
- _acceleration = Vector3.Zero;
- m_rotationalVelocity = Vector3.Zero;
- _orientation = rotation;
- m_taintrot = _orientation;
- _mesh = mesh;
- _pbs = pbs;
- _parent_scene = parent_scene;
- if (pos.Z < 0)
- m_isphysical = false;
- else
- {
- m_isphysical = pisPhysical;
- // If we're physical, we need to be in the master space for now.
- // linksets *should* be in a space together.. but are not currently
- }
- m_primName = primName;
- m_taintadd = true;
- _parent_scene.AddPhysicsActorTaint(this);
- }
- #region PhysicsActor overrides
- public override bool Stopped
- {
- get { return _zeroFlag; }
- }
- public override Vector3 Size
- {
- get { return _size; }
- set { _size = value; }
- }
- public override PrimitiveBaseShape Shape
- {
- set
- {
- _pbs = value;
- m_taintshape = true;
- }
- }
- public override uint LocalID
- {
- set
- {
- //m_log.Info("[PHYSICS]: Setting TrackerID: " + value);
- m_localID = value;
- }
- }
- public override bool Grabbed
- {
- set { return; }
- }
- public override bool Selected
- {
- set
- {
- // This only makes the object not collidable if the object
- // is physical or the object is modified somehow *IN THE FUTURE*
- // without this, if an avatar selects prim, they can walk right
- // through it while it's selected
- m_collisionscore = 0;
- if ((m_isphysical && !_zeroFlag) || !value)
- {
- m_taintselected = value;
- _parent_scene.AddPhysicsActorTaint(this);
- }
- else
- {
- m_taintselected = value;
- m_isSelected = value;
- }
- }
- }
- public override void CrossingFailure()
- {
- m_crossingfailures++;
- if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds)
- {
- base.RaiseOutOfBounds(_position);
- return;
- }
- else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds)
- {
- m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
- }
- }
- public override void link(PhysicsActor obj)
- {
- m_taintparent = obj;
- }
- public override void delink()
- {
- m_taintparent = null;
- }
- public override void LockAngularMotion(Vector3 axis)
- {
- m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
- m_taintAngularLock = axis;
- }
- public override Vector3 Position
- {
- get { return _position; }
- set
- {
- _position = value;
- //m_log.Info("[PHYSICS]: " + _position.ToString());
- }
- }
- public override float Mass
- {
- get { return CalculateMass(); }
- }
- public override Vector3 Force
- {
- //get { return Vector3.Zero; }
- get { return m_force; }
- set { m_force = value; }
- }
- public override int VehicleType
- {
- get { return 0; }
- set { return; }
- }
- public override void VehicleFloatParam(int param, float value)
- {
- //TODO:
- }
- public override void VehicleVectorParam(int param, Vector3 value)
- {
- //TODO:
- }
- public override void VehicleRotationParam(int param, Quaternion rotation)
- {
- //TODO:
- }
- public override void VehicleFlags(int param, bool remove)
- {
- }
- public override void SetVolumeDetect(int param)
- {
- //TODO: GhostObject
- m_isVolumeDetect = (param != 0);
- }
- public override Vector3 GeometricCenter
- {
- get { return Vector3.Zero; }
- }
- public override Vector3 CenterOfMass
- {
- get { return Vector3.Zero; }
- }
- public override Vector3 Velocity
- {
- get
- {
- // Averate previous velocity with the new one so
- // client object interpolation works a 'little' better
- Vector3 returnVelocity;
- returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2;
- returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2;
- returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2;
- return returnVelocity;
- }
- set
- {
- _velocity = value;
- m_taintVelocity = value;
- _parent_scene.AddPhysicsActorTaint(this);
- }
- }
- public override Vector3 Torque
- {
- get
- {
- if (!m_isphysical || Body.Handle == IntPtr.Zero)
- return Vector3.Zero;
- return _torque;
- }
- set
- {
- m_taintTorque = value;
- _parent_scene.AddPhysicsActorTaint(this);
- }
- }
- public override float CollisionScore
- {
- get { return m_collisionscore; }
- set { m_collisionscore = value; }
- }
- public override Vector3 Acceleration
- {
- get { return _acceleration; }
- }
- public override Quaternion Orientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
- public override int PhysicsActorType
- {
- get { return (int)ActorTypes.Prim; }
- set { return; }
- }
- public override bool IsPhysical
- {
- get { return m_isphysical; }
- set { m_isphysical = value; }
- }
- public override bool Flying
- {
- // no flying prims for you
- get { return false; }
- set { }
- }
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
- public override bool ThrottleUpdates
- {
- get { return m_throttleUpdates; }
- set { m_throttleUpdates = value; }
- }
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
- public override bool FloatOnWater
- {
- set
- {
- m_taintCollidesWater = value;
- _parent_scene.AddPhysicsActorTaint(this);
- }
- }
- public override Vector3 RotationalVelocity
- {
- get
- {
- Vector3 pv = Vector3.Zero;
- if (_zeroFlag)
- return pv;
- m_lastUpdateSent = false;
- if (m_rotationalVelocity.ApproxEquals(pv, 0.2f))
- return pv;
- return m_rotationalVelocity;
- }
- set { m_rotationalVelocity = value; }
- }
- public override bool Kinematic
- {
- get { return false; }
- set { }
- }
- public override float Buoyancy
- {
- get { return m_buoyancy; }
- set { m_buoyancy = value; }
- }
- public override Vector3 PIDTarget { set { m_PIDTarget = value; ; } }
- public override bool PIDActive { set { m_usePID = value; } }
- public override float PIDTau { set { m_PIDTau = value; } }
- public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
- public override bool PIDHoverActive { set { m_useHoverPID = value; } }
- public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
- public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
- public override Quaternion APIDTarget { set { return; } }
- public override bool APIDActive { set { return; } }
- public override float APIDStrength { set { return; } }
- public override float APIDDamping { set { return; } }
-
- public override void AddForce(Vector3 force, bool pushforce)
- {
- m_forcelist.Add(force);
- m_taintforce = true;
- //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
- }
- public override void AddAngularForce(Vector3 force, bool pushforce)
- {
- m_angularforcelist.Add(force);
- m_taintaddangularforce = true;
- }
- public override void SetMomentum(Vector3 momentum)
- {
- }
- public override void SubscribeEvents(int ms)
- {
- m_eventsubscription = ms;
- m_requestedUpdateFrequency = ms;
- _parent_scene.addCollisionEventReporting(this);
- }
- public override void UnSubscribeEvents()
- {
- _parent_scene.remCollisionEventReporting(this);
- m_eventsubscription = 0;
- m_requestedUpdateFrequency = 0;
- }
- public override bool SubscribedEvents()
- {
- return (m_eventsubscription > 0);
- }
- #endregion
- public void AddCollision(uint collideWith, ContactPoint contact)
- {
- if (CollisionEventsThisFrame == null)
- {
- CollisionEventsThisFrame = new CollisionEventUpdate();
- }
- CollisionEventsThisFrame.addCollider(collideWith, contact);
- }
- public void SendCollisions()
- {
- if (m_eventsubscription >= m_requestedUpdateFrequency)
- {
- if (CollisionEventsThisFrame != null)
- {
- base.SendCollisionUpdate(CollisionEventsThisFrame);
- }
- CollisionEventsThisFrame = null;
- // m_eventsubscription = 0;
- }
- return;
- }
- internal void Dispose()
- {
- //TODO:
- DisableAxisMotor();
- DisposeOfBody();
- SetCollisionShape(null);
- if (tempMotionState3 != null && tempMotionState3.Handle != IntPtr.Zero)
- {
- tempMotionState3.Dispose();
- tempMotionState3 = null;
- }
- if (tempMotionState2 != null && tempMotionState2.Handle != IntPtr.Zero)
- {
- tempMotionState2.Dispose();
- tempMotionState2 = null;
- }
- if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
- {
- tempMotionState1.Dispose();
- tempMotionState1 = null;
- }
- if (tempTransform4 != null && tempTransform4.Handle != IntPtr.Zero)
- {
- tempTransform4.Dispose();
- tempTransform4 = null;
- }
- if (tempTransform3 != null && tempTransform3.Handle != IntPtr.Zero)
- {
- tempTransform3.Dispose();
- tempTransform3 = null;
- }
- if (tempTransform2 != null && tempTransform2.Handle != IntPtr.Zero)
- {
- tempTransform2.Dispose();
- tempTransform2 = null;
- }
- if (tempTransform1 != null && tempTransform1.Handle != IntPtr.Zero)
- {
- tempTransform1.Dispose();
- tempTransform1 = null;
- }
- if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
- {
- tempOrientation2.Dispose();
- tempOrientation2 = null;
- }
- if (tempOrientation1 != null && tempOrientation1.Handle != IntPtr.Zero)
- {
- tempOrientation1.Dispose();
- tempOrientation1 = null;
- }
- if (tempInertia1 != null && tempInertia1.Handle != IntPtr.Zero)
- {
- tempInertia1.Dispose();
- tempInertia1 = null;
- }
- if (tempInertia2 != null && tempInertia2.Handle != IntPtr.Zero)
- {
- tempInertia2.Dispose();
- tempInertia1 = null;
- }
- if (tempAngularVelocity2 != null && tempAngularVelocity2.Handle != IntPtr.Zero)
- {
- tempAngularVelocity2.Dispose();
- tempAngularVelocity2 = null;
- }
- if (tempAngularVelocity1 != null && tempAngularVelocity1.Handle != IntPtr.Zero)
- {
- tempAngularVelocity1.Dispose();
- tempAngularVelocity1 = null;
- }
- if (tempLinearVelocity2 != null && tempLinearVelocity2.Handle != IntPtr.Zero)
- {
- tempLinearVelocity2.Dispose();
- tempLinearVelocity2 = null;
- }
- if (tempLinearVelocity1 != null && tempLinearVelocity1.Handle != IntPtr.Zero)
- {
- tempLinearVelocity1.Dispose();
- tempLinearVelocity1 = null;
- }
- if (tempSize2 != null && tempSize2.Handle != IntPtr.Zero)
- {
- tempSize2.Dispose();
- tempSize2 = null;
- }
- if (tempSize1 != null && tempSize1.Handle != IntPtr.Zero)
- {
- tempSize1.Dispose();
- tempSize1 = null;
- }
- if (tempPosition3 != null && tempPosition3.Handle != IntPtr.Zero)
- {
- tempPosition3.Dispose();
- tempPosition3 = null;
- }
- if (tempPosition2 != null && tempPosition2.Handle != IntPtr.Zero)
- {
- tempPosition2.Dispose();
- tempPosition2 = null;
- }
- if (tempPosition1 != null && tempPosition1.Handle != IntPtr.Zero)
- {
- tempPosition1.Dispose();
- tempPosition1 = null;
- }
- if (AxisLockLinearLow != null && AxisLockLinearLow.Handle != IntPtr.Zero)
- {
- AxisLockLinearLow.Dispose();
- AxisLockLinearLow = null;
- }
- if (AxisLockLinearHigh != null && AxisLockLinearHigh.Handle != IntPtr.Zero)
- {
- AxisLockLinearHigh.Dispose();
- AxisLockLinearHigh = null;
- }
- }
- public void ProcessTaints(float timestep)
- {
- if (m_taintadd)
- {
- // m_log.Debug("[PHYSICS]: TaintAdd");
- changeadd(timestep);
- }
- if (prim_geom == null)
- {
- CreateGeom(IntPtr.Zero, primMesh);
- if (IsPhysical)
- SetBody(Mass);
- else
- SetBody(0);
- // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
- }
- if (prim_geom.Handle == IntPtr.Zero)
- {
- CreateGeom(IntPtr.Zero, primMesh);
- if (IsPhysical)
- SetBody(Mass);
- else
- SetBody(0);
- // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
- }
- if (!_position.ApproxEquals(m_taintposition, 0f))
- {
- // m_log.Debug("[PHYSICS]: TaintMove");
- changemove(timestep);
- }
- if (m_taintrot != _orientation)
- {
- // m_log.Debug("[PHYSICS]: TaintRotate");
- rotate(timestep);
- } //
- if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent))
- {
- // m_log.Debug("[PHYSICS]: TaintPhysics");
- changePhysicsStatus(timestep);
- }
- //
- if (!_size.ApproxEquals(m_taintsize, 0f))
- {
- // m_log.Debug("[PHYSICS]: TaintSize");
- changesize(timestep);
- }
- //
- if (m_taintshape)
- {
- // m_log.Debug("[PHYSICS]: TaintShape");
- changeshape(timestep);
- } //
- if (m_taintforce)
- {
- // m_log.Debug("[PHYSICS]: TaintForce");
- changeAddForce(timestep);
- }
- if (m_taintaddangularforce)
- {
- // m_log.Debug("[PHYSICS]: TaintAngularForce");
- changeAddAngularForce(timestep);
- }
- if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
- {
- // m_log.Debug("[PHYSICS]: TaintTorque");
- changeSetTorque(timestep);
- }
- if (m_taintdisable)
- {
- // m_log.Debug("[PHYSICS]: TaintDisable");
- changedisable(timestep);
- }
- if (m_taintselected != m_isSelected)
- {
- // m_log.Debug("[PHYSICS]: TaintSelected");
- changeSelectedStatus(timestep);
- }
- if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
- {
- // m_log.Debug("[PHYSICS]: TaintVelocity");
- changevelocity(timestep);
- }
- if (m_taintparent != _parent)
- {
- // m_log.Debug("[PHYSICS]: TaintLink");
- changelink(timestep);
- }
- if (m_taintCollidesWater != m_collidesWater)
- {
- changefloatonwater(timestep);
- }
- if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0))
- {
- // m_log.Debug("[PHYSICS]: TaintAngularLock");
- changeAngularLock(timestep);
- }
- if (m_taintremove)
- {
- DisposeOfBody();
- Dispose();
- }
- }
- #region Physics Scene Change Action routines
- private void changeadd(float timestep)
- {
- //SetCollisionShape(null);
- // Construction of new prim
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- //Body.Dispose();
- }
- //Body = null;
- // TODO: dispose parts that make up body
- }
- if (_parent_scene.needsMeshing(_pbs))
- {
- // Don't need to re-enable body.. it's done in SetMesh
- float meshlod = _parent_scene.meshSculptLOD;
- if (IsPhysical)
- meshlod = _parent_scene.MeshSculptphysicalLOD;
- IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
- // createmesh returns null when it doesn't mesh.
- CreateGeom(IntPtr.Zero, mesh);
- }
- else
- {
- _mesh = null;
- CreateGeom(IntPtr.Zero, null);
- }
- if (IsPhysical)
- SetBody(Mass);
- else
- SetBody(0);
- //changeSelectedStatus(timestep);
- m_taintadd = false;
- }
- private void changemove(float timestep)
- {
- // m_log.Debug("[PHYSICS]: _________ChangeMove");
- if (!m_isphysical)
- {
- tempTransform2 = Body.getWorldTransform();
- btQuaternion quat = tempTransform2.getRotation();
- tempPosition2.setValue(_position.X, _position.Y, _position.Z);
- tempTransform2.Dispose();
- tempTransform2 = new btTransform(quat, tempPosition2);
- Body.setWorldTransform(tempTransform2);
- changeSelectedStatus(timestep);
- resetCollisionAccounting();
- }
- else
- {
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- //Body.Dispose();
- }
- //Body = null;
- // TODO: dispose parts that make up body
- }
- /*
- if (_parent_scene.needsMeshing(_pbs))
- {
- // Don't need to re-enable body.. it's done in SetMesh
- float meshlod = _parent_scene.meshSculptLOD;
- if (IsPhysical)
- meshlod = _parent_scene.MeshSculptphysicalLOD;
- IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
- // createmesh returns null when it doesn't mesh.
- CreateGeom(IntPtr.Zero, mesh);
- }
- else
- {
- _mesh = null;
- CreateGeom(IntPtr.Zero, null);
- }
- SetCollisionShape(prim_geom);
- */
- if (m_isphysical)
- SetBody(Mass);
- else
- SetBody(0);
- changeSelectedStatus(timestep);
- resetCollisionAccounting();
- }
- m_taintposition = _position;
- }
- private void rotate(float timestep)
- {
- // m_log.Debug("[PHYSICS]: _________ChangeRotate");
- tempTransform2 = Body.getWorldTransform();
- tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
- tempTransform2.setRotation(tempOrientation2);
- Body.setWorldTransform(tempTransform2);
- resetCollisionAccounting();
- m_taintrot = _orientation;
- }
- private void changePhysicsStatus(float timestep)
- {
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- //Body.Dispose();
- }
- //Body = null;
- // TODO: dispose parts that make up body
- }
- // m_log.Debug("[PHYSICS]: _________ChangePhysics");
- ProcessGeomCreation();
- if (m_isphysical)
- SetBody(Mass);
- else
- SetBody(0);
- changeSelectedStatus(timestep);
- resetCollisionAccounting();
- m_taintPhysics = m_isphysical;
- }
- internal void ProcessGeomCreation()
- {
- if (_parent_scene.needsMeshing(_pbs))
- {
- ProcessGeomCreationAsTriMesh(Vector3.Zero, Quaternion.Identity);
- // createmesh returns null when it doesn't mesh.
- CreateGeom(IntPtr.Zero, _mesh);
- }
- else
- {
- _mesh = null;
- CreateGeom(IntPtr.Zero, null);
- }
- SetCollisionShape(prim_geom);
- }
- internal bool NeedsMeshing()
- {
- return _parent_scene.needsMeshing(_pbs);
- }
- internal void ProcessGeomCreationAsTriMesh(Vector3 positionOffset, Quaternion orientation)
- {
- // Don't need to re-enable body.. it's done in SetMesh
- float meshlod = _parent_scene.meshSculptLOD;
- if (IsPhysical)
- meshlod = _parent_scene.MeshSculptphysicalLOD;
- IMesh mesh = _parent_scene.mesher.CreateMesh(SOPName, _pbs, _size, meshlod, IsPhysical);
- if (!positionOffset.ApproxEquals(Vector3.Zero, 0.001f) || orientation != Quaternion.Identity)
- {
- float[] xyz = new float[3];
- xyz[0] = positionOffset.X;
- xyz[1] = positionOffset.Y;
- xyz[2] = positionOffset.Z;
- Matrix4 m4 = Matrix4.CreateFromQuaternion(orientation);
- float[,] matrix = new float[3, 3];
- matrix[0, 0] = m4.M11;
- matrix[0, 1] = m4.M12;
- matrix[0, 2] = m4.M13;
- matrix[1, 0] = m4.M21;
- matrix[1, 1] = m4.M22;
- matrix[1, 2] = m4.M23;
- matrix[2, 0] = m4.M31;
- matrix[2, 1] = m4.M32;
- matrix[2, 2] = m4.M33;
- mesh.TransformLinear(matrix, xyz);
- }
- _mesh = mesh;
- }
- private void changesize(float timestep)
- {
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- //Body.Dispose();
- }
- //Body = null;
- // TODO: dispose parts that make up body
- }
- // m_log.Debug("[PHYSICS]: _________ChangeSize");
- SetCollisionShape(null);
- // Construction of new prim
- ProcessGeomCreation();
- if (IsPhysical)
- SetBody(Mass);
- else
- SetBody(0);
- m_taintsize = _size;
- }
- private void changeshape(float timestep)
- {
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- //Body.Dispose();
- }
- //Body = null;
- // TODO: dispose parts that make up body
- }
- // Cleanup of old prim geometry and Bodies
- if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero)
- {
- if (childPrim)
- {
- if (_parent != null)
- {
- BulletDotNETPrim parent = (BulletDotNETPrim)_parent;
- parent.ChildDelink(this);
- }
- }
- else
- {
- //disableBody();
- }
- }
- try
- {
- //SetCollisionShape(null);
- }
- catch (System.AccessViolationException)
- {
- //prim_geom = IntPtr.Zero;
- m_log.Error("[PHYSICS]: PrimGeom dead");
- }
- // we don't need to do space calculation because the client sends a position update also.
- if (_size.X <= 0) _size.X = 0.01f;
- if (_size.Y <= 0) _size.Y = 0.01f;
- if (_size.Z <= 0) _size.Z = 0.01f;
- // Construction of new prim
- ProcessGeomCreation();
- tempPosition1.setValue(_position.X, _position.Y, _position.Z);
- if (tempOrientation1.Handle != IntPtr.Zero)
- tempOrientation1.Dispose();
- tempOrientation1 = new btQuaternion(_orientation.X, Orientation.Y, _orientation.Z, _orientation.W);
- if (tempTransform1 != null && tempTransform1.Handle != IntPtr.Zero)
- tempTransform1.Dispose();
- tempTransform1 = new btTransform(tempOrientation1, tempPosition1);
- //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
- if (IsPhysical)
- {
- SetBody(Mass);
- // Re creates body on size.
- // EnableBody also does setMass()
- }
- else
- {
- SetBody(0);
- }
- changeSelectedStatus(timestep);
- if (childPrim)
- {
- if (_parent is BulletDotNETPrim)
- {
- BulletDotNETPrim parent = (BulletDotNETPrim)_parent;
- parent.ChildSetGeom(this);
- }
- }
- resetCollisionAccounting();
- m_taintshape = false;
- }
- private void resetCollisionAccounting()
- {
- m_collisionscore = 0;
- }
- private void ChildSetGeom(BulletDotNETPrim bulletDotNETPrim)
- {
- // TODO: throw new NotImplementedException();
- }
- private void changeAddForce(float timestep)
- {
- if (!m_isSelected)
- {
- lock (m_forcelist)
- {
- //m_log.Info("[PHYSICS]: dequeing forcelist");
- if (IsPhysical)
- {
- Vector3 iforce = Vector3.Zero;
- for (int i = 0; i < m_forcelist.Count; i++)
- {
- iforce = iforce + m_forcelist[i];
- }
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- if (tempAddForce != null && tempAddForce.Handle != IntPtr.Zero)
- tempAddForce.Dispose();
- enableBodySoft();
- tempAddForce = new btVector3(iforce.X, iforce.Y, iforce.Z);
- Body.applyCentralImpulse(tempAddForce);
- }
- }
- m_forcelist.Clear();
- }
- m_collisionscore = 0;
- m_interpenetrationcount = 0;
- }
- m_taintforce = false;
- }
- private void changeAddAngularForce(float timestep)
- {
- if (!m_isSelected)
- {
- lock (m_angularforcelist)
- {
- //m_log.Info("[PHYSICS]: dequeing forcelist");
- if (IsPhysical)
- {
- Vector3 iforce = Vector3.Zero;
- for (int i = 0; i < m_angularforcelist.Count; i++)
- {
- iforce = iforce + m_angularforcelist[i];
- }
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- if (tempAddForce != null && tempAddForce.Handle != IntPtr.Zero)
- tempAddForce.Dispose();
- enableBodySoft();
- tempAddForce = new btVector3(iforce.X, iforce.Y, iforce.Z);
- Body.applyTorqueImpulse(tempAddForce);
- }
- }
- m_angularforcelist.Clear();
- }
- m_collisionscore = 0;
- m_interpenetrationcount = 0;
- }
- m_taintaddangularforce = false;
- }
- private void changeSetTorque(float timestep)
- {
- if (!m_isSelected)
- {
- if (IsPhysical)
- {
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- tempAngularVelocity2.setValue(m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z);
- Body.applyTorque(tempAngularVelocity2);
- }
- }
- }
- m_taintTorque = Vector3.Zero;
- }
- private void changedisable(float timestep)
- {
- // TODO: throw new NotImplementedException();
- }
- private void changeSelectedStatus(float timestep)
- {
- // TODO: throw new NotImplementedException();
- if (m_taintselected)
- {
- // Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE);
- disableBodySoft();
- }
- else
- {
- // Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
- enableBodySoft();
- }
- m_isSelected = m_taintselected;
- }
- private void changevelocity(float timestep)
- {
- if (!m_isSelected)
- {
- if (IsPhysical)
- {
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- tempLinearVelocity2.setValue(m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
- Body.setLinearVelocity(tempLinearVelocity2);
- }
- }
- //resetCollisionAccounting();
- }
- m_taintVelocity = Vector3.Zero;
- }
- private void changelink(float timestep)
- {
- if (IsPhysical)
- {
- // Construction of new prim
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- //Body.Dispose();
- }
- //Body = null;
- // TODO: dispose parts that make up body
- }
- if (_parent == null && m_taintparent != null)
- {
- if (m_taintparent is BulletDotNETPrim)
- {
- BulletDotNETPrim obj = (BulletDotNETPrim)m_taintparent;
- obj.ParentPrim(this);
- childPrim = true;
- }
- }
- else if (_parent != null && m_taintparent == null)
- {
- if (_parent is BulletDotNETPrim)
- {
- BulletDotNETPrim obj = (BulletDotNETPrim)_parent;
- obj.ChildDelink(obj);
- childPrim = false;
- }
- }
- if (m_taintparent != null)
- {
- Vector3 taintparentPosition = m_taintparent.Position;
- taintparentPosition.Z = m_taintparent.Position.Z + 0.02f;
- m_taintparent.Position = taintparentPosition;
- _parent_scene.AddPhysicsActorTaint(m_taintparent);
- }
- }
- _parent = m_taintparent;
- m_taintPhysics = m_isphysical;
- }
- private void changefloatonwater(float timestep)
- {
- // TODO: throw new NotImplementedException();
- }
- private void changeAngularLock(float timestep)
- {
- if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero)
- {
- if (_parent == null)
- {
- if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f))
- {
- //d.BodySetFiniteRotationMode(Body, 0);
- //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z);
- EnableAxisMotor(m_taintAngularLock);
- }
- else
- {
- DisableAxisMotor();
- }
- }
- }
- m_angularlock = m_taintAngularLock;
- }
- #endregion
- internal void Move(float timestep)
- {
- //TODO:
- float fx = 0;
- float fy = 0;
- float fz = 0;
- if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero && !m_isSelected)
- {
- float m_mass = CalculateMass();
- fz = 0f;
- //m_log.Info(m_collisionFlags.ToString());
- if (m_buoyancy != 0)
- {
- if (m_buoyancy > 0)
- {
- fz = (((-1 * _parent_scene.gravityz) * m_buoyancy) * m_mass) * 0.035f;
- //d.Vector3 l_velocity = d.BodyGetLinearVel(Body);
- //m_log.Info("Using Buoyancy: " + buoyancy + " G: " + (_parent_scene.gravityz * m_buoyancy) + "mass:" + m_mass + " Pos: " + Position.ToString());
- }
- else
- {
- fz = (-1 * (((-1 * _parent_scene.gravityz) * (-1 * m_buoyancy)) * m_mass) * 0.035f);
- }
- }
- if (m_usePID)
- {
- PID_D = 61f;
- PID_G = 65f;
- //if (!d.BodyIsEnabled(Body))
- //d.BodySetForce(Body, 0f, 0f, 0f);
- // If we're using the PID controller, then we have no gravity
- fz = ((-1 * _parent_scene.gravityz) * m_mass) * 1.025f;
- // no lock; for now it's only called from within Simulate()
- // If the PID Controller isn't active then we set our force
- // calculating base velocity to the current position
- if ((m_PIDTau < 1) && (m_PIDTau != 0))
- {
- //PID_G = PID_G / m_PIDTau;
- m_PIDTau = 1;
- }
- if ((PID_G - m_PIDTau) <= 0)
- {
- PID_G = m_PIDTau + 1;
- }
- // TODO: NEED btVector3 for Linear Velocity
- // NEED btVector3 for Position
- Vector3 pos = _position; //TODO: Insert values gotten from bullet
- Vector3 vel = _velocity;
- _target_velocity =
- new Vector3(
- (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep),
- (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep),
- (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep)
- );
- if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
- {
- /* TODO: Do Bullet equiv
- *
- d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z);
- d.BodySetLinearVel(Body, 0, 0, 0);
- d.BodyAddForce(Body, 0, 0, fz);
- return;
- */
- }
- else
- {
- _zeroFlag = false;
- fx = ((_target_velocity.X) - vel.X) * (PID_D);
- fy = ((_target_velocity.Y) - vel.Y) * (PID_D);
- fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
- }
- }
- if (m_useHoverPID && !m_usePID)
- {
- // If we're using the PID controller, then we have no gravity
- fz = (-1 * _parent_scene.gravityz) * m_mass;
- // no lock; for now it's only called from within Simulate()
- // If the PID Controller isn't active then we set our force
- // calculating base velocity to the current position
- if ((m_PIDTau < 1))
- {
- PID_G = PID_G / m_PIDTau;
- }
- if ((PID_G - m_PIDTau) <= 0)
- {
- PID_G = m_PIDTau + 1;
- }
- Vector3 pos = Vector3.Zero; //TODO: Insert values gotten from bullet
- Vector3 vel = Vector3.Zero;
- // determine what our target height really is based on HoverType
- switch (m_PIDHoverType)
- {
- case PIDHoverType.Absolute:
- m_targetHoverHeight = m_PIDHoverHeight;
- break;
- case PIDHoverType.Ground:
- m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
- m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
- break;
- case PIDHoverType.GroundAndWater:
- m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y);
- m_waterHeight = _parent_scene.GetWaterLevel();
- if (m_groundHeight > m_waterHeight)
- {
- m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight;
- }
- else
- {
- m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
- }
- break;
- case PIDHoverType.Water:
- m_waterHeight = _parent_scene.GetWaterLevel();
- m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight;
- break;
- }
- _target_velocity =
- new Vector3(0.0f, 0.0f,
- (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep)
- );
- // if velocity is zero, use position control; otherwise, velocity control
- if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f))
- {
- /* TODO: Do Bullet Equiv
- d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
- d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
- d.BodyAddForce(Body, 0, 0, fz);
- */
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- Body.setLinearVelocity(_parent_scene.VectorZero);
- Body.clearForces();
- }
- return;
- }
- else
- {
- _zeroFlag = false;
- // We're flying and colliding with something
- fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
- }
- }
- fx *= m_mass;
- fy *= m_mass;
- //fz *= m_mass;
- fx += m_force.X;
- fy += m_force.Y;
- fz += m_force.Z;
- //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
- if (fx != 0 || fy != 0 || fz != 0)
- {
- /*
- * TODO: Do Bullet Equiv
- if (!d.BodyIsEnabled(Body))
- {
- d.BodySetLinearVel(Body, 0f, 0f, 0f);
- d.BodySetForce(Body, 0, 0, 0);
- enableBodySoft();
- }
- */
- if (!Body.isActive())
- {
- Body.clearForces();
- enableBodySoft();
- }
- // 35x10 = 350n times the mass per second applied maximum.
- float nmax = 35f * m_mass;
- float nmin = -35f * m_mass;
- if (fx > nmax)
- fx = nmax;
- if (fx < nmin)
- fx = nmin;
- if (fy > nmax)
- fy = nmax;
- if (fy < nmin)
- fy = nmin;
- // TODO: Do Bullet Equiv
- // d.BodyAddForce(Body, fx, fy, fz);
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- Body.activate(true);
- if (tempAddForce != null && tempAddForce.Handle != IntPtr.Zero)
- tempAddForce.Dispose();
- tempAddForce = new btVector3(fx * 0.01f, fy * 0.01f, fz * 0.01f);
- Body.applyCentralImpulse(tempAddForce);
- }
- }
- else
- {
- // if no forces on the prim, make sure everything is zero
- Body.clearForces();
- enableBodySoft();
- }
- }
- else
- {
- if (m_zeroPosition == null)
- m_zeroPosition = Vector3.Zero;
- m_zeroPosition = _position;
- return;
- }
- }
- #region Mass Calculation
- private float CalculateMass()
- {
- float volume = 0;
- // No material is passed to the physics engines yet.. soo..
- // we're using the m_density constant in the class definition
- float returnMass = 0;
- switch (_pbs.ProfileShape)
- {
- case ProfileShape.Square:
- // Profile Volume
- volume = _size.X * _size.Y * _size.Z;
- // If the user has 'hollowed out'
- // ProfileHollow is one of those 0 to 50000 values :P
- // we like percentages better.. so turning into a percentage
- if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
- {
- float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
- // calculate the hollow volume by it's shape compared to the prim shape
- float hollowVolume = 0;
- switch (_pbs.HollowShape)
- {
- case HollowShape.Square:
- case HollowShape.Same:
- // Cube Hollow volume calculation
- float hollowsizex = _size.X * hollowAmount;
- float hollowsizey = _size.Y * hollowAmount;
- float hollowsizez = _size.Z * hollowAmount;
- hollowVolume = hollowsizex * hollowsizey * hollowsizez;
- break;
- case HollowShape.Circle:
- // Hollow shape is a perfect cyllinder in respect to the cube's scale
- // Cyllinder hollow volume calculation
- float hRadius = _size.X / 2;
- float hLength = _size.Z;
- // pi * r2 * h
- hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
- break;
- case HollowShape.Triangle:
- // Equilateral Triangular Prism volume hollow calculation
- // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
- float aLength = _size.Y;
- // 1/2 abh
- hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
- break;
- default:
- hollowVolume = 0;
- break;
- }
- volume = volume - hollowVolume;
- }
- break;
- case ProfileShape.Circle:
- if (_pbs.PathCurve == (byte)Extrusion.Straight)
- {
- // Cylinder
- float volume1 = (float)(Math.PI * Math.Pow(_size.X / 2, 2) * _size.Z);
- float volume2 = (float)(Math.PI * Math.Pow(_size.Y / 2, 2) * _size.Z);
- // Approximating the cylinder's irregularity.
- if (volume1 > volume2)
- {
- volume = (float)volume1 - (volume1 - volume2);
- }
- else if (volume2 > volume1)
- {
- volume = (float)volume2 - (volume2 - volume1);
- }
- else
- {
- // Regular cylinder
- volume = volume1;
- }
- }
- else
- {
- // We don't know what the shape is yet, so use default
- volume = _size.X * _size.Y * _size.Z;
- }
- // If the user has 'hollowed out'
- // ProfileHollow is one of those 0 to 50000 values :P
- // we like percentages better.. so turning into a percentage
- if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
- {
- float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
- // calculate the hollow volume by it's shape compared to the prim shape
- float hollowVolume = 0;
- switch (_pbs.HollowShape)
- {
- case HollowShape.Same:
- case HollowShape.Circle:
- // Hollow shape is a perfect cyllinder in respect to the cube's scale
- // Cyllinder hollow volume calculation
- float hRadius = _size.X / 2;
- float hLength = _size.Z;
- // pi * r2 * h
- hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
- break;
- case HollowShape.Square:
- // Cube Hollow volume calculation
- float hollowsizex = _size.X * hollowAmount;
- float hollowsizey = _size.Y * hollowAmount;
- float hollowsizez = _size.Z * hollowAmount;
- hollowVolume = hollowsizex * hollowsizey * hollowsizez;
- break;
- case HollowShape.Triangle:
- // Equilateral Triangular Prism volume hollow calculation
- // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
- float aLength = _size.Y;
- // 1/2 abh
- hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
- break;
- default:
- hollowVolume = 0;
- break;
- }
- volume = volume - hollowVolume;
- }
- break;
- case ProfileShape.HalfCircle:
- if (_pbs.PathCurve == (byte)Extrusion.Curve1)
- {
- if (_size.X == _size.Y && _size.Z == _size.X)
- {
- // regular sphere
- // v = 4/3 * pi * r^3
- float sradius3 = (float)Math.Pow((_size.X / 2), 3);
- volume = (float)((4 / 3f) * Math.PI * sradius3);
- }
- else
- {
- // we treat this as a box currently
- volume = _size.X * _size.Y * _size.Z;
- }
- }
- else
- {
- // We don't know what the shape is yet, so use default
- volume = _size.X * _size.Y * _size.Z;
- }
- break;
- case ProfileShape.EquilateralTriangle:
- /*
- v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
- // seed mesh
- Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
- Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
- Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
- */
- float xA = -0.25f * _size.X;
- float yA = -0.45f * _size.Y;
- float xB = 0.5f * _size.X;
- float yB = 0;
- float xC = -0.25f * _size.X;
- float yC = 0.45f * _size.Y;
- volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z);
- // If the user has 'hollowed out'
- // ProfileHollow is one of those 0 to 50000 values :P
- // we like percentages better.. so turning into a percentage
- float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
- if (((float)fhollowFactor / 50000f) > 0.0)
- {
- float hollowAmount = (float)fhollowFactor / 50000f;
- // calculate the hollow volume by it's shape compared to the prim shape
- float hollowVolume = 0;
- switch (_pbs.HollowShape)
- {
- case HollowShape.Same:
- case HollowShape.Triangle:
- // Equilateral Triangular Prism volume hollow calculation
- // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
- float aLength = _size.Y;
- // 1/2 abh
- hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
- break;
- case HollowShape.Square:
- // Cube Hollow volume calculation
- float hollowsizex = _size.X * hollowAmount;
- float hollowsizey = _size.Y * hollowAmount;
- float hollowsizez = _size.Z * hollowAmount;
- hollowVolume = hollowsizex * hollowsizey * hollowsizez;
- break;
- case HollowShape.Circle:
- // Hollow shape is a perfect cyllinder in respect to the cube's scale
- // Cyllinder hollow volume calculation
- float hRadius = _size.X / 2;
- float hLength = _size.Z;
- // pi * r2 * h
- hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength) / 2) * hollowAmount);
- break;
- default:
- hollowVolume = 0;
- break;
- }
- volume = volume - hollowVolume;
- }
- break;
- default:
- // we don't have all of the volume formulas yet so
- // use the common volume formula for all
- volume = _size.X * _size.Y * _size.Z;
- break;
- }
- // Calculate Path cut effect on volume
- // Not exact, in the triangle hollow example
- // They should never be zero or less then zero..
- // we'll ignore it if it's less then zero
- // ProfileEnd and ProfileBegin are values
- // from 0 to 50000
- // Turning them back into percentages so that I can cut that percentage off the volume
- float PathCutEndAmount = _pbs.ProfileEnd;
- float PathCutStartAmount = _pbs.ProfileBegin;
- if (((PathCutStartAmount + PathCutEndAmount) / 50000f) > 0.0f)
- {
- float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount) / 50000f);
- // Check the return amount for sanity
- if (pathCutAmount >= 0.99f)
- pathCutAmount = 0.99f;
- volume = volume - (volume * pathCutAmount);
- }
- UInt16 taperX = _pbs.PathScaleX;
- UInt16 taperY = _pbs.PathScaleY;
- float taperFactorX = 0;
- float taperFactorY = 0;
- // Mass = density * volume
- if (taperX != 100)
- {
- if (taperX > 100)
- {
- taperFactorX = 1.0f - ((float)taperX / 200);
- //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
- }
- else
- {
- taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
- //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
- }
- volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
- }
- if (taperY != 100)
- {
- if (taperY > 100)
- {
- taperFactorY = 1.0f - ((float)taperY / 200);
- //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
- }
- else
- {
- taperFactorY = 1.0f - ((100 - (float)taperY) / 100);
- //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
- }
- volume = (float)volume * ((taperFactorY / 3f) + 0.001f);
- }
- returnMass = m_density * volume;
- if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero.
- // Recursively calculate mass
- bool HasChildPrim = false;
- lock (childrenPrim)
- {
- if (childrenPrim.Count > 0)
- {
- HasChildPrim = true;
- }
- }
- if (HasChildPrim)
- {
- BulletDotNETPrim[] childPrimArr = new BulletDotNETPrim[0];
- lock (childrenPrim)
- childPrimArr = childrenPrim.ToArray();
- for (int i = 0; i < childPrimArr.Length; i++)
- {
- if (childPrimArr[i] != null && !childPrimArr[i].m_taintremove)
- returnMass += childPrimArr[i].CalculateMass();
- // failsafe, this shouldn't happen but with OpenSim, you never know :)
- if (i > 256)
- break;
- }
- }
- return returnMass;
- }
- #endregion
- public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh)
- {
- // m_log.Debug("[PHYSICS]: _________CreateGeom");
- if (p_mesh != null)
- {
- //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
- _mesh = p_mesh;
- setMesh(_parent_scene, _mesh);
- }
- else
- {
- if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
- {
- if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
- {
- if (((_size.X / 2f) > 0f))
- {
- //SetGeom to a Regular Sphere
- if (tempSize1 == null)
- tempSize1 = new btVector3(0, 0, 0);
- tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
- SetCollisionShape(new btSphereShape(_size.X * 0.5f));
- }
- else
- {
- // uses halfextents
- if (tempSize1 == null)
- tempSize1 = new btVector3(0, 0, 0);
- tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
- SetCollisionShape(new btBoxShape(tempSize1));
- }
- }
- else
- {
- // uses halfextents
- if (tempSize1 == null)
- tempSize1 = new btVector3(0, 0, 0);
- tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
- SetCollisionShape(new btBoxShape(tempSize1));
- }
- }
- else
- {
- if (tempSize1 == null)
- tempSize1 = new btVector3(0, 0, 0);
- // uses halfextents
- tempSize1.setValue(_size.X * 0.5f, _size.Y * 0.5f, _size.Z * 0.5f);
- SetCollisionShape(new btBoxShape(tempSize1));
- }
- }
- }
- private void setMesh(BulletDotNETScene _parent_scene, IMesh mesh)
- {
- // TODO: Set Collision Body Mesh
- // This sleeper is there to moderate how long it takes between
- // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
- // m_log.Debug("_________SetMesh");
- Thread.Sleep(10);
- //Kill Body so that mesh can re-make the geom
- if (IsPhysical && Body != null && Body.Handle != IntPtr.Zero)
- {
- if (childPrim)
- {
- if (_parent != null)
- {
- BulletDotNETPrim parent = (BulletDotNETPrim)_parent;
- parent.ChildDelink(this);
- }
- }
- else
- {
- //disableBody();
- }
- }
- //IMesh oldMesh = primMesh;
- //primMesh = mesh;
- //float[] vertexList = primMesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
- //int[] indexList = primMesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
- ////Array.Reverse(indexList);
- //primMesh.releaseSourceMeshData(); // free up the original mesh data to save memory
- IMesh oldMesh = primMesh;
- primMesh = mesh;
- float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
- int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
- //Array.Reverse(indexList);
- mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
- int VertexCount = vertexList.GetLength(0) / 3;
- int IndexCount = indexList.GetLength(0);
- if (btshapeArray != null && btshapeArray.Handle != IntPtr.Zero)
- btshapeArray.Dispose();
- //Array.Reverse(indexList);
- btshapeArray = new btTriangleIndexVertexArray(IndexCount / 3, indexList, (3 * sizeof(int)),
- VertexCount, vertexList, 3 * sizeof(float));
- SetCollisionShape(new btGImpactMeshShape(btshapeArray));
- //((btGImpactMeshShape) prim_geom).updateBound();
- ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
- ((btGImpactMeshShape)prim_geom).updateBound();
- _parent_scene.SetUsingGImpact();
- //if (oldMesh != null)
- //{
- // oldMesh.releasePinned();
- // oldMesh = null;
- //}
- }
- private void SetCollisionShape(btCollisionShape shape)
- {
- /*
- if (shape == null)
- m_log.Debug("[PHYSICS]:SetShape!Null");
- else
- m_log.Debug("[PHYSICS]:SetShape!");
-
- if (Body != null)
- {
- DisposeOfBody();
- }
- if (prim_geom != null)
- {
- prim_geom.Dispose();
- prim_geom = null;
- }
- */
- prim_geom = shape;
- //Body.set
- }
- public void SetBody(float mass)
- {
- if (!IsPhysical || childrenPrim.Count == 0)
- {
- if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
- tempMotionState1.Dispose();
- if (tempTransform2 != null && tempTransform2.Handle != IntPtr.Zero)
- tempTransform2.Dispose();
- if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
- tempOrientation2.Dispose();
- if (tempPosition2 != null && tempPosition2.Handle != IntPtr.Zero)
- tempPosition2.Dispose();
- tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
- tempPosition2 = new btVector3(_position.X, _position.Y, _position.Z);
- tempTransform2 = new btTransform(tempOrientation2, tempPosition2);
- tempMotionState1 = new btDefaultMotionState(tempTransform2, _parent_scene.TransZero);
- if (tempInertia1 != null && tempInertia1.Handle != IntPtr.Zero)
- tempInertia1.Dispose();
- tempInertia1 = new btVector3(0, 0, 0);
- prim_geom.calculateLocalInertia(mass, tempInertia1);
- if (mass != 0)
- _parent_scene.addActivePrim(this);
- else
- _parent_scene.remActivePrim(this);
- // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
- //else
- // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
- if (Body == null)
- {
- Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
- // add localID so we can later map bullet object back to OpenSim object
- Body.setUserPointer(new IntPtr((int)m_localID));
- }
-
- if (prim_geom is btGImpactMeshShape)
- {
- ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
- ((btGImpactMeshShape)prim_geom).updateBound();
- }
- //Body.setCollisionFlags(Body.getCollisionFlags() | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
- //Body.setUserPointer((IntPtr) (int)m_localID);
- _parent_scene.AddPrimToScene(this);
- }
- else
- {
- // bool hasTrimesh = false;
- lock (childrenPrim)
- {
- foreach (BulletDotNETPrim chld in childrenPrim)
- {
- if (chld == null)
- continue;
- // if (chld.NeedsMeshing())
- // hasTrimesh = true;
- }
- }
- //if (hasTrimesh)
- //{
- ProcessGeomCreationAsTriMesh(Vector3.Zero, Quaternion.Identity);
- // createmesh returns null when it doesn't mesh.
- /*
- if (_mesh is Mesh)
- {
- }
- else
- {
- m_log.Warn("[PHYSICS]: Can't link a OpenSim.Region.Physics.Meshing.Mesh object");
- return;
- }
- */
- foreach (BulletDotNETPrim chld in childrenPrim)
- {
- if (chld == null)
- continue;
- Vector3 offset = chld.Position - Position;
- Vector3 pos = new Vector3(offset.X, offset.Y, offset.Z);
- pos *= Quaternion.Inverse(Orientation);
- //pos *= Orientation;
- offset = pos;
- chld.ProcessGeomCreationAsTriMesh(offset, chld.Orientation);
- _mesh.Append(chld._mesh);
- }
- setMesh(_parent_scene, _mesh);
- //}
- if (tempMotionState1 != null && tempMotionState1.Handle != IntPtr.Zero)
- tempMotionState1.Dispose();
- if (tempTransform2 != null && tempTransform2.Handle != IntPtr.Zero)
- tempTransform2.Dispose();
- if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
- tempOrientation2.Dispose();
- if (tempPosition2 != null && tempPosition2.Handle != IntPtr.Zero)
- tempPosition2.Dispose();
- tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
- tempPosition2 = new btVector3(_position.X, _position.Y, _position.Z);
- tempTransform2 = new btTransform(tempOrientation2, tempPosition2);
- tempMotionState1 = new btDefaultMotionState(tempTransform2, _parent_scene.TransZero);
- if (tempInertia1 != null && tempInertia1.Handle != IntPtr.Zero)
- tempInertia1.Dispose();
- tempInertia1 = new btVector3(0, 0, 0);
- prim_geom.calculateLocalInertia(mass, tempInertia1);
- if (mass != 0)
- _parent_scene.addActivePrim(this);
- else
- _parent_scene.remActivePrim(this);
- // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
- //else
- // Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
- if (Body == null)
- {
- Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
- // each body has the localID stored into it so we can identify collision objects
- Body.setUserPointer(new IntPtr((int)m_localID));
- }
- if (prim_geom is btGImpactMeshShape)
- {
- ((btGImpactMeshShape)prim_geom).setLocalScaling(new btVector3(1, 1, 1));
- ((btGImpactMeshShape)prim_geom).updateBound();
- }
- _parent_scene.AddPrimToScene(this);
- }
- if (IsPhysical)
- changeAngularLock(0);
- }
- private void DisposeOfBody()
- {
- if (Body != null)
- {
- if (Body.Handle != IntPtr.Zero)
- {
- DisableAxisMotor();
- _parent_scene.removeFromWorld(this, Body);
- Body.Dispose();
- }
- Body = null;
- // TODO: dispose parts that make up body
- }
- }
- private void ChildDelink(BulletDotNETPrim pPrim)
- {
- // Okay, we have a delinked child.. need to rebuild the body.
- lock (childrenPrim)
- {
- foreach (BulletDotNETPrim prm in childrenPrim)
- {
- prm.childPrim = true;
- prm.disableBody();
- }
- }
- disableBody();
- lock (childrenPrim)
- {
- childrenPrim.Remove(pPrim);
- }
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- _parent_scene.remActivePrim(this);
- }
- lock (childrenPrim)
- {
- foreach (BulletDotNETPrim prm in childrenPrim)
- {
- ParentPrim(prm);
- }
- }
- }
- internal void ParentPrim(BulletDotNETPrim prm)
- {
- if (prm == null)
- return;
- lock (childrenPrim)
- {
- if (!childrenPrim.Contains(prm))
- {
- childrenPrim.Add(prm);
- }
- }
- }
- public void disableBody()
- {
- //this kills the body so things like 'mesh' can re-create it.
- /*
- lock (this)
- {
- if (!childPrim)
- {
- if (Body != null && Body.Handle != IntPtr.Zero)
- {
- _parent_scene.remActivePrim(this);
- m_collisionCategories &= ~CollisionCategories.Body;
- m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
- if (prim_geom != null && prim_geom.Handle != IntPtr.Zero)
- {
- // TODO: Set Category bits and Flags
- }
- // TODO: destroy body
- DisposeOfBody();
- lock (childrenPrim)
- {
- if (childrenPrim.Count > 0)
- {
- foreach (BulletDotNETPrim prm in childrenPrim)
- {
- _parent_scene.remActivePrim(prm);
- prm.DisposeOfBody();
- prm.SetCollisionShape(null);
- }
- }
- }
- DisposeOfBody();
- }
- }
- else
- {
- _parent_scene.remActivePrim(this);
- m_collisionCategories &= ~CollisionCategories.Body;
- m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
- if (prim_geom != null && prim_geom.Handle != IntPtr.Zero)
- {
- // TODO: Set Category bits and Flags
- }
- DisposeOfBody();
- }
-
- }
- */
- DisableAxisMotor();
- m_disabled = true;
- m_collisionscore = 0;
- }
- public void disableBodySoft()
- {
- m_disabled = true;
- if (m_isphysical && Body.Handle != IntPtr.Zero)
- {
- Body.clearForces();
- Body.forceActivationState(0);
- }
- }
- public void enableBodySoft()
- {
- if (!childPrim)
- {
- if (m_isphysical && Body.Handle != IntPtr.Zero)
- {
- Body.clearForces();
- Body.forceActivationState(4);
- forceenable = true;
- }
- m_disabled = false;
- }
- }
- public void enableBody()
- {
- if (!childPrim)
- {
- //SetCollisionShape(prim_geom);
- if (IsPhysical)
- SetBody(Mass);
- else
- SetBody(0);
- // TODO: Set Collision Category Bits and Flags
- // TODO: Set Auto Disable data
- m_interpenetrationcount = 0;
- m_collisionscore = 0;
- m_disabled = false;
- // The body doesn't already have a finite rotation mode set here
- if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null)
- {
- // TODO: Create Angular Motor on Axis Lock!
- }
- _parent_scene.addActivePrim(this);
- }
- }
- public void UpdatePositionAndVelocity()
- {
- if (!m_isSelected)
- {
- if (_parent == null)
- {
- Vector3 pv = Vector3.Zero;
- bool lastZeroFlag = _zeroFlag;
- if (tempPosition3 != null && tempPosition3.Handle != IntPtr.Zero)
- tempPosition3.Dispose();
- if (tempTransform3 != null && tempTransform3.Handle != IntPtr.Zero)
- tempTransform3.Dispose();
- if (tempOrientation2 != null && tempOrientation2.Handle != IntPtr.Zero)
- tempOrientation2.Dispose();
- if (tempAngularVelocity1 != null && tempAngularVelocity1.Handle != IntPtr.Zero)
- tempAngularVelocity1.Dispose();
- if (tempLinearVelocity1 != null && tempLinearVelocity1.Handle != IntPtr.Zero)
- tempLinearVelocity1.Dispose();
- tempTransform3 = Body.getInterpolationWorldTransform();
- tempPosition3 = tempTransform3.getOrigin(); // vec
- tempOrientation2 = tempTransform3.getRotation(); // ori
- tempAngularVelocity1 = Body.getInterpolationAngularVelocity(); //rotvel
- tempLinearVelocity1 = Body.getInterpolationLinearVelocity(); // vel
- _torque = new Vector3(tempAngularVelocity1.getX(), tempAngularVelocity1.getX(),
- tempAngularVelocity1.getZ());
- Vector3 l_position = Vector3.Zero;
- Quaternion l_orientation = Quaternion.Identity;
- m_lastposition = _position;
- m_lastorientation = _orientation;
- l_position.X = tempPosition3.getX();
- l_position.Y = tempPosition3.getY();
- l_position.Z = tempPosition3.getZ();
- l_orientation.X = tempOrientation2.getX();
- l_orientation.Y = tempOrientation2.getY();
- l_orientation.Z = tempOrientation2.getZ();
- l_orientation.W = tempOrientation2.getW();
- if (l_position.X > ((int)Constants.RegionSize - 0.05f) || l_position.X < 0f || l_position.Y > ((int)Constants.RegionSize - 0.05f) || l_position.Y < 0f)
- {
- //base.RaiseOutOfBounds(l_position);
- if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds)
- {
- _position = l_position;
- //_parent_scene.remActivePrim(this);
- if (_parent == null)
- base.RequestPhysicsterseUpdate();
- return;
- }
- else
- {
- if (_parent == null)
- base.RaiseOutOfBounds(l_position);
- return;
- }
- }
- if (l_position.Z < -200000f)
- {
- // This is so prim that get lost underground don't fall forever and suck up
- //
- // Sim resources and memory.
- // Disables the prim's movement physics....
- // It's a hack and will generate a console message if it fails.
- //IsPhysical = false;
- //if (_parent == null)
- //base.RaiseOutOfBounds(_position);
- _acceleration.X = 0;
- _acceleration.Y = 0;
- _acceleration.Z = 0;
- _velocity.X = 0;
- _velocity.Y = 0;
- _velocity.Z = 0;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
- if (_parent == null)
- base.RequestPhysicsterseUpdate();
- m_throttleUpdates = false;
- // throttleCounter = 0;
- _zeroFlag = true;
- //outofBounds = true;
- }
- if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
- && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
- && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02)
- && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01))
- {
- _zeroFlag = true;
- m_throttleUpdates = false;
- }
- else
- {
- //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString());
- _zeroFlag = false;
- }
- if (_zeroFlag)
- {
- _velocity.X = 0.0f;
- _velocity.Y = 0.0f;
- _velocity.Z = 0.0f;
- _acceleration.X = 0;
- _acceleration.Y = 0;
- _acceleration.Z = 0;
- //_orientation.w = 0f;
- //_orientation.X = 0f;
- //_orientation.Y = 0f;
- //_orientation.Z = 0f;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
- if (!m_lastUpdateSent)
- {
- m_throttleUpdates = false;
- // throttleCounter = 0;
- m_rotationalVelocity = pv;
- if (_parent == null)
- base.RequestPhysicsterseUpdate();
- m_lastUpdateSent = true;
- }
- }
- else
- {
- if (lastZeroFlag != _zeroFlag)
- {
- if (_parent == null)
- base.RequestPhysicsterseUpdate();
- }
- m_lastVelocity = _velocity;
- _position = l_position;
- _velocity.X = tempLinearVelocity1.getX();
- _velocity.Y = tempLinearVelocity1.getY();
- _velocity.Z = tempLinearVelocity1.getZ();
- _acceleration = ((_velocity - m_lastVelocity) / 0.1f);
- _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f,
- _velocity.Y - m_lastVelocity.Y / 0.1f,
- _velocity.Z - m_lastVelocity.Z / 0.1f);
- //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString());
- if (_velocity.ApproxEquals(pv, 0.5f))
- {
- m_rotationalVelocity = pv;
- }
- else
- {
- m_rotationalVelocity = new Vector3(tempAngularVelocity1.getX(), tempAngularVelocity1.getY(), tempAngularVelocity1.getZ());
- }
- //m_log.Debug("ODE: " + m_rotationalVelocity.ToString());
- _orientation.X = l_orientation.X;
- _orientation.Y = l_orientation.Y;
- _orientation.Z = l_orientation.Z;
- _orientation.W = l_orientation.W;
- m_lastUpdateSent = false;
- //if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate)
- //{
- if (_parent == null)
- base.RequestPhysicsterseUpdate();
- // }
- // else
- // {
- // throttleCounter++;
- //}
- }
- m_lastposition = l_position;
- if (forceenable)
- {
- Body.forceActivationState(1);
- forceenable = false;
- }
- }
- else
- {
- // Not a body.. so Make sure the client isn't interpolating
- _velocity.X = 0;
- _velocity.Y = 0;
- _velocity.Z = 0;
- _acceleration.X = 0;
- _acceleration.Y = 0;
- _acceleration.Z = 0;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
- _zeroFlag = true;
- }
- }
- }
- internal void setPrimForRemoval()
- {
- m_taintremove = true;
- }
- internal void EnableAxisMotor(Vector3 axislock)
- {
- if (m_aMotor != null)
- DisableAxisMotor();
- if (Body == null)
- return;
- if (Body.Handle == IntPtr.Zero)
- return;
- if (AxisLockAngleHigh != null && AxisLockAngleHigh.Handle != IntPtr.Zero)
- AxisLockAngleHigh.Dispose();
- m_aMotor = new btGeneric6DofConstraint(Body, _parent_scene.TerrainBody, _parent_scene.TransZero,
- _parent_scene.TransZero, false);
- float endNoLock = (360 * Utils.DEG_TO_RAD);
- AxisLockAngleHigh = new btVector3((axislock.X == 0) ? 0 : endNoLock, (axislock.Y == 0) ? 0 : endNoLock, (axislock.Z == 0) ? 0 : endNoLock);
- m_aMotor.setAngularLowerLimit(_parent_scene.VectorZero);
- m_aMotor.setAngularUpperLimit(AxisLockAngleHigh);
- m_aMotor.setLinearLowerLimit(AxisLockLinearLow);
- m_aMotor.setLinearUpperLimit(AxisLockLinearHigh);
- _parent_scene.getBulletWorld().addConstraint((btTypedConstraint)m_aMotor);
- //m_aMotor.
- }
- internal void DisableAxisMotor()
- {
- if (m_aMotor != null && m_aMotor.Handle != IntPtr.Zero)
- {
- _parent_scene.getBulletWorld().removeConstraint(m_aMotor);
- m_aMotor.Dispose();
- m_aMotor = null;
- }
- }
- }
- }
|