Пример #1
0
void StickOnCollision::handleEvent(const CollisionEvent& e)
 {

	GameObject obj = e.getOtherObject();
	if (obj.getType() == GameObject::Type::TILE)
	{
		hookPoint = obj.getPos();
		PhysicsComponent * hookPhysics = owner_.getComponent<PhysicsComponent>();
		hookPhysics->setVelX(0);
		hookPhysics->setVelY(0);
		
		auto tileCollider = e.getOtherCollider();
		auto hookCollider = owner_.getComponent<ColliderComponent>();

		float hookBot = hookCollider->getBottom();
		float tileBot = tileCollider.getBottom();
		float tileTop = tileCollider.getTop();

		if (hookBot == tileTop)
		{
			isConnected = false;
		}
		else
		{
			isConnected = true;
		}
		//LOG("INFO") << "Hook is connected at " << hookPoint;
		
	}
}
btScalar ContactCallback::addSingleResult(btManifoldPoint& cp,	const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{
		const btCollisionObject* colObj = colObj0Wrap->getCollisionObject();
		PhysicsComponent* physComp = static_cast<PhysicsComponent*>(colObj->getUserPointer());
		
		if(physComp)
			physComp->OnAddSingleResult(cp,partId0,index0,colObj1Wrap,partId1,index1);

		return 0;
}
void PhysicsComponent::OnAddSingleResult(btManifoldPoint& cp,int partId0,int index0,const btCollisionObjectWrapper* collidedObjWrap,int collidedObjPartId,int collidedObjIndex)
{
	const btCollisionObject* colObj = collidedObjWrap->getCollisionObject();
	PhysicsComponent* physComp = static_cast<PhysicsComponent*>(colObj->getUserPointer());
	if(physComp)
	{
		Entity* entOwner = physComp->GetOwner();
		//entOwner->OnHit();
	}
}
Пример #4
0
void RenderComponent::VUpdate()
{
	/*

		All of this code must go!!! This is shit! Rewrite animation system as a seperate component, starting with a virtual base
		class (AnimationComponent) that can then fork off into a bunch of other more specific animation types (e.g. HumanoidAnimationComponent,
		MachineAnimationComponent, ParticleAnimationComponent, etc.).

	*/
	if(_animated)
	{
		PhysicsComponent* physicsComponent = GetOwner()->GetComponent<PhysicsComponent>(COMPONENT_PHYSICS);

		const uint UP = 1, DOWN = 0, RIGHT = 2, LEFT = 3;
		int direction = -1;// By default, don't change

		if(physicsComponent->GetVelocity().x > 0.5)
		{
			direction = RIGHT;
		}
		else if(physicsComponent->GetVelocity().x < -0.5)
		{
			direction = LEFT;
		}
		else if(physicsComponent->GetVelocity().y > 0.5)
		{
			direction = DOWN;
		}
		else if(physicsComponent->GetVelocity().y < -0.5)
		{
			direction = UP;
		}

		if(direction != -1)// If the texture should change...
		{
			_textureY = direction*(_textureHeight/4);
			_textureX = _currentAnimationFrame*(_textureWidth/3);

			if(SDL_GetTicks() - _lastAnimationChange >= (100))
			{
				_currentAnimationFrame++;
				if(_currentAnimationFrame == 3)
					_currentAnimationFrame = 0;

				_lastAnimationChange = SDL_GetTicks();
			}
		}
		else
		{
			_textureX = 0;
		}
	}
}
Пример #5
0
void Character::Update()
{
	// Update state machine
	mStateMachine.ProcessStateTransitions();
	mStateMachine.UpdateStates();

	// Move character
	const float MAX_SPEED = 100.0f;
	float currSpeed = mSpeedScale * MAX_SPEED;
	mPhysicsComponent.SetSpeed(currSpeed);
	mPhysicsComponent.Move();

	printf("Current speed: %f\n", currSpeed);
}
Пример #6
0
 void updateCamera()
 {
     Actor *actor = game_->findActor("wizard");
     if (actor) {
         PhysicsComponent *component = actor->getPhysicsComponent();
         if (component) {
             b2Body *bodyBody = component->findBody("body");
             if (bodyBody) {
                 b2Vec2 position = bodyBody->GetPosition();
                 cameraPosition_.x = position.x;
                 cameraPosition_.y = position.y;
             }
         }
     }
 }
Пример #7
0
 PHYSICSDLL_API void OrbitComponent::Update(float dt)
 {
   if (targeting_)
   {
     Transform* tr = (Transform*)GetSibling(CT_Transform);
     Vector3 forceVec = current_dir_;
     Vector3 toTarget = target_ - tr->GetPosition();
     float bias = toTarget.Length() / target_dist_;
     forceVec += toTarget.GetNormalized() * bias;
     PhysicsComponent* pComp = (PhysicsComponent*)GetSibling(CT_PhysicsComponent);
     if (pComp)
     {
       pComp->GetRigidBody()->AddForce(forceVec);
       current_dir_ = pComp->GetRigidBody()->GetState().Velocity.GetNormalized();
       pComp->GetRigidBody()->GetState().Velocity = pComp->GetRigidBody()->GetState().Velocity.GetNormalized() * 2.0f;
     }
   }
 }
void LocomotionSystem::Update( float i_dt )
{
    for ( std::map<EntityHandle, Component*>::iterator it = m_components.begin(); it != m_components.end(); it++ )
    {
        LocomotionComponent* pComponent = (LocomotionComponent*) it->second;
        if ( pComponent )
        {
            if ( pComponent->m_locomotionMode )
            {
                pComponent->m_locomotionMode->Update( i_dt );
            }
            PhysicsComponent* pPhysicsComponent = EntitySystem::GetInstance()->GetComponent<PhysicsComponent>( pComponent->m_entityHandle );
            if ( pPhysicsComponent )
            {
                float yVel = pPhysicsComponent->GetVelocity().y;
                JumpState pJumpState;
                if ( yVel > 0.5f )
                {
                    pJumpState = JumpState::JUMPING;
                }
                else if ( yVel < 0.5f )
                {
                    pJumpState = JumpState::FALLING;
                }
                else if ( yVel == 0.0f )
                {
                    pJumpState = JumpState::NOT_JUMPING;
                }
                
                if ( pJumpState == JumpState::FALLING && pComponent->m_jumpState == JumpState::JUMPING )
                {
                    EventManager::GetInstance()->SendEvent( "VelocityApexReached", &pComponent->m_entityHandle );
                }
                
                pComponent->m_jumpState = pJumpState;
            }
        }
    }
}
Пример #9
0
void KeyboardSystem::run(Entity* entity, float time) 
{
    PhysicsComponent* physComp = entity->getComponent<PhysicsComponent>();

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space))
    {
        physComp->jump();
    }

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D))
    {
        physComp->walk(1);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A) )
    {
        physComp->walk(-1);
    }
    else
    {
        physComp->walk(0);
    }
}
Пример #10
0
void ProjectileCollideSystem::update()
{
    for(int subID = 0; subID < subscribedEntities[0].size(); subID++)
    {
        //Get projectile component
        Entity * projectileEnt = entities[subscribedEntities[0][subID]];
        ColliderComponent* projectileCollideComp = static_cast<ColliderComponent*>(projectileEnt->getComponent(ColliderComponent::getStaticID()));
        WorldComponent * projectileWorldComp = static_cast<WorldComponent*>(projectileEnt->getComponent(WorldComponent::getStaticID()));
        PhysicsComponent* projectilePhysicsComp = static_cast<PhysicsComponent*>(projectileEnt->getComponent(PhysicsComponent::getStaticID()));

        //Check projectile for collisions
        for(int i = 0; i < projectileCollideComp->collisionData.size(); i++)
        {
            std::shared_ptr<CollisionPair> collision = projectileCollideComp->collisionData[i];
            int projectilePairID = collision->getCollisionPairID(subscribedEntities[0][subID]);//Projectile's CollisionPairID
            int collidingPairID = collision->getOppositePairID(projectilePairID);//The Colliding Ent's CollisionPairID
            Entity * collidingEnt = entities[collision->getCollisionEntityID(collidingPairID)]; //The Colliding Entity

            //Check the type of the collided entity and perform action
            if(collidingEnt->hasComponent(TerrainComponent::getStaticID()))
            {
                deleteEntity(projectileEnt->entityID);
            }
            if(collidingEnt->hasComponent(PhysicsComponent::getStaticID()) && !collidingEnt->hasComponent(PlayerComponent::getStaticID()))
            {
                glm::vec2 col = collision->getMinimumTranslation(projectilePairID);
                PhysicsComponent* physicsComp = static_cast<PhysicsComponent*>(collidingEnt->getComponent(PhysicsComponent::getStaticID()));
                //Should 1. Be conserving energy
                //Should 2. Be making sure the velocity is transfered correctly
                //http://gafferongames.com/virtual-go/collision-response-and-coulomb-friction/
                float j = -(1+physicsComp->coefficientRestitution)*glm::dot(projectilePhysicsComp->velocity*projectilePhysicsComp->mass,glm::normalize(col)); //projectiles impulse
                float impulseMag = glm::max(j, 0.0f);
                //Logger()<<impulseMag<<std::endl;
                physicsComp->impulse(impulseMag*glm::normalize(-col));
                projectilePhysicsComp->impulse(impulseMag*glm::normalize(col));
            }
        }
    }
}
Пример #11
0
BaseComponent* PhysicsModule::getComponent(Entity* parent, float mass, Shape s, int group,
        int mask, bool hasTrigger)
{

    PhysicsComponent* component;

    // checking if component exists
    if (components.find(parent->getName()) == components.end()) {
        component = hasTrigger ? new GhostComponent((btScalar) mass, s, group, mask)
                : new PhysicsComponent((btScalar) mass, s, group, mask);
        component->setParent(parent);

        components[parent->getName()] = component;

        if (hasTrigger) {
            ghosts[parent->getName()] = (GhostComponent*) component;
        }
    } else {
        component = components[parent->getName()];
    }

    return component;
}
Пример #12
0
int Physics::castRay(float x, float y, float z, float dx, float dy, float dz, float* pos, float* normal)
{
	btCollisionWorld::ClosestRayResultCallback t(btVector3(x,y,z),btVector3(dx,dy,dz));
	m_physicsWorld->rayTest(btVector3(x,y,z),btVector3(dx,dy,dz),t);
	PhysicsComponent* obj = (PhysicsComponent*)(t.m_collisionObject->getUserPointer());
	if(obj)
	{
		if(pos)
		{
			pos[0] = t.m_hitPointWorld.x();
			pos[1] = t.m_hitPointWorld.y();
			pos[2] = t.m_hitPointWorld.z();
		}
		if(normal)
		{
			normal[0] = t.m_hitNormalWorld.x();
			normal[1] = t.m_hitNormalWorld.y();
			normal[2] = t.m_hitNormalWorld.z();
		}
		return obj->owner()->worldId();
	}
	return 0;
}
Пример #13
0
void RenderSystem::update(float dt, std::vector<GameObject*>* objects)
{
	for (Ite i = objects->begin(); i != objects->end(); i++)
	{
		RenderComponent* render = (*i)->getComponent<RenderComponent>();
		if (render != nullptr)
		{
			RectangleShape shape = *render->getDrawable();
			PhysicsComponent* physics = (*i)->getComponent<PhysicsComponent>();
			if (physics != nullptr)
			{
				Vector2f position = mScale * flipY(physics->getBody()->GetPosition());
				shape.setPosition(position);
				shape.setSize(1.02f * mScale * physics->getSize());
				shape.setOrigin(shape.getSize() * 0.5f);

				// positive direction is opposite in Box2D
				shape.setRotation(-1.0f * physics->getBody()->GetAngle() * 180 / b2_pi);
			}
			mWindow->draw(shape);
		}
	}
}
Пример #14
0
  void ModelComponent::Update(float dt)
  {
    Graphics* gSys = (Graphics*)Engine::GetCore()->GetSystem(ST_Graphics);
    gSys->AddDebugModel(this);

    Input* input = (Input*) Engine::GetCore()->GetSystem(ST_Input);
    InputHandler* handler = input->GetHandler();
    Transform* tr = (Transform*)GetSibling(CT_Transform);
    PhysicsComponent* phys = (PhysicsComponent*) GetSibling(CT_PhysicsComponent);
    if(handler->Check("MoveRight"))
    {
      tr->SetPosition(tr->GetPosition() + Vector3(1.0f,0.0f,0.0f) * dt);
      phys->Reset();
    }
    Model* newModel = gSys->GetModel(model_);
    if(newModel && base_ != newModel)
    {
      base_->RemoveInstance(this);
      base_ = newModel;
      base_->AddInstance(this);
    }


  }
