/*! Generate a torque. */ Ogre::Vector3 Stabilizer::NewtonMeter() const { PhysicalObject* physical_object = getObject()->getParent<PhysicalObject>() ; Oriented* oriented = physical_object->getObject()->getTrait<Oriented>() ; Kernel::Object* physical_world = physical_object->getPhysicalWorld() ; if (physical_world && physical_object && oriented) { Mobile* mobile = physical_object->getObject()->getTrait<Mobile>() ; /// get the rotation against const AngularSpeed& speed = mobile->getAngularSpeed() ; InternalMessage("Model","Model::Stabilizer::NewtonMeter angular speed=" + Kernel::toString(speed.RadianPerSecond()[0]) + "," + Kernel::toString(speed.RadianPerSecond()[1]) + "," + Kernel::toString(speed.RadianPerSecond()[2])) ; if (speed.RadianPerSecond().length() > 100) ErrorMessage("Model::Stabilizer::NewtonMeter high speed encountered") ; Ogre::Quaternion object_orientation = oriented->getOrientation(physical_world).getQuaternion() ; InternalMessage("Model","Model::Stabilizer::NewtonMeter object orientation=" + Kernel::toString(object_orientation.w) + "," + Kernel::toString(object_orientation.x) + "," + Kernel::toString(object_orientation.y) + "," + Kernel::toString(object_orientation.z)) ; /// calculate Ogre::Vector3 global_axis = object_orientation*m_axis ; InternalMessage("Model","Model::Stabilizer::NewtonMeter global_axis=" + Kernel::toString(global_axis[0]) + "," + Kernel::toString(global_axis[1]) + "," + Kernel::toString(global_axis[2])) ; // projection of speed onto the axis. float force = global_axis.dotProduct(speed.TurnPerSecond()) ; /// sign of force is : positive when axis and speed are oriented same way float sign ; if (force < 0) { sign = -1 ; } else { sign = +1 ; } InternalMessage("Model","Model::Stabilizer::NewtonMeter force=" + Kernel::toString((float)force)) ; global_axis.normalise() ; global_axis *= -sign*std::min((float)100,std::max(std::max(force,-force),(force*force))) ; InternalMessage("Model","Model::Stabilizer::NewtonMeter result=" + Kernel::toString(global_axis[0]) + "," + Kernel::toString(global_axis[1]) + "," + Kernel::toString(global_axis[2])) ; return global_axis ; } /// return value for not applicable. return Ogre::Vector3(0,0,0) ; }
void DetectorObjectView::check() { InternalMessage("Model","Model::DetectorObjectView::check entering") ; Detector* detector = getViewPoint()->getObserver() ; if (!detector) return ; bool in_range = detector ? detector->canDetect(getObject()) : false ; if (!detector->getComputer()) return ; Computer* computer = detector->getComputer()->getTrait<Computer>() ; if (! computer) return ; if (!in_range && m_detection_information) { // destroy object computer->getMemoryModel()->destroyObject(m_detection_information) ; m_detection_information = NULL ; } else if (in_range) { InternalMessage( "Model", "Model::DetectorObjectView::check in range updating detection data") ; bool mobile = false ; if (! m_detection_information) { Solid* solid = getObject()->getTrait<Solid>() ; // create object m_detection_information = computer->getMemoryModel()->createObject() ; m_detection_information->addTrait(new DetectionData(detector->getComputer())) ; m_detection_information->addTrait(new Positionned()) ; m_detection_information->addTrait(new Solid(solid->getMesh())) ; m_detection_information->getTrait<DetectionData>()->m_detected = getObject() ; } // update object position Position position = getRelativePosition(getObject(), computer->getObject()) ; m_detection_information->getTrait<Positionned>()->setPosition(position) ; // update speed if exists Mobile* mobileTrait = getObject()->getTrait<Mobile>() ; if (mobileTrait) { Mobile* data = m_detection_information->getTrait<Mobile>() ; if (! data) { data = new Mobile() ; m_detection_information->addTrait(data) ; } data->setSpeed(mobileTrait->getSpeed()) ; data->setAngularSpeed(mobileTrait->getAngularSpeed()) ; } // update identification Transponder* identified = getObject()->getTrait<Transponder>() ; Transponder* identifedData = m_detection_information->getTrait<Transponder>() ; if (identified) { if (! identifedData) { // gained identification m_detection_information->addTrait(new Transponder(*identified)) ; } else if (identifedData->getCode() != identified->getCode()) { // changed identification identifedData->setCode(identified) ; } } else if (identifedData) { // lost identification m_detection_information->destroyTrait(identifedData) ; } // update Targetting std::set<TargetingSystem*> systems = getObject()->getChildren<TargetingSystem>() ; TargetingSystem* system_data = m_detection_information->getTrait<TargetingSystem>() ; if (systems.size() == 1) { TargetingSystem* system = *(systems.begin()) ; if (! system_data) { // gained identification m_detection_information->addTrait(new TargetingSystem()) ; m_detection_information->getTrait<TargetingSystem>()->m_target = system->getTarget() ; m_detection_information->getTrait<TargetingSystem>()->notify() ; } else if (system_data->getTarget() != system->getTarget()) { // changed selection system_data->m_target = system->getTarget() ; system_data->notify() ; } } else if (system_data) { // lost targeting system m_detection_information->destroyTrait(system_data) ; } } InternalMessage("Model","Model::DetectorObjectView::check leaving") ; }