Esempio n. 1
0
void WaterPlane::SetVertexPosition( Vector3 pos, int vertexIndex )
{
	switch (vertexIndex)
	{
	case 0:
		this->verts[0].pos = pos;
		break;
	case 1:
		this->verts[1].pos = pos;
		this->verts[4].pos = pos;
		break;
	case 2:
		this->verts[2].pos = pos;
		this->verts[3].pos = pos;
		break;
	case 3:
		this->verts[5].pos = pos;
		break;
	default:
		MaloW::Debug("SetVertexPosition in Waterplane out of index.");
		break;
	}

	// Calculate new normal
	Vector3 newNorm = Vector3(0, 0, 0);
	D3DXVECTOR3 one = this->verts[0].pos - this->verts[5].pos;
	D3DXVECTOR3 two = this->verts[1].pos - this->verts[2].pos;
	Vector3 vone = Vector3(one.x, one.y, one.z);
	Vector3 vtwo = Vector3(two.x, two.y, two.z);
	newNorm = vtwo.GetCrossProduct(vone);
	newNorm.Normalize();
	for(int i = 0; i < 6; i++)
		this->verts[i].normal = newNorm;

	this->VertexDataHasChanged = true;
}
Esempio n. 2
0
void Helicopter::Update(float dt)
{
	// Gravity
	this->direction.y -= GRAVITY * dt;

	// Air friction
	float velocity = this->GetVelocity();
	float newVelocity = velocity - ((AIR_FRICTION_CONSTANT * (velocity * velocity)) / this->mass) * dt;
	float dv = newVelocity / velocity;
	this->direction *= dv;
	
	
	// Collision against terrain
	float terrY = this->terrain->GetYPositionAt(this->pos.x, this->pos.z);
	if(this->pos.y + this->direction.y * dt <= terrY)
	{
		// Bounce
		this->direction.y = 0 - this->direction.y * this->elacticity;

		// Take damage
		float damage = (abs(this->direction.y * 5) + abs(this->direction.x) + abs(this->direction.z)); 
		if(damage > 5.0f)
			this->health -= damage;
	}


	// Regen health:
	this->health += dt;
	if(this->health > 100.0f)
		this->health = 100.0f;
	
	
	// Friction against terrain here if close to it, simplified calculating only in the XZ plane and not angled terrain.
	if(this->pos.y - 0.5f < terrY)
	{
		float frictionForce = GROUND_FRICTION_CONSTANT * this->mass * GRAVITY;
		float frictionAcc = (frictionForce / this->mass) * dt;
		if(frictionAcc > this->GetXZVelocity())
		{
			this->direction.x = 0;
			this->direction.z = 0;
		}
		else
		{
			velocity = this->GetVelocity();
			newVelocity = velocity - frictionAcc;
			dv = newVelocity / velocity;
			this->direction *= dv;
		}

		// Reset rolling when touching ground.
		Vector3 defup = Vector3(0, 1, 0);
		defup.Normalize();
		Vector3 cross = this->up.GetCrossProduct(this->forward);
		cross.Normalize();
		float dotCrossDefup = cross.GetDotProduct(defup);
		// Roll left
		if(dotCrossDefup < 0.0f)
		{
			this->RollLeft(true);
			this->RollRight(false);
		}
		// Roll right
		else if(dotCrossDefup > 0.0f)
		{
			this->RollLeft(false);
			this->RollRight(true);
		}

		float dotForUp = this->forward.GetDotProduct(defup);
		// Roll forward
		if(dotForUp > 0.0f)
		{
			this->RollForward(true);
			this->RollBackward(false);
		}
		// Roll backward
		else if(dotForUp < 0.0f)
		{
			this->RollForward(false);
			this->RollBackward(true);
		}
	}
	
	if(this->health > 95.0f)
		this->UpdateChopperSpec(dt);


	// For funness we need to reset the direction.y a little, it's too hard to handle up&downs otherwise
	//direction.y *= 1.0f - dt;

	// AutoHoverEffect
	this->AutoHover(dt);

	if(this->health > 95.0f)
	{
		this->pos += this->direction * dt;
		this->chopper->SetPosition(this->pos);
		this->rotor->SetPosition(this->pos);
		this->secrotor->SetPosition(this->pos - this->forward * 28 + this->up * 11);	// Adding offset for the second rotor.

		Vector3 lookAt = this->forward;
		lookAt.y = 0.0f;
		GetGraphics()->GetCamera()->SetPosition(this->pos + Vector3(0, this->camOffsetHeight, 0) - lookAt * this->camOffsetDistance);
		GetGraphics()->GetCamera()->LookAt(this->pos + lookAt * 30 + Vector3(0, 10, 0));


		// Attune forward to direction.
		Vector3 xzdir = this->direction;
		xzdir.y = 0.0f;
		float xzlen = xzdir.GetLength();
		xzdir.Normalize();
		Vector3 xzfor = this->forward;
		xzfor.y = 0.0f;
		xzfor.Normalize();
		float dotDirFor = xzdir.GetDotProduct(xzfor);
		Vector3 vecRight = xzfor.GetCrossProduct(Vector3(0, 1, 0));
		vecRight.y = 0.0f;
		vecRight.Normalize();
		float dotDirRight = xzdir.GetDotProduct(vecRight);

		// When flying backwards remove the "BAM SNAP" effect when dot product gets 0.0f at the sides.
		if(dotDirFor < 0.0f)
			dotDirFor = 0.0f;

		float angle = dt * xzlen * xzlen * xzlen * xzlen * (1 - abs(dotDirFor)) * 0.000001f;
		if(dotDirRight < 0.0f)
			angle *= -1.0f;
		this->forward.RotateAroundAxis(this->up, -angle);
		this->chopper->RotateAxis(this->up, -angle);
		this->rotor->RotateAxis(this->up, angle);
	}
}
bool ProjectileArrowBehavior::Update( float dt )
{
	if(!zMoving)
		return true;

	Vector3 newPos;
	Vector3 newDir;
	
	// Update linear position.
	newPos =  this->zActor->GetPosition();
	zVelocity.Normalize();
	zVelocity *= zSpeed;
	newPos += (zVelocity * dt);
	newDir = zVelocity;
	newDir.Normalize();

	//Rotate Mesh
	Vector3 ProjectileStartDirection = Vector3(0,0,-1);
	Vector3 ProjectileMoveDirection = newDir;

	ProjectileStartDirection.Normalize();

	Vector3 around = ProjectileStartDirection.GetCrossProduct(ProjectileMoveDirection);
	float angle = acos(ProjectileStartDirection.GetDotProduct(ProjectileMoveDirection));

	//Set Values
	this->zActor->SetPosition(newPos, false);
	this->zActor->SetRotation(Vector4(0.0f, 0.0f, 0.0f, 1.0f));
	this->zActor->SetRotation(around, angle);
	this->zActor->SetDir(newDir);

	/**Check If the arrow is outside the world.**/
	if( !this->zWorld->IsInside(newPos.GetXZ()) )
	{
		Stop();
		this->zActor->SetPosition(newPos);

		return true;
	}
	//**Check if the projectile has hit the ground**
	float yValue = std::numeric_limits<float>::lowest();
	try
	{
		yValue = this->zWorld->CalcHeightAtWorldPos(newPos.GetXZ());
	}
	catch(...)
	{
		Stop();
		this->zActor->SetPosition(newPos);

		return true;
	}

	// If true, stop the projectile and return.
	float middle = zLength * 0.5f;
	float yTip = newPos.y - middle;
	if(yTip <= yValue )
	{
 		middle += yValue;
 		newPos.y = middle;

		this->Stop();
		this->zActor->SetPosition(newPos);
		
		return true;
	}

	//**Update Velocity for next update**

	// Update linear velocity from the acceleration.
	this->zVelocity += (GRAVITY * dt);

	// Impose drag.
	this->zVelocity *= pow(zDamping, dt);
	
	//Update-Notify Position
	this->zActor->SetPosition(newPos);

	/***Check collisions***/

	//Check if the arrow has hit a dynamic actor
	Actor* collide = RayVsMeshDynamicActorCollision(zLength, newPos);

	if(collide)
	{
		this->Stop();
		ProjectileArrowCollide PAC;
		PAC.zActor = collide;
		NotifyObservers(&PAC);

		if( BioActor* bioActor = dynamic_cast<BioActor*>(collide) )
		{
			if( bioActor->IsAlive() )
			{
				ProjectileActor* projActor = dynamic_cast<ProjectileActor*>(this->zActor);
				bioActor->TakeDamage( projActor->GetDamage(), projActor->GetOwner() );
			}
		}

		this->zHitTarget = collide;
		return true;
	}

	//Check if the arrow has hit a static actor
	collide = RayVsMeshStaticActorCollision(zLength, newPos);

	if(collide)
	{
		this->Stop();
		ProjectileArrowCollide PAC;
		PAC.zActor = collide;
		NotifyObservers(&PAC);

		this->zHitTarget = collide;
		return true;
	}

	return false;
}
Esempio n. 4
0
void FPSCamera::UpdateSpecific(float)
{
	POINT p;
	if(GetCursorPos(&p))
	{
		if(ScreenToClient(this->g_hWnd, &p))
		{
			float diffX = (this->params.windowWidth/2) - (float)p.x;
			float diffY = (this->params.windowHeight/2) - (float)p.y;
			
			this->angleX += diffX * (this->sensitivity * 0.001f);
			this->angleY += diffY * (this->sensitivity * 0.001f);
			
			fmod(angleX, 2 * PI);
			fmod(angleY, 2 * PI);

			//if(angleY > PI/2)
			//	angleY = PI/2;
			//if(angleY < -PI/2)
			//	angleY = -PI/2;
			
			if(angleX > 2*PI)
				angleX -= 2*PI;
			if(angleX < 0)
				angleX += 2 * PI;

			if(angleY > PI)
				angleY = PI;
			if(angleY < -PI)
				angleY = -PI;

			this->forward.x = cos(angleX);
			//this->forward.y = sin(angleY);
			this->forward.y = angleY;
			this->forward.z = sin(angleX);

			this->forward = this->NormalizeVector(this->forward);
			
			//calc new up
			//crossproduct between y-axis & forward vector
			Vector3 yAxis = Vector3(0, 1, 0);
			Vector3 tmpForward = Vector3();//already normalized
			tmpForward.x = this->forward.x;
			tmpForward.y = this->forward.y; 
			tmpForward.z = this->forward.z; 
			Vector3 rightVec = yAxis.GetCrossProduct(tmpForward);
			rightVec.Normalize();
			//crossproduct between forward & right vector 
			Vector3 tmpUp = Vector3();
			tmpUp = tmpForward.GetCrossProduct(rightVec);
			this->up.x = tmpUp.x;
			this->up.y = tmpUp.y;
			this->up.z = tmpUp.z;
			this->up = this->NormalizeVector(this->up);

			POINT np;
			np.x = this->params.windowWidth/2;
			np.y = this->params.windowHeight/2;
			if(ClientToScreen(this->g_hWnd, &np))
			{
				SetCursorPos(np.x, np.y);
			}
		}
	}
}