⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplescenes_crash.h

📁 使用stl技术,(还没看,是听说的)
💻 H
📖 第 1 页 / 共 2 页
字号:
		else if(input->isKeyDown(KC_K)) _main_spd -= (_main_response * time);

		// Thrust left, right, forward, or back
		_thrust_force = Vector3::ZERO;
		if(input->isKeyDown(KC_G)) _thrust_force.z += _thrust;
		if(input->isKeyDown(KC_B)) _thrust_force.z -= _thrust;
		if(input->isKeyDown(KC_V)) _thrust_force.x += _thrust;
		if(input->isKeyDown(KC_N)) _thrust_force.x -= _thrust;

		// Clamp the main rotor speed
		_main_spd = std::max(_main_min,std::min(_main_max,_main_spd));

		// Turn left or right or automatically stop the tail rotor
		if(input->isKeyDown(KC_J)) _tail_spd += (_tail_response * time);
		else if(input->isKeyDown(KC_L)) _tail_spd -= (_tail_response * time);
		else
		{
			if(_tail_spd < 0.0)
			{
				_tail_spd += (_tail_response * time);
				if(_tail_spd > 0.0) _tail_spd = 0.0;
			}
			else if(_tail_spd > 0.0)
			{
				_tail_spd -= (_tail_response * time);
				if(_tail_spd < 0.0) _tail_spd = 0.0;
			}
		}
		
		// Clamp the tail rotor speed
		_tail_spd = std::max(_tail_min,std::min(_tail_max,_tail_spd));

		// Rotate the tail rotor scene node
		_tail_rotor_node->rotate(Vector3::UNIT_X,Radian(_tail_spd * time * _rotate_scale));

		// If there's some power being applied to the main rotor then...
		if((_main_spd > _main_min)||(!input->isKeyDown(KC_K)))
		{
			// Rotate the main rotor scene node
			_main_rotor_node->rotate(Vector3::UNIT_Y,Radian(_main_spd * time * _rotate_scale));
			_apply_damping = true;
		}
		else _apply_damping = false;

		// Fire rockets. Woo!
		_fire_time += time;
		if((_fire_time > _fire_rate)&&(input->isKeyDown(KC_X)))
		{
			_fire_time = 0.0;
			_rockets++;

			// Create a rocket node and attach a particle system to it
			String name = String("Rocket_") + StringConverter::toString(_rockets);
			ParticleSystem* rocket = ParticleSystemManager::getSingleton().createSystem(name,"OgreOdeDemos/Rocket");
			SceneNode* rocket_node = _mgr->getRootSceneNode()->createChildSceneNode(name);
			rocket_node->attachObject(rocket);
			
			// Alternate firing between the left and right pods and 
			// convert it from body coordinates to world
			// Do the same with the firing "force" vector
			Vector3 pos = _apache->getPointWorldPosition(Vector3(1.35 * ((_rockets & 1)?-1.0:1.0),-0.55,0.95));
			Vector3 force =_apache->getVectorToWorld(Vector3(0,0,_fire_force));
			rocket_node->setPosition(pos);

			// Create a sphere for the physical body
			OgreOde::Body* rocket_body = new OgreOde::Body();
			OgreOde::SphereGeometry* rocket_geom = new OgreOde::SphereGeometry(_fire_size,_apache_space);

			rocket_body->setMass(OgreOde::SphereMass(_fire_mass,_fire_size));
			rocket_body->setAffectedByGravity(false);
			rocket_geom->setBody(rocket_body);
			rocket_node->attachObject(rocket_body);
			
			_bodies.push_back(rocket_body);
			_geoms.push_back(rocket_geom);

			// Fire it off by applying an initial force
			rocket_body->addForce(force);

			// Initialise the rocket's life span to zero
			_rocket_list[rocket_geom] = 0.0;
		}

		// Check all the rockets
		for(std::map<OgreOde::SphereGeometry*,Real>::iterator i = _rocket_list.begin();i != _rocket_list.end();)
		{
			// Increase the time it's lived
			i->second += time;

			// If it had it's emitter disabled (see below) more than 2 seconds ago then kill it
			if((i->second < 0.0)&&(i->second > -98.0))
			{
				// Get the geometry's body and kill any particle system attached to the same node
				OgreOde::Body* body = i->first->getBody();
				killParticleSystem(i->first);
					
				// Manually remove the body from the list of managed bodies
				for(std::vector<OgreOde::Body*>::iterator bi = _bodies.begin();bi != _bodies.end();)
				{
					if((*bi) == body) bi = _bodies.erase(bi);
					else ++bi;
				}		
					
				// Manually delete the geometry from the list of managed geometries
				for(std::vector<OgreOde::Geometry*>::iterator gi = _geoms.begin();gi != _geoms.end();)
				{
					if((*gi) == i->first)gi = _geoms.erase(gi);
					else ++gi;
				}			
					
				// Delete the actual body and geometry
				delete body;						
				delete i->first;

				// Erase the rocket from the hashmap
				_rocket_list.erase(i++);
			}
			else 
			{
				// If the rocket has been alive for more than 2 seconds then kill its emitters (so it fades away)
				if(i->second > 2.0)
				{
					killEmitters(i->first,&(i->second));
				}
				++i;
			}
		}
	}
	
	// Override the base collision callback, 'cos we don't want the "if connected" check doing
	bool SimpleScenes_Crash::collision(OgreOde::Contact* contact)
	{
		// If a rocket's hit something then stop emitting particles
		std::map<OgreOde::SphereGeometry*,Real>::iterator li = _rocket_list.find(static_cast<OgreOde::SphereGeometry*>(contact->getFirstGeometry()));
		if(li != _rocket_list.end())
		{
			killEmitters(li->first,&(li->second));
		}
		else
		{
			li = _rocket_list.find(static_cast<OgreOde::SphereGeometry*>(contact->getSecondGeometry()));
			if(li != _rocket_list.end())
			{
				killEmitters(li->first,&(li->second));
			}
		}

		// Set the friction at the contact
		contact->setCoulombFriction(5.0);

		// Yes, this collision is valid
		return true;
	}

	// Will get called just before each time step, since a timestep zeros the force accumulators
	void addForcesAndTorques()
	{
		// Apply the main rotor force
		_apache->addForce(Vector3(0,_main_spd * _main_scale,0));

		// Apply the tail rotor torque
		_apache->addRelativeTorque(Vector3(0,_tail_spd * _tail_scale,0));

		// Apply the thrust force
		_apache->addRelativeForceAtRelative(_thrust_force,_thrust_offs);

		// Apply damping if the engine's not off
		if(_apply_damping)
		{
			// Apply angular damping
			Vector3 a_velocity = _apache->getAngularVelocity();
			_apache->addTorque(a_velocity * -_angular_damp);

			// Apply linear damping
			Vector3 l_velocity = _apache->getLinearVelocity();
			_apache->addForce(l_velocity * -_linear_damp);
		}
	}

