void PointStarfield::addRandomStars (int count) { for (int i = 0; i < count; ++i) { // Generate a vector inside a sphere Ogre::Vector3 pos; do { pos.x = randReal(-1, 1); pos.y = randReal(-1, 1); pos.z = randReal(-1, 1); } while (pos.squaredLength () >= 1); // Convert to rasc/decl angles. LongReal rasc, decl, dist; Astronomy::convertRectangularToSpherical( pos.x, pos.y, pos.z, rasc, decl, dist); Star s; s.RightAscension = Ogre::Degree (rasc); s.Declination = Ogre::Degree (decl); // This distribution is wrong. s.Magnitude = 6 * pos.squaredLength () + 1.5; mStars.push_back(s); } notifyStarVectorChanged (); }
void GPUBillboardSet::updateBoundingBoxAndSphereFromBillboards(const std::vector<PhotoSynth::Vertex>& vertices) { Ogre::AxisAlignedBox box = calculateBillboardsBoundingBox(vertices); setBoundingBox(box); Ogre::Vector3 vmax = box.getMaximum(); Ogre::Vector3 vmin = box.getMinimum(); Ogre::Real sqLen = std::max(vmax.squaredLength(), vmin.squaredLength()); mBBRadius = Ogre::Math::Sqrt(sqLen); }
void IntersectGrid::fillPosition( const PositionArray &posArray ) { size_t posCount = posArray.size(); if ( posCount <= 0 ) return; // if ( posCount > mCurrentVertexCount ) // { // 如果缓冲区不够用了,就扩容一倍 // mCurrentVertexCount = posCount<<1; // 如果不每帧创建缓冲区的话,由于lock时用的是discard,所以上次缓冲区中的内容还是会被显示 mCurrentVertexCount = posCount; _createBuffer(); // } Ogre::Vector3 vmax = posArray[posCount-1]; Ogre::Vector3 vmin = posArray[0]; vmin.y -= 100.0f; vmax.y += 100.0f; Real sqLen = std::max(vmax.squaredLength(), vmin.squaredLength()); mRadius = Ogre::Math::Sqrt(sqLen);// mBox.setExtents(vmin,vmax);// getParentNode()->needUpdate();// float *vertexPos = static_cast<float*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (size_t i = 0; i < posCount; ++i) { *vertexPos++ = posArray[i].x; *vertexPos++ = posArray[i].y+1; *vertexPos++ = posArray[i].z; Ogre::RGBA *pCol; pCol = static_cast<Ogre::RGBA*>(static_cast<void*>(vertexPos)); // 用diffuse来做为alpha来源 Ogre::Root::getSingleton().convertColourValue(mGridsColour, pCol++ ) ; vertexPos = static_cast<float*>(static_cast<void*>(pCol)); } vbuf->unlock(); }
void CharacterController::UpdateAI(float dt) { _CurrentPathAge += dt; //std::cerr << _CurrentPathIndex << " / " << _CurrentPath.size() << "\n"; if (_CurrentPathIndex + 2 <= _CurrentPath.size()) { Ogre::Vector3 const & a = _CurrentPath[_CurrentPathIndex]; Ogre::Vector3 const & b = _CurrentPath[_CurrentPathIndex+1]; Ogre::Vector3 const & m = GetPosition(); Ogre::Vector3 const ab = b - a; Ogre::Vector3 const am = m - a; Ogre::Vector3 const mb = b - m; Ogre::Vector3 const mb_unit = mb.normalisedCopy(); float remaining = mb.length(); for(size_t i = _CurrentPathIndex + 1; i + 2 <= _CurrentPath.size(); ++i) { remaining += _CurrentPath[i].distance(_CurrentPath[i+1]); } //std::cerr << "Remaining distance: " << remaining << " m\n"; float lambda = am.dotProduct(ab) / ab.squaredLength(); //const float tau = 0.1; SetVelocity(_CurrentVelocity * mb_unit); if (lambda > 1) _CurrentPathIndex++; /*if (_CurrentPathIndex + 1 == _CurrentPath.size()) SetVelocity(Ogre::Vector3(0.));*/ } }
void GameState::EnergyExplosion(Ogre::Vector3 location,Ogre::Real size, double EnergyAdjustment,const std::string& Material) { float sqSize = size*size; auto it = _actors.begin(); while(it != _actors.end()) { Ogre::Vector3 diff = (*it)->GetLocation() - location; if(diff.squaredLength() <= sqSize) (*it)->AdjustEnergy(EnergyAdjustment); ++it; } if(Material != "") { _billboardManager->AddBillboard( location, Material, Ogre::Vector2(1.0f,1.0f)*size*EnergyExplosionSizeFactor, Ogre::ColourValue(1.0f,1.0f,1.0f,1.0f), EnergyExplosionDuration, BillboardManager::OPTIONS_FADE_OUT | BillboardManager::OPTIONS_ALIGNED | BillboardManager::OPTIONS_SCALE_UP, Ogre::Vector2(1.0f,1.0f)*size*EnergyExplosionSizeFactor); } }
Object* ObjectManager::collisionAABB(const Ogre::Vector3& fromPoint, const Ogre::Vector3& toPoint, int queryMask) { Ogre::Vector3 direction = toPoint - fromPoint; Ogre::Ray ray(fromPoint, direction); mRayQuery->setRay(ray); mRayQuery->setQueryMask(queryMask); // The rays are sorted by the distance query set, [very important] mRayQuery->setSortByDistance(true); Ogre::RaySceneQueryResult& result = mRayQuery->execute(); Ogre::RaySceneQueryResult::iterator itr = result.begin(); // Just get the nearest object if (itr != result.end() && itr->movable) { Ogre::MovableObject *object = itr->movable; Ogre::Vector3 pos = object->getParentSceneNode()->getPosition(); // If the current starting point of an object in the distance is less than a predetermined range // then return this obj // Avoid using the square root operation squaredLength if ((pos - fromPoint).squaredLength() <= direction.squaredLength()) return getObject(itr->movable->getName()); } return NULL; }
Ogre::Real DeferredLight::getSquaredViewDepth(const Ogre::Camera* camera) const { if (ignoreWorld) { return 0.0; } else { Ogre::Vector3 dist = camera->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition(); return dist.squaredLength(); } }
Cell* NavigationMesh::findCell(const Ogre::Vector3& pos) { Ogre::Vector3 v; Ogre::Vector3 minDistance = Ogre::Vector3(500.0, 500.0, 500.0); Cell* closestCell = 0; for (Cells::iterator i = _cells.begin(); i != _cells.end(); ++i) { if ((*i)->containsPoint(pos)) { return *i; } v = (*i)->getCenter() - pos; if (v.squaredLength() < minDistance.squaredLength()) { minDistance = v; closestCell = (*i); } } return closestCell; }
bool CEditor::frameRenderingQueued(const Ogre::FrameEvent& evt) { // manually call sample callback to ensure correct order mGuiMgr->frameRenderingQueued(evt); if ( mHaveLevel ) { // build our acceleration vector based on keyboard input composite Ogre::Vector3 accel = Ogre::Vector3::ZERO; if (mGoingForward) accel += mCamera->getDirection(); if (mGoingBack) accel -= mCamera->getDirection(); if (mGoingRight) accel += mCamera->getRight(); if (mGoingLeft) accel -= mCamera->getRight(); if (mGoingUp) accel += mCamera->getUp(); if (mGoingDown) accel -= mCamera->getUp(); // if accelerating, try to reach top speed in a certain time Ogre::Real topSpeed = mTopSpeed; if (accel.squaredLength() != 0) { accel.normalise(); mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; } // if not accelerating, try to stop in a certain time else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon(); // keep camera velocity below top speed and above epsilon if (mVelocity.squaredLength() > topSpeed * topSpeed) { mVelocity.normalise(); mVelocity *= topSpeed; } else if (mVelocity.squaredLength() < tooSmall * tooSmall) mVelocity = Ogre::Vector3::ZERO; if (mVelocity != Ogre::Vector3::ZERO) { mCamera->move(mVelocity * evt.timeSinceLastFrame); } else { mpEntityMgr->UpdatePageManager(); } } return true; }
//----------------------------------------------------------------------- inline void GravityAffector::_affect(ParticleTechnique* particleTechnique, Particle* particle, Ogre::Real timeElapsed) { /** Applying Newton's law of universal gravitation. */ Ogre::Vector3 distance = mDerivedPosition - particle->position; Ogre::Real length = distance.squaredLength(); if (length > 0) { Ogre::Real force = (mGravity * particle->mass * mass) / length; particle->direction += force * distance * timeElapsed * _calculateAffectSpecialisationFactor(particle); } }
bool CameraMan::frameRenderingQueued(const Ogre::FrameEvent& evt) { CameraStyle mStyle = getCameraStyle(); if (mStyle == CS_FREELOOK) { // build our acceleration vector based on keyboard input composite Ogre::Vector3 accel = Ogre::Vector3::ZERO; if (mGoingForward) accel += mCamera->getDirection(); if (mGoingBack) accel -= mCamera->getDirection(); if (mGoingRight) accel += mCamera->getRight(); if (mGoingLeft) accel -= mCamera->getRight(); if (mGoingUp) accel += mCamera->getUp(); if (mGoingDown) accel -= mCamera->getUp(); // if accelerating, try to reach top speed in a certain time Ogre::Real topSpeed = mFastMove ? mTopSpeed * mFastFactor : mTopSpeed; if (accel.squaredLength() != 0) { accel.normalise(); mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; } // if not accelerating, try to stop in a certain time else { Ogre::Vector3 dir = mVelocity; mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; if (mVelocity.dotProduct(dir) < 0.) mVelocity = Ogre::Vector3::ZERO; } Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon(); // keep camera velocity below top speed and above epsilon if (mVelocity.squaredLength() > topSpeed * topSpeed) { mVelocity.normalise(); mVelocity *= topSpeed; } else if (mVelocity.squaredLength() < tooSmall * tooSmall) mVelocity = Ogre::Vector3::ZERO; if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame); } return true; }
/* distance(target_positon+t*target_speed) = t*interceptor_speed formal solver gives : delta = (-target_positon.y^2-target_positon.x^2)*target_speed.z^2 +(2*target_positon.y*target_positon.z*target_speed.y+2*target_positon.x*target_positon.z*target_speed.x)*target_speed.z +(-target_positon.z^2-target_positon.x^2)*target_speed.y^2 +2*target_positon.x*target_positon.y*target_speed.x*target_speed.y +(-target_positon.z^2-target_positon.y^2)*target_speed.x^2 +interceptor_speed^2*target_positon.z^2 +interceptor_speed^2*target_positon.y^2 +interceptor_speed^2*target_positon.x^2 if delta > 0 t = (sqrt(delta) -target_positon.z*target_speed.z-target_positon.y*target_speed.y-target_positon.x*target_speed.x) /(target_speed.z^2+target_speed.y^2+target_speed.x^2-laser_speed^2) special case for delta=0 when equation becomes linear */ std::pair<bool,float> calculateInterceptionTime( const Ogre::Vector3& target_position, const Ogre::Vector3& target_speed, const float& interceptor_speed) { // result ; float time = 0 ; if (target_speed.length() != 0) { float delta = (-pow(target_position.y,2)-pow(target_position.x,2))*pow(target_speed.z,2) +(2*target_position.y*target_position.z*target_speed.y+2*target_position.x*target_position.z*target_speed.x)*target_speed.z +(-pow(target_position.z,2)-pow(target_position.x,2))*pow(target_speed.y,2) +2*target_position.x*target_position.y*target_speed.x*target_speed.y +(-pow(target_position.z,2)-pow(target_position.y,2))*pow(target_speed.x,2) +pow(interceptor_speed,2)*pow(target_position.z,2) +pow(interceptor_speed,2)*pow(target_position.y,2) +pow(interceptor_speed,2)*pow(target_position.x,2) ; float divisor = target_speed.squaredLength()-pow(interceptor_speed,2) ; if (delta > 0 && fabs(divisor) > 1e-10) { float b = -target_position.z*target_speed.z-target_position.y*target_speed.y-target_position.x*target_speed.x ; time = (sqrt(delta)+b)/divisor ; if (time < 0) time = (-sqrt(delta)+b)/divisor ; } else { /// no real solution : target is unreachable by interceptor return std::pair<bool,float>(false,0) ; } } else { time = target_position.length()/interceptor_speed ; } return std::pair<bool,float>(true,time) ; }
void BubbleController::Update(float dt){ if (m_apply_impulse){ Ogre::Vector3 impulse = (m_impulse_direction * m_velocity) * dt; m_messenger->Notify(MSG_RIGIDBODY_APPLY_IMPULSE, &impulse, "body"); m_apply_impulse = false; if (m_owner->GetType() == GAME_OBJECT_PINK_BUBBLE){ m_distance -= impulse.squaredLength(); } } if (m_owner->GetType() == GAME_OBJECT_PINK_BUBBLE){ float percent = m_max_distance * 0.5f; if (m_distance < percent){ Ogre::SceneNode* node = NULL; m_messenger->Notify(MSG_NODE_GET_NODE, &node); if (node){ float scale_inc = (m_scale_increment * (percent / m_distance)) * dt; if (m_scale_state == 0) { // increase size Ogre::Vector3 scale = node->getScale() + scale_inc; node->setScale(scale); if (node->getScale().y > m_max_scale){ node->setScale(Ogre::Vector3(m_max_scale)); m_scale_state = 1; } } else if (m_scale_state == 1){ // decrease size Ogre::Vector3 scale = node->getScale() - scale_inc; node->setScale(scale); if (node->getScale().y < m_original_scale){ node->setScale(Ogre::Vector3(m_original_scale)); m_scale_state = 0; } } } } if (m_distance <= 0.0f){ SoundData2D pop_sound = m_owner->GetGameObjectManager()->GetSoundManager()->Create2DData("Bubble_Burst", false, false, false, false, 1.0, 1.0); m_owner->GetGameObjectManager()->GetGameObject("Player")->GetComponentMessenger()->Notify(MSG_SFX2D_PLAY, &pop_sound); m_owner->RemoveGameObject(m_owner); } } }
//----------------------------------------------------------------------- bool Plane::intersect(const Plane& other, Line& outputLine) const { //TODO : handle the case where the plane is perpendicular to T Ogre::Vector3 point1; Ogre::Vector3 direction = normal.crossProduct(other.normal); if (direction.squaredLength() < 1e-08) return false; Ogre::Real denom = 1./(normal.x*other.normal.y-other.normal.x*normal.y); { Ogre::Real d1 = d; Ogre::Real d2 = other.d; point1.x = (normal.y*d2-other.normal.y*d1)*denom; point1.y = (other.normal.x*d1-normal.x*d2)*denom; point1.z = 0; } outputLine = Line(point1, direction); return true; }
BoundingSphere::BoundingSphere(const BoundingSphere &one, const BoundingSphere &two) { Ogre::Vector3 centerOffset = two.center - one.center; real distance = centerOffset.squaredLength(); real radiusDiff = two.radius - one.radius; // Check if the larger sphere encloses the small one if (radiusDiff*radiusDiff >= distance) { if (one.radius > two.radius) { center = one.center; radius = one.radius; } else { center = two.center; radius = two.radius; } } // Otherwise we need to work with partially // overlapping spheres else { distance = Ogre::Math::Sqrt(distance); radius = (distance + one.radius + two.radius) * ((real)0.5); // The new centre is based on one's centre, moved towards // two's centre by an ammount proportional to the spheres' // radii. center = one.center; if (distance > 0) { center += centerOffset * ((radius - one.radius)/distance); } } }
void CameraMan::frameRendered(const Ogre::FrameEvent &evt) { if (mStyle == CS_FREELOOK) { // build our acceleration vector based on keyboard input composite Ogre::Vector3 accel = Ogre::Vector3::ZERO; Ogre::Matrix3 axes = mCamera->getLocalAxes(); if (mGoingForward) accel -= axes.GetColumn(2); if (mGoingBack) accel += axes.GetColumn(2); if (mGoingRight) accel += axes.GetColumn(0); if (mGoingLeft) accel -= axes.GetColumn(0); if (mGoingUp) accel += axes.GetColumn(1); if (mGoingDown) accel -= axes.GetColumn(1); // if accelerating, try to reach top speed in a certain time Ogre::Real topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed; if (accel.squaredLength() != 0) { accel.normalise(); mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; } // if not accelerating, try to stop in a certain time else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon(); // keep camera velocity below top speed and above epsilon if (mVelocity.squaredLength() > topSpeed * topSpeed) { mVelocity.normalise(); mVelocity *= topSpeed; } else if (mVelocity.squaredLength() < tooSmall * tooSmall) mVelocity = Ogre::Vector3::ZERO; if (mVelocity != Ogre::Vector3::ZERO) mCamera->translate(mVelocity * evt.timeSinceLastFrame); } }
float ogreVectorLength(Ogre::Vector3 v) { return v.squaredLength(); }
bool PhysicsEngine::PerformSphereSphereCollisionTest(const Ogre::FrameEvent &fe, PhysicsEntity *sphere1, PhysicsEntity *sphere2) { float overlapMagnitude = (sphere1->GetRadius() + sphere2->GetRadius()) - sphere1->getPosition().distance(sphere2->getPosition()); if (overlapMagnitude >= 0.0f) { Ogre::Vector3 d = sphere2->getPosition() - sphere1->getPosition(); Ogre::Vector3 relativeVelocity = d * (d.dotProduct(sphere1->GetVelocity() - sphere2->GetVelocity()) / d.squaredLength()); Ogre::Vector3 impulse1 = (((sphere2->GetRestitution() + 1.0f) * relativeVelocity) / ((1 / sphere1->GetMass()) + (1 / sphere2->GetMass()))); Ogre::Vector3 impulse2 = -(((sphere1->GetRestitution() + 1.0f) * relativeVelocity) / ((1 / sphere1->GetMass()) + (1 / sphere2->GetMass()))); //Ogre::Vector3 currentImpulse1 = d * (d.dotProduct(sphere1->GetAppliedForce()) / d.squaredLength()); //Ogre::Vector3 currentImpulse2 = -d * (d.dotProduct(sphere2->GetAppliedForce()) / d.squaredLength()); if (sphere1->GetBodyType() == ENTITY_BODY_SPHERE && sphere2->GetBodyType() == ENTITY_BODY_SPHERE) { sphere1->translate(-d.normalisedCopy() * (overlapMagnitude / 2.0f)); sphere2->translate(d.normalisedCopy() * (overlapMagnitude / 2.0f)); sphere2->ApplyForce(impulse1);// + currentImpulse1); sphere1->ApplyForce(impulse2);// + currentImpulse2); } sphere1->Collide(fe, sphere2); sphere2->Collide(fe, sphere1); return true; } return false; }
void PhysicsEngine::Update(const Ogre::FrameEvent &fe) { std::vector<PhysicsEntity *> gravitationalEntities; std::vector<PhysicsEntity *> dynamicEntities; std::vector<PhysicsEntity *> collidableEntities; for (std::vector<PhysicsEntity *>::iterator it = physicsEntities.begin(); it != physicsEntities.end(); ++it) { if ((*it)->isAlive()) { if ((*it)->IsGravitational()) { gravitationalEntities.push_back(*it); } if ((*it)->IsDynamic()) { dynamicEntities.push_back(*it); } if ((*it)->GetBodyType() != ENTITY_BODY_METAPHYSICAL) { collidableEntities.push_back(*it); } } } for (std::vector<PhysicsEntity *>::iterator it = dynamicEntities.begin(); it != dynamicEntities.end(); ++it) { for (std::vector<PhysicsEntity *>::iterator gr = gravitationalEntities.begin(); gr != gravitationalEntities.end(); ++gr) { if (*it != *gr) { Ogre::Vector3 distance = (*gr)->getPosition() - (*it)->getPosition(); if (distance.squaredLength() != 0.0f) { Ogre::Vector3 force = distance.normalisedCopy() * gravitationalConstant * (((*it)->GetMass() * (*gr)->GetMass()) / ((*gr)->IsAbsoluteGravitationalPull() ? ((*gr)->GetRadius() + (*it)->GetRadius()) : distance.squaredLength())); (*it)->ApplyForce(force); if ((*gr)->IsDynamic()) { (*gr)->ApplyForce(force); } } } } } while (collidableEntities.size() > 0) { PhysicsEntity *i = collidableEntities.back(); for (std::vector<PhysicsEntity *>::reverse_iterator it = collidableEntities.rbegin(); it != collidableEntities.rend(); ++it) { if (i != (*it) && i->isAlive() && (*it)->isAlive() && //i->GetObjectID() != (*it)->GetObjectID() && i->GetParentID() != (*it)->GetParentID() && i->GetObjectID() != (*it)->GetParentID() && i->GetParentID() != (*it)->GetObjectID()) { if (i->GetBodyType() == ENTITY_BODY_SPHERE || i->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE) { if ((*it)->GetBodyType() == ENTITY_BODY_SPHERE || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE) { PerformSphereSphereCollisionTest(fe, i, *it); } else if ((*it)->GetBodyType() == ENTITY_BODY_RAY || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_RAY) { PerformRaySphereCollisionTest(fe, *it, i); } } else if (i->GetBodyType() == ENTITY_BODY_RAY || i->GetBodyType() == ENTITY_BODY_METAPHYSICAL_RAY) { if ((*it)->GetBodyType() == ENTITY_BODY_SPHERE || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE) { PerformRaySphereCollisionTest(fe, i, *it); } } } } collidableEntities.pop_back(); } }
void AIFlyNAttack1Strategy::Step(unsigned timeMs) { /* смотрим существует ли цель если режим исходный: устанавливаем режим подхода если режим подхода: если цель критически близко - строим вектор отхода за цель (по собств. скорости), не стреляем, смотрим по ходу движения, у подчиненных включаем стратегию смотреть по ходу движения и включаем режим отхода если цель на подходящем расстоянии - подходим прямо на нее и атакуем если режим отхода: если цель на подходящем расстоянии включаем режим подхода если цель близко - корректируем вектор скорости */ #ifdef FNAS1_DEBUG char log[100]; #endif IPhysical *phys = Parent->GetPhysical(); IScenable *scen = Parent->GetScenable(); if (TargetID<0) { return; } if (TargetID==0) { if (Owner) { TargetID = Owner->SelectTargetID(); } if (TargetID<=0) { TargetID=-1; IEquipped *eq = Parent->GetEquipped(); if (eq) { eq->SetTargetPosition(Ogre::Vector3::ZERO); eq->SetShooting(false); } return; } } IAAObject *obj = CommonDeclarations::GetIDObject(TargetID); if (NULL==obj) { TargetID=0; return; } IScenable* Target; Target = obj->GetScenable(); if (NULL==Target) return; #ifdef FNAS1_DEBUG sprintf(log,"start: %d\n", (int)FlyNAttack1State); Debugging::Log("fnas",log); #endif if (FA1_NONE == FlyNAttack1State) FlyNAttack1State = FA1_SEEKING; Ogre::Vector3 tpos = Target->GetPosition(); int tradius=300; Ogre::Vector3 target_pos = tpos, own_pos = Parent->GetPosition(); Ogre::Vector3 direction = target_pos - own_pos; Ogre::Vector3 orient_direction=Ogre::Vector3::ZERO; int actual_rotation_fps = RotationSpeed; AIPathFinderStrategy *pf = Owner->GetPathFinder(); bool is_out_of_rooms = false, is_target_out_of_rooms = false; IRoomable *rmbl = obj->GetRoomable(); if (rmbl) { IRoomable::RoomsPool *pool = rmbl->GetRooms(); if (pool->IsEmpty()) is_target_out_of_rooms = true; } rmbl = Parent->GetRoomable(); if (rmbl) { IRoomable::RoomsPool *pool = rmbl->GetRooms(); if (pool->IsEmpty()) is_out_of_rooms = true; } if (is_out_of_rooms || is_target_out_of_rooms) { SwarmStrategy.Step(timeMs); return; } { PrevState = FlyNAttack1State; switch(FlyNAttack1State) { case FA1_SEEKING: //if (FA1_SEEKING == FlyNAttack1State) { FleeingTime=0; //Ogre::Vector3 target_pos = Target->GetPosition(), own_pos = Parent->GetPosition(); //Ogre::Vector3 direction = target_pos - own_pos; if (direction.squaredLength()<MinDistance*MinDistance) { #ifdef FNAS1_DEBUG sprintf(log,"seek close\n"); Debugging::Log("fnas",log); #endif FlyNAttack1State = FA1_SEEKING2FLEEING; Ogre::Vector3 BoundingPoints[8]; Target->GetBoundingPoints(Target->GetBoundingBox(false).getSize().z+phys->GetRadius()*2, BoundingPoints); IEquipped *eq = Parent->GetEquipped(); if (eq) { eq->SetTargetPosition(Ogre::Vector3::ZERO); eq->SetShooting(false); } if (pf) { Ogre::Vector3 target_point = BoundingPoints[int(7*AAUtilities::Rand())]; pf->SetTargetPoint(target_point); FleeingDirection = target_point - own_pos; //orient_direction = target_point - own_pos; } } else { if (direction.squaredLength()<MaxDistance*MaxDistance) { #ifdef FNAS1_DEBUG sprintf(log,"seek go on\n"); Debugging::Log("fnas",log); #endif //std::pair<bool, Ogre::Real> intersection_res; IPhysical *phys = obj->GetPhysical(); IEquipped *eq = Parent->GetEquipped(); if (phys) { tpos = eq->CalculateTargetPosition(obj->GetPosition(), phys->GetLastVelocity()/PHYSICS_UPDATE_INTERVAL_MS); tradius = phys->GetRadius(); } eq->TryToShoot(tpos, tradius); Ogre::Vector3 sight_origin = eq->GetSightOrigin(); sight_origin.z=0; tpos -= scen->GetOrientation()*sight_origin; direction = tpos - own_pos; } if (pf) { pf->SetTargetPoint(tpos); } orient_direction = direction; actual_rotation_fps = actual_rotation_fps/4; } } break; case FA1_SEEKING2FLEEING: //if (FA1_SEEKING2FLEEING == FlyNAttack1State) { FleeingTime+=timeMs; if (phys) orient_direction = FleeingDirection; //-phys->GetForwardDirection().normalisedCopy(); /*if (FleeingTime>MaxFleeingTime) { #ifdef FNAS1_DEBUG sprintf(log,"seek2flee to breakaway\n"); Debugging::Log("fnas",log); #endif FlyNAttack1State = FA1_BREAKAWAY; FleeingTime=0; } else*/ if (direction.squaredLength()>(MinDistance+BufferZone)*(MinDistance+BufferZone)) { #ifdef FNAS1_DEBUG sprintf(log,"seek2flee switch off\n"); Debugging::Log("fnas",log); #endif FlyNAttack1State = FA1_FLEEING; } else { //AIPathFinderStrategy *pf = Owner->GetPathFinder(); #ifdef FNAS1_DEBUG sprintf(log,"seek2flee go on\n"); Debugging::Log("fnas",log); #endif //actual_rotation_fps = actual_rotation_fps*4; if (pf) { Ogre::Vector3 target_point = own_pos+orient_direction*100000; pf->SetTargetPoint(target_point); } } } break; case FA1_FLEEING: //if (FA1_FLEEING == FlyNAttack1State) { FleeingTime+=timeMs; if (phys) orient_direction = -phys->GetForwardDirection(); //AIPathFinderStrategy *pf = Owner->GetPathFinder(); if (direction.squaredLength()>(MaxDistance+BufferZone)*(MaxDistance+BufferZone)) { #ifdef FNAS1_DEBUG sprintf(log,"flee far\n"); Debugging::Log("fnas",log); #endif FlyNAttack1State = FA1_FLEEING2SEEKING; } else { #ifdef FNAS1_DEBUG sprintf(log,"flee go on\n"); Debugging::Log("fnas",log); #endif if (pf) { Ogre::Vector3 target_point = own_pos+orient_direction*10000; pf->SetTargetPoint(target_point); } } } break; case FA1_FLEEING2SEEKING: //if (FA1_FLEEING2SEEKING == FlyNAttack1State) { FleeingTime = 0; if (direction.squaredLength()<MaxDistance*MaxDistance) { #ifdef FNAS1_DEBUG sprintf(log,"flee2seek switch off\n"); Debugging::Log("fnas",log); #endif FlyNAttack1State = FA1_SEEKING; /*if (pf) { Ogre::Vector3 target_point = target_pos; pf->SetTargetPoint(target_point); orient_direction = target_point - own_pos; }*/ } else { #ifdef FNAS1_DEBUG sprintf(log,"flee2seek go on\n"); Debugging::Log("fnas",log); #endif actual_rotation_fps = actual_rotation_fps*5; if (pf) { orient_direction = direction; Ogre::Vector3 target_point = Ogre::Vector3::NEGATIVE_UNIT_Z*10000; Ogre::Quaternion orientation = scen->GetOrientation(); target_point = orientation * target_point; target_point = own_pos + target_point; pf->SetTargetPoint(target_point); } } //if (phys) // orient_direction = -phys->GetForwardDirection(); } break; case FA1_BREAKAWAY: //if (FA1_FLEEING2SEEKING == FlyNAttack1State) { FleeingTime = 0; if (direction.squaredLength()>(MinDistance+BufferZone)*(MinDistance+BufferZone)) { #ifdef FNAS1_DEBUG sprintf(log,"BREAKAWAY switch off\n"); Debugging::Log("fnas",log); #endif FlyNAttack1State = FA1_FLEEING; } else { #ifdef FNAS1_DEBUG sprintf(log,"BREAKAWAY go on\n"); Debugging::Log("fnas",log); #endif actual_rotation_fps = actual_rotation_fps*5; if (pf) { orient_direction = direction; Ogre::Vector3 target_point = Ogre::Vector3::NEGATIVE_UNIT_Z*10000; Ogre::Quaternion orientation = scen->GetOrientation(); target_point = orientation * target_point; target_point = own_pos + target_point; pf->SetTargetPoint(target_point); } } //if (phys) // orient_direction = -phys->GetForwardDirection(); } break; }; #ifdef FNAS1_DEBUG sprintf(log,"end: %d\n", (int)FlyNAttack1State); Debugging::Log("fnas",log); #endif }/* else { actual_rotation_fps = actual_rotation_fps*5; if (pf) { orient_direction = direction; Ogre::Vector3 target_point = Ogre::Vector3::NEGATIVE_UNIT_Z*10000; Ogre::Quaternion orientation = scen->GetOrientation(); target_point = orientation * target_point; target_point = own_pos + target_point; pf->SetTargetPoint(target_point); } }*/ if (!orient_direction.isZeroLength() && PrevOrientDirection != orient_direction) { Ogre::Quaternion OurOrientation = scen->GetOrientation(); //Ogre::Vector3 direction = Target->GetPosition()-scen->GetPosition(); orient_direction.normalise(); Ogre::Vector3 up =CommonDeclarations::GetUpVector(); Vector3 xVec = up.crossProduct(orient_direction); xVec.normalise(); Vector3 yVec = orient_direction.crossProduct(xVec); yVec.normalise(); Quaternion unitZToTarget = Quaternion(xVec, yVec, orient_direction); Quaternion targetOrientation = Quaternion(-unitZToTarget.y, -unitZToTarget.z, unitZToTarget.w, unitZToTarget.x); PrevOrientDirection = orient_direction; RotationUnit.StartRotation(OurOrientation, targetOrientation, actual_rotation_fps); } if(RotationUnit.mRotating) { RotationUnit.Step(); if(RotationUnit.mRotating) // Process timed rotation { Ogre::Quaternion delta = RotationUnit.Slerp(); scen->SetOrientation(delta); } } }
void PhysicalCamera::grasp() { if (!mGraspedObject) { // Fire a ray into the scene to find an object to grasp. If // an object is found, attach it to the grasping Motor and, // if using long range grasping mode, store the intersection // position relative to the camera as the grasp offset. // First update the ray casting Sensor's ray. Ogre::Vector3 camForward = mOgreCamera->getDerivedDirection(); if (0 != camForward.squaredLength()) { camForward.normalise(); } opal::Vec3r rayDir(camForward[0], camForward[1], camForward[2]); if (PHYSICAL == mType) { // The ray's origin will be updated automatically since // it is attached to the camera's Solid. Its direction // should be set manually here because we constantly // reset the camera's orientation. opal::Point3r dummyPoint; opal::Rayr r(dummyPoint, rayDir); mGraspingSensor->setRay(r); } else { // The ray should start at the camera's position and fire // straight forward into the scene. Ogre::Vector3 ogreCamPos = mOgreCamera->getDerivedPosition(); opal::Point3r opalCamPos(ogreCamPos[0], ogreCamPos[1], ogreCamPos[2]); opal::Rayr r(opalCamPos, rayDir); mGraspingSensor->setRay(r); } // Fire the ray. opal::RaycastResult result = mGraspingSensor->fireRay(mMaxReach); if (result.solid) // && !result.solid->isStatic()) { // Store the grasped object. mGraspedObject = result.solid; // Initialize the grasping Motor with the new data. opal::SpringMotorData data; data.solid = result.solid; data.mode = mGraspingMotorMode; data.linearKs = mGraspingLinearKs; data.linearKd = mGraspingLinearKd; data.angularKs = mGraspingAngularKs; data.angularKd = mGraspingAngularKd; opal::Matrix44r solidTransform = result.solid->getTransform(); //data.desiredUp = solidTransform.getUp(); //data.desiredForward = solidTransform.getForward(); //data.desiredRight = solidTransform.getRight(); // Desired position will be updated in the "update" // function. mGraspingMotor->init(data); if (PHYSICAL == mType) { //// Grab it where the ray intersected it. //mGraspingMotor->setGlobalAttachPoint(result.intersection); // Just grab it in the middle. mGraspingMotor->setGlobalAttachPoint(result.solid-> getPosition()); } else { mGraspingMotor->setGlobalAttachPoint(result.intersection); // Set the offset (from the camera) to be the same distance // as when it was grasped. mPhysicalGraspOffset.set(0, 0, -result.distance); } // Compute the grasped object's offset transform from the camera // which is only used for desired orientation. Ogre::Matrix4 ogreMat; mOgreCamera->getParentSceneNode()->getWorldTransforms(&ogreMat); opal::Matrix44r camTransform( ogreMat[0][0], ogreMat[1][0], ogreMat[2][0], ogreMat[3][0], ogreMat[0][1], ogreMat[1][1], ogreMat[2][1], ogreMat[3][1], ogreMat[0][2], ogreMat[1][2], ogreMat[2][2], ogreMat[3][2], ogreMat[0][3], ogreMat[1][3], ogreMat[2][3], ogreMat[3][3]); camTransform.invert(); opal::Matrix44r objTransInv = mGraspedObject->getTransform(); objTransInv.invert(); mGraspedObjectOffsetTransform = objTransInv * camTransform; // Set the desired transform for orientation only (the position // part should be overwritten below). opal::Matrix44r desiredObjTransform = mGraspedObjectOffsetTransform * camTransform; desiredObjTransform.invert(); mGraspingMotor->setDesiredTransform(desiredObjTransform); // Update the the desired position. mGraspingMotor->setDesiredPosition(getGraspGlobalPos()); // Apply extra angular damping. result.solid->setAngularDamping(3); } } }
bool RoomsManager::UpdateObject(Room::ObjectType* object) { bool updated=false, inrooms=false; Room *room; //std::vector<Room*>::iterator iPos=Rooms.begin(), iEnd=Rooms.end(); inrooms=false; //for (size_t i=0;i<Rooms.Size;++i) Ogre::AxisAlignedBox box = object->GetRoomable()->GetBoundingBox(), *RoomBox; //assert() for (RoomsPool::ListNode *pos = Rooms.GetBegin(); pos!=NULL; pos=pos->Next) { room = pos->Value; RoomBox = room->GetBox(); if (RoomBox->intersects(box)) { updated = room->UpdateObject(object); if (updated) { inrooms=true; } } } if (!inrooms) { /*char log[100]; sprintf(log,"Rooms 1: empty room set for object %d\n",object->GetScriptable()->GetID()); Debugging::Log("Warnings.log",log);*/ IRoomable *rmbl = object->GetRoomable(); IPhysical *phys = object->GetPhysical(); if (rmbl) { rmbl->RemoveFromRooms(); rmbl->GetRooms()->Clear(); switch (rmbl->GetRoomOnly()) { case IRoomable::ROM_RESTORE: { for (RoomsPool::ListNode *pos = Rooms.GetBegin(); pos!=NULL; pos=pos->Next) { Ogre::AxisAlignedBox *box = pos->Value->GetBox(); Ogre::Vector3 center = box->getCenter(); Ogre::Vector3 position = object->GetPosition(); Ogre::Vector3 dist = position - center; int sqradius = AAUtilities::f2i(box->getHalfSize().squaredLength())+3*phys->GetRadius(); int sqdist = AAUtilities::f2i(dist.squaredLength()); if (sqradius>sqdist) { //GetPhysical()->SetForwardDirection(GetOrientation()*Vector3::UNIT_Z); //object->GetPhysical(); //object->RestoreBackupPosition(); //Ogre::Vector3 newdir=phys->GetLastVelocity(); //phys->Stop(); phys->SetReplacingDirection(-dist.normalisedCopy()*10); break; } } AddOuterObject(object); //object->RestoreBackupPosition(); break; } case IRoomable::ROM_DESTROY: { CommonDeclarations::DeleteObjectRequest(object); break; } case IRoomable::ROM_SCRIPT: { IScriptable *scr = object->GetScriptable(); if (scr && scr->GetID()>0) ScriptManager::GetInstance()->Call("OnOutOfRooms", "i", false, object->GetScriptable()->GetID()); break; } case IRoomable::ROM_NONE: { AddOuterObject(object); break; } }; } } return inrooms; }
bool CameraMan::frameRenderingQueued(const Ogre::FrameEvent& evt) { // update accelerations Ogre::Vector3 accel = calculateAccelerations(); // if accelerating, try to reach top speed in a certain time Ogre::Real topSpeed = mFastMove ? mTopSpeed * 2 : mTopSpeed; double y_tmp = mVelocity.y; if (accel.squaredLength() != 0) { accel.normalise(); mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; } // if not accelerating, try to stop in a certain time else { mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; } mVelocity.y = y_tmp; // vertical movement if (mJump) mVelocity.y = jumpSpeed; mJump = false; mVelocity.y -= gravityAccel * evt.timeSinceLastFrame; Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon(); y_tmp = mVelocity.y; mVelocity.y = 0; // keep camera velocity below top speed and above epsilon if (mVelocity.squaredLength() > topSpeed * topSpeed) { mVelocity.normalise(); mVelocity *= topSpeed; } else if (mVelocity.squaredLength() < tooSmall * tooSmall) { mVelocity = Ogre::Vector3::ZERO; } mVelocity.y = y_tmp; // terrain handling, raycast each unit direction PolyVox::RaycastResult resultXH; PolyVox::RaycastResult resultXL; PolyVox::RaycastResult resultY; PolyVox::RaycastResult resultZH; PolyVox::RaycastResult resultZL; double width = 0.5; PolyVox::Vector3DFloat cameraPos( mCamera->getPosition().x, mCamera->getPosition().y, mCamera->getPosition().z ); PolyVox::Vector3DFloat cameraPosH( mCamera->getPosition().x, mCamera->getPosition().y + width, mCamera->getPosition().z ); PolyVox::Vector3DFloat cameraPosL( mCamera->getPosition().x, mCamera->getPosition().y - charHeight + width, mCamera->getPosition().z ); if( mVelocity.x > 0 ) { mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( width, 0, 0), resultXH); mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( width, 0, 0), resultXL); } else if( mVelocity.x < 0 ) { mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat(-width, 0, 0), resultXH); mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat(-width, 0, 0), resultXL); } else { resultXH.foundIntersection = false; resultXL.foundIntersection = false; } if( mVelocity.y > 0 ) { mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( 0, width, 0), resultY); } else if( mVelocity.y < 0 ) { mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( 0,-width, 0), resultY); } else { resultY.foundIntersection = false; } if( mVelocity.z > 0 ) { mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( 0, 0, width), resultZH); mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( 0, 0, width), resultZL); } else if( mVelocity.z < 0 ) { mTerrain->raycast( cameraPosH, PolyVox::Vector3DFloat( 0, 0,-width), resultZH); mTerrain->raycast( cameraPosL, PolyVox::Vector3DFloat( 0, 0,-width), resultZL); } else { resultZH.foundIntersection = false; resultZL.foundIntersection = false; } Ogre::Vector3 camPos( mCamera->getPosition() ); // handle horizontal movement if( resultXH.foundIntersection || resultXL.foundIntersection ) { mVelocity.x = 0; if( resultXH.foundIntersection ) { camPos.x = resultXH.previousVoxel.getX(); } else { camPos.x = resultXL.previousVoxel.getX(); } } if( resultZH.foundIntersection || resultZL.foundIntersection ) { mVelocity.z = 0; if( resultZH.foundIntersection ) { camPos.z = resultZH.previousVoxel.getZ(); } else { camPos.z = resultZL.previousVoxel.getZ(); } } // handle ground/ceiling if( resultY.foundIntersection ) { camPos.y = resultY.previousVoxel.getY(); if( mVelocity.y < 0 ) { camPos.y += charHeight - 1.0; } mVelocity.y = 0; } else { if( mVelocity.y < -fallSpeedMax ) { mVelocity.y = -fallSpeedMax; } } // set new position, not in a voxel mCamera->setPosition( camPos ); if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame); return true; }