void CCS::FreeCameraMode::update(const Ogre::Real &timeSinceLastFrame) { Ogre::Vector3 dirVector = mCameraCS->getOgreCamera()->getRealDirection(); Ogre::Vector3 lateralVector = dirVector.crossProduct(mFixedAxis).normalisedCopy(); Ogre::Vector3 upVector = -dirVector.crossProduct(lateralVector).normalisedCopy(); Ogre::Vector3 displacement = ((dirVector * mLongitudinalDisplacement) + (upVector * mVerticalDisplacement) + (lateralVector * mLateralDisplacement)) * timeSinceLastFrame * mMoveFactor; mCameraPosition += displacement; if(mCollisionsEnabled) { mCameraPosition = collisionDelegate(mCameraCS->getCameraTargetPosition(), mCameraPosition); } Ogre::Quaternion offsetX(mRotY,Ogre::Vector3::UNIT_X); Ogre::Quaternion offsetY(mRotX,mFixedAxis); mCameraOrientation = offsetY * offsetX; mLongitudinalDisplacement = 0; mLateralDisplacement = 0; mVerticalDisplacement = 0; }
//----------------------------------------------------------------------------------------- void CCameraEditor::setDirection(const Ogre::Vector3 &vec) { if (vec == Ogre::Vector3::ZERO) return; Ogre::Vector3 zAdjustVec = -vec; zAdjustVec.normalise(); Ogre::Quaternion orientation; Ogre::Vector3 YawFixedAxis = Ogre::Vector3::UNIT_Y; Ogre::Vector3 xVec = YawFixedAxis.crossProduct( zAdjustVec ); xVec.normalise(); Ogre::Vector3 yVec = zAdjustVec.crossProduct( xVec ); yVec.normalise(); orientation.FromAxes( xVec, yVec, zAdjustVec ); // transform to parent space if (mParentEditor->get()) { orientation = mParentEditor->get()->getNode()->_getDerivedOrientation().Inverse() * orientation; } mOrientation->set(orientation); }
Ogre::Vector3 ParticleChain::computeFrictionDamping(const Ogre::Vector3 &normal, const Ogre::Vector3 &velocity) { int minAxis = 0; if (normal.y*normal.y < normal.x*normal.x) minAxis = 1; Ogre::Vector3 axis(0, 0, 0); axis[minAxis] = 1; Ogre::Vector3 u = normal.crossProduct(axis); Ogre::Vector3 v = u.crossProduct(normal); return mFriction * (velocity.dotProduct(u) * u + velocity.dotProduct(v) * v); }
Ogre::Vector2 SceneObject::getCoordByTriangle(Ogre::Vector3 _position, const Ogre::Vector3& _corner0, const Ogre::Vector3& _corner1, const Ogre::Vector3& _corner2) const { Ogre::Vector2 result; // результат Ogre::Vector3 dirX = _corner1 - _corner0; Ogre::Vector3 dirY = _corner2 - _corner0; _position -= _corner0; // расстояние от начала координат (от точки 0) Ogre::Vector3 div = (dirX.crossProduct(dirY)); if (div.x != 0.0) { result = Ogre::Vector2((_position.crossProduct(dirY)).x, (dirX.crossProduct(_position)).x); result /= div.x; } else if (div.y != 0.0) { result = Ogre::Vector2((_position.crossProduct(dirY)).y, (dirX.crossProduct(_position)).y); result /= div.y; } else if (div.z != 0.0) { result = Ogre::Vector2((_position.crossProduct(dirY)).z, (dirX.crossProduct(_position)).z); result /= div.z; } else { // пипец } return result; }
void EditorApplication::mouseMovedObjectsPalettePreview(const OIS::MouseEvent &arg) { float mouse_x=arg.state.X.abs/float(arg.state.width); float mouse_y=arg.state.Y.abs/float(arg.state.height); viewport->convertMouseToLocalScreen(mouse_x, mouse_y); // Raycast from camera to viewport Ogre::Vector3 raycast_point(0.0f); Ogre::Vector3 raycast_normal(0.0f); viewport->raycastPlacement(mouse_x, mouse_y, 15.0f, &raycast_point, &raycast_normal, EDITOR_NODE_QUERY_TERRAIN | EDITOR_NODE_QUERY_HAVOK); if (placement_grid_snap > 0.0f) { float half_placement_grid_snap = placement_grid_snap/2.0f; float grid_offset = fmod(raycast_point.x, placement_grid_snap); if (grid_offset < half_placement_grid_snap) raycast_point.x -= grid_offset; else raycast_point.x += placement_grid_snap - grid_offset; grid_offset = fmod(raycast_point.y, placement_grid_snap); if (grid_offset < half_placement_grid_snap) raycast_point.y -= grid_offset; else raycast_point.y += placement_grid_snap - grid_offset; grid_offset = fmod(raycast_point.z, placement_grid_snap); if (grid_offset < half_placement_grid_snap) raycast_point.z -= grid_offset; else raycast_point.z += placement_grid_snap - grid_offset; } // Calculate current preview's center Ogre::Vector3 center=Ogre::Vector3::ZERO; for (list<ObjectNode *>::iterator it=current_palette_nodes.begin(); it!=current_palette_nodes.end(); it++) { center += (*it)->getPosition(); } center /= current_palette_nodes.size(); // Translate all nodes from center of the list Ogre::Vector3 translate = raycast_point - center; for (list<ObjectNode *>::iterator it=current_palette_nodes.begin(); it!=current_palette_nodes.end(); it++) { (*it)->translate(translate); } // Calculate rotation Ogre::Quaternion rotation; if (!raycast_normal.isZeroLength()) { Ogre::Vector3 right = raycast_normal.crossProduct(Ogre::Vector3::UNIT_Z); Ogre::Vector3 forward = right.crossProduct(raycast_normal); rotation = Ogre::Quaternion(right, raycast_normal, forward); } else { rotation = Ogre::Quaternion::IDENTITY; } // Rotate all nodes for (list<ObjectNode *>::iterator it=current_palette_nodes.begin(); it!=current_palette_nodes.end(); it++) { (*it)->setRotation(rotation); } }
void Body::addGlobalForce( Ogre::Vector3& force, Ogre::Vector3& pos ) { Ogre::Vector3 bodypos; Ogre::Quaternion bodyorient; getPositionOrientation( bodyorient, bodypos ); Ogre::Vector3 topoint = pos - bodypos; Ogre::Vector3 torque = topoint.crossProduct( force ); addForce( force ); addTorque( torque ); }
void CSpaghettiRigidBody::AddTorqueAtPoint( Ogre::Vector3 &force, Ogre::Vector3 &point ) { // Convert to coordinates relative to center of mass. Ogre::Vector3 pt = point; pt = m_position - pt; Ogre::Vector3 ptxi = force.crossProduct(pt); m_torque = m_torque + ptxi; }
void RacketPhysics::testCollisionWithBall() { if (timeSinceLastHit < 0.5f) return; Ogre::Vector3 racketNormal = Ogre::Vector3::UNIT_Y; racketNormal = ori * racketNormal; Ogre::Vector3 ballPos = ball->getPosition(); Ogre::Plane racketPlane(racketNormal, pos); float distanceFromPlane = racketPlane.getDistance(ballPos); if (distanceFromPlane < 0.0f) { racketNormal = -racketNormal; distanceFromPlane = -distanceFromPlane; } //if (distanceFromPlane < g_RacketThickness + g_BallRadius) if (distanceFromPlane < 0.03f) { Ogre::Vector3 distanceVector = racketNormal * distanceFromPlane; Ogre::Vector3 nearestPointOnPlane = ballPos - distanceVector; Ogre::Vector3 distanceOnPlane = nearestPointOnPlane - pos; //odprintf("dist before: %f, %f, %f", distanceOnPlane.x, distanceOnPlane.y, distanceOnPlane.z); distanceOnPlane.z *= 0.5f; distanceOnPlane.y *= 0.5f; //odprintf("dist after: %f, %f, %f", distanceOnPlane.x, distanceOnPlane.y, distanceOnPlane.z); float projectedDistance = distanceOnPlane.length(); //odprintf("dist sum: %f", projectedDistance); //if (projectedDistance < g_RacketRadiusB) if (projectedDistance < 0.3f) { odprintf("HIT, time sinc last hit: %f", timeSinceLastHit); timeSinceLastHit = 0; // Collision ballPos += distanceVector * (0.03f/abs(distanceFromPlane)); ball->setPosition(ballPos); Ogre::Vector3 ballSpeed = ball->getSpeed(); ballSpeed = ballSpeed.reflect(racketNormal); // Perpendicular element, used for spin Ogre::Vector3 speedPerp = racketPlane.projectVector(speed); ball->setSpin(speedPerp.crossProduct(racketNormal)); // Parallel element, used for speed Ogre::Vector3 speedPara = speed - speedPerp; ballSpeed += speedPara * g_HitStrength; ball->setSpeed(ballSpeed); gameLogic->onTouchRacket(playerId); } else { //odprintf("no hit, time sinc last hit: %f", timeSinceLastHit); } } }
Ogre::Quaternion DetectedVehicle::getOrientation() const { Ogre::Vector3 speed = getSpeed() ; Ogre::Vector3 side(-speed.y,speed.x,-speed.z) ; side.normalise() ; Ogre::Vector3 forward = speed ; forward.normalise() ; Ogre::Vector3 up = forward.crossProduct(side) ; up.normalise() ; return Ogre::Quaternion(side,up,forward) ; }
std::pair<Ogre::Vector3, Ogre::Quaternion> CombatCamera::CameraPositionAndOrientation(Ogre::Real distance) const { // Here, we calculate where m_camera should be relative to its parent // m_camera_node. m_camera_node always stays on the ecliptic, and the // camera moves away from it a bit to look at the position it occupies. // This code was originally written using the high-level Ogre::Camera API, // but now the camera position sometimes needs to be known without // actually moving the camera. The original lines of code are preserved // here as comments, and under each one is the equivalent code cut from // OgreCamera.cpp. std::pair<Ogre::Vector3, Ogre::Quaternion> retval; // Ogre::Camera::setPosition(Ogre::Vector3::ZERO); retval.first = Ogre::Vector3::ZERO; // Ogre::Camera::setDirection(Ogre::Vector3::NEGATIVE_UNIT_Z); { Ogre::Vector3 zAdjustVec = -Ogre::Vector3::NEGATIVE_UNIT_Z; Ogre::Vector3 xVec = Ogre::Vector3::UNIT_Y.crossProduct( zAdjustVec ); xVec.normalise(); Ogre::Vector3 yVec = zAdjustVec.crossProduct( xVec ); yVec.normalise(); retval.second.FromAxes( xVec, yVec, zAdjustVec ); } // Ogre::Camera::roll(m_roll); { Ogre::Vector3 zAxis = retval.second * Ogre::Vector3::UNIT_Z; Ogre::Quaternion roll_q(m_roll, zAxis); roll_q.normalise(); retval.second = roll_q * retval.second; } // Ogre::Camera::pitch(m_pitch); { Ogre::Vector3 xAxis = retval.second * Ogre::Vector3::UNIT_X; Ogre::Quaternion pitch_q(m_pitch, xAxis); pitch_q.normalise(); retval.second = pitch_q * retval.second; } // Ogre::Camera::moveRelative(Ogre::Vector3(0, 0, distance)); { Ogre::Vector3 trans = retval.second * Ogre::Vector3(0, 0, distance); retval.first += trans; } return retval; }
void OrientationControlet::injectMouseMove(int _absx, int _absy, int _absz){ if( mPick && (_absx!=mMouseX || _absy!=mMouseY) ){ /*计算和摇杆球面的交点 */ Game& game = Game::getSingleton(); int sx = game.getScreenWidth(); int sy = game.getScreenHeight(); Ogre::Vector3 eye = game.getCamera()->getPosition(); Ogre::Ray A = game.getCamera()->getCameraToViewportRay( (Ogre::Real)mMouseX/(Ogre::Real)sx, (Ogre::Real)mMouseY/(Ogre::Real)sy ); Ogre::Ray B = game.getCamera()->getCameraToViewportRay( (Ogre::Real)_absx/(Ogre::Real)sx, (Ogre::Real)_absy/(Ogre::Real)sy ); //计算和旋转盘的交点,旋转盘是一个平面 //平面的法向量是Local Z轴,平面通过Local原点 Ogre::Matrix3 m3 = mNode->getLocalAxes(); Ogre::Vector3 v3 = mNode->getPosition(); Ogre::Vector3 axis = m3.GetColumn(2); Ogre::Sphere S(v3,mRaduis); Math3d::CalcResult result1 = Math3d::CalcRaySphereNearFarPoint(A,S,mNearFar); Math3d::CalcResult result2 = Math3d::CalcRaySphereNearFarPoint(B,S,mNearFar); if( result1.first && result2.first ){//都相交 //然后使用直线的参数方程计算出具体的焦点 Ogre::Vector3 a = result1.second; Ogre::Vector3 b = result2.second; a -= v3;b -= v3; a.normalise(); b.normalise(); Ogre::Vector3 c = b.crossProduct(a); Ogre::Real sinv = c.length(); Ogre::Real ang = -asinf(sinv); c.normalise(); mNode->rotate( c,Ogre::Radian(ang),Ogre::Node::TS_WORLD ); mNotify( mName,c,ang ); } mMouseX = _absx; mMouseY = _absy; } mouseFocus( _absx,_absy ); }
void setDirection( const Ogre::Vector3 &dir ) { assert(mIndicatorSceneNode); // 分别计算出节点三个轴上的方向 Ogre::Vector3 yAdjustVec = -dir; yAdjustVec.normalise(); Ogre::Vector3 xVec = mIndicatorSceneNode->getOrientation().zAxis().crossProduct( yAdjustVec ); xVec.normalise(); Ogre::Vector3 zVec = xVec.crossProduct( yAdjustVec ); zVec.normalise(); mIndicatorSceneNode->setOrientation(Ogre::Quaternion( xVec, yAdjustVec, zVec )); }
void PhysicsRagDoll::setInheritedVelOmega(const Ogre::Vector3& vel, const Ogre::Vector3& omega) { // find main position. Ogre::Vector3 mainpos = mNode->_getDerivedPosition(); for (RagBoneMapIterator it = mRagBonesMap.begin(); it != mRagBonesMap.end(); it++) { Ogre::Vector3 pos; Ogre::Quaternion orient; if (it->second->getBody()) { it->second->getBody()->getPositionOrientation(pos, orient); it->second->getBody()->setVelocity(vel + omega.crossProduct(pos - mainpos)); } } }
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); } } }
bool AxisRenderable::collideAxis(Ogre::Ray& ray) { Ogre::Vector3 dir = getWorldPosition() - ray.getOrigin(); Ogre::Real mAxisGizmoProjLen = mLength / mViewport->getActualWidth() * dir.length() * Ogre::Math::Tan(mCamera->getFOVy()); dir.normalise(); mAxisGizmoSelAxis = -1; // find axis to use... for(unsigned int i = 0; i < 3; i++) { Ogre::Vector3 up, normal; up = dir.crossProduct(mAxisGizmoVector[i]); normal = up.crossProduct(mAxisGizmoVector[i]); if(normal.isZeroLength()) break; Ogre::Plane plane(normal,getWorldPosition()); // width of the axis poly is 1/10 the run Ogre::Vector3 a = up * mAxisGizmoProjLen / 10; Ogre::Vector3 b = mAxisGizmoVector[i] * mAxisGizmoProjLen; Ogre::Vector3 poly [] = { Ogre::Vector3(getWorldPosition() + a), Ogre::Vector3(getWorldPosition() + a + b), Ogre::Vector3(getWorldPosition() - a + b), Ogre::Vector3(getWorldPosition() - a) }; Ogre::Vector3 end = ray.getPoint(mProjectDistance); Ogre::Real t = intersect(&plane,ray.getOrigin(), end); if(t >= 0 && t <= 1) { Ogre::Vector3 pos = interpolate(ray.getOrigin(), end, t); // check if inside our 'poly' of this axis vector... bool inside = true; for(unsigned int j = 0; inside && (j < 4); j++) { unsigned int k = (j+1) % 4; Ogre::Vector3 vec1 = poly[k] - poly[j]; Ogre::Vector3 vec2 = pos - poly[k]; if(vec1.dotProduct(vec2) >0.f) inside = false; } // if(inside) { mAxisGizmoSelAxis = i; return(true); } } } return(false); }
void CSpaghettiRigidBody::HandleCollision( CSpaghettiWorld *world, /*!< The world we are moving in */ CSpaghettiRigidBody *otherRigidBody, /*!< The other rigid body to compare against */ const float deltaTime, /*!< Delta time */ std::vector<CCollision> &worldCollisionList ) { std::vector<CCollision> collisions; if (!m_bounds->Intersects(otherRigidBody->GetBounds(), collisions)) return; // no collisions stored, but there was a bound overlap if (collisions.empty()) return; static const float restitution = 0.9f; float sumOfMass = 0.0f; Ogre::Vector3 relativeVeclocity = Ogre::Vector3::ZERO; const float inverseMassBodyOne = 1.0f / GetMass(); const float inverseMassBodyTwo = 1.0f / otherRigidBody->GetMass(); if (otherRigidBody->IsStatic()) { sumOfMass = inverseMassBodyOne; relativeVeclocity = GetVelocity(); } else { sumOfMass = inverseMassBodyOne + inverseMassBodyTwo; relativeVeclocity = GetVelocity() - otherRigidBody->GetVelocity(); } unsigned int noofCollision = collisions.size(); for (unsigned int collisionIndex = 0; collisionIndex < noofCollision; ++collisionIndex) { worldCollisionList.push_back(collisions[collisionIndex]); Ogre::Vector3 collisionNormal = collisions[collisionIndex].collisionNormal; Ogre::Vector3 collisionPoint = collisions[collisionIndex].collisionPoint; float rvDn = relativeVeclocity.dotProduct(collisionNormal); Ogre::Vector3 impulseLinear = (collisionNormal * -(1 + restitution) * rvDn) / sumOfMass; SetVelocity(GetVelocity() + (impulseLinear * inverseMassBodyOne)); SetPosition(GetPosition() + (-collisionNormal * collisions[collisionIndex].penetration)); //angular Ogre::Vector3 collisionTangent = collisionNormal.crossProduct(relativeVeclocity.normalisedCopy()); collisionTangent = collisionTangent.crossProduct(collisionNormal); static const float mu = -0.2f; Ogre::Vector3 frictionForce = ((collisionTangent * impulseLinear.length()) * mu) / deltaTime; AddTorqueAtPoint(frictionForce + (impulseLinear / deltaTime), collisionPoint); if (!otherRigidBody->IsStatic()) { otherRigidBody->SetVelocity(otherRigidBody->GetVelocity() - (impulseLinear * inverseMassBodyTwo)); otherRigidBody->SetPosition(otherRigidBody->GetPosition() + (collisionNormal * collisions[collisionIndex].penetration)); otherRigidBody->AddTorqueAtPoint(-(frictionForce + (impulseLinear / deltaTime)), collisionPoint); } } }
// 是否选中一个三角型 bool IsSelTri( Ogre::Vector3 dir, Ogre::Vector3 orig, Ogre::Vector3 v1, Ogre::Vector3 v2, Ogre::Vector3 v3, float& t, float& u, float& v ) { float fu = 0; float fv = 0; float fDist = 0; float fDet = 0; Ogre::Vector3 edge1 = v2 - v1; Ogre::Vector3 edge2 = v3 - v1; Ogre::Vector3 pvec; pvec = dir.crossProduct(edge2); fDet = edge1.dotProduct(pvec); Ogre::Vector3 tvec; if( fDet > 0 ) { tvec = orig - v1; } else { tvec = v1 - orig; fDet = -fDet; } if( fDet < 0.0001f ) return false; fu = tvec.dotProduct(pvec); if( fu < 0.0f || fu > fDet ) { return false; } // Prepare to test V parameter Ogre::Vector3 qvec; qvec = tvec.crossProduct(edge1); // Calculate V parameter and test bounds fv = dir.dotProduct(qvec); if( fv < 0.0f || fu + fv > fDet ) { return false; } fDist = edge2.dotProduct(qvec); float fInvDet = 1.0f / fDet; fDist *= fInvDet; fu *= fInvDet; fv *= fInvDet; t = fDist; u = fu; v = fv; return true; }
void RenderBoxWrap::updateViewport() { // при нуле вылетает if ((mRenderBox->getWidth() <= 1) || (mRenderBox->getHeight() <= 1) ) return; if ((nullptr != mEntity) && (nullptr != mRttCam)) { // не ¤сно, нужно ли раст¤гивать камеру, установленную юзером mRttCam->setAspectRatio((float)mRenderBox->getWidth() / (float)mRenderBox->getHeight()); //System::Console::WriteLine("Width {0}, Height {1}", getWidth(), getHeight()); // вычисл¤ем рассто¤ние, чтобы был виден весь объект Ogre::AxisAlignedBox box;// = mNode->_getWorldAABB();//mEntity->getBoundingBox(); VectorEntity::iterator iter = mVectorEntity.begin(); while (iter != mVectorEntity.end()) { box.merge((*iter)->getBoundingBox().getMinimum() + (*iter)->getParentSceneNode()->_getDerivedPosition()); box.merge((*iter)->getBoundingBox().getMaximum() + (*iter)->getParentSceneNode()->_getDerivedPosition()); iter++; } if (box.isNull()) return; //box.scale(Ogre::Vector3(1.41f,1.41f,1.41f)); //System::Console::WriteLine("Minimum({0}), Maximum({1})", // gcnew System::String(Ogre::StringConverter::toString(box.getMinimum()).c_str()), // gcnew System::String(Ogre::StringConverter::toString(box.getMaximum()).c_str())); //box.getCenter(); Ogre::Vector3 vec = box.getSize(); // коррекци¤ под левосторонюю систему координат с осью Z направленную вверх #ifdef LEFT_HANDED_CS_UP_Z float width = sqrt(vec.x*vec.x + vec.y*vec.y); // самое длинное - диагональ (если крутить модель) float len2 = width; // mRttCam->getAspectRatio(); float height = vec.z; float len1 = height; if (len1 < len2) len1 = len2; len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view // центр объекта по вертикали + отъехать так, чтобы влезла ближн¤¤ грань BoundingBox'а + чуть вверх и еще назад дл¤ красоты Ogre::Vector3 result = box.getCenter() - Ogre::Vector3(vec.y/2 + len1, 0, 0) - Ogre::Vector3(len1*0.2, 0, -height*0.1); result.x *= mCurrentScale; mCamNode->setPosition(result); Ogre::Vector3 x = Ogre::Vector3(0, 0, box.getCenter().z + box.getCenter().z * (1-mCurrentScale)) - mCamNode->getPosition(); Ogre::Vector3 y = Ogre::Vector3(Ogre::Vector3::UNIT_Z).crossProduct(x); Ogre::Vector3 z = x.crossProduct(y); mCamNode->setOrientation(Ogre::Quaternion( x.normalisedCopy(), y.normalisedCopy(), z.normalisedCopy())); #else float width = sqrt(vec.x*vec.x + vec.z*vec.z); // самое длинное - диагональ (если крутить модель) float len2 = width / mRttCam->getAspectRatio(); float height = vec.y; float len1 = height; if (len1 < len2) len1 = len2; len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view // центр объекта по вертикали + отъехать так, чтобы влезла ближн¤¤ грань BoundingBox'а + чуть вверх и еще назад дл¤ красоты Ogre::Vector3 result = box.getCenter() + Ogre::Vector3(0, 0, vec.z/2 + len1) + Ogre::Vector3(0, height*0.1, len1*0.2); result.z *= mCurrentScale; Ogre::Vector3 look = Ogre::Vector3(0, box.getCenter().y /*+ box.getCenter().y * (1-mCurrentScale)*/, 0); mCamNode->setPosition(result); mCamNode->lookAt(look, Ogre::Node::TS_WORLD); #endif } }
void AIInConeAttackStrategy::Step(unsigned timeMs) { 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(); 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/* || phys->IsCollided()*/) return; if(RotationUnit.mRotating) { RotationUnit.Step(); if(RotationUnit.mRotating) // Process timed rotation { Ogre::Quaternion delta = RotationUnit.Slerp(); scen->SetOrientation(delta); } }// else { int actual_rotation_speed = RotationSpeed; IPhysical *phys = Parent->GetPhysical(); AICommander *commander = Owner->GetCommander(); Ogre::Vector3 src = Ogre::Vector3::ZERO; if (commander) { IAAObject *obj = commander->GetParent(); if (obj) { IScenable *scen = obj->GetScenable(); if (scen) { src = scen->GetOrientation()*Ogre::Vector3::NEGATIVE_UNIT_Z; } } } else { src = -phys->GetForwardDirection(); //OurOrientation * Ogre::Vector3::NEGATIVE_UNIT_Z; } Ogre::Vector3 direction = Target->GetPosition()-scen->GetPosition(); direction.normalise(); Ogre::Real cs = src.dotProduct(direction); if (src.isZeroLength() || cs>=AngleCosinusModule) { actual_rotation_speed = actual_rotation_speed/2; /*char log[100]; sprintf(log,"in cone %f %f %f\n",direction.x, direction.y, direction.z); Debugging::Log("icas",log);*/ } else { direction = src; /*char log[100]; sprintf(log,"not in cone %f %f %f\n",direction.x, direction.y, direction.z); Debugging::Log("icas",log);*/ } Ogre::Vector3 up =CommonDeclarations::GetUpVector(); Ogre::Quaternion OurOrientation = scen->GetOrientation(); Vector3 xVec = up.crossProduct(direction); xVec.normalise(); Vector3 yVec = direction.crossProduct(xVec); yVec.normalise(); Quaternion unitZToTarget = Quaternion(xVec, yVec, direction); Quaternion targetOrientation = Quaternion(-unitZToTarget.y, -unitZToTarget.z, unitZToTarget.w, unitZToTarget.x); RotationUnit.StartRotation(OurOrientation, targetOrientation, actual_rotation_speed); } std::pair<bool, Ogre::Real> intersection_res; IEquipped *eq = Parent->GetEquipped(); Ogre::Ray pl_ray = eq->GetSightRay(); intersection_res = pl_ray.intersects(Target->GetBoundingBox(true)); if (intersection_res.first) { eq->SetTargetPosition(Target->GetPosition(), intersection_res.second); eq->SetShooting(true); } else { eq->SetTargetPosition(Ogre::Vector3::ZERO); eq->SetShooting(false); } }
void AILookStrategy::Step(unsigned timeMs) { IPhysical *phys = Parent->GetPhysical(); IScenable *scen = Parent->GetScenable(); if(RotationUnit.mRotating) { RotationUnit.Step(); if(RotationUnit.mRotating) // Process timed rotation { Ogre::Quaternion delta = RotationUnit.Slerp(); scen->SetOrientation(delta); } } else { Ogre::Quaternion OurOrientation = scen->GetOrientation(); //Ogre::Vector3 src = OurOrientation * Ogre::Vector3::NEGATIVE_UNIT_Z; Ogre::Vector3 direction = Ogre::Vector3::ZERO; switch(LookType) { case LT_FORWARD: direction = -phys->GetForwardDirection(); break; case LT_DIRECTION: direction = Direction; break; case LT_OBJECT: { if (TargetID<0) { assert(false); } if (TargetID==0) { if (Owner) { TargetID = Owner->SelectTargetID(); } } IAAObject *obj = CommonDeclarations::GetIDObject(TargetID); //assert(obj); if (obj) direction = obj->GetPosition()-scen->GetPosition(); break; } }; if (!direction.isZeroLength()) { Vector3 xVec = Ogre::Vector3::UNIT_Y.crossProduct(direction); xVec.normalise(); Vector3 yVec = direction.crossProduct(xVec); yVec.normalise(); Quaternion unitZToTarget = Quaternion(xVec, yVec, direction); Quaternion targetOrientation = Quaternion(-unitZToTarget.y, -unitZToTarget.z, unitZToTarget.w, unitZToTarget.x); RotationUnit.StartRotation(OurOrientation, targetOrientation); } } }