/* * PVVMUD a 3D MUD * Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "pvvmud.H" #include "worldobject.H" #include "worldworld.H" #include "waupdateposition.H" #include "waupdatedirection.H" #include "warotate.H" CWorldObject::CWorldObject(DWORD objectId, CWorldHierarchy * parent, DWORD geometryId, const CPosition & position, const CDirection & direction):CWorldHierarchy(objectId,parent){ m_geometryId = geometryId; m_bBox = NULL; m_BSDTree = NULL; m_collidable = 0; m_cellPVS = NULL; _updatePosition(position); _updateDirection(direction); } CWorldObject::~CWorldObject(){ if (m_bBox != NULL) delete m_bBox; if (m_BSDTree != NULL) delete m_BSDTree; if (m_cellPVS != NULL) delete m_cellPVS; } DWORD CWorldObject::getGeometryId(){ return m_geometryId; } CPosition & CWorldObject::getPosition(){ return m_position; } CDirection & CWorldObject::getDirection(){ return m_direction; } char * CWorldObject::getObjectType(){ return "object"; } CWorldObject * CWorldObject::getMasterCell(){ if (getParentId() == ID_UNKNOWN) return this; CWorldObject * parent = (CWorldObject*)getParent(); if (parent != NULL) return parent->getMasterCell(); return NULL; } CGeometry * CWorldObject::getGeometry(){ cdebug << "CWorldObject::getGeometry: Not overloaded!\n"; return NULL; } CPVCell* CWorldObject::addPVCell(DWORD PVCellId, const CPosition & position){ if (m_cellPVS == NULL) m_cellPVS = new CCellPVS(getWorld()); return m_cellPVS->addPVCell(PVCellId,position); } CCellPVS* CWorldObject::getPVS(){ return m_cellPVS; } void CWorldObject::updatePosition( const CPosition & position ){ // cdebug << "CWorldObject::updatePosition " << position << " on object " << getObjectId() << "\n"; CWorldWorld * world = getWorld(); world->addAnimation(new CWAUpdatePosition(getObjectId(),position), this ); } void CWorldObject::updateDirection( const CDirection & direction ){ // cdebug << "CWorldObject::updateDirection " << direction << " on object " << getObjectId() << "\n"; CWorldWorld * world = getWorld(); world->addAnimation(new CWAUpdateDirection(getObjectId(),direction), this ); } void CWorldObject::rotate( const CDirection & angleSpeed ){ // cdebug << "CWorldObject::rotate " << angleSpeed << " on object " << getObjectId() << "\n"; CWorldWorld * world = getWorld(); world->addAnimation(new CWARotate(getObjectId(),angleSpeed), this ); } void CWorldObject::_updateDirection( const CDirection & direction ){ // cdebug << "CWorldObject::_updateDirection " << direction << " on object " << getObjectId() << "\n"; m_direction = direction; } void CWorldObject::_updatePosition( const CPosition & position ){ // cdebug << "CWorldObject::_updatePosition " << position << " on object " << getObjectId() << "\n"; m_position = position; } void CWorldObject::setBBox( CBBox * bBox ){ m_bBox = bBox; } CBBox * CWorldObject::getBBox( ){ return m_bBox; } void CWorldObject::setCollidable(BYTE coll){ m_collidable =coll; } BYTE CWorldObject::getCollidable(){ return m_collidable ; } void CWorldObject::setBSDTree( CBSDTree * BSDTree ){ m_BSDTree = BSDTree; } CBSDTree * CWorldObject::getBSDTree( ){ return m_BSDTree; } CWorldObject * CWorldObject::createObject( char * objectName, DWORD objectId, DWORD geometryId, const CPosition & position, const CDirection & direction ){ CWorldObject * object = getWorld()->newObject(objectName, objectId,this,geometryId,position,direction); addObject( object ); return object; } int CWorldObject::checkPosition(const CPosition & position){ if (m_BSDTree != NULL) return m_BSDTree->inside( position ); else if (getBBox() != NULL) return getBBox()->inside( position ); else return FALSE; } int CWorldObject::moveTo( CWorldObject * parent ){ setParent( parent ); return TRUE; } void CWorldObject::getGlobalTransform( CMatrix & transform ){ getTransform( transform ); if (getParentId() != ID_UNKNOWN){ CWorldObject * parent = (CWorldObject*)getParent(); if (parent != NULL) parent->getGlobalTransform( transform ); } } void CWorldObject::getTransform( CMatrix & transform ){ transform.translate( getPosition() ); transform.rotate( getDirection() ); } void CWorldObject::getInvGlobalTransform( CMatrix & transform ){ getInvTransform( transform ); if (getParentId() != ID_UNKNOWN){ CWorldObject * parent = (CWorldObject*)getParent(); if (parent != NULL) parent->getInvGlobalTransform( transform ); } } void CWorldObject::getInvTransform( CMatrix & transform ){ transform.rotate( -getDirection() ); transform.translate( -getPosition() ); } void CWorldObject::distances(CDoubleArray & distArray, const CBeam & beam, double min, double max){ if (m_collidable ) return; CGeometry * geometry = getGeometry(); CMatrix transform; getInvTransform(transform); CBeam objBeam = beam; objBeam.transform(transform); if (geometry != NULL){ if ( objBeam.intersect(geometry->calculateBBox())){ cdebug << "CWorldObject( " << getName() << " )::distances: Beam " << objBeam << "\n"; geometry->distances(distArray,objBeam,min,max); // Test sub objects CObjectListItem * item = getFirst(); while (item != NULL){ CWorldObject * obj = (CWorldObject*)item->getObject(); obj->distances(distArray,objBeam,min,max); item = item->getNext(); } } else { cdebug << "CWorldObject( " << getName() << " )::distances: Don't intersect!\n"; } } else { cdebug << "CWorldObject( " << getName() << " )::distances: Don't have geometry!\n"; } } void CWorldObject::dump(int tab){ int ii; for (ii = 0; ii < tab; ii++) cdebug << "\t"; cdebug << "Object: Id: " << getObjectId() << " Geo: " << getGeometryId() << " Pos: " << getPosition() << " Dir: " << getDirection() << "\n"; CObjectListItem * item = getFirst(); while (item != NULL){ CWorldObject * object = (CWorldObject*)item->getObject(); object->dump(tab+1); item = item->getNext(); } }