Пример #15
0
	void PhysicsComponent::OnHierarchyChange()
	{
		// Clear out old data
		if(absoluteCShape != nullptr)
			delete absoluteCShape;

		absoluteMass = mass;

		if(children.size() == 0)
		{
			absoluteCOG = cog;
			absoluteCShape = cShape;
		}
		else
		{
			btCompoundShape* compAbsShape = new btCompoundShape();
			absoluteCShape = compAbsShape;
			compAbsShape->addChildShape(btTransform(), cShape);

			for(auto it = children.begin(); it != children.end(); ++it)
			{
				PhysicsComponent* curr = static_cast<PhysicsComponent*>(*it);
				compAbsShape->addChildShape(curr->getTransform(), curr->absoluteCShape);
				absoluteMass += curr->absoluteMass;
			}

			absoluteCOG.setValue(0.0f, 0.0f, 0.0f);
			absoluteCOG += cog * (mass / absoluteMass);

			for(auto it = children.begin(); it != children.end(); ++it)
			{
				PhysicsComponent* curr = static_cast<PhysicsComponent*>(*it);
				absoluteCOG += curr->cog
					* (curr->absoluteMass / absoluteMass);
			}
		}
		// Allow collision shape to be traced back to us
		absoluteCShape->setUserPointer(owner);

		// Only entities with no parents should have rigid bodies.
		if(parent == nullptr)
		{
			//TODO: Update body mass and possibly motionstate
			
			// If the body already exists, this entity was already a parent
			// beforehand.  We just need to update it's collision shape
			// with the new absolute shape.
			if(body != nullptr)
			{
				body->setCollisionShape(absoluteCShape);
				body->setMassProps(absoluteMass, btVector3());
			}
			// Otherwise we need to instantiate a new rigid body and register
			// it with the physics world.
			else
			{
				btRigidBody::btRigidBodyConstructionInfo ci(absoluteMass, nullptr,
					absoluteCShape);
				body = new btRigidBody(ci);

			}

			// Set new center of gravity
			btTransform comTrans;
			comTrans.setOrigin(absoluteCOG);
			body->setCenterOfMassTransform(comTrans);
		}
		// If the entitiy is no longer a parent, remove it from the world
		else if(body != nullptr)
		{
			physMan->GetWorld()->removeRigidBody(body);
			delete body;
			body = nullptr;
		}
		// There is no else. Child objects do not get their own rigid body
	}
