/** * CActor::setPosition * @date Modified Mar 07, 2006 */ void CActor::setOrientation(D3DXVECTOR3 &vOrient) { // make sure the length of the orientation is about one float fLength= D3DXVec3Dot(&vOrient, &vOrient); if(fLength > 1.02f || fLength < 0.98f) { // normalize the orientation vector fLength = fastSqrtf(fLength); fLength = 1.0f/fLength; vOrient *= fLength; } // find the new right axis of the matrix with the current up vector D3DXVECTOR3 vRight(m_ActorMatrix._21/m_vScale.x, m_ActorMatrix._22/m_vScale.y, m_ActorMatrix._23/m_vScale.z); D3DXVec3Cross(&vRight, &vRight, &vOrient); D3DXVec3Normalize(NULL, &vRight, &vRight); // set the matrix with the scale back in it m_ActorMatrix._11 = vRight.x*m_vScale.x; m_ActorMatrix._12 = vRight.y*m_vScale.y; m_ActorMatrix._13 = vRight.z*m_vScale.z; m_ActorMatrix._31 = vOrient.x*m_vScale.x; m_ActorMatrix._32 = vOrient.y*m_vScale.y; m_ActorMatrix._33 = vOrient.z*m_vScale.z; }
float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd, const glm::vec3& relativePosition) { glm::quat inverseOrientation = glm::inverse(listeningNodeStream.getOrientation()); glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition; // project the rotated source position vector onto the XZ plane rotatedSourcePosition.y = 0.0f; const float SOURCE_DISTANCE_THRESHOLD = 1e-30f; float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition); if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) { // produce an oriented angle about the y-axis glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2)); float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward" return (direction.x < 0.0f) ? -angle : angle; } else { // no azimuth if they are in same spot return 0.0f; } }
/** * CCoin::gravitate * @date Modified May 15, 2006 */ bool CCoin::gravitate(void) { // if it isn't active it needs to try and gravitate to the player if (!isActive()) { if (m_fGravDist < FLT_MAX) { if (m_poPlayer == NULL) { // kill the coin if it's trying to go to a player that doesn't exist CObjectManager::getInstance().removeObject((CObject*)this); return false; } // store the elapsed time float fElapsedTime; // update at 60fps if(!m_oTimer.tick(&fElapsedTime)) return false; D3DXVECTOR3 vPlayerPos = ((CPlayer*)(m_poPlayer))->getPickupSphere().centerPt; setPosition(D3DXVECTOR3( vPlayerPos.x + (m_fGravDist * cos(m_fAngle)), vPlayerPos.y, vPlayerPos.z + (m_fGravDist * sin(m_fAngle)))); (m_fAngle < 0.0f) ? m_fAngle -= 5.0f * fElapsedTime : m_fAngle += 5.0f * fElapsedTime; setBV(getPosition(), getBV().fRadius); m_fGravDist -= 50.0f * fElapsedTime; return false; } else { // all this see if the closest player is close enough for his gravity to effect this coin float fDist = FLT_MAX, fShortest = FLT_MAX; CObjectManager::ObjectList loPlayers; CObjectManager::getInstance().getObjects(OBJ_PLAYER, &loPlayers); CObjectManager::ObjectList::iterator oPlayerIter = loPlayers.begin(); while (oPlayerIter != loPlayers.end()) { fDist = computeDistanceSquared(((CActor*)(*oPlayerIter))->getPosition(), getPosition()); if (fDist > MAX_PLAYER_GRAV_DIST) { oPlayerIter++; continue; } if (fDist < fShortest) { fShortest = fDist; m_poPlayer = ((CActor*)(*oPlayerIter)); } oPlayerIter++; } if (m_poPlayer == NULL) return false; // set the values for circling m_fGravDist = fastSqrtf(fShortest); // get the initial angle D3DXVECTOR3 vPlayerToCoin; D3DXVec3Subtract(&vPlayerToCoin, &getPosition(), &m_poPlayer->getPosition()); D3DXVec3Normalize(NULL, &vPlayerToCoin, &vPlayerToCoin); // calculate the initial angle m_fAngle = D3DXVec3Dot(&vPlayerToCoin, &D3DXVECTOR3(1.0f,0.0f,0.0f)); m_fAngle = acos(m_fAngle); // positive or negative if (D3DXVec3Dot(&vPlayerToCoin, &D3DXVECTOR3(0.0f,0.0f,1.0f)) < 0.0f) m_fAngle *= -1.0f; } return false; } return true; }