Motor V. Ütközés detektálás és válasz Szécsi László.

Slides:



Advertisements
Hasonló előadás
Eisenbahn-Unfalluntersuchungsstelle des Bundes KBSZ Szakmai találkozó Siófok, október 8. Bundesministerium für Verkehr, Bau- und Stadtentwicklung.
Advertisements

1. foreach( fejlesztő in Lurdyház ) { fejlesztő.Agy. Delete If( delegate ( Content c ) { return c.ContainsAny( „Win32 / User32.dll”, „GDI”,„GDI+”,„WindowsForms”,
Térfogatvizualizáció Szirmay-Kalos László. Térfogati modellek v(x,y,z) hőmérséklet sűrűség légnyomás potenciál anyagfeszültség... v(x,y,z) tárolás: 3D.
Bevezetés a tárgyakhoz Tárgyak  Objects are the containers for values of a specified type  Objects are either signals, variables or constants  Once.
FelültöltésVHDL Felültöltés (Overloading) n Áttekintés n Példák.
Szécsi László. June 2010 DirectX SDK Visual Studio 2010.
Grafikus játékok fejlesztése Szécsi László t14-physics
 Lineáris egyenlet  algebrai egyenlet  konstansok és első fokú ismeretlenek  pl.: egyenes egyenlete  Lineáris egyenletrendszer  lineáris egyenletek.
 Gauss szűrő uniform sampler2D colorMap; const float kernel[9] = float[9]( 1.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 1.0); out vec4 outColor; void main(){
 Fény fotonok szimulációja  Nem változtatja meg a frekvenciát ütközéskor  Homogén és inhomogén közegben.
Socket programozás Példák
Basics A few things one must know. Slides Insert a title slide Put a title on it.
Kapcsolat az adatabázishoz - Előkészületek // Implementation public: void ReleaseDataBase(); void ConnectDataBase(CString s); virtual ~CBankDoc(); protected:
TRANZIENS ADATTÁROLÁS State objektum Egy alkalmazásszintű gyűjtemény (Dictionary), mely Tombstone esetén megőrzi tartalmát a memóriában kulcs/érték párokként.
Programozás II. 3. Gyakorlat C++ alapok.
Delegátumok C#-ban Krizsán Zoltán iit 1.0.
Course Situation and Event Driven Models for Multilevel Abstraction Based Virtual Engineering Spaces Óbuda University John von Neumann Faculty of Informatics.
The worlds biggest hole is located in Russia. The giant hole is actually a diamond mine in Eastern Siberia near the town of Mirna.It is 525 m deep and.
Oracle multimédia Kiss Attila Információs Rendszerek Tanszék
Bevezetés a kísérleti részecskefizikába 2OO7.
PHP VI Adatbázisok, MySQL
PHP V Osztályok, Objektumok. Osztály class Person { var $name; // tulajdonság, változó function getName() { // metódus, tagfüggvény return $this->name;
Windows Server 2008 { PowerShell }
Gábor Dénes Főiskola (IAI)Programozási technológia (Java) - III. / 1 13.Állományok, bejegyzések 14.Folyamok 15.Közvetlen hozzáférésű állomány.
Hasznos ismeretek Hogyan bővítsük ismereteinket AVRDUDEflags -E noreset.
Vizuális programozás Rajzolás Windows Forms alkalmazásokban GDI+
Tervezési példák és ötletek Összeadók Összeadók Vektor szorzás Vektor szorzás Erőforrás megosztás Erőforrás megosztás Összehasonlítók (comparators) Összehasonlítók.
Könyvtár, csomag és alprogramokVHDL Könyvtár, csomag és alprogram n Library és use n Package n Alprogramok –Procedure –Function –Resolution function Egy.
Termikus szimuláció kiegészítés. Heat equation Boundary conditions ­second kind (Neumann) ­third kind (Robin) ­first kind (Dirichlet)
Típusváltás (Type Conversion) n Áttekintés n Példák.
1 AAO folytatás ++ Csink László. 2 Rekurzív bináris keresés (rendezett tömbben) public static int binker(int[] tomb, int value, int low, int high) public.
Térfogatvizualizáció Szirmay-Kalos László. Térfogati modellek v(x,y,z) hőmérséklet sűrűség légnyomás potenciál anyagfeszültség... v(x,y,z) tárolás: 3D.
Motor IIII. Vezérlés Szécsi László. Letöltés diák: //l09-engine4.ppt.
Motor IIII. PhysX utáni rendberakás Vezérlés Szécsi László.
Pozitron-Emission Tomography Reconstruction (A computer graphics view) Szirmay-Kalos László.
Motor II. Env map Spotlight Szécsi László. Letöltés /code/E/code/EggCoreSecondBase.zip Kibontani (vagy előző labor folyt.):
Terep Szécsi László. Mechanizmus NxHeightField-ek definiálása PhysicsModel-be NxHeightFieldShapeDesc-ek betöltése Mesh-ek gyártása az NxHeightField- ekből.
PhysX autó Szécsi László. Letöltés diák: bagira.iit.bme.hu/~szecsi/GraphGame //l12-car.ppt modell: bagira.iit.bme.hu/~szecsi/GraphGame //pickup.zip.
DirectX9 empty project Szécsi László. Visual Studio Első indításkor C++ választása.
Motor I. Scene graph XML Rendering Szécsi László.
Environment mapping Szécsi László. Új osztály: Lab3EnvMap copy&paste: Lab2Trafo.h -> Lab3EnvMap.h copy&paste: Lab2Trafo.cpp -> Lab3EnvMap.cpp copy&paste:
Vízfelület Szécsi László. Nyílt víz a nyílt óceánon a felületi cseppecskék körmozgást végeznek trochoid hullámforma hullámhossz hullámmagasság amplitúdó.
PhysX integráció Szécsi László. Letöltés diák: bagira.iit.bme.hu/~szecsi/GraphGame //l11-physx.ppt modell: bagira.iit.bme.hu/~szecsi/GraphGame //pickup.zip.
Transzformációk, textúrák, árnyalás Szécsi László.
DirectX9 empty project Szécsi László. Project létrehozása Microsoft DirectX SDK (August 2008) telepítése Start Menu \ Microsoft DirectX SDK (August 2008)\
V. labor Thread, animáció. Animáció A figurák a lépés kijelölése után nem rögtön az új helyen teremnek, hanem egyenes vonal mentén mozognak a cél felé.
OIS. Kezdeti teendők Letöltés: OgreLabControllersBase.zip Kicsomagol, betölt:.sln Additional include és library path beállítása Working directory beállítása.
Analitikus geometria gyorstalpaló
II. labor Lépések kezelése. Új metódus a Square osztályba public static int letterToFileIndex(char letter) throws NumberFormatException { int i = 0; for.
III. labor AWT, eseménykezelés Applet. Új class: ButtonView import java.awt.*; import java.awt.event.*; import java.util.LinkedList; public class ButtonView.
Kamera, 3D, transzformációk Szécsi László. Math.zip kibontása az Egg projectkönyvtárba – float2, foat3, float4 típusok, HLSL-ben megszokott műveletekkel.
Effect framework, HLSL shader László Szécsi. forráskódban elérhető egyszerűsíti a shaderek fordítását, rajzolási állapot beállítását – pass: egy ilyen.
Geometry instancing Szécsi László. copy-paste-rename gg009-Gui folder vcxproj, filters átnevezés solution/add existing project rename project working.
User interface Szécsi László. Egg projectben DXUTgui.cpp – CDXUTDialogResourceManager::CDXUTDialogReso urceManager() m_SpriteBufferBytes11 = 0; ezt kihagyták,
Textúrázás Szécsi László. giraffe.jpg letöltése SolutionDir/Media folderbe.
 Map  Reduce  Scan  Histogram  Compact const size_t dataSize = 1024; cl_kernel mapKernel = cl.createKernel(clProgram, "map"); float* hData = new.
 Kvantált kép fényesség értékei: G [ 0, Gmax ]  G fényességű pontok száma: P(G)
GPGPU labor XII. Tomográfiás rekonstrukció. Kezdeti teendők Tantárgy honlapja, Monte Carlo szimuláció A labor kiindulási alapjának letöltése (lab12_base.zip),
GPGPU labor X. Monte Carlo módszerek. Kezdeti teendők Tantárgy honlapja, Monte Carlo módszerek A labor kiindulási alapjának letöltése (lab10_base.zip),
GPGPU labor IX. Lineáris egyenletrendszerek megoldása.
GPGPU Labor 15.. Párhuzamos primitívek Map Reduce Scan Histogram Compact.
GPGPU labor II. GPU mint vektor processzor. Kezdeti teendők Tantárgy honlapja, Bevezetés – Alap könyvtárak letöltése Tantárgy honlapja, GPU mint vektor.
Készült az ERFP – DD2002 – HU – B – 01 szerzősésszámú projekt támogatásával Chapter 7 / 1 C h a p t e r 7 Behaviour of Plate Elements of Steel Frames.
Készült az ERFP – DD2002 – HU – B – 01 szerzősésszámú projekt támogatásával Chapter 6 / 1 C h a p t e r 6 Elastic Critical Plate Buckling Loads.
HTTP kommunikáció Androidon HttpClient-en keresztűl HttpPost/HttpGet objektum használatával HttpClient execute metódusának meghívása.
2. gyakorlat DirectX 2007/2008 tavasz Klár Gergely
ELTE-IK, Számítógépes grafika 2./haladó 2. gyakorlat Klár Gergely.
Motor IIII. PhysX utáni rendberakás Vezérlés Szécsi László.
Ruletták a Minkowski síkon
ZUMTOBEL CARICA-T M 1/35W QT12 ETR BK Description
Előadás másolata:

Motor V. Ütközés detektálás és válasz Szécsi László

Letöltés diák: //l10-collision.ppt

Új osztály: FatCollider class FatCollider { friend class RigidBody; friend class RigidModel; protected: double thickness; double density; double restitution; double friction;

FatCollider folyt. FatCollider(double density, double thickness, double restitution, double friction); double getRestitution(); double getFriction(); virtual double getMass()=0; virtual void getAngularMass(D3DXMATRIX& massMatrix)=0;

FatCollider folyt. virtual void getNearestPointTo( const D3DXVECTOR3& b, D3DXVECTOR3& out)=0; virtual void getReferencePoint(D3DXVECTOR3& out)=0; virtual FatCollider* makeTransformedClone( const D3DXMATRIX& transformationMatrix)=0; virtual void translate(const D3DXVECTOR3& offset)=0; };

FatCollider.cpp FatCollider::FatCollider(double density, double thickness, double restitution, double friction) { this->density = density; this->thickness = thickness; this->restitution = restitution; this->friction = friction; } double FatCollider::getRestitution() { return restitution; } double FatCollider::getFriction() {return friction; }

Új class: FatCylinder class FatCylinder : public FatCollider { double radius; double height; D3DXVECTOR3 position; D3DXVECTOR3 discNormal;

FatCylinder folyt. public: FatCylinder(double density, double thickness, double restitution, double friction, double radius, double height, const D3DXVECTOR3& position, const D3DXVECTOR3& discNormal); double getMass(); void getAngularMass(D3DXMATRIX& massMatrix);

FatCylinder folyt. void getNearestPointTo(const D3DXVECTOR3& b, D3DXVECTOR3& out); void getReferencePoint(D3DXVECTOR3& out); FatCollider* makeTransformedClone(const D3DXMATRIX& transformationMatrix); void translate(const D3DXVECTOR3& offset); };

FatCylinder.cpp FatCylinder::FatCylinder(double density, double thickness, double restitution, double friction, double radius, double height, const D3DXVECTOR3& position, const D3DXVECTOR3& discNormal) :FatCollider(density, thickness, restitution, friction) { this->radius = radius; this->position = position; this->discNormal = discNormal; this->height = height; }

FatCylinder.cpp double FatCylinder::getMass() { return density * (radius + thickness) * (radius + thickness) * 3.14 * (height + thickness * 2.0); }

FatCylinder.cpp void FatCylinder::getAngularMass(D3DXMATRIX& massMatrix) { double mass = getMass(); double cylinderRadius = radius + thickness; double cylinderRadius2 = cylinderRadius * cylinderRadius; double cylinderHeight2 = (height + thickness * 2.0) * (height + thickness * 2.0); D3DXMatrixScaling(&massMatrix, mass * (3.0 * cylinderRadius2 + cylinderHeight2) / 12.0, mass * cylinderRadius2 * 0.5, mass * (3.0 * cylinderRadius2 + cylinderHeight2) / 12.0); D3DXVECTOR3 rotationAxis; D3DXVec3Cross(&rotationAxis, &discNormal, &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); float rotationAngle = acos(discNormal.y); D3DXMATRIX transformMatrix, transposedTransformMatrix; D3DXMatrixRotationAxis(&transformMatrix, &rotationAxis, rotationAngle); D3DXMatrixTranspose(&transposedTransformMatrix, &transformMatrix); D3DXMATRIX translationMassMatrix; float mrr = mass * D3DXVec3LengthSq(&position); D3DXMatrixScaling(&translationMassMatrix, mrr, mrr, mrr); D3DXMATRIX posProducts( mass * position.x * position.x, mass * position.x * position.y, mass * position.x * position.z, 0.0f, mass * position.y * position.x, mass * position.y * position.y, mass * position.y * position.z, 0.0f, mass * position.z * position.x, mass * position.z * position.y, mass * position.z * position.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); translationMassMatrix -= posProducts; massMatrix = transposedTransformMatrix * massMatrix * transformMatrix + translationMassMatrix; }

FatCylinder.cpp void FatCylinder::getNearestPointTo(const D3DXVECTOR3& b, D3DXVECTOR3& out) { out = b; out -= position; D3DXVECTOR3 onNormal = discNormal * D3DXVec3Dot(&out, &discNormal); D3DXVECTOR3 onTangent = out - onNormal; float ln = D3DXVec3Length(&onNormal); if(ln > height * 0.5) onNormal *= height * 0.5 / ln; float ld = D3DXVec3Length(&onTangent); if(ld > radius) onTangent *= radius / ld; out = onNormal + onTangent + position; }

FatCylinder.cpp void FatCylinder::getReferencePoint( D3DXVECTOR3& out) { out = position; } void FatCylinder::translate(const D3DXVECTOR3& offset) { position += offset; }

FatCylinder.cpp FatCollider* FatCylinder::makeTransformedClone(const D3DXMATRIX& transformationMatrix) { D3DXVECTOR3transformedPosition, transformedNormal; D3DXVec3TransformCoord(&transformedPosition, &position, &transformationMatrix); D3DXVec3TransformNormal(&transformedNormal, &discNormal, &transformationMatrix); return new FatCylinder(density, thickness, restitution, friction, radius, height, transformedPosition, transformedNormal); }

RigidModel kieg. #include "FatCollider.h" class RigidModel{ D3DXVECTOR3 centreOfMass; std::vector colliders; void recomputeMass();

RigidModel public: void addFatCollider(FatCollider* collider); void translateToCentreOfMass(); const D3DXVECTOR3& getCentreOfMass();

RigidModel.cpp void RigidModel::addFatCollider(FatCollid er* collider) { colliders.push_back(collider); recomputeMass(); }

RigidModel.cpp void RigidModel::recomputeMass() { double mass = 0; D3DXMATRIX angularMass; D3DXMatrixScaling(&angularMass, 0.0f, 0.0f, 0.0f); std::vector ::iterator i = colliders.begin(); while(i != colliders.end()){ if( (*i)->density == 0.0){ invMass = 0.0;D3DXMatrixScaling(&invAngularMass, 0, 0, 0); return;} mass += (*i)->getMass(); D3DXMATRIX colliderAngularMass; (*i)->getAngularMass(colliderAngularMass); angularMass += colliderAngularMass; i++; } invMass = 1.0 / mass; angularMass._44 = 1.0f; D3DXMatrixInverse(&invAngularMass, NULL, &angularMass); }

RigidModel.cpp void RigidModel::translateToCentreOfMass() { centreOfMass = D3DXVECTOR3(0, 0, 0); std::vector ::iterator i = colliders.begin(); while(i != colliders.end()){ if( (*i)->density == 0.0) {centreOfMass == D3DXVECTOR3(0, 0, 0); return;} double m = (*i)->getMass(); D3DXVECTOR3 com; (*i)->getReferencePoint(com); centreOfMass += com * m; i++; } centreOfMass *= invMass; std::vector ::iterator ii = colliders.begin(); while(ii != colliders.end()){ (*ii)->translate(-centreOfMass);ii++;} recomputeMass(); }

RigidModel.cpp const D3DXVECTOR3& RigidModel::getCentreOfMass() { return centreOfMass; }

EngineCore::loadRigidModels loadFatCylinders(rigidModelNode, rigidModel); rigidModel->translateToCentreOfMass(); rigidModelDirectory[rigidModelName] = rigidModel;

EngineCore osztályba void loadFatCylinders( XMLNode& rigidModelNode, RigidModel* rigidModel);

EngineCore.cpp #include "FatCylinder.h" void EngineCore::loadFatCylinders(XMLNode& rigidModelNode, RigidModel* rigidModel) { int iFatCylinder = 0; XMLNode colliderNode; while( !(colliderNode = rigidModelNode.getChildNode(L"FatCylinder", iFatCylinder)).isEmpty() ) { double density = colliderNode.readDouble(L"density", 1.0); double restitution = colliderNode.readDouble(L"restitution", 0.7); double friction = colliderNode.readDouble(L"friction", 0.2); double thickness = colliderNode.readDouble(L"thickness", 1.0); double radius = colliderNode.readDouble(L"radius", 3.0); double height = colliderNode.readDouble(L"height", 3.0); D3DXVECTOR3 position = colliderNode.readVector(L"position"); D3DXVECTOR3 axis = colliderNode.readVector(L"axis"); rigidModel->addFatCollider(new FatCylinder(density, thickness, restitution, friction, radius, height, position, axis)); iFatCylinder++; }

XML <RigidModel name="ship" invMass="1" invAngularMassX="1" invAngularMassY="1" invAngularMassZ="1" drag.x="0.2" drag.y="1" drag.z="1" angularDrag.x="50" angularDrag.y="50" angularDrag.z="50">

Próba Tömeg az ütköző geometria alapján számolva Kevés az erő és a forgatónyomaték ehhez Állítsuk nagyobbra a motorcontrolban |force| = 35 |torque| = 100

Entity kieg. virtual RigidBody* asRigidBody(); //cpp RigidBody* Entity::asRigidBody() { return NULL; }

RigidBody RigidBody* asRigidBody(); //cpp RigidBody* RigidBody::asRigidBody() { return this; }

RigidBody class RigidBody { D3DXVECTOR3 positionCorrection; D3DXVECTOR3 impulse; D3DXVECTOR3 angularImpulse; public: virtual void interact(Entity* target); virtual void affect(Entity* affector); D3DXVECTOR3 getPointVelocity(const D3DXVECTOR3& point);

RigidBody::animate momentum += force * dt + impulse; D3DXVECTOR3 velocity = momentum * rigidModel->invMass; position += velocity * dt + positionCorrection; angularMomentum += torque * dt + angularImpulse;

RigidBody::control force = D3DXVECTOR3(0.0, 0.0, 0.0); torque = D3DXVECTOR3(0.0, 0.0, 0.0); impulse = D3DXVECTOR3(0.0, 0.0, 0.0); angularImpulse = D3DXVECTOR3(0.0, 0.0, 0.0); positionCorrection = D3DXVECTOR3(0.0, 0.0, 0.0);

RigidBody::control if(controller) controller->apply(this, context); context.interactors->interact(this); }

void RigidBody::interact(Entity* target) { if(target == this) return; target->affect(this); }

RigidBody::getPointVelocity D3DXVECTOR3 RigidBody::getPointVelocity( const D3DXVECTOR3& point) { D3DXVECTOR3 rp = point - position; D3DXMATRIX worldSpaceInvMassMatrix; getWorldInvMassMatrix(worldSpaceInvMassMatrix); // compute angular velocity vector D3DXVECTOR3 angularVelocity; D3DXVec3TransformCoord(&angularVelocity, &angularMomentum, &worldSpaceInvMassMatrix); // compute tangential velocity from angular velocity D3DXVECTOR3 velo; D3DXVec3Cross(&velo, &angularVelocity, &rp); // add object velocity velo += momentum * rigidModel->invMass; return velo; }

RigidBody::affect Másik entitás RigidBody-e? A másik fatCollidereit áttranszformáljuk a mi modellezési koordináta rendszerünkbe –model 2 ->world->model 1 Minden collider párra –Iteratívan megkeressük a legközelebbi pontokat –Ha közelebb vannak, mint amilyen vastagok, akkor ütközés-válasz Impulzus: képlet szerint

RigidBody::affect void RigidBody::affect(Entity* affector) { RigidBody* antiBody = affector->asRigidBody(); // rigid body collision detection if(antiBody) { std::vector & antiColliders = antiBody->rigidModel->colliders; // for each collider i in antiColliders std::vector ::iterator i = antiColliders.begin(); while(i != antiColliders.end()) { // transform i to my model space // other * o.rotationMatrix * o.translation / t.translationMatrix / t.rotationMatrix D3DXMATRIX otherPosMinusMyPosMatrix; D3DXMatrixTranslation(&otherPosMinusMyPosMatrix, antiBody->position.x - position.x, antiBody->position.y - position.y, antiBody->position.z - position.z); D3DXMATRIX rotateBackMatrix; D3DXMatrixTranspose(&rotateBackMatrix, &rotationMatrix); FatCollider* otherColliderInMyModelSpace = (*i)->makeTransformedClone(antiBody->rotationMatrix * otherPosMinusMyPosMatrix * rotateBackMatrix); // for each collider j in colliders std::vector & myColliders = rigidModel->colliders; std::vector ::iterator j = myColliders.begin(); while(j != myColliders.end()) { D3DXVECTOR3 a, b; (*j)->getReferencePoint(a); for(int c=0; c<10; c++) { otherColliderInMyModelSpace->getNearestPointTo(a, b); (*j)->getNearestPointTo(b, a); } D3DXVECTOR3 collisionNormal = a - b; float abDistance = D3DXVec3Length(&collisionNormal); if(abDistance < 0.1) { D3DXVECTOR3 aCenter, bCenter; (*j)->getReferencePoint(aCenter); aCenter -= a; D3DXVec3Normalize(&aCenter, &aCenter); aCenter *= (*j)->thickness * 0.5; a += aCenter; (*i)->getReferencePoint(bCenter); bCenter -= b; D3DXVec3Normalize(&bCenter, &bCenter); bCenter *= (*i)->thickness * 0.5; b += bCenter; } float objectDistance = abDistance - (*i)->thickness - (*j)->thickness; if(objectDistance < 0) { // to world collision point and normal D3DXVec3Normalize(&collisionNormal, &collisionNormal); D3DXVECTOR3 collisionPoint = (a - collisionNormal * (*j)->thickness + b + collisionNormal * (*i)->thickness) * 0.5; D3DXVec3TransformNormal(&collisionNormal, &collisionNormal, &rotationMatrix); D3DXVec3TransformNormal(&collisionPoint, &collisionPoint, &rotationMatrix); collisionPoint += position; // compute relative velocity of colliding points D3DXVECTOR3 relativeVelocity = antiBody- >getPointVelocity(collisionPoint) - getPointVelocity(collisionPoint); float normalVelocityLength = D3DXVec3Dot( &relativeVelocity, &collisionNormal); D3DXVECTOR3 normalVelocity = collisionNormal * normalVelocityLength; D3DXVECTOR3 frictionVelocity = relativeVelocity - normalVelocity; if( D3DXVec3Length(&frictionVelocity) > 1.0) D3DXVec3Normalize(&frictionVelocity, &frictionVelocity); // compute impulse float invMassDiv = 0.0; invMassDiv += rigidModel->invMass; invMassDiv += antiBody->rigidModel->invMass; D3DXVECTOR3 arma = collisionPoint - position; D3DXVECTOR3 armb = collisionPoint - antiBody->position; D3DXVECTOR3 kan, kbn, ikan, ikbn, ikank, ikbnk; // compute inverse mass matrix D3DXMATRIX myWorldInvMassMatrix, antiWorldInvMassMatrix; this->getWorldInvMassMatrix(myWorldInvMassMatrix); antiBody->getWorldInvMassMatrix(antiWorldInvMassMatrix); D3DXVec3Cross(&kan, &arma, &collisionNormal); D3DXVec3Cross(&kbn, &armb, &collisionNormal); D3DXVec3TransformNormal(&ikan, &kan, &myWorldInvMassMatrix); D3DXVec3TransformNormal(&ikbn, &kbn, &antiWorldInvMassMatrix); D3DXVec3Cross(&ikank, &ikan, &arma); D3DXVec3Cross(&ikbnk, &ikbn, &armb); invMassDiv += D3DXVec3Dot(&collisionNormal, &ikank); invMassDiv += D3DXVec3Dot(&collisionNormal, &ikbnk); D3DXVECTOR3 impulse = (1 + (*i)->getRestitution() * (*j)->getRestitution()) * (normalVelocity + frictionVelocity * (*i)->getFriction() * (*j)->getFriction()) / invMassDiv; // add collision response this->impulse += impulse; D3DXVECTOR3 angularImpulse; D3DXVec3Cross(&angularImpulse, &arma, &impulse); this->angularImpulse += angularImpulse; this->positionCorrection -= collisionNormal * (objectDistance * 0.55f) * rigidModel->invMass / (rigidModel->invMass + antiBody->rigidModel->invMass); } j++; } delete otherColliderInMyModelSpace; i++; }

XML – másik RigidBody

Próba nekitolatunk: elpördülnek.fx-ben a lámpákat kivehetjük, hogy lássuk is mi történik. Pl. float4 psBasic(TrafoOutput input) : COLOR0 { float3 lighting = abs(input.normal.y) * 2; /*for(int il=0; il<nSpotlights; il++) { float3 lightDiff = spotlights[il].position - input.worldPos; float3 lightDir = normalize(lightDiff); lighting += spotlights[il].peakRadiance * max(0, dot(input.normal, lightDir))* pow(max(0,dot(-lightDir, spotlights[il].direction)), spotlights[il].focus) / dot(lightDiff, lightDiff); }*/ return float4(lighting * tex2D(kdMapSampler, input.tex) * kdColor, 1); }

Pozíció nem stimmel Ütközőket elmozgattuk, hogy az origóban legyen a tömegközéppont A rajzolt modellt is mozgassuk el

RigidBody::render D3DXMATRIX positionMatrix; D3DXMatrixTranslation(&positionMatrix, position.x, position.y, position.z); D3DXMATRIX massOffsetMatrix; D3DXMatrixTranslation( &massOffsetMatrix, -rigidModel->centreOfMass.x, -rigidModel->centreOfMass.y, -rigidModel->centreOfMass.z); D3DXMATRIX bodyModelMatrix = massOffsetMatrix * rotationMatrix * positionMatrix;

Próba Ütközés működik Mozogjon ez is: Vezérlés célokkal Target ~ Motor TargetControl ~ MotorControl

XML

Új class: Target class Entity; class Target { friend class TargetControl; D3DXVECTOR3 position; double radius; Entity* mark; public: Target(const D3DXVECTOR3& position, double radius); void setMark(Entity* mark); };

Target.cpp Target::Target(const D3DXVECTOR3& position, double radius) { mark = NULL; this->radius = radius; this->position = position; } void Target::setMark(Entity* mark) { this->mark = mark; }

Új class: TargetControl #include class Target; class TargetControl : public RigidBodyControl { std::vector targets; std::vector ::iterator currentTarget; double maxForce; double maxTorque; public: TargetControl(double maxForce, double maxTorque); ~TargetControl(void); void addTarget(Target* target); void apply(RigidBody* controlledBody, const ControlContext& context); };

TargetControl.cpp TargetControl::TargetControl(double maxForce, double maxTorque) { currentTarget = targets.end(); this->maxForce = maxForce; this->maxTorque = maxTorque; }

TargetControl.cpp void TargetControl::addTarget(Target* target) { targets.push_back(target); currentTarget = targets.begin(); } TargetControl::~TargetControl(void) { std::vector ::iterator i = targets.begin(); while(i != targets.end()) { delete *i; i++; }

TargetControl::apply void TargetControl::apply(RigidBody* controlledBody, const ControlContext& context) { if(!targets.empty()) { Target* target = *currentTarget; D3DXVECTOR3 markDifference = target->position - controlledBody->position; if(target->mark) markDifference += target->mark->getPosition(); if(D3DXVec3Length(&markDifference) radius) { currentTarget++; if(currentTarget == targets.end()) currentTarget = targets.begin(); }

TargetControl::apply D3DXVECTOR3 markDirection; D3DXVec3Normalize(&markDirection, &markDifference); D3DXMATRIX modelMatrix; controlledBody->getModelMatrix(modelMatrix); D3DXVECTOR3 ahead; D3DXVec3TransformNormal(&ahead, &D3DXVECTOR3(1, 0, 0), &modelMatrix); D3DXVECTOR3 turnAxis; D3DXVec3Cross(&turnAxis, &ahead, &markDirection); controlledBody->torque += turnAxis * maxTorque; controlledBody->force += ahead * D3DXVec3Dot(&ahead, &markDirection) * maxForce; }

RigidBody-hoz hozzáférés class RigidBody : public Entity { friend class TargetControl;

EngineCore // vezérlők legyártása entitások betöltése előtt void loadTargetControls(XMLNode& xMainNode); // célpontok bekötése entitások betöltése után void finishTargetControls(XMLNode& xMainNode); void loadTargets(XMLNode& targetControlNode, TargetControl* targetControl);

EngineCore::loadTargetControls void EngineCore::loadTargetControls(XMLNode& xMainNode) { int iTargetControl = 0; XMLNode targetControlNode; while( !(targetControlNode = xMainNode.getChildNode(L"TargetControl", iTargetControl)).isEmpty() ) { const wchar_t* targetControlName = targetControlNode|L"name"; TargetControl* targetControl = new TargetControl( targetControlNode.readDouble(L"maxForce"), targetControlNode.readDouble(L"maxTorque")); rigidBodyControlDirectory[targetControlName] = targetControl; iTargetControl++; }

EngineCore::finishTargetControls void EngineCore::finishTargetControls(XMLNode& xMainNode) { int iTargetControl = 0; XMLNode targetControlNode; while( !(targetControlNode = xMainNode.getChildNode(L"targetControl", iTargetControl)).isEmpty() ) { const wchar_t* targetControlName = targetControlNode|L"name"; TargetControl* targetControl = (TargetControl*)rigidBodyControlDirectory [targetControlName]; loadTargets(targetControlNode, targetControl); iTargetControl++; }

EngineCore::loadTargets void EngineCore::loadTargets(XMLNode& targetControlNode, TargetControl* targetControl) { int iTarget = 0; XMLNode targetNode; while( !(targetNode = targetControlNode.getChildNode(L"Target", iTarget)).isEmpty() ) { D3DXVECTOR3 pos = targetNode.readVector(L"position"); double radius = targetNode.readDouble(L"radius", 10); Target* target = new Target(pos, radius); const wchar_t* markEntityName = targetNode|L"mark"; if(markEntityName != NULL) { EntityDirectory::iterator iEntity = entityDirectory.find(markEntityName); if(iEntity != entityDirectory.end()) target->setMark(iEntity->second); } targetControl->addTarget(target); iTarget++; }

EngineCore::loadLevel loadTargetControls(xMainNode); XMLNode groupNode = xMainNode.getChildNode(L"Group"); sceneRoot = NULL; loadGroup(groupNode, sceneRoot); finishTargetControls(xMainNode);

XML

RigidBody::getPosition D3DXVECTOR3 RigidBody::getPosition() { return position; } // kell, mert az Entity::getPosition nem jó pozíciót ad vissza

Próba Legyen a control cruiser helyett interceptor Üldözi a játékos hajóját és nekimegy