Пример #16
0
void Client::Play() {
    OgreEasy::SimpleOgreInit lOgreInit;
    if(!lOgreInit.initOgre()) {
        std::cout<<"Could not init ogre"<<std::endl;
        return;
    }
    Ogre::Root* lRoot = lOgreInit.mRoot.get();
    Ogre::RenderWindow* lWindow = lOgreInit.mWindow;
    World* w = new World();
    w->SetDebugMode(false);
    GameObject camObject = w->AddObject("camera");
    camObject.AddCameraComponent("camera");
    camObject.SetPosition(Ogre::Vector3(0,0,0));
    camObject.LookAt(Ogre::Vector3(0,0,0));

    GameObject& light2 = w->AddObject("point_light");
    light2.AddLightComponent(Ogre::Light::LT_DIRECTIONAL);
    light2.SetPosition(Ogre::Vector3(0,0,40));
    light2.LookAt(Ogre::Vector3(0,100,0));

    GameObject& c = w->AddPhysicsObject("esine", "cube/Cube.mesh");
    c.SetPosition(Ogre::Vector3(0,0,0));
    c.AddBoxCollider(1,1,1);
    PhysicsComponent phys = c.GetPhysicsComponent();
    phys.SetMass(1.0);
    c.SetMaterial("tex");

    GameObject& c2 = w->AddPhysicsObject("esine2", "cube/Cube.mesh");
    c2.SetPosition(Ogre::Vector3(1,2,1));
    c2.AddBoxCollider(1,1,1);
    PhysicsComponent phys2 = c2.GetPhysicsComponent();
    phys2.SetMass(1.0);
    c2.SetMaterial("tex");

    GameObject& taso = w->AddPhysicsObject("taso", "cube/other/Cube.mesh");
    taso.SetPosition(Ogre::Vector3(0, -10, 0));
    taso.AddBoxCollider(10,0.1,10);
    taso.SetMaterial("plane");
    PhysicsComponent phys3 = taso.GetPhysicsComponent();
    phys3.SetMass(0.0);

    GameObject& anim = w->AddObject("anim"  , "second_anim/Cube.mesh");
    anim.SetPosition(Ogre::Vector3(0, -5, 0));
    anim.SetMaterial("tex");

    lRoot->clearEventTimes();
    float f=0.0;
    unsigned long t=0;
    double d;
    Ogre::Timer* a = new Ogre::Timer();
    while(!lWindow->isClosed()) {
        t=a->getMicroseconds();

        camObject.SetPosition(Ogre::Vector3(cos(f)*15.0, -5, sin(f)*15.0));
        camObject.LookAt(Ogre::Vector3(-0,-10,-0), Ogre::Vector3::UNIT_Y);
        w->Update(d);

        f+=d*.5;
        d = (double)(a->getMicroseconds()-t)/1000000;
    }
    delete w;
}
Пример #17
0
void InputModule::moveSphere(Ogre::Vector3 rotation)
{
    PhysicsComponent* component = dynamic_cast<PhysicsComponent*> (ENGINE->getPhysics()->getComponent(ENGINE->getEntity("playerSphere")));
    Ogre::Vector3 vect = Ogre::Vector3(rotation.x, rotation.y, rotation.z);
    component->setComponentGravity(rotation * 10);
}
string PhysicsController::run(string myState, float time_since_last_tick)
{
	string game_state_request = " ";
	for(vector<Entity*>::size_type i = 0; i != controlled_entities.size(); i++) 
	{
		if(controlled_entities[i]->getGameState()==myState)
		{
			if(controlled_entities[i]->getActive())
			{
				//PULL THE MOVING OBJECTS INFORMATION
				PhysicsComponent* physics = (PhysicsComponent*)controlled_entities[i]->getComponent("Physics");
				PositionComponent* position = (PositionComponent*)controlled_entities[i]->getComponent("Position");

				//PULLING ALL THE MASS AND FORCE INFORMATION

				float total_mass = 0 + physics->getMass();
				float total_translation [2] = {0,0};

				float moment_of_inertia = 0 + physics->getMass();
				float total_torque = 0;

				if( controlled_entities[i]->checkIfHasComponent("Collection"))
				{
					CollectionComponent* collection = (CollectionComponent*) controlled_entities[i]->getComponent("Collection");
					vector<Entity*> attached_entities = collection->getAttachedEntities();

					//Cycling through attached entities
					for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
					{
						Entity* attached_entity = attached_entities[p];

						TetheredComponent* tethered = (TetheredComponent*) attached_entity->getComponent("Tethered");
						PhysicsComponent* attached_physics = (PhysicsComponent*) attached_entity->getComponent("Physics");
						PositionComponent* attached_position = (PositionComponent*) attached_entity->getComponent("Position");
						RocketComponent* rocket = (RocketComponent*) attached_entity->getComponent("Rocket");

						float radian_from_center_mass = tethered->getDirectionRadian();
						float radian_to_center_mass = radian_from_center_mass + 3.1415926;
						float t = attached_position->getAngle() - radian_to_center_mass ;
				
						tethered->setT(t);

						//Translational
						vector<float> attached_vector_forces = attached_physics->getNetTranslationalForce();
						total_translation[0] += attached_vector_forces[0];
						total_translation[1] += attached_vector_forces[1];
					
						total_mass+= attached_physics->getMass();

						//Angular
						float attached_net_angular_force = attached_physics->getNetAngularForce();
						total_torque += attached_net_angular_force;

						float distance = tethered->getDistance();
						moment_of_inertia += attached_physics->getMass()*(distance*distance);
					}
			
				}

				//Apparently on forces that have a distance can spin it
				//So after we've pulled all the angular forces we can find the angular acceleration

				//and then you use torque = I*a

				physics->setAngularAcceleration(total_torque/moment_of_inertia);
		

				//PLANAR MOVEMENT

				//We already have the tethered objects' forces so now we need the forces affectin the main object itself
				vector<float> vector_forces = physics->getNetTranslationalForce();
				total_translation[0] += vector_forces[0];
				total_translation[1] += vector_forces[1];
		

				//Calculating the net acceleration net forces and net mass
				physics->setAccelerationX(total_translation[0]/total_mass);
				physics->setAccelerationY(total_translation[1]/total_mass);

				//Determine its new velocity
				physics->setVelocityX(physics->getVelocity()[0]+physics->getAcceleration()[0]*time_since_last_tick);
				physics->setVelocityY(physics->getVelocity()[1]+physics->getAcceleration()[1]*time_since_last_tick);

				//Determine its new position if its not tethered to something
				if( !controlled_entities[i]->checkIfHasComponent("Tethered"))
				{
					position->setX(position->getPosition()[0]+physics->getVelocity()[0]*time_since_last_tick);
					position->setY(position->getPosition()[1]+physics->getVelocity()[1]*time_since_last_tick);
				}
			
				//ANGULAR MOVEMENT
				//	Both tethered and collected entities get this because a tethered can be rotating on its own
				//	on top of being rotated by the collectors movement.
				//  On it's own, a tethered object cannot have an angular acceleration, it must be machine assisted.
		
				physics->setAngularVelocity(physics->getAngularVelocity()+physics->getAngularAcceleration()*time_since_last_tick);
				position->setAngle(position->getAngle()+physics->getAngularVelocity()*time_since_last_tick);

				//To make sure the tethered objects get moved we make sure the collector handles them we he is passed into this controller
				if( controlled_entities[i]->checkIfHasComponent("Collection"))
				{
					CollectionComponent* collection = (CollectionComponent*) controlled_entities[i]->getComponent("Collection");
					vector<Entity*> attached_entities = collection->getAttachedEntities();

					//Go throuhg all the attached entities and update their tethered position wiht the new positon of the collector
					for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
					{
						Entity* attached_entity = attached_entities[p];

						TetheredComponent* tethered = (TetheredComponent*) attached_entity->getComponent("Tethered");
						PhysicsComponent* attached_physics = (PhysicsComponent*) attached_entity->getComponent("Physics");
						PositionComponent* attached_position = (PositionComponent*) attached_entity->getComponent("Position");

						////Determine its new position

						//As the object spins so will all the tethered objects
						tethered->setDirectionRadian( tethered->getDirectionRadian() + physics->getAngularVelocity()*time_since_last_tick);

						float radian_from_center_mass = tethered->getDirectionRadian();
						float radian_to_center_mass = radian_from_center_mass + 3.1415926;
						attached_position->setAngle(radian_to_center_mass + tethered->getT());
				
						//Need to update the angle of the rocket as the main ship spins

						//Set the tethered object to the new position in the new direction
						attached_position->setX( position->getPosition()[0] + cos(tethered->getDirectionRadian())*tethered->getDistance());
						attached_position->setY( position->getPosition()[1] + sin(tethered->getDirectionRadian())*tethered->getDistance());
					}
				}
				position->calculateBucketPosition(BUCKET_WIDTH);
			}
		}
	}
	return game_state_request;
}
Пример #19
0
void PhysicsComponent::loadFromXml(const XMLNode* description) {
	GameLog::logMessage("LOADING BULLET FROM XML");
	// Delete old physics representation
	//release();

	Matrix4f objTrans;
	m_owner->executeEvent(&GameEvent(GameEvent::E_TRANSFORMATION, &GameEventData((float*) objTrans.x, 16), this));

	Vec3f t, r, s;
	objTrans.decompose(t, r, s);

	// Parse Physics Node Configuration
	float mass = static_cast<float>(atof(description->getAttribute("mass", "0.0")));

	const char* shape = description->getAttribute("shape", "Box");
	// create collision shape based on the node configuration
	if (shape && _stricmp(shape, "Box") == 0) // Bounding Box Shape
			{
		float dimX = static_cast<float>(atof(description->getAttribute("x", "1.0")));
		float dimY = static_cast<float>(atof(description->getAttribute("y", "1.0")));
		float dimZ = static_cast<float>(atof(description->getAttribute("z", "1.0")));
		// update box settings with node scaling (TODO is this necessary if we already set the scale by using setLocalScaling?)
		//m_collisionShape = new btBoxShape(btVector3(dimX * s.x, dimY * s.y, dimZ * s.z));
		m_collisionShape = new btBoxShape(btVector3(dimX, dimY, dimZ));
	} else if (shape && _stricmp(shape, "Sphere") == 0) // Sphere Shape
			{
		float radius = static_cast<float>(atof(description->getAttribute("radius", "1.0")));
		m_collisionShape = new btSphereShape(radius);
	} else if (shape && _stricmp(shape, "Cylinder") == 0) // Cylinder Shape
			{
		float radius0 = static_cast<float>(atof(description->getAttribute("radius", "1.0")));
		float height = static_cast<float>(atof(description->getAttribute("height", "1.0")));
		m_collisionShape = new btCylinderShape(btVector3(radius0, height, radius0));
	} else // Mesh Shape
	{
		MeshData meshData;
		GameEvent meshEvent(GameEvent::E_MESH_DATA, &meshData, this);
		// get mesh data from graphics engine
		m_owner->executeEvent(&meshEvent);

		if (meshData.VertexBase && (meshData.TriangleBase32 || meshData.TriangleBase16)) {
			// Create new mesh in physics engine
			m_btTriangleMesh = new btTriangleMesh();
			int offset = 3;
			if (meshData.TriangleMode == 5) // Triangle Strip
				offset = 1;

			// copy mesh from graphics to physics
			bool index16 = false;
			if (meshData.TriangleBase16)
				index16 = true;
			for (unsigned int i = 0; i < meshData.NumTriangleIndices - 2; i += offset) {
				unsigned int index1 = index16 ? (meshData.TriangleBase16[i] - meshData.VertRStart) * 3 : (meshData.TriangleBase32[i] - meshData.VertRStart) * 3;
				unsigned int index2 = index16 ? (meshData.TriangleBase16[i + 1] - meshData.VertRStart) * 3 : (meshData.TriangleBase32[i + 1] - meshData.VertRStart) * 3;
				unsigned int index3 = index16 ? (meshData.TriangleBase16[i + 2] - meshData.VertRStart) * 3 : (meshData.TriangleBase32[i + 2] - meshData.VertRStart) * 3;
				m_btTriangleMesh->addTriangle(btVector3(meshData.VertexBase[index1], meshData.VertexBase[index1 + 1], meshData.VertexBase[index1 + 2]),
						btVector3(meshData.VertexBase[index2], meshData.VertexBase[index2 + 1], meshData.VertexBase[index2 + 2]),
						btVector3(meshData.VertexBase[index3], meshData.VertexBase[index3 + 1], meshData.VertexBase[index3 + 2]));
			}

			bool useQuantizedAabbCompression = true;

			if (mass > 0) {
				//btGImpactMeshShape* shape = new btGImpactMeshShape(m_btTriangleMesh);

				btGImpactConvexDecompositionShape* shape = new btGImpactConvexDecompositionShape(m_btTriangleMesh, btVector3(1.f, 1.f, 1.f), btScalar(0.1f), true);

				shape->updateBound();

				//btCollisionDispatcher* dispatcher = static_cast<btCollisionDispatcher *>(Physics::instance()->dispatcher());
				//btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);

				m_collisionShape = shape;

				//m_collisionShape = new btConvexTriangleMeshShape(m_btTriangleMesh);
			} else
				// BvhTriangleMesh can be used only for static objects
				m_collisionShape = new btBvhTriangleMeshShape(m_btTriangleMesh, useQuantizedAabbCompression);
		} else {
			GameLog::errorMessage("The mesh data for the physics representation couldn't be retrieved");
			return;
		}
	}

	GameLog::logMessage("PARSED SHAPE FROM XML");

	bool kinematic = _stricmp(description->getAttribute("kinematic", "false"), "true") == 0 || _stricmp(description->getAttribute("kinematic", "0"), "1") == 0;

	bool nondynamic = _stricmp(description->getAttribute("static", "false"), "true") == 0 || _stricmp(description->getAttribute("static", "0"), "1") == 0;

	bool ragdoll = _stricmp(description->getAttribute("ragdoll", "false"), "true") == 0 || _stricmp(description->getAttribute("ragdoll", "0"), "1") == 0;
	// Create initial transformation without scale
	btTransform tr;
	tr.setIdentity();
	tr.setRotation(btQuaternion(r.x, r.y, r.z));

	btMatrix3x3 rot = tr.getBasis();

	XMLNode offsetXMLNode = description->getChildNode("Offset");

	if (!offsetXMLNode.isEmpty()) {
		lX = static_cast<float>(atof(offsetXMLNode.getAttribute("lX", "0.0")));
		lY = static_cast<float>(atof(offsetXMLNode.getAttribute("lY", "0.0")));
		lZ = static_cast<float>(atof(offsetXMLNode.getAttribute("lZ", "0.0")));
	}

	btVector3 offset = btVector3(lX * s.x, lY * s.y, lZ * s.z);

	tr.setOrigin(btVector3(t.x, t.y, t.z) + rot * offset);
	// Set local scaling in collision shape because Bullet does not support scaling in the world transformation matrices
	m_collisionShape->setLocalScaling(btVector3(s.x, s.y, s.z));
	btVector3 localInertia(0, 0, 0);
	//rigidbody is dynamic if and only if mass is non zero otherwise static
	if (mass != 0)
		m_collisionShape->calculateLocalInertia(mass, localInertia);
	if (mass != 0 || kinematic)
		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
		m_motionState = new btDefaultMotionState(tr);

	btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, m_motionState, m_collisionShape, localInertia);
	rbInfo.m_startWorldTransform = tr;
	//rbInfo.m_restitution = btScalar( atof(description->getAttribute("restitution", "0")) );
	//rbInfo.m_friction = btScalar( atof(description->getAttribute("static_friction", "0.5")) );
	// Threshold for deactivation of objects (if movement is below this value the object gets deactivated)
	//rbInfo.m_angularSleepingThreshold = 0.8f;
	//rbInfo.m_linearSleepingThreshold = 0.8f;

	m_rigidBody = new btRigidBody(rbInfo);
	m_rigidBody->setUserPointer(this);
	m_rigidBody->setDeactivationTime(2.0f);

	// Add support for collision detection if mass is zero but kinematic is explicitly enabled
	if (kinematic && mass == 0 && !nondynamic) {
		m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
		m_rigidBody->setActivationState(DISABLE_DEACTIVATION);
	}
	if (nondynamic && mass == 0) {
		m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
	}

	bool isTrigger = _stricmp(description->getAttribute("solid", "true"), "false") == 0 || _stricmp(description->getAttribute("solid", "1"), "0") == 0;
	if (isTrigger) {
		setCollisionResponse(true);
	}

	GameLog::logMessage("I'm a new Physics body: %s my Motion state: %d", m_owner->id().c_str(), m_motionState);
	printf("I'm a new Physics body: %s my Motion state: %d\n", m_owner->id().c_str(), m_motionState);

	if(!ragdoll) Physics::instance()->addObject(this);

	/*Geometry Proxy*/
	XMLNode proxyXMLNode = description->getChildNode("Proxy");
	if (proxyXMLNode.isEmpty())
		return;

	m_proxy = GameModules::gameWorld()->entity(proxyXMLNode.getAttribute("name", ""));

	if (m_proxy) {
		m_proxy->addListener(GameEvent::E_SET_TRANSFORMATION, this);
		m_proxy->addListener(GameEvent::E_SET_TRANSLATION, this);
		m_proxy->addListener(GameEvent::E_SET_ROTATION, this);
		m_proxy->addListener(GameEvent::E_TRANSLATE_LOCAL, this);
		m_proxy->addListener(GameEvent::E_TRANSLATE_GLOBAL, this);
		m_proxy->addListener(GameEvent::E_ROTATE_LOCAL, this);
	} else
		printf("No PROXY FOUND with EntityID: %s\n", proxyXMLNode.getAttribute("name", ""));

	/*Adding constraints*/

	XMLNode constraintXMLNode = description->getChildNode("Constraint");
	if (constraintXMLNode.isEmpty())
		return;

	const char* constraintType = constraintXMLNode.getAttribute("type", "Hinge");
	const char* parentName = constraintXMLNode.getAttribute("parent", "");
	PhysicsComponent* parent = getParent(parentName);

	if (!parent) {
		printf("NO PARENT FOUND\n");
		return;
	}

	XMLNode transformXMLNode = constraintXMLNode.getChildNode("TransformA");
	float qX = static_cast<float>(atof(transformXMLNode.getAttribute("qx", "1.0")));
	float qY = static_cast<float>(atof(transformXMLNode.getAttribute("qy", "1.0")));
	float qZ = static_cast<float>(atof(transformXMLNode.getAttribute("qz", "1.0")));
	float qW = static_cast<float>(atof(transformXMLNode.getAttribute("qw", "1.0")));
	float vX = static_cast<float>(atof(transformXMLNode.getAttribute("vx", "1.0")));
	float vY = static_cast<float>(atof(transformXMLNode.getAttribute("vy", "1.0")));
	float vZ = static_cast<float>(atof(transformXMLNode.getAttribute("vz", "1.0")));
	btTransform transformA;
	transformA.setIdentity();
	printf("%f \t %f \t %f  \n ", qX, qY, qZ);
	transformA.getBasis().setEulerZYX(qZ, qY, qX);
