12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954 |
- //
- // The multimedia graphics platform GLScene https://github.com/glscene
- //
- unit NGD.Manager;
- (*
- The Newton Game Dynamics Manager for GLScene.
- Notes: This code is still under development so any part of it may change at anytime.
- *)
- interface
- { .$I GLScene.inc }
- uses
- System.Classes, // TComponent TList TWriter TReader TPersistent
- System.SysUtils,
- System.Math, // Samevalue isZero to compare single
- System.Types,
- NGD.Import,
- /// NGD.Joints, // old joints
- /// NGD.NewtonImport, // new version 4.0
- GLS.VectorTypes,
- GLS.VectorGeometry, // PGLVector TGLVector TGLMatrix PGLMatrix NullHmgVector...
- GLS.VectorLists, // TGLAffineVectorList for Tree
- GLS.XCollection, // TXCollection file function
- GLS.GeometryBB, // For show debug
- GLS.BaseClasses,
- GLS.PersistentClasses,
- GLS.Scene,
- GLS.Manager,
- GLS.Coordinates,
- GLS.Objects,
- GLS.GeomObjects,
- GLS.VectorFileObjects, // cube cone freeform...
- GLS.Color;
- type
- TGLNGDHeightField = record
- heightArray: array of Word;
- width: Integer;
- depth: Integer;
- gridDiagonals: Boolean;
- widthDepthScale: Single;
- heightScale: Single;
- end;
- TGLNGDBehaviour = class;
- TGLNGDManager = class;
- TGLNGDSurfaceItem = class;
- TGLNGDJoint = class;
- TGLNGDSolverModels = (smExact = 0, smLinear1, smLinear2, smLinear3, smLinear4, smLinear5,
- smLinear6, smLinear7, smLinear8, smLinear9);
- TGLNGDFrictionModels = (fmExact = 0, fmAdaptive);
- TGLNGDPickedActions = (paAttach = 0, paMove, paDetach);
- TGLNGDManagerDebug = (mdShowGeometry, mdShowAABB, mdShowCenterOfMass, mdShowContact, mdShowJoint,
- mdShowForce, mdShowAppliedForce, mdShowAppliedVelocity);
- TGLNGDManagerDebugs = set of TGLNGDManagerDebug;
- TGLNGDCollisions = (nc_Primitive = 0, nc_Convex, nc_BBox, nc_BSphere, nc_Tree, nc_Mesh, nc_Null,
- nc_HeightField, nc_NGDFile);
- TGLNGDJoints = (nj_BallAndSocket, nj_Hinge, nj_Slider, nj_Corkscrew, nj_Universal,
- nj_CustomBallAndSocket, nj_CustomHinge, nj_CustomSlider, nj_UpVector, nj_KinematicController);
- TGLNGDBehaviourList = class(TList)
- protected
- function GetBehav(index: Integer): TGLNGDBehaviour;
- procedure PutBehav(index: Integer; Item: TGLNGDBehaviour);
- public
- property ItemsBehav[index: Integer]: TGLNGDBehaviour read GetBehav write PutBehav; default;
- end;
- // Events for Newton Callback
- TCollisionIteratorEvent = procedure(const userData: Pointer; vertexCount: Integer;
- const cfaceArray: PdFloat; faceId: Integer) of object;
- TApplyForceAndTorqueEvent = procedure(const cbody: PNewtonBody; timestep: dFloat;
- threadIndex: Integer) of object;
- TSetTransformEvent = procedure(const cbody: PNewtonBody; const cmatrix: PdFloat;
- threadIndex: Integer) of object;
- TSerializeEvent = procedure(serializeHandle: Pointer; const cbuffer: Pointer; size: Cardinal)
- of object;
- TDeSerializeEvent = procedure(serializeHandle: Pointer; buffer: Pointer; size: Cardinal)
- of object;
- TAABBOverlapEvent = function(const cmaterial: PNewtonMaterial; const cbody0: PNewtonBody;
- const cbody1: PNewtonBody; threadIndex: Integer): Boolean of object;
- TContactProcessEvent = procedure(const ccontact: PNewtonJoint; timestep: dFloat;
- threadIndex: Integer) of object;
- TGLNGDDebugOption = class(TPersistent)
- strict private
- FManager: TGLNGDManager;
- FGeomColorDyn: TGLColor; // Green
- FGeomColorStat: TGLColor; // Red
- FAABBColor: TGLColor; // Yellow
- FAABBColorSleep: TGLColor; // Orange
- FCenterOfMassColor: TGLColor; // Purple dot
- FContactColor: TGLColor; // White
- FJointAxisColor: TGLColor; // Blue
- FJointPivotColor: TGLColor; // Aquamarine
- FForceColor: TGLColor; // Black
- FAppliedForceColor: TGLColor; // Silver
- FAppliedVelocityColor: TGLColor; // Lime
- FCustomColor: TGLColor; // Aqua
- FDotAxisSize: Single; // 1
- FManagerDebugs: TGLNGDManagerDebugs; // Default All false
- procedure SetManagerDebugs(const Value: TGLNGDManagerDebugs);
- procedure SetDotAxisSize(const Value: Single);
- function StoredDotAxis: Boolean;
- public
- constructor Create(AOwner: TComponent);
- destructor Destroy; override;
- published
- property GeomColorDyn: TGLColor read FGeomColorDyn write FGeomColorDyn;
- property GeomColorStat: TGLColor read FGeomColorStat write FGeomColorStat;
- property AABBColor: TGLColor read FAABBColor write FAABBColor;
- property AABBColorSleep: TGLColor read FAABBColorSleep write FAABBColorSleep;
- property CenterOfMassColor: TGLColor read FCenterOfMassColor write FCenterOfMassColor;
- property ContactColor: TGLColor read FContactColor write FContactColor;
- property JointAxisColor: TGLColor read FJointAxisColor write FJointAxisColor;
- property JointPivotColor: TGLColor read FJointPivotColor write FJointPivotColor;
- property ForceColor: TGLColor read FForceColor write FForceColor;
- property AppliedForceColor: TGLColor read FAppliedForceColor write FAppliedForceColor;
- property AppliedVelocityColor: TGLColor read FAppliedVelocityColor write FAppliedVelocityColor;
- property CustomColor: TGLColor read FCustomColor write FCustomColor;
- property NGDManagerDebugs: TGLNGDManagerDebugs read FManagerDebugs write SetManagerDebugs
- default [];
- property DotAxisSize: Single read FDotAxisSize write SetDotAxisSize stored StoredDotAxis;
- end;
- TGLNGDManager = class(TComponent)
- strict private
- FVisible: Boolean; // Show Debug at design time
- FVisibleAtRunTime: Boolean; // Show Debug at run time
- FDllVersion: Integer;
- FSolverModel: TGLNGDSolverModels; // Default=Exact
- FFrictionModel: TGLNGDFrictionModels; // Default=Exact
- FMinimumFrameRate: Integer; // Default=60
- FWorldSizeMin: TGLCoordinates; // Default=-100, -100, -100
- FWorldSizeMax: TGLCoordinates; // Default=100, 100, 100
- FThreadCount: Integer; // Default=1
- FGravity: TGLCoordinates; // Default=(0,-9.81,0)
- FNewtonSurfaceItem: TCollection;
- FNewtonSurfacePair: TOwnedCollection;
- FNewtonJointGroup: TOwnedCollection;
- FNewtonDebugOption: TGLNGDDebugOption;
- FGLLines: TGLLines;
- private
- FNewtonWorld: PNewtonWorld;
- FNGDBehaviours: TGLNGDBehaviourList;
- FCurrentColor: TGLColor;
- protected
- procedure Loaded; override;
- procedure SetVisible(const Value: Boolean);
- procedure SetVisibleAtRunTime(const Value: Boolean);
- procedure SetSolverModel(const Value: TGLNGDSolverModels);
- procedure SetFrictionModel(const Value: TGLNGDFrictionModels);
- procedure SetMinimumFrameRate(const Value: Integer);
- procedure SetThreadCount(const Value: Integer);
- procedure SetGLLines(const Value: TGLLines);
- function GetBodyCount: Integer;
- function GetConstraintCount: Integer;
- procedure AddNode(const coords: TGLCustomCoordinates); overload;
- procedure AddNode(const X, Y, Z: Single); overload;
- procedure AddNode(const Value: TGLVector); overload;
- procedure AddNode(const Value: TAffineVector); overload;
- procedure RebuildAllMaterial;
- procedure RebuildAllJoint(Sender: TObject);
- // Events
- procedure NotifyWorldSizeChange(Sender: TObject);
- procedure NotifyChange(Sender: TObject); // Debug view
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Step(deltatime: Single);
- published
- property Visible: Boolean read FVisible write SetVisible default True;
- property VisibleAtRunTime: Boolean read FVisibleAtRunTime write SetVisibleAtRunTime
- default False;
- property SolverModel: TGLNGDSolverModels read FSolverModel write SetSolverModel default smExact;
- property FrictionModel: TGLNGDFrictionModels read FFrictionModel write SetFrictionModel
- default fmExact;
- property MinimumFrameRate: Integer read FMinimumFrameRate write SetMinimumFrameRate default 60;
- property ThreadCount: Integer read FThreadCount write SetThreadCount default 1;
- property DllVersion: Integer read FDllVersion;
- property NewtonBodyCount: Integer read GetBodyCount;
- property NewtonConstraintCount: Integer read GetConstraintCount;
- property Gravity: TGLCoordinates read FGravity write FGravity;
- property WorldSizeMin: TGLCoordinates read FWorldSizeMin write FWorldSizeMin;
- property WorldSizeMax: TGLCoordinates read FWorldSizeMax write FWorldSizeMax;
- property NewtonSurfaceItem: TCollection read FNewtonSurfaceItem write FNewtonSurfaceItem;
- property NewtonSurfacePair: TOwnedCollection read FNewtonSurfacePair write FNewtonSurfacePair;
- property DebugOption: TGLNGDDebugOption read FNewtonDebugOption write FNewtonDebugOption;
- property Line: TGLLines read FGLLines write SetGLLines;
- property NewtonJoint: TOwnedCollection read FNewtonJointGroup write FNewtonJointGroup;
- end;
- // Basis structures for Behaviour style implementations.
- TGLNGDBehaviour = class(TGLBehaviour)
- private
- FManager: TGLNGDManager;
- FManagerName: string;
- FInitialized: Boolean;
- FNewtonBody: PNewtonBody;
- FCollision: PNewtonCollision;
- FNewtonBodyMatrix: TGLMatrix; // Position and Orientation
- FContinuousCollisionMode: Boolean; // Default=False
- FNewtonCollisions: TGLNGDCollisions;
- FCollisionIteratorEvent: TCollisionIteratorEvent;
- FOwnerBaseSceneObject: TGLBaseSceneObject;
- // FNullCollisionMass: Single; // Default=0
- FTreeCollisionOptimize: Boolean; // Default=True
- FConvexCollisionTolerance: Single; // Default=0.01 1%
- FFileCollision: string;
- FSurfaceItem: TGLNGDSurfaceItem;
- FHeightFieldOptions: TGLNGDHeightField;
- protected
- procedure Initialize; virtual;
- procedure Finalize; virtual;
- procedure WriteToFiler(writer: TWriter); override;
- procedure ReadFromFiler(reader: TReader); override;
- procedure Loaded; override;
- procedure SetManager(Value: TGLNGDManager);
- procedure SetNewtonBodyMatrix(const Value: TGLMatrix);
- procedure SetContinuousCollisionMode(const Value: Boolean);
- function GetNewtonBodyMatrix: TGLMatrix;
- function GetNewtonBodyAABB: TAABB;
- procedure UpdCollision; virtual;
- procedure Render; virtual;
- procedure SetNewtonCollisions(const Value: TGLNGDCollisions);
- procedure SetNewtonSurfaceItem(const Value: TGLNGDSurfaceItem);
- procedure SetHeightFieldOptions(const Value: TGLNGDHeightField);
- function GetPrimitiveCollision(): PNewtonCollision;
- function GetConvexCollision(): PNewtonCollision;
- function GetBBoxCollision(): PNewtonCollision;
- function GetBSphereCollision(): PNewtonCollision;
- function GetTreeCollision(): PNewtonCollision;
- function GetMeshCollision(): PNewtonCollision;
- function GetNullCollision(): PNewtonCollision;
- function GetHeightFieldCollision(): PNewtonCollision;
- function GetNGDFileCollision(): PNewtonCollision;
- function StoredTolerance: Boolean;
- // Event
- procedure OnCollisionIteratorEvent(const userData: Pointer; vertexCount: Integer;
- const cfaceArray: PdFloat; faceId: Integer);
- // CallBack
- class procedure NewtonCollisionIterator(const userData: Pointer; vertexCount: Integer;
- const faceArray: PdFloat; faceId: Integer); static; cdecl;
- class procedure NewtonSerialize(serializeHandle: Pointer; const buffer: Pointer;
- size: Cardinal); static; cdecl;
- class procedure NewtonDeserialize(serializeHandle: Pointer; buffer: Pointer; size: Cardinal);
- static; cdecl;
- public
- constructor Create(AOwner: TXCollection); override;
- destructor Destroy; override;
- procedure Reinitialize;
- property Initialized: Boolean read FInitialized;
- class function UniqueItem: Boolean; override;
- property NewtonBodyMatrix: TGLMatrix read GetNewtonBodyMatrix write SetNewtonBodyMatrix;
- property NewtonBodyAABB: TAABB read GetNewtonBodyAABB;
- procedure Serialize(filename: string);
- procedure DeSerialize(filename: string);
- property HeightFieldOptions: TGLNGDHeightField read FHeightFieldOptions
- write SetHeightFieldOptions;
- published
- property Manager: TGLNGDManager read FManager write SetManager;
- property ContinuousCollisionMode: Boolean read FContinuousCollisionMode
- write SetContinuousCollisionMode default False;
- property NGDNewtonCollisions: TGLNGDCollisions read FNewtonCollisions write SetNewtonCollisions
- default nc_Primitive;
- property TreeCollisionOptimize: Boolean read FTreeCollisionOptimize write FTreeCollisionOptimize
- default True;
- property ConvexCollisionTolerance: Single read FConvexCollisionTolerance
- write FConvexCollisionTolerance stored StoredTolerance;
- property FileCollision: string read FFileCollision write FFileCollision;
- property NGDSurfaceItem: TGLNGDSurfaceItem read FSurfaceItem write SetNewtonSurfaceItem;
- end;
- TGLNGDDynamic = class(TGLNGDBehaviour)
- strict private
- FAABBmin: TGLCoordinates;
- FAABBmax: TGLCoordinates;
- FForce: TGLCoordinates;
- FTorque: TGLCoordinates;
- FCenterOfMass: TGLCoordinates;
- FAutoSleep: Boolean; // Default=True
- FLinearDamping: Single; // default=0.1
- FAngularDamping: TGLCoordinates; // Default=0.1
- FDensity: Single; // Default=1
- FUseGravity: Boolean; // Default=True
- FNullCollisionVolume: Single; // Default=0
- FApplyForceAndTorqueEvent: TApplyForceAndTorqueEvent;
- FSetTransformEvent: TSetTransformEvent;
- FCustomForceAndTorqueEvent: TApplyForceAndTorqueEvent;
- // Read Only
- FVolume: Single;
- FMass: Single;
- FAppliedForce: TGLCoordinates;
- FAppliedTorque: TGLCoordinates;
- FAppliedOmega: TGLCoordinates;
- FAppliedVelocity: TGLCoordinates;
- function StoredDensity: Boolean;
- function StoredLinearDamping: Boolean;
- function StoredNullCollisionVolume: Boolean;
- protected
- procedure SetAutoSleep(const Value: Boolean);
- procedure SetLinearDamping(const Value: Single);
- procedure SetDensity(const Value: Single); virtual;
- procedure Initialize; override;
- procedure Finalize; override;
- procedure WriteToFiler(writer: TWriter); override;
- procedure ReadFromFiler(reader: TReader); override;
- procedure Loaded; override;
- procedure Render; override;
- // Events
- procedure NotifyCenterOfMassChange(Sender: TObject);
- procedure NotifyAngularDampingChange(Sender: TObject);
- procedure OnApplyForceAndTorqueEvent(const cbody: PNewtonBody; timestep: dFloat;
- threadIndex: Integer);
- procedure OnSetTransformEvent(const cbody: PNewtonBody; const cmatrix: PdFloat;
- threadIndex: Integer);
- // Callback
- class procedure NewtonApplyForceAndTorque(const body: PNewtonBody; timestep: dFloat;
- threadIndex: Integer); static; cdecl;
- class procedure NewtonSetTransform(const body: PNewtonBody; const matrix: PdFloat;
- threadIndex: Integer); static; cdecl;
- public
- constructor Create(AOwner: TXCollection); override;
- destructor Destroy; override;
- procedure AddImpulse(const veloc, pointposit: TGLVector);
- function GetOmega: TGLVector;
- procedure SetOmega(const Omega: TGLVector);
- function GetVelocity: TGLVector;
- procedure SetVelocity(const Velocity: TGLVector);
- class function FriendlyName: string; override;
- property CustomForceAndTorqueEvent: TApplyForceAndTorqueEvent read FCustomForceAndTorqueEvent
- write FCustomForceAndTorqueEvent;
- property Velocity: TGLVector read GetVelocity write SetVelocity;
- property Omega: TGLVector read GetOmega write SetOmega;
- published
- property Force: TGLCoordinates read FForce write FForce;
- property Torque: TGLCoordinates read FTorque write FTorque;
- property CenterOfMass: TGLCoordinates read FCenterOfMass write FCenterOfMass;
- property AutoSleep: Boolean read FAutoSleep write SetAutoSleep default True;
- property LinearDamping: Single read FLinearDamping write SetLinearDamping
- stored StoredLinearDamping;
- property AngularDamping: TGLCoordinates read FAngularDamping write FAngularDamping;
- property Density: Single read FDensity write SetDensity stored StoredDensity;
- property UseGravity: Boolean read FUseGravity write FUseGravity default True;
- property NullCollisionVolume: Single read FNullCollisionVolume write FNullCollisionVolume
- stored StoredNullCollisionVolume;
- // Read Only
- property AppliedOmega: TGLCoordinates read FAppliedOmega;
- property AppliedVelocity: TGLCoordinates read FAppliedVelocity;
- property AppliedForce: TGLCoordinates read FAppliedForce;
- property AppliedTorque: TGLCoordinates read FAppliedTorque;
- property Volume: Single read FVolume;
- property Mass: Single read FMass;
- end;
- TGLNGDStatic = class(TGLNGDBehaviour)
- protected
- procedure Render; override;
- public
- class function FriendlyName: string; override;
- published
- end;
- TGLNGDSurfaceItem = class(TCollectionItem)
- private
- FDisplayName: string;
- protected
- function GetDisplayName: string; override;
- procedure SetDisplayName(const Value: string); override;
- published
- property DisplayName;
- property ID;
- end;
- TGLNGDSurfacePair = class(TCollectionItem)
- strict private
- FManager: TGLNGDManager;
- FSurfaceItem1: TGLNGDSurfaceItem;
- FSurfaceItem2: TGLNGDSurfaceItem;
- FAABBOverlapEvent: TAABBOverlapEvent;
- FContactProcessEvent: TContactProcessEvent;
- FSoftness: Single; // 0.1
- FElasticity: Single; // 0.4
- FCollidable: Boolean; // true
- FStaticFriction: Single; // 0.9
- FKineticFriction: Single; // 0.5
- FContinuousCollisionMode: Boolean; // False
- FThickness: Boolean; // False
- procedure SetCollidable(const Value: Boolean);
- procedure SetElasticity(const Value: Single);
- procedure SetKineticFriction(const Value: Single);
- procedure SetSoftness(const Value: Single);
- procedure SetStaticFriction(const Value: Single);
- procedure SetContinuousCollisionMode(const Value: Boolean);
- procedure SetThickness(const Value: Boolean);
- function StoredElasticity: Boolean;
- function StoredKineticFriction: Boolean;
- function StoredSoftness: Boolean;
- function StoredStaticFriction: Boolean;
- private
- // Callback
- class function NewtonAABBOverlap(const material: PNewtonMaterial; const body0: PNewtonBody;
- const body1: PNewtonBody; threadIndex: Integer): Integer; static; cdecl;
- class procedure NewtonContactsProcess(const contact: PNewtonJoint; timestep: dFloat;
- threadIndex: Integer); static; cdecl;
- // Event
- function OnNewtonAABBOverlapEvent(const cmaterial: PNewtonMaterial; const cbody0: PNewtonBody;
- const cbody1: PNewtonBody; threadIndex: Integer): Boolean;
- procedure OnNewtonContactsProcessEvent(const ccontact: PNewtonJoint; timestep: dFloat;
- threadIndex: Integer);
- public
- constructor Create(Collection: TCollection); override;
- procedure SetMaterialItems(const item1, item2: TGLNGDSurfaceItem);
- property NGDSurfaceItem1: TGLNGDSurfaceItem read FSurfaceItem1;
- property NGDSurfaceItem2: TGLNGDSurfaceItem read FSurfaceItem2;
- published
- property Softness: Single read FSoftness write SetSoftness stored StoredSoftness;
- property Elasticity: Single read FElasticity write SetElasticity stored StoredElasticity;
- property Collidable: Boolean read FCollidable write SetCollidable default True;
- property StaticFriction: Single read FStaticFriction write SetStaticFriction
- stored StoredStaticFriction;
- property KineticFriction: Single read FKineticFriction write SetKineticFriction
- stored StoredKineticFriction;
- property ContinuousCollisionMode: Boolean read FContinuousCollisionMode
- write SetContinuousCollisionMode default False;
- property Thickness: Boolean read FThickness write SetThickness default False;
- property ContactProcessEvent: TContactProcessEvent read FContactProcessEvent
- write FContactProcessEvent;
- property AABBOverlapEvent: TAABBOverlapEvent read FAABBOverlapEvent write FAABBOverlapEvent;
- end;
- TGLNGDJointPivot = class(TPersistent)
- private
- FManager: TGLNGDManager;
- FPivotPoint: TGLCoordinates;
- FOuter: TGLNGDJoint;
- public
- constructor Create(AOwner: TComponent; aOuter: TGLNGDJoint); virtual;
- destructor Destroy; override;
- published
- property PivotPoint: TGLCoordinates read FPivotPoint write FPivotPoint;
- end;
- TGLNGDJointPin = class(TGLNGDJointPivot)
- private
- FPinDirection: TGLCoordinates;
- public
- constructor Create(AOwner: TComponent; aOuter: TGLNGDJoint); override;
- destructor Destroy; override;
- published
- property PinDirection: TGLCoordinates read FPinDirection write FPinDirection;
- end;
- TGLNGDJointPin2 = class(TGLNGDJointPin)
- private
- FPinDirection2: TGLCoordinates;
- public
- constructor Create(AOwner: TComponent; aOuter: TGLNGDJoint); override;
- destructor Destroy; override;
- published
- property PinDirection2: TGLCoordinates read FPinDirection2 write FPinDirection2;
- end;
- TGLNGDJointBallAndSocket = class(TGLNGDJointPivot)
- private
- FConeAngle: Single; // 90
- FMinTwistAngle: Single; // -90
- FMaxTwistAngle: Single; // 90
- procedure SetConeAngle(const Value: Single);
- procedure SetMaxTwistAngle(const Value: Single);
- procedure SetMinTwistAngle(const Value: Single);
- function StoredMaxTwistAngle: Boolean;
- function StoredMinTwistAngle: Boolean;
- function StoredConeAngle: Boolean;
- public
- constructor Create(AOwner: TComponent; aOuter: TGLNGDJoint); override;
- published
- property ConeAngle: Single read FConeAngle write SetConeAngle stored StoredConeAngle;
- property MinTwistAngle: Single read FMinTwistAngle write SetMinTwistAngle
- stored StoredMinTwistAngle;
- property MaxTwistAngle: Single read FMaxTwistAngle write SetMaxTwistAngle
- stored StoredMaxTwistAngle;
- end;
- TGLNGDJointHinge = class(TGLNGDJointPin)
- private
- FMinAngle: Single; // -90
- FMaxAngle: Single; // 90
- procedure SetMaxAngle(const Value: Single);
- procedure SetMinAngle(const Value: Single);
- function StoredMaxAngle: Boolean;
- function StoredMinAngle: Boolean;
- public
- constructor Create(AOwner: TComponent; aOuter: TGLNGDJoint); override;
- published
- property MinAngle: Single read FMinAngle write SetMinAngle stored StoredMinAngle;
- property MaxAngle: Single read FMaxAngle write SetMaxAngle stored StoredMaxAngle;
- end;
- TGLNGDJointSlider = class(TGLNGDJointPin)
- private
- FMinDistance: Single; // -10
- FMaxDistance: Single; // 10
- procedure SetMaxDistance(const Value: Single);
- procedure SetMinDistance(const Value: Single);
- function StoredMaxDistance: Boolean;
- function StoredMinDistance: Boolean;
- public
- constructor Create(AOwner: TComponent; aOuter: TGLNGDJoint); override;
- published
- property MinDistance: Single read FMinDistance write SetMinDistance stored StoredMinDistance;
- property MaxDistance: Single read FMaxDistance write SetMaxDistance stored StoredMaxDistance;
- end;
- TGLNGDJointKinematicController = class(TPersistent)
- private
- FPickModeLinear: Boolean; // False
- FLinearFriction: Single; // 750
- FAngularFriction: Single; // 250
- function StoredAngularFriction: Boolean;
- function StoredLinearFriction: Boolean;
- public
- constructor Create();
- published
- property PickModeLinear: Boolean read FPickModeLinear write FPickModeLinear default False;
- property LinearFriction: Single read FLinearFriction write FLinearFriction
- stored StoredLinearFriction;
- property AngularFriction: Single read FAngularFriction write FAngularFriction
- stored StoredAngularFriction;
- end;
- TGLNGDJoint = class(TCollectionItem)
- private
- // Global
- FManager: TGLNGDManager;
- FParentObject: TGLBaseSceneObject;
- FJointType: TGLNGDJoints;
- FStiffness: Single; // 0.9
- // With Two object
- // Every joint except nj_UpVector and nj_KinematicController
- FChildObject: TGLBaseSceneObject;
- FCollisionState: Boolean; // False
- // With classic joint
- // nj_BallAndSocket, nj_Hinge, nj_Slider, nj_Corkscrew
- // nj_Universal, nj_UpVector
- FNewtonJoint: PNewtonJoint;
- // With CustomJoint
- // nj_CustomBallAndSocket, nj_CustomHinge, nj_CustomSlider
- // nj_KinematicController
- FNewtonUserJoint: Pointer;
- // nj_UpVector
- FUPVectorDirection: TGLCoordinates;
- FBallAndSocketOptions: TGLNGDJointPivot;
- FHingeOptions: TGLNGDJointPin;
- FSliderOptions: TGLNGDJointPin;
- FCorkscrewOptions: TGLNGDJointPin;
- FUniversalOptions: TGLNGDJointPin2;
- FCustomBallAndSocketOptions: TGLNGDJointBallAndSocket;
- FCustomHingeOptions: TGLNGDJointHinge;
- FCustomSliderOptions: TGLNGDJointSlider;
- FKinematicOptions: TGLNGDJointKinematicController;
- procedure SetJointType(const Value: TGLNGDJoints);
- procedure SetChildObject(const Value: TGLBaseSceneObject);
- procedure SetCollisionState(const Value: Boolean);
- procedure SetParentObject(const Value: TGLBaseSceneObject);
- procedure SetStiffness(const Value: Single);
- procedure Render;
- function StoredStiffness: Boolean;
- procedure DestroyNewtonData;
- public
- constructor Create(Collection: TCollection); override;
- destructor Destroy; override;
- procedure KinematicControllerPick(pickpoint: TGLVector; PickedActions: TGLNGDPickedActions);
- published
- property BallAndSocketOptions: TGLNGDJointPivot read FBallAndSocketOptions
- write FBallAndSocketOptions;
- property HingeOptions: TGLNGDJointPin read FHingeOptions write FHingeOptions;
- property SliderOptions: TGLNGDJointPin read FSliderOptions write FSliderOptions;
- property CorkscrewOptions: TGLNGDJointPin read FCorkscrewOptions write FCorkscrewOptions;
- property UniversalOptions: TGLNGDJointPin2 read FUniversalOptions write FUniversalOptions;
- property CustomBallAndSocketOptions: TGLNGDJointBallAndSocket read FCustomBallAndSocketOptions
- write FCustomBallAndSocketOptions;
- property CustomHingeOptions: TGLNGDJointHinge read FCustomHingeOptions
- write FCustomHingeOptions;
- property CustomSliderOptions: TGLNGDJointSlider read FCustomSliderOptions
- write FCustomSliderOptions;
- property KinematicControllerOptions: TGLNGDJointKinematicController read FKinematicOptions
- write FKinematicOptions;
- property JointType: TGLNGDJoints read FJointType write SetJointType;
- property ParentObject: TGLBaseSceneObject read FParentObject write SetParentObject;
- property ChildObject: TGLBaseSceneObject read FChildObject write SetChildObject;
- property CollisionState: Boolean read FCollisionState write SetCollisionState default False;
- property Stiffness: Single read FStiffness write SetStiffness stored StoredStiffness;
- property UPVectorDirection: TGLCoordinates read FUPVectorDirection write FUPVectorDirection;
- end;
- // Global function
- function GetNGDStatic(Obj: TGLBaseSceneObject): TGLNGDStatic;
- function GetOrCreateNGDStatic(Obj: TGLBaseSceneObject): TGLNGDStatic;
- function GetNGDDynamic(Obj: TGLBaseSceneObject): TGLNGDDynamic;
- function GetOrCreateNGDDynamic(Obj: TGLBaseSceneObject): TGLNGDDynamic;
- function GetBodyFromGLSceneObject(Obj: TGLBaseSceneObject): PNewtonBody;
- // ----------------------------------------------------------------------
- implementation
- // ----------------------------------------------------------------------
- const
- epsilon = 0.0000001; // 1E-07
- function GetNGDStatic(Obj: TGLBaseSceneObject): TGLNGDStatic;
- begin
- Result := TGLNGDStatic(Obj.Behaviours.GetByClass(TGLNGDStatic));
- end;
- function GetOrCreateNGDStatic(Obj: TGLBaseSceneObject): TGLNGDStatic;
- begin
- Result := TGLNGDStatic(Obj.GetOrCreateBehaviour(TGLNGDStatic));
- end;
- function GetNGDDynamic(Obj: TGLBaseSceneObject): TGLNGDDynamic;
- begin
- Result := TGLNGDDynamic(Obj.Behaviours.GetByClass(TGLNGDDynamic));
- end;
- function GetOrCreateNGDDynamic(Obj: TGLBaseSceneObject): TGLNGDDynamic;
- begin
- Result := TGLNGDDynamic(Obj.GetOrCreateBehaviour(TGLNGDDynamic));
- end;
- function GetBodyFromGLSceneObject(Obj: TGLBaseSceneObject): PNewtonBody;
- var
- Behaviour: TGLNGDBehaviour;
- begin
- Behaviour := TGLNGDBehaviour(Obj.Behaviours.GetByClass(TGLNGDBehaviour));
- Assert(Behaviour <> nil, 'NGD Behaviour (static or dynamic) is missing for this object');
- Result := Behaviour.FNewtonBody;
- end;
- // -----------------------
- // TGLNGDDebugOption
- // -----------------------
- constructor TGLNGDDebugOption.Create(AOwner: TComponent);
- begin
- FManager := AOwner as TGLNGDManager;
- with FManager do
- begin
- FGeomColorDyn := TGLColor.CreateInitialized(self, clrGreen, NotifyChange);
- FGeomColorStat := TGLColor.CreateInitialized(self, clrRed, NotifyChange);
- FAABBColor := TGLColor.CreateInitialized(self, clrYellow, NotifyChange);
- FAABBColorSleep := TGLColor.CreateInitialized(self, clrOrange, NotifyChange);
- FCenterOfMassColor := TGLColor.CreateInitialized(self, clrPurple, NotifyChange);
- FContactColor := TGLColor.CreateInitialized(self, clrWhite, NotifyChange);
- FJointAxisColor := TGLColor.CreateInitialized(self, clrBlue, NotifyChange);
- FJointPivotColor := TGLColor.CreateInitialized(self, clrAquamarine, NotifyChange);
- FForceColor := TGLColor.CreateInitialized(self, clrBlack, NotifyChange);
- FAppliedForceColor := TGLColor.CreateInitialized(self, clrSilver, NotifyChange);
- FAppliedVelocityColor := TGLColor.CreateInitialized(self, clrLime, NotifyChange);
- FCustomColor := TGLColor.CreateInitialized(self, clrAqua, NotifyChange);
- end;
- FDotAxisSize := 1;
- FManagerDebugs := [];
- FManager := AOwner as TGLNGDManager;
- end;
- destructor TGLNGDDebugOption.Destroy;
- begin
- FGeomColorDyn.Free;
- FGeomColorStat.Free;
- FAABBColor.Free;
- FAABBColorSleep.Free;
- FCenterOfMassColor.Free;
- FContactColor.Free;
- FJointAxisColor.Free;
- FJointPivotColor.Free;
- FForceColor.Free;
- FAppliedForceColor.Free;
- FAppliedVelocityColor.Free;
- FCustomColor.Free;
- inherited;
- end;
- procedure TGLNGDDebugOption.SetDotAxisSize(const Value: Single);
- begin
- FDotAxisSize := Value;
- FManager.NotifyChange(self);
- end;
- procedure TGLNGDDebugOption.SetManagerDebugs(const Value: TGLNGDManagerDebugs);
- begin
- FManagerDebugs := Value;
- FManager.NotifyChange(self);
- end;
- function TGLNGDDebugOption.StoredDotAxis: Boolean;
- begin
- Result := not SameValue(FDotAxisSize, 1, epsilon);
- end;
- // ------------------------
- // TGLNGDManager
- // ------------------------
- procedure TGLNGDManager.AddNode(const Value: TGLVector);
- begin
- if Assigned(FGLLines) then
- begin
- FGLLines.Nodes.AddNode(Value);
- with (FGLLines.Nodes.Last as TGLLinesNode) do
- Color := FCurrentColor;
- end;
- end;
- procedure TGLNGDManager.AddNode(const coords: TGLCustomCoordinates);
- begin
- if Assigned(FGLLines) then
- begin
- FGLLines.Nodes.AddNode(coords);
- (FGLLines.Nodes.Last as TGLLinesNode).Color := FCurrentColor;
- end;
- end;
- procedure TGLNGDManager.AddNode(const X, Y, Z: Single);
- begin
- if Assigned(FGLLines) then
- begin
- FGLLines.Nodes.AddNode(X, Y, Z);
- (FGLLines.Nodes.Last as TGLLinesNode).Color := FCurrentColor;
- end;
- end;
- procedure TGLNGDManager.AddNode(const Value: TAffineVector);
- begin
- if Assigned(FGLLines) then
- begin
- FGLLines.Nodes.AddNode(Value);
- (FGLLines.Nodes.Last as TGLLinesNode).Color := FCurrentColor;
- end;
- end;
- constructor TGLNGDManager.Create(AOwner: TComponent);
- var
- minworld, maxworld: TGLVector;
- begin
- inherited;
- FNGDBehaviours := TGLNGDBehaviourList.Create;
- FVisible := True;
- FVisibleAtRunTime := False;
- FSolverModel := smExact;
- FFrictionModel := fmExact;
- FMinimumFrameRate := 60;
- FWorldSizeMin := TGLCoordinates.CreateInitialized(self, VectorMake(-100, -100, -100, 0), csPoint);
- FWorldSizeMax := TGLCoordinates.CreateInitialized(self, VectorMake(100, 100, 100, 0), csPoint);
- // Using Events because we need to call API Function when
- // theses TGLCoordinates change.
- FWorldSizeMin.OnNotifyChange := NotifyWorldSizeChange;
- FWorldSizeMax.OnNotifyChange := NotifyWorldSizeChange;
- FThreadCount := 1;
- FGravity := TGLCoordinates3.CreateInitialized(self, VectorMake(0, -9.81, 0, 0), csVector);
- FNewtonWorld := NewtonCreate(nil, nil);
- FDllVersion := NewtonWorldGetVersion(FNewtonWorld);
- // This is to prevent body out the world at startTime
- minworld := VectorMake(-1E50, -1E50, -1E50);
- maxworld := VectorMake(1E50, 1E50, 1E50);
- NewtonSetWorldSize(FNewtonWorld, @minworld, @maxworld);
- NewtonWorldSetUserData(FNewtonWorld, self);
- FNewtonSurfaceItem := TCollection.Create(TGLNGDSurfaceItem);
- FNewtonSurfacePair := TOwnedCollection.Create(self, TGLNGDSurfacePair);
- FNewtonJointGroup := TOwnedCollection.Create(self, TGLNGDJoint);
- FNewtonDebugOption := TGLNGDDebugOption.Create(self);
- RegisterManager(self);
- end;
- destructor TGLNGDManager.Destroy;
- begin
- // for joint before body.
- FreeAndNil(FNewtonJointGroup);
- // Unregister everything
- while FNGDBehaviours.Count > 0 do
- FNGDBehaviours[0].Manager := nil;
- // Clean up everything
- FreeAndNil(FNGDBehaviours);
- FreeAndNil(FWorldSizeMin);
- FreeAndNil(FWorldSizeMax);
- FreeAndNil(FGravity);
- FreeAndNil(FNewtonSurfaceItem);
- FreeAndNil(FNewtonSurfacePair);
- FreeAndNil(FNewtonDebugOption);
- NewtonDestroyAllBodies(FNewtonWorld);
- NewtonMaterialDestroyAllGroupID(FNewtonWorld);
- NewtonDestroy(FNewtonWorld);
- FNewtonWorld := nil;
- DeregisterManager(self);
- inherited;
- end;
- procedure TGLNGDManager.Loaded;
- begin
- inherited;
- NotifyWorldSizeChange(self);
- RebuildAllJoint(self);
- end;
- function TGLNGDManager.GetBodyCount: Integer;
- begin
- if (csDesigning in ComponentState) then
- Result := FNGDBehaviours.Count
- else
- Result := NewtonWorldGetBodyCount(FNewtonWorld);
- end;
- function TGLNGDManager.GetConstraintCount: Integer;
- begin
- if (csDesigning in ComponentState) then
- Result := FNewtonJointGroup.Count
- else
- // Constraint is the number of joint
- Result := NewtonWorldGetConstraintCount(FNewtonWorld);
- end;
- procedure TGLNGDManager.NotifyChange(Sender: TObject);
- var
- I: Integer;
- begin
- // This event is raise
- // when debugOptions properties are edited,
- // when a behavior is initialized/finalize,
- // when joints are rebuilded, (runtime only)
- // when visible and visibleAtRuntime are edited (designTime only),
- // in manager.step, and in SetGLLines.
- // Here the manager call render method for bodies and joints in its lists
- if not Assigned(FGLLines) then
- exit;
- FGLLines.Nodes.Clear;
- if not Visible then
- exit;
- if not(csDesigning in ComponentState) then
- if not VisibleAtRunTime then
- exit;
- for I := 0 to FNGDBehaviours.Count - 1 do
- FNGDBehaviours[I].Render;
- if mdShowJoint in FNewtonDebugOption.NGDManagerDebugs then
- for I := 0 to NewtonJoint.Count - 1 do //
- (NewtonJoint.Items[I] as TGLNGDJoint).Render;
- end;
- procedure TGLNGDManager.SetFrictionModel(const Value: TGLNGDFrictionModels);
- begin
- FFrictionModel := Value;
- if not(csDesigning in ComponentState) then
- NewtonSetFrictionModel(FNewtonWorld, Ord(FFrictionModel));
- end;
- procedure TGLNGDManager.SetGLLines(const Value: TGLLines);
- begin
- if Assigned(FGLLines) then
- FGLLines.Nodes.Clear;
- FGLLines := Value;
- if Assigned(FGLLines) then
- begin
- FGLLines.SplineMode := lsmSegments;
- FGLLines.NodesAspect := lnaInvisible;
- FGLLines.Options := [loUseNodeColorForLines];
- FGLLines.Pickable := False;
- NotifyChange(self);
- end;
- end;
- procedure TGLNGDManager.SetMinimumFrameRate(const Value: Integer);
- begin
- if (Value >= 60) and (Value <= 1000) then
- FMinimumFrameRate := Value;
- if not(csDesigning in ComponentState) then
- NewtonSetMinimumFrameRate(FNewtonWorld, FMinimumFrameRate);
- end;
- procedure TGLNGDManager.SetSolverModel(const Value: TGLNGDSolverModels);
- begin
- FSolverModel := Value;
- if not(csDesigning in ComponentState) then
- NewtonSetSolverModel(FNewtonWorld, Ord(FSolverModel));
- end;
- procedure TGLNGDManager.SetThreadCount(const Value: Integer);
- begin
- if Value > 0 then
- FThreadCount := Value;
- NewtonSetThreadsCount(FNewtonWorld, FThreadCount);
- FThreadCount := NewtonGetThreadsCount(FNewtonWorld);
- end;
- procedure TGLNGDManager.SetVisible(const Value: Boolean);
- begin
- FVisible := Value;
- if (csDesigning in ComponentState) then
- NotifyChange(self);
- end;
- procedure TGLNGDManager.SetVisibleAtRunTime(const Value: Boolean);
- begin
- FVisibleAtRunTime := Value;
- if (csDesigning in ComponentState) then
- NotifyChange(self);
- end;
- procedure TGLNGDManager.NotifyWorldSizeChange(Sender: TObject);
- begin
- if not(csDesigning in ComponentState) then
- NewtonSetWorldSize(FNewtonWorld, @FWorldSizeMin.AsVector, @FWorldSizeMax.AsVector);
- end;
- procedure TGLNGDManager.RebuildAllJoint(Sender: TObject);
- procedure BuildBallAndSocket(Joint: TGLNGDJoint);
- begin
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- FNewtonJoint := NewtonConstraintCreateBall(FNewtonWorld,
- @(FBallAndSocketOptions.FPivotPoint.AsVector), GetBodyFromGLSceneObject(FChildObject),
- GetBodyFromGLSceneObject(FParentObject));
- NewtonJointSetCollisionState(FNewtonJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(FNewtonJoint, FStiffness);
- end;
- end;
- procedure BuildHinge(Joint: TGLNGDJoint);
- begin
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- FNewtonJoint := NewtonConstraintCreateHinge(FNewtonWorld,
- @(FHingeOptions.FPivotPoint.AsVector), @(FHingeOptions.FPinDirection.AsVector),
- GetBodyFromGLSceneObject(FChildObject), GetBodyFromGLSceneObject(FParentObject));
- NewtonJointSetCollisionState(FNewtonJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(FNewtonJoint, FStiffness);
- end;
- end;
- procedure BuildSlider(Joint: TGLNGDJoint);
- begin
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- FNewtonJoint := NewtonConstraintCreateSlider(FNewtonWorld,
- @(FSliderOptions.FPivotPoint.AsVector), @(FSliderOptions.FPinDirection.AsVector),
- GetBodyFromGLSceneObject(FChildObject), GetBodyFromGLSceneObject(FParentObject));
- NewtonJointSetCollisionState(FNewtonJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(FNewtonJoint, FStiffness);
- end;
- end;
- procedure BuildCorkscrew(Joint: TGLNGDJoint);
- begin
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- FNewtonJoint := NewtonConstraintCreateCorkscrew(FNewtonWorld,
- @(FCorkscrewOptions.FPivotPoint.AsVector), @(FCorkscrewOptions.FPinDirection.AsVector),
- GetBodyFromGLSceneObject(FChildObject), GetBodyFromGLSceneObject(FParentObject));
- NewtonJointSetCollisionState(FNewtonJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(FNewtonJoint, FStiffness);
- end;
- end;
- procedure BuildUniversal(Joint: TGLNGDJoint);
- begin
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- FNewtonJoint := NewtonConstraintCreateUniversal(FNewtonWorld,
- @(FUniversalOptions.FPivotPoint.AsVector), @(FUniversalOptions.FPinDirection.AsVector),
- @(FUniversalOptions.FPinDirection2.AsVector), GetBodyFromGLSceneObject(FChildObject),
- GetBodyFromGLSceneObject(FParentObject));
- NewtonJointSetCollisionState(FNewtonJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(FNewtonJoint, FStiffness);
- end;
- end;
- procedure BuildCustomBallAndSocket(Joint: TGLNGDJoint);
- var
- pinAndPivot: TGLMatrix;
- begin
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- pinAndPivot := IdentityHmgMatrix;
- pinAndPivot.W := FCustomBallAndSocketOptions.FPivotPoint.AsVector;
- (* // from dJointLibrary.dll
- FNewtonUserJoint := CreateCustomBallAndSocket(@pinAndPivot,
- GetBodyFromGLSceneObject(FChildObject),
- GetBodyFromGLSceneObject(FParentObject));
- BallAndSocketSetConeAngle(FNewtonUserJoint,
- DegToRadian(FCustomBallAndSocketOptions.FConeAngle));
- BallAndSocketSetTwistAngle(FNewtonUserJoint,
- DegToRadian(FCustomBallAndSocketOptions.FMinTwistAngle),
- DegToRadian(FCustomBallAndSocketOptions.FMaxTwistAngle));
- CustomSetBodiesCollisionState(FNewtonUserJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(CustomGetNewtonJoint(FNewtonUserJoint),
- FStiffness);
- *)
- end;
- end;
- procedure BuildCustomHinge(Joint: TGLNGDJoint);
- var
- pinAndPivot: TGLMatrix;
- bso: TGLBaseSceneObject;
- begin
- (* Newton wait from FPinAndPivotMatrix a structure like that:
- First row: the pin direction
- Second and third rows are set to create an orthogonal matrix
- Fourth: The pivot position
- The BaseSceneObjects direction is the third row,
- because the first row is the right vector (second row is up vector). *)
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- bso := TGLBaseSceneObject.Create(FManager);
- bso.AbsolutePosition := FCustomHingeOptions.FPivotPoint.AsVector;
- bso.AbsoluteDirection := FCustomHingeOptions.FPinDirection.AsVector;
- pinAndPivot := bso.AbsoluteMatrix;
- pinAndPivot.X := bso.AbsoluteMatrix.Z;
- pinAndPivot.Z := bso.AbsoluteMatrix.X;
- bso.Free;
- (* from dJointLibrary.dll
- FNewtonUserJoint := CreateCustomHinge(@pinAndPivot,
- GetBodyFromGLSceneObject(FChildObject),
- GetBodyFromGLSceneObject(FParentObject));
- HingeEnableLimits(FNewtonUserJoint, 1);
- HingeSetLimits(FNewtonUserJoint,
- DegToRadian(FCustomHingeOptions.FMinAngle),
- DegToRadian(FCustomHingeOptions.FMaxAngle));
- CustomSetBodiesCollisionState(FNewtonUserJoint, Ord(FCollisionState));
- NewtonJointSetStiffness(CustomGetNewtonJoint(FNewtonUserJoint),
- FStiffness);
- CustomSetUserData(FNewtonUserJoint, CustomHingeOptions);
- *)
- end;
- end;
- procedure BuildCustomSlider(Joint: TGLNGDJoint);
- var
- pinAndPivot: TGLMatrix;
- bso: TGLBaseSceneObject;
- begin
- (*
- Newton wait from FPinAndPivotMatrix a structure like that:
- First row: the pin direction
- Second and third rows are set to create an orthogonal matrix
- Fourth: The pivot position
- In GLS.Scene, the GLBaseSceneObjects direction is the third row,
- because the first row is the right vector (second row is up vector).
- *)
- with Joint do
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- bso := TGLBaseSceneObject.Create(FManager);
- bso.AbsolutePosition := FCustomSliderOptions.FPivotPoint.AsVector;
- bso.AbsoluteDirection := FCustomSliderOptions.FPinDirection.AsVector;
- pinAndPivot := bso.AbsoluteMatrix;
- pinAndPivot.X := bso.AbsoluteMatrix.Z;
- pinAndPivot.Z := bso.AbsoluteMatrix.X;
- bso.Free;
- (* from dJointLibrary.dll
- FNewtonUserJoint := CreateCustomSlider(@pinAndPivot,
- GetBodyFromGLSceneObject(FChildObject),
- GetBodyFromGLSceneObject(FParentObject));
- SliderEnableLimits(FNewtonUserJoint, 1);
- SliderSetLimits(FNewtonUserJoint, FCustomSliderOptions.FMinDistance,
- FCustomSliderOptions.FMaxDistance);
- NewtonJointSetStiffness(CustomGetNewtonJoint(FNewtonUserJoint), 0);
- CustomSetBodiesCollisionState(FNewtonUserJoint, Ord(FCollisionState));
- CustomSetUserData(FNewtonUserJoint, CustomSliderOptions);
- *)
- end;
- end;
- procedure BuildUpVector(Joint: TGLNGDJoint);
- begin
- with Joint do
- if Assigned(FParentObject) then
- begin
- FNewtonJoint := NewtonConstraintCreateUpVector(FNewtonWorld, @FUPVectorDirection.AsVector,
- GetBodyFromGLSceneObject(FParentObject));
- end;
- end;
- procedure BuildKinematicController(Joint: TGLNGDJoint);
- begin
- // do nothing
- end;
- procedure BuildOneJoint(Joint: TGLNGDJoint);
- begin
- case Joint.FJointType of
- nj_BallAndSocket:
- begin
- Joint.DestroyNewtonData;
- BuildBallAndSocket(Joint);
- end;
- nj_Hinge:
- begin
- Joint.DestroyNewtonData;
- BuildHinge(Joint);
- end;
- nj_Slider:
- begin
- Joint.DestroyNewtonData;
- BuildSlider(Joint);
- end;
- nj_Corkscrew:
- begin
- Joint.DestroyNewtonData;
- BuildCorkscrew(Joint);
- end;
- nj_Universal:
- begin
- Joint.DestroyNewtonData;
- BuildUniversal(Joint);
- end;
- nj_CustomBallAndSocket:
- begin
- Joint.DestroyNewtonData;
- BuildCustomBallAndSocket(Joint);
- end;
- nj_CustomHinge:
- begin
- Joint.DestroyNewtonData;
- BuildCustomHinge(Joint);
- end;
- nj_CustomSlider:
- begin
- Joint.DestroyNewtonData;
- BuildCustomSlider(Joint);
- end;
- nj_UpVector:
- begin
- Joint.DestroyNewtonData;
- BuildUpVector(Joint);
- end;
- nj_KinematicController:
- begin
- // DestroyJoint(Joint);
- // BuildKinematicController(Joint);
- end;
- end;
- end;
- var
- I: Integer;
- begin
- if not(csDesigning in ComponentState) and not(csLoading in ComponentState) then
- begin
- if Sender is TGLNGDManager then
- for I := 0 to NewtonJoint.Count - 1 do
- BuildOneJoint(NewtonJoint.Items[I] as TGLNGDJoint);
- if (Sender is TGLNGDJoint) then
- BuildOneJoint((Sender as TGLNGDJoint));
- if Sender is TGLCoordinates then
- BuildOneJoint(((Sender as TGLCoordinates).Owner as TGLNGDJoint));
- NotifyChange(self);
- end;
- end;
- procedure TGLNGDManager.RebuildAllMaterial;
- procedure BuildMaterialPair;
- var
- I, ID0, ID1: Integer;
- begin
- for I := 0 to FNewtonSurfacePair.Count - 1 do
- with (FNewtonSurfacePair.Items[I] as TGLNGDSurfacePair) do
- begin
- if Assigned(NGDSurfaceItem1) and Assigned(NGDSurfaceItem2) then
- begin
- ID0 := NGDSurfaceItem1.ID;
- ID1 := NGDSurfaceItem2.ID;
- NewtonMaterialSetContinuousCollisionMode(FNewtonWorld, ID0, ID1,
- Ord(ContinuousCollisionMode));
- if Thickness then
- NewtonMaterialSetSurfaceThickness(FNewtonWorld, ID0, ID1, 1);
- NewtonMaterialSetDefaultSoftness(FNewtonWorld, ID0, ID1, Softness);
- NewtonMaterialSetDefaultElasticity(FNewtonWorld, ID0, ID1, Elasticity);
- NewtonMaterialSetDefaultCollidable(FNewtonWorld, ID0, ID1, Ord(Collidable));
- NewtonMaterialSetDefaultFriction(FNewtonWorld, ID0, ID1, StaticFriction, KineticFriction);
- NewtonMaterialSetCollisionCallback(FNewtonWorld, ID0, ID1, FNewtonSurfacePair.Items[I],
- @TGLNGDSurfacePair.NewtonAABBOverlap, @TGLNGDSurfacePair.NewtonContactsProcess);
- end;
- end;
- end;
- var
- I: Integer;
- maxID: Integer;
- begin
- maxID := 0;
- if not(csDesigning in ComponentState) then
- begin
- // for newton materials
- NewtonMaterialDestroyAllGroupID(FNewtonWorld);
- // Creates materialID
- for I := 0 to FNewtonSurfaceItem.Count - 1 do
- maxID := MaxInteger((FNewtonSurfaceItem.Items[I] as TGLNGDSurfaceItem).ID, maxID);
- for I := 0 to maxID - 1 do
- NewtonMaterialCreateGroupID(FNewtonWorld);
- // assign matID to bodies
- for I := 0 to FNGDBehaviours.Count - 1 do
- with FNGDBehaviours[I] do
- if Assigned(FSurfaceItem) then
- NewtonBodySetMaterialGroupID(FNewtonBody, FSurfaceItem.ID)
- else
- NewtonBodySetMaterialGroupID(FNewtonBody, 0);
- // Set values to newton material pair :callback userdata friction...
- BuildMaterialPair;
- end;
- end;
- procedure TGLNGDManager.Step(deltatime: Single);
- begin
- if not(csDesigning in ComponentState) then
- NewtonUpdate(FNewtonWorld, deltatime);
- NotifyChange(self);
- end;
- // ---------------------------
- // TGLNGDBehaviour
- // ---------------------------
- constructor TGLNGDBehaviour.Create(AOwner: TXCollection);
- begin
- inherited;
- FInitialized := False;
- FOwnerBaseSceneObject := OwnerBaseSceneObject;
- FContinuousCollisionMode := False;
- FNewtonBody := nil;
- FCollision := nil;
- FNewtonCollisions := nc_Primitive;
- FCollisionIteratorEvent := OnCollisionIteratorEvent;
- FTreeCollisionOptimize := True;
- FConvexCollisionTolerance := 0.01;
- FFileCollision := '';
- name := 'NGD Static';
- end;
- destructor TGLNGDBehaviour.Destroy;
- begin
- if Assigned(FManager) then
- Manager := nil; // This will call finalize
- inherited;
- end;
- procedure TGLNGDBehaviour.Finalize;
- var
- I: Integer;
- begin
- FInitialized := False;
- if Assigned(FManager) then
- begin
- if Assigned(FManager.NewtonJoint) then
- for I := FManager.NewtonJoint.Count - 1 downto 0 do
- begin
- if ((FManager.NewtonJoint.Items[I] as TGLNGDJoint).ParentObject = FOwnerBaseSceneObject) or
- ((FManager.NewtonJoint.Items[I] as TGLNGDJoint).ChildObject = FOwnerBaseSceneObject) then
- begin
- FManager.NewtonJoint.Items[I].Free;
- end;
- end;
- NewtonDestroyBody(FManager.FNewtonWorld, FNewtonBody);
- FNewtonBody := nil;
- FCollision := nil;
- end;
- end;
- function TGLNGDBehaviour.GetBBoxCollision: PNewtonCollision;
- var
- vc: array [0 .. 7] of TGLVector;
- I: Integer;
- begin
- for I := 0 to 8 - 1 do
- vc[I] := AABBToBB(FOwnerBaseSceneObject.AxisAlignedBoundingBoxEx).BBox[I];
- Result := NewtonCreateConvexHull(FManager.FNewtonWorld, 8, @vc[0], SizeOf(TGLVector),
- 0.01, 0, nil);
- end;
- function TGLNGDBehaviour.GetBSphereCollision: PNewtonCollision;
- var
- boundingSphere: TBSphere;
- collisionOffsetMatrix: TGLMatrix;
- begin
- AABBToBSphere(FOwnerBaseSceneObject.AxisAlignedBoundingBoxEx, boundingSphere);
- collisionOffsetMatrix := IdentityHmgMatrix;
- collisionOffsetMatrix.W := VectorMake(boundingSphere.Center, 1);
- Result := NewtonCreateSphere(FManager.FNewtonWorld, boundingSphere.Radius, boundingSphere.Radius,
- boundingSphere.Radius, 0, @collisionOffsetMatrix);
- end;
- function TGLNGDBehaviour.GetConvexCollision: PNewtonCollision;
- var
- I, J: Integer;
- vertexArray: array of TVertex;
- begin
- if FOwnerBaseSceneObject is TGLBaseMesh then
- begin
- with (FOwnerBaseSceneObject as TGLBaseMesh) do
- begin
- for I := 0 to MeshObjects.Count - 1 do
- for J := 0 to MeshObjects[I].Vertices.Count - 1 do
- begin
- SetLength(vertexArray, Length(vertexArray) + 1);
- vertexArray[Length(vertexArray) - 1] := MeshObjects[I].Vertices[J];
- end;
- if Length(vertexArray) > 0 then
- Result := NewtonCreateConvexHull(FManager.FNewtonWorld, Length(vertexArray),
- @vertexArray[0], SizeOf(TVertex), FConvexCollisionTolerance, 0, nil)
- else
- Result := GetNullCollision;
- end;
- end
- else
- Result := GetNullCollision;
- end;
- function TGLNGDBehaviour.GetHeightFieldCollision: PNewtonCollision;
- var
- I: Integer;
- attributeMap: array of ShortInt;
- begin
- SetLength(attributeMap, Length(FHeightFieldOptions.heightArray));
- for I := 0 to Length(FHeightFieldOptions.heightArray) - 1 do
- attributeMap[I] := 0;
- Result := NewtonCreateHeightFieldCollision(FManager.FNewtonWorld, FHeightFieldOptions.width,
- FHeightFieldOptions.depth, Ord(FHeightFieldOptions.gridDiagonals),
- PUnsigned_short(FHeightFieldOptions.heightArray), P2Char(attributeMap),
- FHeightFieldOptions.widthDepthScale, FHeightFieldOptions.heightScale, 0);
- end;
- function TGLNGDBehaviour.GetMeshCollision: PNewtonCollision;
- var
- collisionArray: array of PNewtonCollision;
- I, J: Integer;
- vertexArray: array of TVertex;
- begin
- if FOwnerBaseSceneObject is TGLBaseMesh then
- begin
- with (FOwnerBaseSceneObject as TGLBaseMesh) do
- begin
- // Iterate trough mesh of GLobject
- for I := 0 to MeshObjects.Count - 1 do
- begin
- // Iterate trough vertices of mesh
- for J := 0 to MeshObjects[I].Vertices.Count - 1 do
- begin
- SetLength(vertexArray, Length(vertexArray) + 1);
- vertexArray[Length(vertexArray) - 1] := MeshObjects[I].Vertices[J];
- end;
- if Length(vertexArray) > 3 then
- begin
- SetLength(collisionArray, Length(collisionArray) + 1);
- collisionArray[Length(collisionArray) - 1] :=
- NewtonCreateConvexHull(FManager.FNewtonWorld, Length(vertexArray), @vertexArray[0],
- SizeOf(TVertex), FConvexCollisionTolerance, 0, nil);
- // Remove last collision if the newton function was not successful
- if collisionArray[Length(collisionArray) - 1] = nil then
- SetLength(collisionArray, Length(collisionArray) - 1);
- end;
- SetLength(vertexArray, 0);
- end;
- if Length(collisionArray) > 0 then
- Result := NewtonCreateCompoundCollision(FManager.FNewtonWorld, Length(collisionArray),
- TCollisionPrimitiveArray(@collisionArray[0]), 0)
- else
- Result := GetNullCollision;
- end;
- end
- else
- Result := GetNullCollision;
- end;
- function TGLNGDBehaviour.GetNewtonBodyMatrix: TGLMatrix;
- begin
- if Assigned(FManager) then
- NewtonBodyGetmatrix(FNewtonBody, @FNewtonBodyMatrix);
- Result := FNewtonBodyMatrix;
- end;
- function TGLNGDBehaviour.GetNewtonBodyAABB: TAABB;
- begin
- if Assigned(FManager) then
- NewtonBodyGetAABB(FNewtonBody, @(Result.min), @(Result.max));
- end;
- function TGLNGDBehaviour.GetNGDFileCollision: PNewtonCollision;
- var
- MyFile: TFileStream;
- begin
- if FileExists(FFileCollision) then
- begin
- MyFile := TFileStream.Create(FFileCollision, fmOpenRead);
- Result := NewtonCreateCollisionFromSerialization(FManager.FNewtonWorld,
- @TGLNGDBehaviour.NewtonDeserialize, Pointer(MyFile));
- MyFile.Free;
- end
- else
- Result := NewtonCreateNull(FManager.FNewtonWorld);
- end;
- function TGLNGDBehaviour.GetNullCollision: PNewtonCollision;
- begin
- Result := NewtonCreateNull(FManager.FNewtonWorld);
- end;
- function TGLNGDBehaviour.GetPrimitiveCollision: PNewtonCollision;
- var
- collisionOffsetMatrix: TGLMatrix; // For cone capsule and cylinder
- begin
- collisionOffsetMatrix := IdentityHmgMatrix;
- if (FOwnerBaseSceneObject is TGLCube) then
- begin
- with (FOwnerBaseSceneObject as TGLCube) do
- Result := NewtonCreateBox(FManager.FNewtonWorld, CubeWidth, CubeHeight, CubeDepth, 0,
- @collisionOffsetMatrix);
- end
- else if (FOwnerBaseSceneObject is TGLSphere) then
- begin
- with (FOwnerBaseSceneObject as TGLSphere) do
- Result := NewtonCreateSphere(FManager.FNewtonWorld, Radius, Radius, Radius, 0,
- @collisionOffsetMatrix);
- end
- else if (FOwnerBaseSceneObject is TGLCone) then
- begin
- collisionOffsetMatrix := MatrixMultiply(collisionOffsetMatrix, CreateRotationMatrixZ(Pi / 2.0));
- with (FOwnerBaseSceneObject as TGLCone) do
- Result := NewtonCreateCone(FManager.FNewtonWorld, BottomRadius, Height, 0,
- @collisionOffsetMatrix);
- end
- else if (FOwnerBaseSceneObject is TGLCapsule) then
- begin
- collisionOffsetMatrix := MatrixMultiply(collisionOffsetMatrix, CreateRotationMatrixY(Pi / 2.0));
- with (FOwnerBaseSceneObject as TGLCapsule) do
- // Use Cylinder shape for buoyancy
- Result := NewtonCreateCapsule(FManager.FNewtonWorld, Radius, Height + 2 * Radius, 0,
- @collisionOffsetMatrix);
- end
- else if (FOwnerBaseSceneObject is TGLCylinder) then
- begin
- collisionOffsetMatrix := MatrixMultiply(collisionOffsetMatrix, CreateRotationMatrixZ(Pi / 2.0));
- with (FOwnerBaseSceneObject as TGLCylinder) do
- Result := NewtonCreateCylinder(FManager.FNewtonWorld, BottomRadius, Height, 0,
- @collisionOffsetMatrix);
- end
- else
- Result := GetNullCollision;
- end;
- function TGLNGDBehaviour.GetTreeCollision: PNewtonCollision;
- var
- meshIndex, triangleIndex: Integer;
- triangleList: TGLAffineVectorList;
- v: array [0 .. 2] of TAffineVector;
- begin
- if FOwnerBaseSceneObject is TGLBaseMesh then
- begin
- with (FOwnerBaseSceneObject as TGLBaseMesh) do
- begin
- Result := NewtonCreateTreeCollision(FManager.FNewtonWorld, 0);
- NewtonTreeCollisionBeginBuild(Result);
- for meshIndex := 0 to MeshObjects.Count - 1 do
- begin
- triangleList := MeshObjects[meshIndex].ExtractTriangles;
- for triangleIndex := 0 to triangleList.Count - 1 do
- begin
- if triangleIndex mod 3 = 0 then
- begin
- v[0] := triangleList.Items[triangleIndex];
- // ScaleVector(v[0], FOwnerBaseSceneObject.Scale.X);
- v[1] := triangleList.Items[triangleIndex + 1];
- // ScaleVector(v[1], FOwnerBaseSceneObject.Scale.Y);
- v[2] := triangleList.Items[triangleIndex + 2];
- // ScaleVector(v[2], FOwnerBaseSceneObject.Scale.Z);
- NewtonTreeCollisionAddFace(Result, 3, @(v), SizeOf(TAffineVector), 1);
- end;
- end;
- triangleList.Free;
- end;
- NewtonTreeCollisionEndBuild(Result, Ord(FTreeCollisionOptimize));
- end;
- end
- else
- Result := GetNullCollision;
- end;
- procedure TGLNGDBehaviour.Initialize;
- begin
- FInitialized := True;
- if Assigned(FManager) then
- begin
- // Creates NewtonBody with null collision
- FCollision := NewtonCreateNull(FManager.FNewtonWorld);
- FNewtonBodyMatrix := FOwnerBaseSceneObject.AbsoluteMatrix;
- FNewtonBody := NewtonCreateBody(FManager.FNewtonWorld, FCollision, @FNewtonBodyMatrix);
- // Release NewtonCollision
- NewtonReleaseCollision(FManager.FNewtonWorld, FCollision);
- // Set Link between glscene and newton
- NewtonBodySetUserdata(FNewtonBody, self);
- // Set position and orientation
- SetNewtonBodyMatrix(FOwnerBaseSceneObject.AbsoluteMatrix);
- // Set Collision
- UpdCollision;
- end;
- end;
- procedure TGLNGDBehaviour.Loaded;
- var
- mng: TComponent;
- begin
- inherited;
- if FManagerName <> '' then
- begin
- mng := FindManager(TGLNGDManager, FManagerName);
- if Assigned(mng) then
- Manager := TGLNGDManager(mng);
- FManagerName := '';
- end;
- if Assigned(FManager) then
- begin
- SetContinuousCollisionMode(FContinuousCollisionMode);
- end;
- end;
- class procedure TGLNGDBehaviour.NewtonCollisionIterator(const userData: Pointer;
- vertexCount: Integer; const faceArray: PdFloat; faceId: Integer)cdecl;
- begin
- TGLNGDBehaviour(userData).FCollisionIteratorEvent(userData, vertexCount, faceArray, faceId);
- end;
- // Serializes are called by NGDBehaviour to save and load collision in file
- // It's better to save/load big collisions [over 50000 polygones] to reduce
- // loading time
- class procedure TGLNGDBehaviour.NewtonDeserialize(serializeHandle, buffer: Pointer;
- size: Cardinal)cdecl;
- begin
- TFileStream(serializeHandle).read(buffer^, size);
- end;
- class procedure TGLNGDBehaviour.NewtonSerialize(serializeHandle: Pointer; const buffer: Pointer;
- size: Cardinal)cdecl;
- begin
- TFileStream(serializeHandle).write(buffer^, size);
- end;
- procedure TGLNGDBehaviour.OnCollisionIteratorEvent(const userData: Pointer; vertexCount: Integer;
- const cfaceArray: PdFloat; faceId: Integer);
- var
- I: Integer;
- v0, v1: array [0 .. 2] of Single;
- vA: array of Single;
- begin
- // This algorithme draw Collision Shape for Debuggin.
- // Taken to Sascha Willems in SDLNewton-Demo at
- // http://www.saschawillems.de/?page_id=82
- // Leave if there is no or to much vertex
- if (vertexCount = 0) then
- exit;
- SetLength(vA, vertexCount * 3);
- Move(cfaceArray^, vA[0], vertexCount * 3 * SizeOf(Single));
- v0[0] := vA[(vertexCount - 1) * 3];
- v0[1] := vA[(vertexCount - 1) * 3 + 1];
- v0[2] := vA[(vertexCount - 1) * 3 + 2];
- for I := 0 to vertexCount - 1 do
- begin
- v1[0] := vA[I * 3];
- v1[1] := vA[I * 3 + 1];
- v1[2] := vA[I * 3 + 2];
- FManager.AddNode(v0[0], v0[1], v0[2]);
- FManager.AddNode(v1[0], v1[1], v1[2]);
- v0 := v1;
- end;
- end;
- procedure TGLNGDBehaviour.Reinitialize;
- begin
- if Initialized then
- begin
- // Set Appropriate NewtonCollision
- UpdCollision();
- // Set position and orientation
- SetNewtonBodyMatrix(FOwnerBaseSceneObject.AbsoluteMatrix);
- end;
- Loaded;
- end;
- procedure TGLNGDBehaviour.Render;
- var
- M: TGLMatrix;
- begin
- // Rebuild collision in design time
- if (csDesigning in FOwnerBaseSceneObject.ComponentState) then
- Reinitialize;
- if self is TGLNGDDynamic then
- FManager.FCurrentColor := FManager.DebugOption.GeomColorDyn
- else
- FManager.FCurrentColor := FManager.DebugOption.GeomColorStat;
- M := FOwnerBaseSceneObject.AbsoluteMatrix;
- if mdShowGeometry in FManager.DebugOption.NGDManagerDebugs then
- NewtonCollisionForEachPolygonDo(FCollision, @M, @TGLNGDBehaviour.NewtonCollisionIterator, self);
- end;
- // In this procedure, we assign collision to body
- // [Because when initialised, the collision for body is type NULL]
- procedure TGLNGDBehaviour.UpdCollision;
- var
- collisionInfoRecord: TNewtonCollisionInfoRecord;
- begin
- case FNewtonCollisions of
- nc_Primitive:
- FCollision := GetPrimitiveCollision;
- nc_Convex:
- FCollision := GetConvexCollision;
- nc_BBox:
- FCollision := GetBBoxCollision;
- nc_BSphere:
- FCollision := GetBSphereCollision;
- nc_Tree:
- FCollision := GetTreeCollision;
- nc_Mesh:
- FCollision := GetMeshCollision;
- nc_Null:
- FCollision := GetNullCollision;
- nc_HeightField:
- FCollision := GetHeightFieldCollision;
- nc_NGDFile:
- FCollision := GetNGDFileCollision;
- end;
- if Assigned(FCollision) then
- begin
- NewtonBodySetCollision(FNewtonBody, FCollision);
- // The API Ask for releasing Collision to avoid memory leak
- NewtonCollisionGetInfo(FCollision, @collisionInfoRecord);
- if collisionInfoRecord.m_collisionType > 2 then
- NewtonReleaseCollision(FManager.FNewtonWorld, FCollision);
- end;
- end;
- procedure TGLNGDBehaviour.SetContinuousCollisionMode(const Value: Boolean);
- begin
- // for continue collision to be active the continue collision mode must on
- // the material pair of the colliding bodies as well as on at
- // least one of the two colliding bodies.
- // see NewtonBodySetContinuousCollisionMode
- // see NewtonMaterialSetContinuousCollisionMode
- FContinuousCollisionMode := Value;
- if not(csDesigning in FOwnerBaseSceneObject.ComponentState) then
- if Assigned(FManager) then
- NewtonBodySetContinuousCollisionMode(FNewtonBody, Ord(Value));
- end;
- procedure TGLNGDBehaviour.SetHeightFieldOptions(const Value: TGLNGDHeightField);
- begin
- FHeightFieldOptions := Value;
- Reinitialize;
- end;
- procedure TGLNGDBehaviour.SetManager(Value: TGLNGDManager);
- begin
- if FManager <> Value then
- begin
- if Assigned(FManager) then
- begin
- if Initialized then
- Finalize;
- FManager.FNGDBehaviours.Remove(self);
- // FManager.NotifyChange(self);
- end;
- FManager := Value;
- if Assigned(FManager) then
- begin
- Initialize;
- FManager.FNGDBehaviours.Add(self);
- FManager.NotifyChange(self);
- end;
- end;
- end;
- procedure TGLNGDBehaviour.SetNewtonBodyMatrix(const Value: TGLMatrix);
- begin
- FNewtonBodyMatrix := Value;
- if Assigned(FManager) then
- NewtonBodySetmatrix(FNewtonBody, @FNewtonBodyMatrix);
- end;
- procedure TGLNGDBehaviour.SetNewtonCollisions(const Value: TGLNGDCollisions);
- begin
- FNewtonCollisions := Value;
- if Assigned(FManager) then
- UpdCollision;
- end;
- procedure TGLNGDBehaviour.SetNewtonSurfaceItem(const Value: TGLNGDSurfaceItem);
- begin
- FSurfaceItem := Value;
- FManager.RebuildAllMaterial;
- end;
- function TGLNGDBehaviour.StoredTolerance: Boolean;
- begin
- Result := not SameValue(FConvexCollisionTolerance, 0.01, epsilon);
- end;
- class function TGLNGDBehaviour.UniqueItem: Boolean;
- begin
- Result := True;
- end;
- procedure TGLNGDBehaviour.ReadFromFiler(reader: TReader);
- var
- version: Integer;
- begin
- inherited;
- with reader do
- begin
- version := ReadInteger; // read data version
- Assert(version <= 1); // Archive version
- FManagerName := ReadString;
- FContinuousCollisionMode := ReadBoolean;
- read(FNewtonCollisions, SizeOf(TGLNGDCollisions));
- FTreeCollisionOptimize := ReadBoolean;
- if version <= 0 then
- FConvexCollisionTolerance := ReadSingle
- else
- FConvexCollisionTolerance := ReadFloat;
- FFileCollision := ReadString;
- end;
- end;
- procedure TGLNGDBehaviour.WriteToFiler(writer: TWriter);
- begin
- inherited;
- with writer do
- begin
- WriteInteger(1); // Archive version
- if Assigned(FManager) then
- WriteString(FManager.GetNamePath)
- else
- WriteString('');
- WriteBoolean(FContinuousCollisionMode);
- write(FNewtonCollisions, SizeOf(TGLNGDCollisions));
- WriteBoolean(FTreeCollisionOptimize);
- WriteFloat(FConvexCollisionTolerance);
- WriteString(FFileCollision);
- end;
- end;
- procedure TGLNGDBehaviour.Serialize(filename: string);
- var
- MyFile: TFileStream;
- begin
- MyFile := TFileStream.Create(filename, fmCreate or fmOpenReadWrite);
- NewtonCollisionSerialize(FManager.FNewtonWorld, FCollision, @TGLNGDBehaviour.NewtonSerialize,
- Pointer(MyFile));
- MyFile.Free;
- end;
- procedure TGLNGDBehaviour.DeSerialize(filename: string);
- var
- MyFile: TFileStream;
- collisionInfoRecord: TNewtonCollisionInfoRecord;
- begin
- MyFile := TFileStream.Create(filename, fmOpenRead);
- FCollision := NewtonCreateCollisionFromSerialization(FManager.FNewtonWorld,
- @TGLNGDBehaviour.NewtonDeserialize, Pointer(MyFile));
- // SetCollision;
- NewtonBodySetCollision(FNewtonBody, FCollision);
- // Release collision
- NewtonCollisionGetInfo(FCollision, @collisionInfoRecord);
- if collisionInfoRecord.m_collisionType > 2 then
- NewtonReleaseCollision(FManager.FNewtonWorld, FCollision);
- MyFile.Free;
- end;
- // -------------------------
- // TGLNGDDynamic
- // -------------------------
- procedure TGLNGDDynamic.AddImpulse(const veloc, pointposit: TGLVector);
- begin
- if Assigned(FNewtonBody) then
- NewtonBodyAddImpulse(FNewtonBody, @veloc, @pointposit);
- end;
- constructor TGLNGDDynamic.Create(AOwner: TXCollection);
- begin
- inherited;
- FAutoSleep := True;
- FLinearDamping := 0.1;
- FAngularDamping := TGLCoordinates.CreateInitialized(self, VectorMake(0.1, 0.1, 0.1, 0), csPoint);
- FAngularDamping.OnNotifyChange := NotifyAngularDampingChange;
- FDensity := 1;
- FVolume := 1;
- FForce := TGLCoordinates.CreateInitialized(self, NullHmgVector, csVector);
- FTorque := TGLCoordinates.CreateInitialized(self, NullHmgVector, csVector);
- FCenterOfMass := TGLCoordinates.CreateInitialized(self, NullHmgVector, csPoint);
- FCenterOfMass.OnNotifyChange := NotifyCenterOfMassChange;
- FAABBmin := TGLCoordinates.CreateInitialized(self, NullHmgVector, csPoint);
- FAABBmax := TGLCoordinates.CreateInitialized(self, NullHmgVector, csPoint);
- FAppliedOmega := TGLCoordinates.CreateInitialized(self, NullHmgVector, csVector);
- FAppliedVelocity := TGLCoordinates.CreateInitialized(self, NullHmgVector, csVector);
- FAppliedForce := TGLCoordinates.CreateInitialized(self, NullHmgVector, csVector);
- FAppliedTorque := TGLCoordinates.CreateInitialized(self, NullHmgVector, csVector);
- FUseGravity := True;
- FNullCollisionVolume := 0;
- FApplyForceAndTorqueEvent := OnApplyForceAndTorqueEvent;
- FSetTransformEvent := OnSetTransformEvent;
- name := 'NGD Dynamic'
- end;
- destructor TGLNGDDynamic.Destroy;
- begin
- // Clean up everything
- FAngularDamping.Free;
- FForce.Free;
- FTorque.Free;
- FCenterOfMass.Free;
- FAABBmin.Free;
- FAABBmax.Free;
- FAppliedForce.Free;
- FAppliedTorque.Free;
- FAppliedVelocity.Free;
- FAppliedOmega.Free;
- inherited;
- end;
- procedure TGLNGDDynamic.Finalize;
- begin
- if not(csDesigning in FOwnerBaseSceneObject.ComponentState) then
- if Assigned(FManager) then
- begin
- // Removing Callback
- NewtonBodySetForceAndTorqueCallback(FNewtonBody, nil);
- NewtonBodySetTransformCallback(FNewtonBody, nil);
- end;
- inherited;
- end;
- class function TGLNGDDynamic.FriendlyName: string;
- begin
- Result := 'NGD Dynamic';
- end;
- procedure TGLNGDDynamic.Initialize;
- begin
- inherited;
- if not(csDesigning in FOwnerBaseSceneObject.ComponentState) then
- if Assigned(FManager) then
- begin
- // Set Density, Mass and inertie matrix
- SetDensity(FDensity);
- // Set Callback
- NewtonBodySetForceAndTorqueCallback(FNewtonBody, @TGLNGDDynamic.NewtonApplyForceAndTorque);
- NewtonBodySetTransformCallback(FNewtonBody, @TGLNGDDynamic.NewtonSetTransform);
- end;
- end;
- procedure TGLNGDDynamic.Render;
- procedure DrawAABB(min, max: TGLCoordinates3);
- begin
- (*
- // H________G
- // /. /|
- // / . / |
- // D__._____C |
- // | . | |
- // | E.-----|--F
- // | . | /
- // |. |/
- // A________B
- *)
- // Back
- FManager.AddNode(min.X, min.Y, min.Z); // E
- FManager.AddNode(max.X, min.Y, min.Z); // F
- FManager.AddNode(max.X, min.Y, min.Z); // F
- FManager.AddNode(max.X, max.Y, min.Z); // G
- FManager.AddNode(max.X, max.Y, min.Z); // G
- FManager.AddNode(min.X, max.Y, min.Z); // H
- FManager.AddNode(min.X, max.Y, min.Z); // H
- FManager.AddNode(min.X, min.Y, min.Z); // E
- // Front
- FManager.AddNode(min.X, min.Y, max.Z); // A
- FManager.AddNode(max.X, min.Y, max.Z); // B
- FManager.AddNode(max.X, min.Y, max.Z); // B
- FManager.AddNode(max.X, max.Y, max.Z); // C
- FManager.AddNode(max.X, max.Y, max.Z); // C
- FManager.AddNode(min.X, max.Y, max.Z); // D
- FManager.AddNode(min.X, max.Y, max.Z); // D
- FManager.AddNode(min.X, min.Y, max.Z); // A
- // Edges
- FManager.AddNode(min.X, min.Y, max.Z); // A
- FManager.AddNode(min.X, min.Y, min.Z); // E
- FManager.AddNode(max.X, min.Y, max.Z); // B
- FManager.AddNode(max.X, min.Y, min.Z); // F
- FManager.AddNode(max.X, max.Y, max.Z); // C
- FManager.AddNode(max.X, max.Y, min.Z); // G
- FManager.AddNode(min.X, max.Y, max.Z); // D
- FManager.AddNode(min.X, max.Y, min.Z); // H
- end;
- procedure DrawContact;
- var
- cnt: PNewtonJoint;
- thisContact: PNewtonJoint;
- material: PNewtonMaterial;
- pos, nor: TGLVector;
- begin
- FManager.FCurrentColor := FManager.DebugOption.ContactColor;
- cnt := NewtonBodyGetFirstContactJoint(FNewtonBody);
- while cnt <> nil do
- begin
- thisContact := NewtonContactJointGetFirstContact(cnt);
- while thisContact <> nil do
- begin
- material := NewtonContactGetMaterial(thisContact);
- NewtonMaterialGetContactPositionAndNormal(material, FNewtonBody, @pos, @nor);
- FManager.AddNode(pos);
- nor := VectorAdd(pos, nor);
- FManager.AddNode(nor);
- thisContact := NewtonContactJointGetNextContact(cnt, thisContact);
- end;
- cnt := NewtonBodyGetNextContactJoint(FNewtonBody, cnt);
- end;
- end;
- function GetAbsCom(): TGLVector;
- var
- M: TGLMatrix;
- begin
- NewtonBodyGetCentreOfMass(FNewtonBody, @Result);
- M := IdentityHmgMatrix;
- M.W := Result;
- M.W.W := 1;
- M := MatrixMultiply(M, FOwnerBaseSceneObject.AbsoluteMatrix);
- Result := M.W;
- end;
- procedure DrawForce;
- var
- pos: TGLVector;
- nor: TGLVector;
- begin
- pos := GetAbsCom;
- if mdShowForce in FManager.DebugOption.NGDManagerDebugs then
- begin
- FManager.FCurrentColor := FManager.DebugOption.ForceColor;
- nor := VectorAdd(pos, FForce.AsVector);
- FManager.AddNode(pos);
- FManager.AddNode(nor);
- end;
- if mdShowAppliedForce in FManager.DebugOption.NGDManagerDebugs then
- begin
- FManager.FCurrentColor := FManager.DebugOption.AppliedForceColor;
- nor := VectorAdd(pos, FAppliedForce.AsVector);
- FManager.AddNode(pos);
- FManager.AddNode(nor);
- end;
- if mdShowAppliedVelocity in FManager.DebugOption.NGDManagerDebugs then
- begin
- FManager.FCurrentColor := FManager.DebugOption.AppliedVelocityColor;
- nor := VectorAdd(pos, FAppliedVelocity.AsVector);
- FManager.AddNode(pos);
- FManager.AddNode(nor);
- end;
- end;
- procedure DrawCoM;
- var
- com: TGLVector;
- size: Single;
- begin
- FManager.FCurrentColor := FManager.DebugOption.CenterOfMassColor;
- size := FManager.DebugOption.DotAxisSize;
- com := GetAbsCom;
- FManager.AddNode(VectorAdd(com, VectorMake(0, 0, size)));
- FManager.AddNode(VectorAdd(com, VectorMake(0, 0, -size)));
- FManager.AddNode(VectorAdd(com, VectorMake(0, size, 0)));
- FManager.AddNode(VectorAdd(com, VectorMake(0, -size, 0)));
- FManager.AddNode(VectorAdd(com, VectorMake(size, 0, 0)));
- FManager.AddNode(VectorAdd(com, VectorMake(-size, 0, 0)));
- end;
- begin
- inherited;
- // Move/Rotate NewtonObject if matrix are not equal in design time.
- if (csDesigning in FOwnerBaseSceneObject.ComponentState) then
- if not MatrixEquals(NewtonBodyMatrix, FOwnerBaseSceneObject.AbsoluteMatrix) then
- SetNewtonBodyMatrix(FOwnerBaseSceneObject.AbsoluteMatrix);
- NewtonBodyGetAABB(FNewtonBody, @(FAABBmin.AsVector), @(FAABBmax.AsVector));
- if NewtonBodyGetSleepState(FNewtonBody) = 1 then
- FManager.FCurrentColor := FManager.DebugOption.AABBColorSleep
- else
- FManager.FCurrentColor := FManager.DebugOption.AABBColor;
- if mdShowAABB in FManager.DebugOption.NGDManagerDebugs then
- DrawAABB(FAABBmin, FAABBmax);
- if mdShowContact in FManager.DebugOption.NGDManagerDebugs then
- DrawContact;
- DrawForce; // Draw Force, AppliedForce and AppliedVelocity
- if mdShowCenterOfMass in FManager.DebugOption.NGDManagerDebugs then
- DrawCoM;
- end;
- procedure TGLNGDDynamic.SetAutoSleep(const Value: Boolean);
- begin
- FAutoSleep := Value;
- if not(csDesigning in FOwnerBaseSceneObject.ComponentState) then
- if Assigned(FManager) then
- NewtonBodySetAutoSleep(FNewtonBody, Ord(FAutoSleep));
- end;
- procedure TGLNGDDynamic.SetDensity(const Value: Single);
- var
- inertia: TGLVector;
- origin: TGLVector;
- begin
- if Assigned(FManager) then
- if Value >= 0 then
- begin
- FDensity := Value;
- FVolume := NewtonConvexCollisionCalculateVolume(FCollision);
- NewtonConvexCollisionCalculateInertialMatrix(FCollision, @inertia, @origin);
- if IsZero(FVolume, epsilon) then
- begin
- FVolume := FNullCollisionVolume;
- inertia := VectorMake(FNullCollisionVolume, FNullCollisionVolume, FNullCollisionVolume, 0);
- end;
- FMass := FVolume * FDensity;
- if not(csDesigning in FOwnerBaseSceneObject.ComponentState) then
- NewtonBodySetMassMatrix(FNewtonBody, FMass, FMass * inertia.X, FMass * inertia.Y,
- FMass * inertia.Z);
- FCenterOfMass.AsVector := origin;
- end;
- end;
- procedure TGLNGDDynamic.SetLinearDamping(const Value: Single);
- begin
- if (Value >= 0) and (Value <= 1) then
- FLinearDamping := Value;
- if not(csDesigning in FOwnerBaseSceneObject.ComponentState) then
- if Assigned(FManager) then
- NewtonBodySetLinearDamping(FNewtonBody, FLinearDamping);
- end;
- function TGLNGDDynamic.GetOmega: TGLVector;
- begin
- NewtonBodyGetOmega(FNewtonBody, @Result);
- end;
- procedure TGLNGDDynamic.SetOmega(const Omega: TGLVector);
- begin
- NewtonBodySetOmega(FNewtonBody, @Omega);
- end;
- function TGLNGDDynamic.GetVelocity: TGLVector;
- begin
- NewtonBodyGetVelocity(FNewtonBody, @Result);
- end;
- procedure TGLNGDDynamic.SetVelocity(const Velocity: TGLVector);
- begin
- NewtonBodySetVelocity(FNewtonBody, @Velocity);
- end;
- function TGLNGDDynamic.StoredDensity: Boolean;
- begin
- Result := not SameValue(FDensity, 1, epsilon);
- end;
- function TGLNGDDynamic.StoredLinearDamping: Boolean;
- begin
- Result := not SameValue(FLinearDamping, 0.1, epsilon);
- end;
- function TGLNGDDynamic.StoredNullCollisionVolume: Boolean;
- begin
- Result := not SameValue(FNullCollisionVolume, 0, epsilon);
- end;
- procedure TGLNGDDynamic.WriteToFiler(writer: TWriter);
- begin
- inherited;
- with writer do
- begin
- WriteInteger(1); // Archive version
- WriteBoolean(FAutoSleep);
- WriteFloat(FLinearDamping);
- WriteFloat(FDensity);
- WriteBoolean(FUseGravity);
- WriteFloat(FNullCollisionVolume);
- end;
- FForce.WriteToFiler(writer);
- FTorque.WriteToFiler(writer);
- FCenterOfMass.WriteToFiler(writer);
- FAngularDamping.WriteToFiler(writer);
- end;
- procedure TGLNGDDynamic.ReadFromFiler(reader: TReader);
- var
- version: Integer;
- begin
- inherited;
- with reader do
- begin
- version := ReadInteger; // read data version
- Assert(version <= 1); // Archive version
- FAutoSleep := ReadBoolean;
- if version <= 0 then
- FLinearDamping := ReadSingle
- else
- FLinearDamping := ReadFloat;
- if version <= 0 then
- FDensity := ReadSingle
- else
- FDensity := ReadFloat;
- // if Version >= 1 then
- FUseGravity := ReadBoolean;
- if version <= 0 then
- FNullCollisionVolume := ReadSingle
- else
- FNullCollisionVolume := ReadFloat;
- end;
- FForce.ReadFromFiler(reader);
- FTorque.ReadFromFiler(reader);
- FCenterOfMass.ReadFromFiler(reader);
- FAngularDamping.ReadFromFiler(reader);
- end;
- procedure TGLNGDDynamic.Loaded;
- begin
- inherited;
- if Assigned(FManager) then
- begin
- SetAutoSleep(FAutoSleep);
- SetLinearDamping(FLinearDamping);
- SetDensity(FDensity);
- NotifyCenterOfMassChange(self);
- NotifyAngularDampingChange(self);
- end;
- end;
- class procedure TGLNGDDynamic.NewtonApplyForceAndTorque(const body: PNewtonBody; timestep: dFloat;
- threadIndex: Integer); cdecl;
- begin
- TGLNGDDynamic(NewtonBodyGetUserData(body)).FApplyForceAndTorqueEvent(body, timestep, threadIndex);
- end;
- class procedure TGLNGDDynamic.NewtonSetTransform(const body: PNewtonBody; const matrix: PdFloat;
- threadIndex: Integer); cdecl;
- begin
- TGLNGDDynamic(NewtonBodyGetUserData(body)).FSetTransformEvent(body, matrix, threadIndex);
- end;
- procedure TGLNGDDynamic.NotifyAngularDampingChange(Sender: TObject);
- begin
- FAngularDamping.OnNotifyChange := nil;
- if (FAngularDamping.X >= 0) and (FAngularDamping.X <= 1) and (FAngularDamping.Y >= 0) and
- (FAngularDamping.Y <= 1) and (FAngularDamping.Z >= 0) and (FAngularDamping.Z <= 1) then
- if Assigned(FManager) then
- NewtonBodySetAngularDamping(FNewtonBody, @(FAngularDamping.AsVector));
- FAngularDamping.OnNotifyChange := NotifyAngularDampingChange;
- end;
- procedure TGLNGDDynamic.NotifyCenterOfMassChange(Sender: TObject);
- begin
- FCenterOfMass.OnNotifyChange := nil;
- if Assigned(FManager) then
- NewtonBodySetCentreOfMass(FNewtonBody, @(FCenterOfMass.AsVector));
- FCenterOfMass.OnNotifyChange := NotifyCenterOfMassChange;
- end;
- procedure TGLNGDDynamic.OnApplyForceAndTorqueEvent(const cbody: PNewtonBody; timestep: dFloat;
- threadIndex: Integer);
- var
- worldGravity: TGLVector;
- begin
- // Read Only: We get the force and torque resulting from every interaction on this body
- NewtonBodyGetForce(cbody, @(FAppliedForce.AsVector));
- NewtonBodyGetTorque(cbody, @(FAppliedTorque.AsVector));
- NewtonBodyGetVelocity(cbody, @(FAppliedVelocity.AsVector));
- NewtonBodyGetOmega(cbody, @(FAppliedOmega.AsVector));
- // Raise Custom event
- if Assigned(FCustomForceAndTorqueEvent) then
- FCustomForceAndTorqueEvent(cbody, timestep, threadIndex)
- else
- begin
- NewtonBodySetForce(cbody, @(Force.AsVector));
- NewtonBodySetTorque(cbody, @(Torque.AsVector));
- // Add Gravity from World
- if FUseGravity then
- begin
- worldGravity := VectorScale(FManager.Gravity.AsVector, FMass);
- NewtonBodyAddForce(cbody, @(worldGravity));
- end;
- end;
- end;
- procedure TGLNGDDynamic.OnSetTransformEvent(const cbody: PNewtonBody; const cmatrix: PdFloat;
- threadIndex: Integer);
- var
- epsi: Single;
- begin
- // The Newton API does not support scale [scale modifie value in matrix],
- // so this line reset scale of the glsceneObject to (1,1,1)
- // to avoid crashing the application
- epsi := 0.0001;
- with FOwnerBaseSceneObject do
- if not SameValue(Scale.X, 1.0, epsi) or not SameValue(Scale.Y, 1.0, epsi) or
- not SameValue(Scale.Z, 1.0, epsi) then
- begin
- Scale.SetVector(1, 1, 1);
- SetNewtonBodyMatrix(AbsoluteMatrix);
- end
- else
- // Make the Position and orientation of the glscene-Object relative to the
- // NewtonBody position and orientation.
- FOwnerBaseSceneObject.AbsoluteMatrix := PGLMatrix(cmatrix)^;
- end;
- // ------------------------
- // TGLNGDStatic
- // ------------------------
- procedure TGLNGDStatic.Render;
- begin
- inherited;
- // Move/Rotate NewtonObject if matrix are not equal in run time.
- if not MatrixEquals(NewtonBodyMatrix, FOwnerBaseSceneObject.AbsoluteMatrix) then
- SetNewtonBodyMatrix(FOwnerBaseSceneObject.AbsoluteMatrix);
- end;
- class function TGLNGDStatic.FriendlyName: string;
- begin
- Result := 'NGD Static';
- end;
- // ------------------------
- // TGLNGDSurfaceItem
- // ------------------------
- function TGLNGDSurfaceItem.GetDisplayName: string;
- begin
- if FDisplayName = '' then
- FDisplayName := 'Iron';
- Result := FDisplayName;
- end;
- procedure TGLNGDSurfaceItem.SetDisplayName(const Value: string);
- begin
- inherited;
- FDisplayName := Value;
- end;
- // ------------------------
- // TGLNGDSurfacePair
- // ------------------------
- constructor TGLNGDSurfacePair.Create(Collection: TCollection);
- begin
- inherited;
- FSoftness := 0.1;
- FElasticity := 0.4;
- FCollidable := True;
- FStaticFriction := 0.9;
- FKineticFriction := 0.5;
- FContinuousCollisionMode := False;
- FThickness := False;
- FAABBOverlapEvent := OnNewtonAABBOverlapEvent;
- FContactProcessEvent := OnNewtonContactsProcessEvent;
- FManager := TGLNGDManager(Collection.Owner);
- FManager.RebuildAllMaterial;
- end;
- class function TGLNGDSurfacePair.NewtonAABBOverlap(const material: PNewtonMaterial;
- const body0, body1: PNewtonBody; threadIndex: Integer): Integer; cdecl;
- begin
- Result := Ord(TGLNGDSurfacePair(NewtonMaterialGetMaterialPairUserData(material))
- .FAABBOverlapEvent(material, body0, body1, threadIndex));
- end;
- class procedure TGLNGDSurfacePair.NewtonContactsProcess(const contact: PNewtonJoint;
- timestep: dFloat; threadIndex: Integer); cdecl;
- begin
- TGLNGDSurfacePair(NewtonMaterialGetMaterialPairUserData
- (NewtonContactGetMaterial(NewtonContactJointGetFirstContact(contact))))
- .FContactProcessEvent(contact, timestep, threadIndex);
- end;
- function TGLNGDSurfacePair.OnNewtonAABBOverlapEvent(const cmaterial: PNewtonMaterial;
- const cbody0, cbody1: PNewtonBody; threadIndex: Integer): Boolean;
- begin
- Result := True;
- end;
- procedure TGLNGDSurfacePair.OnNewtonContactsProcessEvent(const ccontact: PNewtonJoint;
- timestep: dFloat; threadIndex: Integer);
- begin
- //
- end;
- procedure TGLNGDSurfacePair.SetCollidable(const Value: Boolean);
- begin
- FCollidable := Value;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetContinuousCollisionMode(const Value: Boolean);
- begin
- FContinuousCollisionMode := Value;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetElasticity(const Value: Single);
- begin
- if (Value >= 0) then
- FElasticity := Value;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetKineticFriction(const Value: Single);
- begin
- if (Value >= 0) and (Value <= 1) then
- FKineticFriction := Value;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetMaterialItems(const item1, item2: TGLNGDSurfaceItem);
- begin
- FSurfaceItem1 := item1;
- FSurfaceItem2 := item2;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetSoftness(const Value: Single);
- begin
- if (Value >= 0) and (Value <= 1) then
- FSoftness := Value;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetStaticFriction(const Value: Single);
- begin
- if (Value >= 0) and (Value <= 1) then
- FStaticFriction := Value;
- FManager.RebuildAllMaterial;
- end;
- procedure TGLNGDSurfacePair.SetThickness(const Value: Boolean);
- begin
- FThickness := Value;
- FManager.RebuildAllMaterial;
- end;
- function TGLNGDSurfacePair.StoredElasticity: Boolean;
- begin
- Result := not SameValue(FElasticity, 0.4, epsilon);
- end;
- function TGLNGDSurfacePair.StoredKineticFriction: Boolean;
- begin
- Result := not SameValue(FKineticFriction, 0.5, epsilon);
- end;
- function TGLNGDSurfacePair.StoredSoftness: Boolean;
- begin
- Result := not SameValue(FSoftness, 0.1, epsilon);
- end;
- function TGLNGDSurfacePair.StoredStaticFriction: Boolean;
- begin
- Result := not SameValue(FStaticFriction, 0.9, epsilon);
- end;
- // ------------------------
- // TGLNGDJoint
- // ------------------------
- constructor TGLNGDJoint.Create(Collection: TCollection);
- begin
- inherited;
- FCollisionState := False;
- FStiffness := 0.9;
- FNewtonJoint := nil;
- FNewtonUserJoint := nil;
- FParentObject := nil;
- FChildObject := nil;
- FManager := TGLNGDManager(Collection.Owner);
- FBallAndSocketOptions := TGLNGDJointPivot.Create(FManager, self);
- FHingeOptions := TGLNGDJointPin.Create(FManager, self);
- FSliderOptions := TGLNGDJointPin.Create(FManager, self);
- FCorkscrewOptions := TGLNGDJointPin.Create(FManager, self);
- FUniversalOptions := TGLNGDJointPin2.Create(FManager, self);
- FCustomBallAndSocketOptions := TGLNGDJointBallAndSocket.Create(FManager, self);
- FCustomHingeOptions := TGLNGDJointHinge.Create(FManager, self);
- FCustomSliderOptions := TGLNGDJointSlider.Create(FManager, self);
- FKinematicOptions := TGLNGDJointKinematicController.Create;
- FUPVectorDirection := TGLCoordinates.CreateInitialized(self, YHmgVector, csVector);
- FUPVectorDirection.OnNotifyChange := FManager.RebuildAllJoint;
- end;
- destructor TGLNGDJoint.Destroy;
- begin
- DestroyNewtonData;
- FParentObject := nil;
- FChildObject := nil;
- // Free options
- FBallAndSocketOptions.Free;
- FHingeOptions.Free;
- FSliderOptions.Free;
- FCorkscrewOptions.Free;
- FUniversalOptions.Free;
- FCustomBallAndSocketOptions.Free;
- FCustomHingeOptions.Free;
- FCustomSliderOptions.Free;
- FKinematicOptions.Free;
- FUPVectorDirection.Free;
- inherited;
- end;
- procedure TGLNGDJoint.DestroyNewtonData;
- begin
- if FNewtonJoint <> nil then
- begin
- Assert((FManager <> nil) and (FManager.FNewtonWorld <> nil));
- NewtonDestroyJoint(FManager.FNewtonWorld, FNewtonJoint);
- FNewtonJoint := nil;
- end;
- if FNewtonUserJoint <> nil then
- begin
- (* CustomDestroyJoint(FNewtonUserJoint); *) // from dJointLibrary.dll
- FNewtonUserJoint := nil;
- end;
- end;
- procedure TGLNGDJoint.KinematicControllerPick(pickpoint: TGLVector;
- PickedActions: TGLNGDPickedActions);
- begin
- (* CustomDestroyJoint(FNewtonUserJoint); //from dJointLibrary.dll
- if FJointType = nj_KinematicController then
- if Assigned(FParentObject) then
- begin
- // Creates the joint
- if PickedActions = paAttach then
- begin
- if not Assigned(FNewtonUserJoint) then
- if Assigned(GetNGDDynamic(FParentObject).FNewtonBody) then
- FNewtonUserJoint := CreateCustomKinematicController
- (GetNGDDynamic(FParentObject).FNewtonBody, @pickpoint);
- end;
- // Change the TargetPoint
- if (PickedActions = paMove) or (PickedActions = paAttach) then
- begin
- if Assigned(FNewtonUserJoint) then
- begin
- CustomKinematicControllerSetPickMode(FNewtonUserJoint,
- Ord(FKinematicOptions.FPickModeLinear));
- CustomKinematicControllerSetMaxLinearFriction(FNewtonUserJoint,
- FKinematicOptions.FLinearFriction);
- CustomKinematicControllerSetMaxAngularFriction(FNewtonUserJoint,
- FKinematicOptions.FAngularFriction);
- CustomKinematicControllerSetTargetPosit(FNewtonUserJoint, @pickpoint);
- end;
- end;
- // Delete the joint
- if PickedActions = paDetach then
- begin
- if Assigned(FNewtonUserJoint) then
- begin
- CustomDestroyJoint(FNewtonUserJoint);
- FNewtonUserJoint := nil;
- // Reset autosleep because this joint turns it off
- NewtonBodySetAutoSleep(GetNGDDynamic(FParentObject).FNewtonBody,
- Ord(GetNGDDynamic(FParentObject).AutoSleep));
- end;
- ParentObject := nil;
- end;
- end;
- *)
- end;
- procedure TGLNGDJoint.Render;
- procedure DrawPivot(pivot: TGLVector);
- var
- size: Single;
- begin
- size := FManager.DebugOption.DotAxisSize;
- FManager.FCurrentColor := FManager.DebugOption.JointPivotColor;
- FManager.AddNode(VectorAdd(pivot, VectorMake(0, 0, size)));
- FManager.AddNode(VectorAdd(pivot, VectorMake(0, 0, -size)));
- FManager.AddNode(VectorAdd(pivot, VectorMake(0, size, 0)));
- FManager.AddNode(VectorAdd(pivot, VectorMake(0, -size, 0)));
- FManager.AddNode(VectorAdd(pivot, VectorMake(size, 0, 0)));
- FManager.AddNode(VectorAdd(pivot, VectorMake(-size, 0, 0)));
- end;
- procedure DrawPin(pin, pivot: TGLVector);
- begin
- FManager.FCurrentColor := FManager.DebugOption.JointAxisColor;
- FManager.AddNode(VectorAdd(pivot, pin));
- FManager.AddNode(VectorAdd(pivot, VectorNegate(pin)));
- end;
- procedure DrawJoint(pivot: TGLVector);
- begin
- FManager.FCurrentColor := FManager.DebugOption.CustomColor;
- FManager.AddNode(FParentObject.AbsolutePosition);
- FManager.AddNode(pivot);
- FManager.AddNode(pivot);
- FManager.AddNode(FChildObject.AbsolutePosition);
- end;
- procedure DrawKinematic;
- var
- pickedMatrix: TGLMatrix;
- size: Single;
- begin
- size := FManager.DebugOption.DotAxisSize;
- /// From dJointLibrary.dll
- /// CustomKinematicControllerGetTargetMatrix(FNewtonUserJoint, @pickedMatrix);
- FManager.FCurrentColor := FManager.DebugOption.JointAxisColor;
- FManager.AddNode(FParentObject.AbsolutePosition);
- FManager.AddNode(pickedMatrix.W);
- FManager.FCurrentColor := FManager.DebugOption.JointPivotColor;
- FManager.AddNode(VectorAdd(pickedMatrix.W, VectorMake(0, 0, size)));
- FManager.AddNode(VectorAdd(pickedMatrix.W, VectorMake(0, 0, -size)));
- FManager.AddNode(VectorAdd(pickedMatrix.W, VectorMake(0, size, 0)));
- FManager.AddNode(VectorAdd(pickedMatrix.W, VectorMake(0, -size, 0)));
- FManager.AddNode(VectorAdd(pickedMatrix.W, VectorMake(size, 0, 0)));
- FManager.AddNode(VectorAdd(pickedMatrix.W, VectorMake(-size, 0, 0)));
- end;
- begin
- case FJointType of
- nj_BallAndSocket:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FBallAndSocketOptions.FPivotPoint.AsVector);
- DrawPivot(FBallAndSocketOptions.FPivotPoint.AsVector);
- end;
- nj_Hinge:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FHingeOptions.FPivotPoint.AsVector);
- DrawPin(FHingeOptions.FPinDirection.AsVector, FHingeOptions.FPivotPoint.AsVector);
- DrawPivot(FHingeOptions.FPivotPoint.AsVector);
- end;
- nj_Slider:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FSliderOptions.FPivotPoint.AsVector);
- DrawPin(FSliderOptions.FPinDirection.AsVector, FSliderOptions.FPivotPoint.AsVector);
- DrawPivot(FSliderOptions.FPivotPoint.AsVector);
- end;
- nj_Corkscrew:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FCorkscrewOptions.FPivotPoint.AsVector);
- DrawPin(FCorkscrewOptions.FPinDirection.AsVector, FCorkscrewOptions.FPivotPoint.AsVector);
- DrawPivot(FCorkscrewOptions.FPivotPoint.AsVector);
- end;
- nj_Universal:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FUniversalOptions.FPivotPoint.AsVector);
- DrawPin(FUniversalOptions.FPinDirection.AsVector, FUniversalOptions.FPivotPoint.AsVector);
- DrawPin(FUniversalOptions.FPinDirection2.AsVector, FUniversalOptions.FPivotPoint.AsVector);
- DrawPivot(FUniversalOptions.FPivotPoint.AsVector);
- end;
- nj_CustomBallAndSocket:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FCustomBallAndSocketOptions.FPivotPoint.AsVector);
- DrawPivot(FCustomBallAndSocketOptions.FPivotPoint.AsVector);
- end;
- nj_CustomHinge:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FCustomHingeOptions.FPivotPoint.AsVector);
- DrawPin(FCustomHingeOptions.FPinDirection.AsVector,
- FCustomHingeOptions.FPivotPoint.AsVector);
- DrawPivot(FCustomHingeOptions.FPivotPoint.AsVector);
- end;
- nj_CustomSlider:
- if Assigned(FParentObject) and Assigned(FChildObject) then
- begin
- DrawJoint(FCustomSliderOptions.FPivotPoint.AsVector);
- DrawPin(FCustomSliderOptions.FPinDirection.AsVector,
- FCustomSliderOptions.FPivotPoint.AsVector);
- DrawPivot(FCustomSliderOptions.FPivotPoint.AsVector);
- end;
- nj_UpVector:
- if Assigned(FParentObject) then
- begin // special
- FManager.FCurrentColor := FManager.DebugOption.JointAxisColor;
- FManager.AddNode(FParentObject.AbsolutePosition);
- FManager.AddNode(VectorAdd(FParentObject.AbsolutePosition, FUPVectorDirection.AsVector));
- end;
- nj_KinematicController:
- if Assigned(FParentObject) and Assigned(FNewtonUserJoint) then
- begin // special
- DrawKinematic;
- end;
- end;
- end;
- procedure TGLNGDJoint.SetChildObject(const Value: TGLBaseSceneObject);
- begin
- FChildObject := Value;
- FManager.RebuildAllJoint(self);
- end;
- procedure TGLNGDJoint.SetCollisionState(const Value: Boolean);
- begin
- FCollisionState := Value;
- FManager.RebuildAllJoint(self);
- end;
- procedure TGLNGDJoint.SetJointType(const Value: TGLNGDJoints);
- begin
- FJointType := Value;
- FManager.RebuildAllJoint(self);
- end;
- procedure TGLNGDJoint.SetParentObject(const Value: TGLBaseSceneObject);
- begin
- FParentObject := Value;
- FManager.RebuildAllJoint(self);
- end;
- procedure TGLNGDJoint.SetStiffness(const Value: Single);
- begin
- if (Value >= 0) and (Value <= 1) then
- begin
- FStiffness := Value;
- FManager.RebuildAllJoint(self);
- end;
- end;
- function TGLNGDJoint.StoredStiffness: Boolean;
- begin
- Result := not SameValue(FStiffness, 0.9, epsilon);
- end;
- // ------------------------
- // TGLNGDJointPivot
- // ------------------------
- constructor TGLNGDJointPivot.Create(AOwner: TComponent; aOuter: TGLNGDJoint);
- begin
- FManager := AOwner as TGLNGDManager;
- FOuter := aOuter;
- FPivotPoint := TGLCoordinates.CreateInitialized(aOuter, NullHMGPoint, csPoint);
- FPivotPoint.OnNotifyChange := FManager.RebuildAllJoint;
- end;
- destructor TGLNGDJointPivot.Destroy;
- begin
- FPivotPoint.Free;
- inherited;
- end;
- // ------------------------
- // TGLNGDJointPin
- // ------------------------
- constructor TGLNGDJointPin.Create(AOwner: TComponent; aOuter: TGLNGDJoint);
- begin
- inherited;
- FPinDirection := TGLCoordinates.CreateInitialized(aOuter, NullHmgVector, csVector);
- FPinDirection.OnNotifyChange := FManager.RebuildAllJoint;
- end;
- destructor TGLNGDJointPin.Destroy;
- begin
- FPinDirection.Free;
- inherited;
- end;
- // ------------------------
- // TGLNGDJointPin2
- // ------------------------
- constructor TGLNGDJointPin2.Create(AOwner: TComponent; aOuter: TGLNGDJoint);
- begin
- inherited;
- FPinDirection2 := TGLCoordinates.CreateInitialized(aOuter, NullHmgVector, csVector);
- FPinDirection2.OnNotifyChange := FManager.RebuildAllJoint;
- end;
- destructor TGLNGDJointPin2.Destroy;
- begin
- FPinDirection2.Free;
- inherited;
- end;
- // ------------------------
- // TGLNGDJointBallAndSocket
- // ------------------------
- constructor TGLNGDJointBallAndSocket.Create(AOwner: TComponent; aOuter: TGLNGDJoint);
- begin
- inherited;
- FConeAngle := 90;
- FMinTwistAngle := -90;
- FMaxTwistAngle := 90;
- end;
- procedure TGLNGDJointBallAndSocket.SetConeAngle(const Value: Single);
- begin
- FConeAngle := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- procedure TGLNGDJointBallAndSocket.SetMaxTwistAngle(const Value: Single);
- begin
- FMaxTwistAngle := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- procedure TGLNGDJointBallAndSocket.SetMinTwistAngle(const Value: Single);
- begin
- FMinTwistAngle := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- function TGLNGDJointBallAndSocket.StoredConeAngle: Boolean;
- begin
- Result := not SameValue(FConeAngle, 90, epsilon);
- end;
- function TGLNGDJointBallAndSocket.StoredMaxTwistAngle: Boolean;
- begin
- Result := not SameValue(FMaxTwistAngle, 90, epsilon);
- end;
- function TGLNGDJointBallAndSocket.StoredMinTwistAngle: Boolean;
- begin
- Result := not SameValue(FMinTwistAngle, -90, epsilon);
- end;
- // ------------------------
- // TGLNGDJointHinge
- // ------------------------
- constructor TGLNGDJointHinge.Create(AOwner: TComponent; aOuter: TGLNGDJoint);
- begin
- inherited;
- FMinAngle := -90;
- FMaxAngle := 90;
- end;
- procedure TGLNGDJointHinge.SetMaxAngle(const Value: Single);
- begin
- FMaxAngle := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- procedure TGLNGDJointHinge.SetMinAngle(const Value: Single);
- begin
- FMinAngle := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- function TGLNGDJointHinge.StoredMaxAngle: Boolean;
- begin
- Result := not SameValue(FMaxAngle, 90, epsilon);
- end;
- function TGLNGDJointHinge.StoredMinAngle: Boolean;
- begin
- Result := not SameValue(FMinAngle, -90, epsilon);
- end;
- // ------------------------
- // TGLNGDJointSlider
- // ------------------------
- constructor TGLNGDJointSlider.Create(AOwner: TComponent; aOuter: TGLNGDJoint);
- begin
- inherited;
- FMinDistance := -10;
- FMaxDistance := 10;
- end;
- procedure TGLNGDJointSlider.SetMaxDistance(const Value: Single);
- begin
- FMaxDistance := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- procedure TGLNGDJointSlider.SetMinDistance(const Value: Single);
- begin
- FMinDistance := Value;
- FManager.RebuildAllJoint(FOuter);
- end;
- function TGLNGDJointSlider.StoredMaxDistance: Boolean;
- begin
- Result := not SameValue(FMaxDistance, 10, epsilon);
- end;
- function TGLNGDJointSlider.StoredMinDistance: Boolean;
- begin
- Result := not SameValue(FMinDistance, -10, epsilon);
- end;
- // ----------------------------------
- // TGLNGDJointKinematicController
- // ----------------------------------
- constructor TGLNGDJointKinematicController.Create;
- begin
- FPickModeLinear := False;
- FLinearFriction := 750;
- FAngularFriction := 250;
- end;
- function TGLNGDJointKinematicController.StoredAngularFriction: Boolean;
- begin
- Result := not SameValue(FAngularFriction, 250, epsilon);
- end;
- function TGLNGDJointKinematicController.StoredLinearFriction: Boolean;
- begin
- Result := not SameValue(FLinearFriction, 750, epsilon);
- end;
- // ------------------------
- // TGLNGDBehaviourList
- // ------------------------
- function TGLNGDBehaviourList.GetBehav(index: Integer): TGLNGDBehaviour;
- begin
- Result := Items[index];
- end;
- procedure TGLNGDBehaviourList.PutBehav(index: Integer; Item: TGLNGDBehaviour);
- begin
- inherited put(index, Item);
- end;
- // ------------------------------------------------------------------
- initialization
- // ------------------------------------------------------------------
- RegisterXCollectionItemClass(TGLNGDDynamic);
- RegisterXCollectionItemClass(TGLNGDStatic);
- // ------------------------------------------------------------------
- finalization
- // ------------------------------------------------------------------
- UnregisterXCollectionItemClass(TGLNGDDynamic);
- UnregisterXCollectionItemClass(TGLNGDStatic);
- // CloseNGD;
- end.
|