#include "dxstdafx.h" #include ".\node.h" #include "Scene.h" #include "GameManager.h" Node::Node(void) { this->testAgainstFrustum = true; this->behaveAs = NORMAL; this->updateMe = true; this->visible = true; this->standBy = false; this->rendererAdded = false; this->aClone = false; this->calcBoundingBox = true; this->absMaxAABBox.x = 0.1f; this->absMaxAABBox.y = 0.1f; this->absMaxAABBox.z = 0.1f; this->absMinAABBox.x = -0.1f; this->absMinAABBox.y = -0.1f; this->absMinAABBox.z = -0.1f; this->absBoxCenter.x = 0.0f; this->absBoxCenter.y = 0.0f; this->absBoxCenter.z = 0.0f; D3DXMatrixIdentity(&this->myWorldMatrix); //Physic Stuff this->pActor = NULL; this->pActorDesc.density = 10.0f; this->pActorDesc.body = &this->pBodyDesc; this->pMaterialId = 0; this->bOverrideWorldMatrix = false; this->timeToLive = -100; this->pColDetGroup = 0; this->nodeType = 0; this->maxAge = 0; this->userData = NULL; this->father = NULL; //this->pShapeDescSize = 0; this->softKill = false; this->softKillDuration = 0; this->doingSoftKill = false; this->softKillAlpha = 1.0f; } Node::~Node(void) { this->children.clear(); //if(this->pActor!=NULL) // this->myScene->pScene->releaseActor(*this->pActor); } void Node::setBehaveAs(int _behaveAs) { if(_behaveAs > this->NORMAL && this->pActor==NULL) { this->pActorDesc.globalPose.t.set(this->myPosition.getNxVector()); if(_behaveAs == this->STATIC) { this->pActorDesc.body = NULL; this->calcStaticPhysicWorldMatrix(); } this->pActorDesc.userData = this; if(!this->pActorDesc.isValid()) { this->myScene->manager->printToConsole("ActorDescriptor is not valid!!"); return; } this->pActor = this->myScene->pScene->createActor(this->pActorDesc); this->pActor->userData = this; if(_behaveAs == this->KINEMATIC) { this->pActor->raiseBodyFlag(NX_BF_KINEMATIC); } else { this->pActor->clearBodyFlag(NX_BF_KINEMATIC); } } else if(_behaveAs == this->KINEMATIC && this->pActor!=NULL) { this->pActor->raiseBodyFlag(NX_BF_KINEMATIC); } else { this->pActor->clearBodyFlag(NX_BF_KINEMATIC); } this->behaveAs = _behaveAs; } void Node::setRenderer(SPTR &_myRenderer) { this->rendererAdded = true; this->myRenderer = _myRenderer; } void Node::removeRenderer() { if(this->rendererAdded) { this->rendererAdded = false; Renderer* r = this->myRenderer.get(); this->myScene->deleteRendererInList(r); this->myRenderer.reset(); } } SPTR Node::getRenderer() { return this->myRenderer; } bool Node::hasRenderer() { return this->rendererAdded; } void Node::setVisible(bool _visible) { this->visible = _visible; std::list >::iterator it; for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->setVisible(_visible); } } bool Node::isVisible() { return this->visible; } void Node::setStandBy(bool _standBy) { this->standBy = _standBy; std::list >::iterator it; for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->setStandBy(_standBy); } if(this->pActor) { if(_standBy) { this->pActor->putToSleep(); } else { this->pActor->wakeUp(); } } } bool Node::onStandBy() { return this->standBy; } void Node::translate(float dx, float dy, float dz) { if(this->behaveAs != this->STATIC) { this->myPosition.x += dx; this->myPosition.y += dy; this->myPosition.z += dz; if(this->pActor==NULL) { this->pActorDesc.globalPose.t+=NxVec3(dx, dy, dz); } } } void Node::translate(Vector &tv) { if(this->behaveAs != this->STATIC) { this->myPosition += tv; if(this->pActor==NULL) { this->pActorDesc.globalPose.t+=tv.getNxVector(); } } } void Node::rotate(float dalpha, float dbeta, float dgamma) { if(this->behaveAs != this->STATIC) { this->myRotation.x += dalpha; this->myRotation.y += dbeta; this->myRotation.z += dgamma; if(this->pActor==NULL) { NxQuat q; q.setx(this->myRotation.x); q.sety(this->myRotation.y); q.setz(this->myRotation.z); q.setw(1); NxMat33 m(q); this->pActorDesc.globalPose.M = this->pActorDesc.globalPose.M*m; } } } void Node::setPosition(float x, float y, float z) { if(this->behaveAs == this->PARTICLE) { this->pActor->setGlobalPosition(NxVec3(x,y,z)); return; } if(this->behaveAs != this->STATIC) { this->myPosition.x = x; this->myPosition.y = y; this->myPosition.z = z; if(this->pActor==NULL) { this->pActorDesc.globalPose.t.x = x; this->pActorDesc.globalPose.t.y = y; this->pActorDesc.globalPose.t.z = z; } }/* else if(this->behaveAs == this->PARTICLE) { //ZIEMLICHER SCHWACHSINN nach != STATIC!! this->pActor->setGlobalPosition(NxVec3(x,y,z)); }*/ } void Node::setPosition(Vector &p) { if(this->behaveAs == this->PARTICLE) { this->pActor->setGlobalPosition(p.getNxVector()); return; } if(this->behaveAs != this->STATIC) { this->myPosition = p; if(this->pActor==NULL) { this->pActorDesc.globalPose.t=p.getNxVector(); } } } Vector Node::getPosition() { return this->myPosition; } void Node::setRotation(float alpha, float beta, float gamma) { if(this->behaveAs != this->STATIC) { this->myRotation.x = alpha; this->myRotation.y = beta; this->myRotation.z = gamma; if(this->pActor==NULL) { /*NxQuat q; q.setx(this->myRotation.x); q.sety(this->myRotation.y); q.setz(this->myRotation.z); q.setw(1);*/ NxMat33 m(this->myRotation.getNxQuatRotation()); this->pActorDesc.globalPose.M = m*this->pActorDesc.globalPose.M; } } } void Node::setRotation(Vector &r) { if(this->behaveAs != this->STATIC) { this->myRotation = r; if(this->pActor==NULL) { /*NxQuat q; q.setx(this->myRotation.x); q.sety(this->myRotation.y); q.setz(this->myRotation.z); q.setw(1);*/ NxMat33 m(this->myRotation.getNxQuatRotation()); this->pActorDesc.globalPose.M = m*this->pActorDesc.globalPose.M; } } } float Node::getRotationX() { return this->myRotation.x; } float Node::getRotationY() { return this->myRotation.y; } float Node::getRotationZ() { return this->myRotation.z; } std::list >::iterator Node::addChild(SPTR _child) { //_child->myScene = this->myScene; //this->myScene->nodeList.push_back(_child); if(_child->getFather()) { _child->getFather()->removeChild(_child); } _child->father = this; this->children.push_back(_child); std::list >::iterator it = this->children.end(); it--; return it; } void Node::removeChild(std::list >::iterator _it) { this->children.remove((SPTR) *_it); } void Node::removeChild(SPTR _child) { this->children.remove(_child); } void Node::removeAllChildren() { std::list >::iterator it; for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->killMe(); } //this->children.clear(); } Vector* Node::getAbsMinBBox() { return &this->absMinAABBox; } Vector* Node::getAbsMaxBBox() { return &this->absMaxAABBox; } Vector Node::getAbsBoxCenter() { return this->absBoxCenter; } void Node::update(float dt) { std::list >::iterator it; for(it=this->children.begin(); it!=this->children.end();it++) { if(!(*it)->standBy && (*it)->updateMe) { (*it)->update(dt); } } if(this->timeToLive!=-100) { this->timeToLive-=dt; if(this->timeToLive<=this->softKillDuration) { this->doingSoftKill = true; this->softKillAlpha = this->timeToLive/this->softKillDuration; } if(this->timeToLive<=0) { this->setVisible(false); this->killMe(); } } } void Node::calcWorldMatrix(D3DXMATRIX &pMatWorld) { if(this->standBy) { return; } std::list >::iterator it; if(this->bOverrideWorldMatrix) { this->bOverrideWorldMatrix = false; for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->calcWorldMatrix(this->myWorldMatrix); } return; } switch(this->behaveAs) { case NORMAL: this->calcNormalWorldMatrix(pMatWorld); break; /*case STATIC: this->calcStaticPhysicWorldMatrix(pMatWorld); break;*/ case KINEMATIC: this->calcKinematicWorldMatrix(pMatWorld); break; case RIGIDBODY: case PARTICLE: this->calcPhysicWorldMatrix(pMatWorld); break; } for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->calcWorldMatrix(this->myWorldMatrix); } this->getAbsoluteVector(this->absMinAABBox, this->minAABBox); this->getAbsoluteVector(this->absMaxAABBox, this->maxAABBox); this->getAbsoluteVector(this->myAbsPos, Vector(0, 0, 0)); Vector camPos = this->myScene->getActiveCamera()->getAbsolutePosition(); this->camDistance = (camPos - this->getAbsolutePosition()).length(); } void Node::calcNormalWorldMatrix(D3DXMATRIX &pMatWorld) { D3DXQUATERNION quat; D3DXMATRIX tempWorld; D3DXMATRIX tempTrans; D3DXMATRIX MatRot; // Final rotation matrix, applied to // pMatWorld. float x = this->myPosition.x; float y = this->myPosition.y; float z = this->myPosition.z; float a = this->myRotation.x; float b = this->myRotation.y; float g = this->myRotation.z; //tempWorld = pMatWorld; D3DXMatrixTranslation(&tempTrans, x, y, z); D3DXMatrixMultiply(&this->myWorldMatrix, &tempTrans, &pMatWorld); if(a!=0 || b!=0 || g!=0) { D3DXQuaternionIdentity(&quat); D3DXQuaternionRotationYawPitchRoll(&quat, b, a, g); D3DXMatrixRotationQuaternion(&MatRot, &quat); D3DXMatrixMultiply(&this->myWorldMatrix, &MatRot, &this->myWorldMatrix); } } void Node::calcKinematicWorldMatrix(D3DXMATRIX &pMatWorld) { //calculate position of physic actor or particle if(this->pActor!=NULL) { //this->pActor->moveGlobalPosition(this->myPosition.getNxVector()); NxMat33 m(this->myRotation.getNxQuatRotation()); NxMat34 mat; mat.M = m; mat.t = this->myPosition.getNxVector(); this->pActor->moveGlobalPose(mat); } this->calcPhysicWorldMatrix(pMatWorld); } void Node::calcPhysicWorldMatrix(D3DXMATRIX &pMatWorld) { if(this->pActor!=NULL) { this->pActor->getGlobalPose().getColumnMajor44(((NxF32 *) &this->myWorldMatrix.m[0][0])); } } void Node::calcStaticPhysicWorldMatrix() { NxMat34 m(this->pActorDesc.globalPose.M, this->pActorDesc.globalPose.t); m.getColumnMajor44(((NxF32 *) &this->myWorldMatrix.m[0][0])); } void Node::getAbsoluteVector(Vector &pOut, Vector &pin) { //D3DXVECTOR4 temp; D3DXVec4Transform(&pOut, &pin, &this->myWorldMatrix); //Vector v(temp.x, temp.y, temp.z); //return v; } void Node::getAbsoluteDirectionVector(Vector &dirOut, Vector &dirIn) { Vector temp; temp = this->getAbsolutePosition(); this->getAbsoluteVector(dirOut, dirIn); dirOut.x-= temp.x; dirOut.y-= temp.y; dirOut.z-= temp.z; } Vector Node::getAbsolutePosition() { /*Vector origin(0, 0, 0); this->getAbsoluteVector(origin, origin); return origin;*/ return this->myAbsPos; } void Node::setWorldMatrix(D3DXMATRIXA16 &worldMatrix) { this->bOverrideWorldMatrix = true; this->myWorldMatrix = worldMatrix; this->getAbsoluteVector(this->myAbsPos, Vector(0, 0, 0)); } D3DXMATRIXA16* Node::getWorldMatrix() { return &this->myWorldMatrix; } void Node::setScene(Scene &scene) { this->myScene = &scene; } void Node::killMe() { std::list >::iterator it; for(it=this->children.begin();it!=this->children.end();it++) { (*it)->killMe(); } //this->myScene->manager->printToConsole("killMe called, but not yet implemented!"); //delete my, in father, the phyisc model, in scene...with (virtual void Scene::killNode(Node *node)) this->myScene->deleteNode(this); this->updateMe = false; } NxActorDesc* Node::getActorDescriptor() { return &this->pActorDesc; } NxBodyDesc* Node::getBodyDescriptor() { return &this->pBodyDesc; } NxActor* Node::getActor() { return this->pActor; } void Node::setPMaterial(int id) { this->pMaterialId = id; if(this->pActor) { int nbShapes = this->pActor->getNbShapes(); for(int i=0;ipActor->getShapes()[i]->setMaterial(id); } } } void Node::setColDetGroup(int group) { this->pColDetGroup = group; if(this->pActor) { bool disableRayCasting; disableRayCasting = (group==UserContactReport::COLGROUP_NOCOL) ? true : false; NxU32 shapeNb = this->pActor->getNbShapes(); NxShape *const* shapes = this->pActor->getShapes(); for(UINT i=0;isetGroup(group); (*shapes)->setFlag(NX_SF_DISABLE_RAYCASTING, disableRayCasting); shapes++; } this->pActor->setGroup(group); }/* else { this->myScene->manager->printToConsole("Node::setColDetGroup called before actor created!!!"); }*/ } Node* Node::getFather() { return this->father; } std::list > *Node::getChildren() { return &this->children; } void Node::setParticleGroup(int _group) { this->particleGroup = _group; if(this->pActorDesc.shapes.size()==0) { this->myScene->manager->printToConsole("I HAVE NO SHAPES!!!"); } else { this->setBehaveAs(this->PARTICLE); } } int Node::getParticleGroup() { return this->particleGroup; } Node* Node::clone() { return NULL; } void Node::setTimeToLive(float _timeToLive) { /*std::list >::iterator it; for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->setTimeToLive(_timeToLive); }*/ this->timeToLive = _timeToLive; this->maxAge = _timeToLive; } float Node::getTimeToLive() { return this->timeToLive; } void Node::cloneChildren(Node *clonedNode) { Node* n; std::list >::iterator it; for(it=this->children.begin();it!=this->children.end();it++) { n = (*it).get(); SPTR sn = this->myScene->getSmartPointer(n->clone()); clonedNode->addChild(sn); } } void Node::updateBBox() { std::list >::iterator it; std::list >::iterator itEnd; Node* node; itEnd = this->children.end(); if(this->calcBoundingBox) { Vector childMinBBox(9999999,9999999,9999999); Vector childMaxBBox(-9999999,-9999999,-9999999); for(it=this->children.begin();it!=itEnd;it++) { node = (*it).get(); if(!node->onStandBy() && node->isVisible()) { node->updateBBox(); } } /*for(it=this->children.begin();it!=itEnd;it++) { node = (*it).get(); if(!node->onStandBy() && node->isVisible() && node->absMinAABBox.x!=0 && node->absMinAABBox.y!=0 && node->absMinAABBox.z!=0) { //min childMinBBox.x = (childMinBBox.x < node->absMinAABBox.x) ? childMinBBox.x : node->absMinAABBox.x; childMinBBox.y = (childMinBBox.y < node->absMinAABBox.y) ? childMinBBox.y : node->absMinAABBox.y; childMinBBox.z = (childMinBBox.z < node->absMinAABBox.z) ? childMinBBox.z : node->absMinAABBox.z; //max childMaxBBox.x = (childMaxBBox.x > node->absMaxAABBox.x) ? childMaxBBox.x : node->absMaxAABBox.x; childMaxBBox.y = (childMaxBBox.y > node->absMaxAABBox.y) ? childMaxBBox.y : node->absMaxAABBox.y; childMaxBBox.z = (childMaxBBox.z > node->absMaxAABBox.z) ? childMaxBBox.z : node->absMaxAABBox.z; } }*/ corner[0] = this->minAABBox; corner[1] = this->minAABBox; corner[1].x = this->maxAABBox.x; corner[2] = this->maxAABBox; corner[2].y = this->minAABBox.y; corner[3] = this->minAABBox; corner[3].z = this->maxAABBox.z; corner[4] = this->minAABBox; corner[4].y = this->maxAABBox.y; corner[5] = this->maxAABBox; corner[5].z = this->minAABBox.z; corner[6] = this->maxAABBox; corner[7] = this->maxAABBox; corner[7].x = this->minAABBox.x; for(int i=0;i<8;i++) { this->getAbsoluteVector(corner[i], corner[i]); //min childMinBBox.x = (childMinBBox.x < corner[i].x) ? childMinBBox.x : corner[i].x; childMinBBox.y = (childMinBBox.y < corner[i].y) ? childMinBBox.y : corner[i].y; childMinBBox.z = (childMinBBox.z < corner[i].z) ? childMinBBox.z : corner[i].z; childMaxBBox.x = (childMaxBBox.x > corner[i].x) ? childMaxBBox.x : corner[i].x; childMaxBBox.y = (childMaxBBox.y > corner[i].y) ? childMaxBBox.y : corner[i].y; childMaxBBox.z = (childMaxBBox.z > corner[i].z) ? childMaxBBox.z : corner[i].z; } this->absMinAABBox = childMinBBox; this->absMaxAABBox = childMaxBBox; this->absBoxCenter = (this->absMinAABBox + this->absMaxAABBox)/2; } else { for(it=this->children.begin();it!=itEnd;it++) { node = (*it).get(); if(!node->onStandBy() && node->isVisible()) { node->updateBBox(); } } } } void Node::setDetail(Vector ObjectCenter) { //nothing happens here, only in Object3d... } void Node::orientAndMove(Vector direction, Vector upVec, Vector moveVec, bool moveRelative) { Vector globalPos; //wenn !moveRelative ....absPos+=moveVec if(moveRelative) { globalPos = this->getAbsolutePosition(); } else { this->getAbsoluteVector(globalPos, moveVec); } //X Axis berechnen mit crossProd Vector xAxis; direction.normalize(); //z Axis upVec.normalize(); //y Axis xAxis = upVec.crossProd(direction); //x Axis xAxis.normalize(); upVec = direction.crossProd(xAxis); upVec.normalize(); /*Vector xAxis; direction.normalize(); //z Axis upVec.normalize(); //y Axis xAxis = upVec.crossProd(direction); //x Axis*/ //Matrix zusammensetzen + translation D3DXMATRIXA16 wMat; D3DXMatrixIdentity(&wMat); wMat._11 = xAxis.x; wMat._12 = upVec.x; wMat._13 = direction.x; wMat._21 = xAxis.y; wMat._22 = upVec.y; wMat._23 = direction.y; wMat._31 = xAxis.z; wMat._32 = upVec.z; wMat._33 = direction.z; wMat._41 = globalPos.x; wMat._42 = globalPos.y; wMat._43 = globalPos.z; //wenn moveRelative, translationsMatrix erstellen und "moven" if(moveRelative) { D3DXMATRIXA16 trans; D3DXMatrixTranslation(&trans, moveVec.x, moveVec.y, moveVec.z); D3DXMatrixMultiply(&wMat, &trans, &wMat); } //wenn pActor-> matrix dort auch setzen if(this->pActor!=NULL) { NxMat34 pMat; //pMat.setColumnMajor44(((NxF32 *) &wMat.m[0][0])); pMat.setRowMajor44(((NxF32 *) &wMat.m[0][0])); this->pActor->setGlobalPose(pMat); this->pActor->setGlobalPosition(globalPos.getNxVector()); } else { this->setWorldMatrix(wMat); } this->myPosition = globalPos; } bool Node::isA(int _nodeType) { return (this->nodeType & _nodeType); } void Node::clonePhysicStuff(Node* obj) { /* obj->pBodyDesc = this->pBodyDesc; obj->pActorDesc.body = &obj->pBodyDesc; obj->pActorDesc = this->pActorDesc; obj->pActorDesc.shapes.clear(); this->pShapeDescSize = 0; for(int i=0;ipActorDesc.shapes.size();i++) { NxShapeDesc shapeDesc = *this->pActorDesc.shapes[i]; //this->pShapeDescVector.push_back(shapeDesc); this->pShapeDesc[this->pShapeDescSize] = shapeDesc; this->pShapeDescSize++; //obj->pActorDesc.shapes.pushBack(&this->pShapeDescVector.at(i)); }*/ } void Node::OnLostDevice( void* pUserContext ) { } void Node::OnDestroyDevice( void* pUserContext ) { } HRESULT Node::OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { return S_OK; } void Node::setSoftKill(bool _softKill, float _duration) { this->softKill = _softKill; this->softKillDuration = _duration; std::list >::iterator it; for(it=this->children.begin(); it!=this->children.end();it++) { (*it)->setSoftKill(_softKill, _duration); } } bool Node::getSoftKill() { return this->softKill; }