//	transformA.getBasis().setEulerZYX(M_PI_2,0,0);
	transformA.setOrigin(btVector3(vX * s.x, vY * s.y, vZ * s.z));
//	printf("%f \t %f \t %f \t %s \n ", vX*s.x, vY*s.y, vZ*s.z, m_owner ? m_owner->id().c_str() : "no name");
//	btTransform transformA = btTransform(btQuaternion(qX, qY, qZ, qW), btVector3(vX*s.x, vY*s.y, vZ*s.z));

	transformXMLNode = constraintXMLNode.getChildNode("TransformB");
	qX = static_cast<float>(atof(transformXMLNode.getAttribute("qx", "1.0")));
	qY = static_cast<float>(atof(transformXMLNode.getAttribute("qy", "1.0")));
	qZ = static_cast<float>(atof(transformXMLNode.getAttribute("qz", "1.0")));
	qW = static_cast<float>(atof(transformXMLNode.getAttribute("qw", "1.0")));
	vX = static_cast<float>(atof(transformXMLNode.getAttribute("vx", "1.0")));
	vY = static_cast<float>(atof(transformXMLNode.getAttribute("vy", "1.0")));
	vZ = static_cast<float>(atof(transformXMLNode.getAttribute("vz", "1.0")));
//	btTransform transformB = btTransform(btQuaternion(qX, qY, qZ, qW), btVector3(vX*s.x, vY*s.y, vZ*s.z));
	btTransform transformB;
	transformB.setIdentity();
	transformB.getBasis().setEulerZYX(qZ, qY, qX);
//	transformB.getBasis().setEulerZYX(M_PI_2,0,0);
	transformB.setOrigin(btVector3(vX * s.x, vY * s.y, vZ * s.z));

	XMLNode limitXMLNode = constraintXMLNode.getChildNode("Limit");

	if (_stricmp(constraintType, "Hinge") == 0) {
		btHingeConstraint* parentConstraint = new btHingeConstraint(*(parent->rigidBody()), *m_rigidBody, transformA, transformB);
		float low = static_cast<float>(atof(limitXMLNode.getAttribute("low", "0.0")));
		float high = static_cast<float>(atof(limitXMLNode.getAttribute("high", "0.75")));
		float softness = static_cast<float>(atof(limitXMLNode.getAttribute("softness", "0.9")));
		float biasFactor = static_cast<float>(atof(limitXMLNode.getAttribute("biasFactor", "0.3")));
		float relaxationFactor = static_cast<float>(atof(limitXMLNode.getAttribute("relaxationFactor", "1.0")));

		parentConstraint->setLimit(low, high, softness, biasFactor, relaxationFactor);
		m_parentConstraint = parentConstraint;
	} else if (_stricmp(constraintType, "ConeTwist") == 0) {
		btConeTwistConstraint* parentConstraint = new btConeTwistConstraint(*(parent->rigidBody()), *m_rigidBody, transformA, transformB);
		float swingSpan1 = static_cast<float>(atof(limitXMLNode.getAttribute("swingSpan1", "1.0")));
		float swingSpan2 = static_cast<float>(atof(limitXMLNode.getAttribute("swingSpan2", "1.0")));
		float twistSpan = static_cast<float>(atof(limitXMLNode.getAttribute("twistSpan", "1.0")));
		float softness = static_cast<float>(atof(limitXMLNode.getAttribute("softness", "0.9")));
		float biasFactor = static_cast<float>(atof(limitXMLNode.getAttribute("biasFactor", "0.3")));
		float relaxationFactor = static_cast<float>(atof(limitXMLNode.getAttribute("relaxationFactor", "1.0")));

		parentConstraint->setLimit(swingSpan1, swingSpan2, twistSpan, softness, biasFactor, relaxationFactor);
		m_parentConstraint = parentConstraint;
	}

	if(!ragdoll) Physics::instance()->addConstraint(m_parentConstraint);

}
void wrapTickCallback(btDynamicsWorld *world, btScalar timeStep)
{
    PhysicsComponent *component = static_cast<PhysicsComponent *>(world->getWorldUserInfo());
	component->detectedCollisionsDuringStepSimulation(timeStep);
}
Пример #21
0
string RocketController::run(string myState)
{
	string game_state_request;
	for(vector<Entity*>::size_type i = 0; i != controlled_entities.size(); i++) 
	{
		Entity* ent = controlled_entities[i];
		if(ent->getGameState() == myState)
			{
			if(ent->getActive())
			{
				//SUBTRACT FUEL
				SpaceshipComponent* spaceship = (SpaceshipComponent*) ent->getComponent("Spaceship");
				float current_fuel = spaceship->getCurrentFuel();

				CollectionComponent* collection = (CollectionComponent*) ent->getComponent("Collection");
				vector<Entity*> attached_entities = collection->getAttachedEntities();

				//Cycling through attached entities
				for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
				{
					Entity* attached_entity = attached_entities[p];
					attached_entity->setActive(true);

					if(attached_entity->checkIfHasComponent("Rocket"))
					{
						RocketComponent* rocket = (RocketComponent*) attached_entity->getComponent("Rocket");
						TetheredComponent* tethered = (TetheredComponent*) attached_entity->getComponent("Tethered");
						PositionComponent* position = (PositionComponent*) attached_entity->getComponent("Position");
						PhysicsComponent* physics = (PhysicsComponent*) attached_entity->getComponent("Physics");

						physics->clearForces();

						if(rocket->getOnOrOff())
						{
							if(spaceship->getCurrentFuel() - rocket->getFuelConsumption() >= 0)
							{
								//The rocket is on
								float force_exerted = rocket->getForceExerted();
								float angle = position->getAngle();

								float x =  rocket->getForceExerted()*cos(angle);
								float y =  rocket->getForceExerted()*sin(angle);
						
								physics->addTranslationalForce(x,y);

								//Angular Forces

								float distance = tethered->getDistance();
								float angular_force = distance *  rocket->getForceExerted() * -sin(tethered->getT());

								physics->addAngularForce(angular_force);

								//Burning fuel
								spaceship->subtractCurrentFuel(rocket->getFuelConsumption());
							}
						}
					}
				}
			}
			else
			{
				CollectionComponent* collection = (CollectionComponent*) ent->getComponent("Collection");
				vector<Entity*> attached_entities = collection->getAttachedEntities();

				//Cycling through attached entities
				for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
				{
					attached_entities[p]->setActive(false);
				}
			}
		}
	}
	return game_state_request;
}
Пример #22
0
void GhostComponent::checkOverlappingObjects()
{
    int max = ghostObject->getNumOverlappingObjects();
    std::set<std::string> currentlyCollidingObjects;

    for (int i = 0; i < max; i++) {
        btCollisionObject* collidee = ghostObject->getOverlappingObject(i);
        PhysicsComponent* component = static_cast<PhysicsComponent*> (collidee->getUserPointer());

        std::string colliderName = component->getParent()->getName();
        currentlyCollidingObjects.insert(colliderName);

        std::set<std::string>::iterator colliderIterator = lastKnownColliders.begin();

        bool previouslyCollided = false;

        for (; colliderIterator != lastKnownColliders.end(); colliderIterator++) {
            if (colliderName == *colliderIterator) {
                previouslyCollided = true;
            }
        }

        Event* e;

        if (!previouslyCollided) {
            e = new Event(Event::COLLISION_ENTER);
        } else {
            e = new Event(Event::COLLISION);
        }

        e->entity = component->getParent();
        this->parent->receiveEvent(e);
        //delete e;
    }

    int setDeltas = lastKnownColliders.size() - currentlyCollidingObjects.size();

    if (setDeltas > 0) {

        // handling exit collisions
        std::vector<std::string>::iterator it;
        std::vector<std::string> delta(setDeltas);

        it = std::set_difference(lastKnownColliders.begin(),
                lastKnownColliders.end(),
                currentlyCollidingObjects.begin(),
                currentlyCollidingObjects.end(),
                delta.begin());

        for (; it != delta.end(); it++) {
            Entity* exitCollision = ENGINE->getEntity(*it);
            Event* exitEvent = new Event(Event::COLLISION_EXIT);
            exitEvent->entity = exitCollision;
            parent->receiveEvent(exitEvent);
            delete exitEvent;
        }
        //@todo delete events after sending them. Right now they all remain on the heap
    }

    lastKnownColliders = currentlyCollidingObjects;
}
Пример #23
0
 bool deserialize(JsonNode& root, PhysicsComponent& physics)
 {
    physics.set_size(deserialize_vec3f(root["size"]) * TILE_SIZE);
    return true;
 }