protected:

	// Kill the emitters for any particle systems attached to the same node
	// as the body with which the specified geometry is associated (if that makes sense!)
	void killEmitters(OgreOde::SphereGeometry* geom,Real* time = 0)
	{
		// Find the body
		OgreOde::Body* body = geom->getBody();
		if(body)
		{
			// Find the associated scene node
			SceneNode* node = static_cast<SceneNode*>(body->getParentNode());
			if(node)
			{
				// Kill the emitters of any attached particle systems
				for(int i = 0;i < node->numAttachedObjects();i++)
				{
					MovableObject* obj = node->getAttachedObject(i);
					if(obj->getMovableType() == "ParticleSystem")
					{ 
						static_cast<ParticleSystem*>(obj)->removeAllEmitters();
					}
				}
			}

			// Set the life span value so that we can easily tell 
			// that its had its emitters deleted
			if(time) *time = -100.0;
		}
	}

	// Kill the particle system and scene node associated with this geometry
	void killParticleSystem(OgreOde::SphereGeometry* geom)
	{
		// Find the body
		OgreOde::Body* body = geom->getBody();
		if(body)
		{
			// Find the scene node
			SceneNode* node = static_cast<SceneNode*>(body->getParentNode());
			if(node)
			{							
				MovableObject* obj = 0;				
				for(int i = 0;i < node->numAttachedObjects();i++)
				{
					// If this object isn't an OgreOde::Body then it must be
					// (in our demo) a particle system that we need to delete
					MovableObject* can_obj = node->getAttachedObject(i);
					if(can_obj->getMovableType() != "OgreOde::Body") obj = can_obj;
				}

				// Delete the node
				_mgr->getRootSceneNode()->removeAndDestroyChild(node->getName());

				// If we found a particle system then delete it
				if(obj) ParticleSystemManager::getSingleton().destroySystem(obj->getName());
			}
		}
	}

protected:
	// Things we'll control and delete manually
	Entity *_apache_body,*_main_rotor,*_tail_rotor;
	SceneNode *_apache_body_node,*_main_rotor_node,*_tail_rotor_node;

	Real _rotate_scale;
	
	// Physical things we'll need to apply forces to and delete manually
	OgreOde::Body *_apache,*_rear_wheel,*_left_front,*_right_front;
	OgreOde::SimpleSpace* _apache_space;

	bool _apply_damping;

	// The worst helicopter flight model in the world!
	Real _main_spd,_main_response,_main_scale,_main_min,_main_max;
	Real _tail_spd,_tail_response,_tail_scale,_tail_min,_tail_max;
	Real _thrust,_linear_damp,_angular_damp;
	Vector3 _thrust_offs,_thrust_force;

	// Stuff to help us shoot things
	Real _fire_rate,_fire_time,_fire_force,_fire_mass,_fire_size;
	std::map<OgreOde::SphereGeometry*,Real> _rocket_list;
	int _rockets;
};

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -