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; }
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; }
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); } } } }