Пример #24
0
void InputModule::moveSphere(Ogre::Vector3 direction)
{
    PhysicsComponent* component = dynamic_cast<PhysicsComponent*> (ENGINE->getPhysics()
            ->getComponent(ENGINE->getEntity("playerSphere")));
    component->setComponentGravity((direction) * 10);
}
Пример #25
0
Level* GameInfo::loadLevel(string filename, std::shared_ptr<GenericPool<PhysicsComponent>> physicsPool)
{
	picojson::value v;
	ifstream levelStream;
	levelStream.open(filename);
	int currentTileLayer = 1;
	std::string tileString = "Tile Layer ";
	int width = 0;
	int height = 0;
	int x = 0;
	int y = 0;
	const picojson::array* tileArray = NULL;

	levelStream >> v;
	if (levelStream.fail())
	{
		std::cerr << picojson::get_last_error() << std::endl;
		return NULL;
	}

	//std::cout << "---- dump input ----" << std::endl;
	//std::cout << v << std::endl;

	//std::cout << "---- analyzing input ----" << std::endl;
	/*if (v.is<picojson::null>())
	{
		std::cout << "input is null" << std::endl;
	}
	else if (v.is<bool>())
	{
		std::cout << "input is " << (v.get<bool>() ? "true" : "false") << std::endl;
	}
	else if (v.is<double>())
	{
		std::cout << "input is " << v.get<double>() << std::endl;
	}
	else if (v.is<std::string>())
	{
		std::cout << "input is " << v.get<std::string>() << std::endl;
	}
	else if (v.is<picojson::array>())
	{
		std::cout << "input is an array" << std::endl;
		const picojson::array& a = v.get<picojson::array>();
		for (picojson::array::const_iterator i = a.begin(); i != a.end(); ++i)
		{
			std::cout << "  " << *i << std::endl;
		}
	}*/
	if (v.is<picojson::object>())
	{
		const picojson::object& o = v.get<picojson::object>();
		for (picojson::object::const_iterator i = o.begin(); i != o.end(); ++i)
		{
			if (i->first == "height")
				height = (int)i->second.get<double>();

			else if (i->first == "width")
				width = (int)i->second.get<double>();
		}
	}
	Locator::getLog()->printToFile("GameInfo-LoadLevel", "Width: " + std::to_string(width) + ", Height: " + std::to_string(height));

	Level_Tile_3DVector_.resize(MAXTILELAYERS, std::vector<std::vector<int>>(width, std::vector<int>(height, 0)));

	if (v.is<picojson::object>())
	{
		//std::cout << "input is an object" << std::endl;
		const picojson::object& o = v.get<picojson::object>();
		for (picojson::object::const_iterator i = o.begin(); i != o.end(); ++i)
		{
			if (i->second.is<picojson::array>())
			{
				//std::cout << "2nd is an array" << std::endl;
				const picojson::array& a = i->second.get<picojson::array>();
				for (picojson::array::const_iterator i = a.begin(); i != a.end(); ++i)
				{
					auto g = *i;

					if (g.is<std::string>())
					{
						//std::cout << "g is a string" << std::endl;
					}
					else if (g.is<picojson::object>())	//gets the objects within the layers array
					{
						//std::cout << "g is an object" << std::endl;
						const picojson::object& q = g.get<picojson::object>();
						for (picojson::object::const_iterator p = q.begin(); p != q.end(); ++p)
						{
							if (p->first == "name")
							{
								if (p->second.is<std::string>())
								{
									std::string tempString = p->second.get<std::string>();
									for (int ggg = 0; ggg < MAXTILELAYERS; ggg++)
									{
										if (tempString == tileString + std::to_string(ggg + 1))
										{
											currentTileLayer = ggg;
										}
									}

								}
							}
						}

						for (picojson::object::const_iterator p = q.begin(); p != q.end(); ++p)
						{

							if (p->first == "data")	//tile information
							{
								//we found the tiles here! finally!
								if (p->second.is<picojson::array>())
								{
									//std::cout << "FREAK OUT AGAIN" << std::endl;
									//tileArray = &p->second.get<picojson::array>();
									tileArray = &p->second.get<picojson::array>();
									for (picojson::array::const_iterator u = tileArray->begin(); u != tileArray->end(); ++u)
									{
										auto l = *u;
										//if (l.is<std::string>())	std::cout << "l is a string" << std::endl;
										if (l.is<double>())
										{
											Level_Tile_3DVector_[currentTileLayer][x][y] = (int)l.get<double>();
											x++;

											if (x == width)
											{
												x = 0;
												y++;
											}
											if (y == height)
											{
												x = 0; 
												y = 0;
											}

											//levelTiles_.push_back((int)l.get<double>());

												//std::cout << "added: " << currentTileLayer << std::endl;
										}
									}
									//found the array containing the tile data!
									//const picojson::array& a = p->second.get<picojson::array>();

								}
							}
							
							else if (p->first == "objects")	//collision objects (or any object)
							{
								if (p->second.is<picojson::array>())	//array of actual objects
								{
									tileArray = &p->second.get<picojson::array>();
									for (picojson::array::const_iterator u = tileArray->begin(); u != tileArray->end(); ++u)
									{
										auto l = *u;

										if (l.is<picojson::object>())	//found an actual collision object now!
										{
											const picojson::object& ww = l.get<picojson::object>();	//get the object
											double h = -1, w = -1, xtemp = -1, ytemp = -1;
											for (picojson::object::const_iterator qq = ww.begin(); qq != ww.end(); ++qq)	//iterate through data
											{
												if (qq->first == "height")
													h = qq->second.get<double>();
												else if (qq->first == "width")
													w = qq->second.get<double>();
												else if (qq->first == "x")
													xtemp = qq->second.get<double>();
												else if (qq->first == "y")
													ytemp = qq->second.get<double>();
											}
											PhysicsComponent* phys = physicsPool->getAvailableElement();
											phys->setCoordsAndDimensions(xtemp, ytemp, w, h);
											phys->setPhysicsType(BLOCK);
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	//std::cout << "Width: " << width << std::endl;
	//std::cout << "Height: " << height << std::endl;
	if (currentLevel_ != nullptr)
		delete currentLevel_;
	currentLevel_ = new Level(Level_Tile_3DVector_, physicsPool);
	currentLevel_->backgroundTex.create(width*TILESIZE, height*TILESIZE);
	return currentLevel_;
}