Bool Camera::SetupMatrix() { Vid::SetCameraTransform( WorldMatrix()); viewMatrix = Vid::Math::viewMatrix; pyramid[0] = WorldMatrix().Position(); WorldMatrix().Transform( &pyramid[1], &frustrum[4], 4); // possible meters-in-view // boxMin = boxMax = pyramid[0]; for (U32 i = 1; i < 5; i++) { if (boxMin.x > pyramid[i].x) { boxMin.x = pyramid[i].x; } if (boxMax.x < pyramid[i].x) { boxMax.x = pyramid[i].x; } if (boxMin.z > pyramid[i].z) { boxMin.z = pyramid[i].z; } if (boxMax.z < pyramid[i].z) { boxMax.z = pyramid[i].z; } #if 0 if (boxMin.y > pyramid[i].y) { boxMin.y = pyramid[i].y; } if (boxMax.y < pyramid[i].y) { boxMax.y = pyramid[i].y; } #endif } #ifdef DOOCCULSION if (Occlusion) { Occlusion->Setup(); } #endif return TRUE; }
// // ProjectileObj::Setup // // Setup a created projectile // void ProjectileObj::Setup(UnitObj *sourceIn, Team *teamIn, Weapon::Type *weaponTypeIn, const Target &targetIn, S32 damageIn, F32 speedIn) { startPosit = WorldMatrix().posit; source = sourceIn; sourceTeam = teamIn; weaponType = weaponTypeIn; target = targetIn; firingWeaponId = weaponType->GetDamage().GetDamageId(); damage = damageIn; // Set the velocity of the projectile using the current world matrix SetSpeed(speedIn); SetVelocity(WorldMatrix().front * speedIn); }
void CModel::ResetTransform(){ for( CEntity *child=Children();child;child=child->Next() ){ if( CModel *model=dynamic_cast<CModel*>( child ) ) model->ResetTransform(); } TransformSurfaces( WorldMatrix() ); SetWorldMatrix( CMat4() ); }
void BoneMoveable::OnUpdateWorldBoundingBox(BoundingBox& outVal, int32 dirtyFlag) { CubeF cube; cube.Origin = Point3F::Zero; cube.Size = mSize; outVal = WorldMatrix().Transform(cube); }
void Camera::Mirror( const Plane & plane) { SaveMatrix(); // SetProjTransform( nearPlane, farPlane + 10.0f, fov); Matrix matrix = WorldMatrix(); matrix.Mirror( plane); SetWorldAll( matrix); }
void FamilyNode::SetWorldRecurse( const Matrix &world) { CalcWorldMatrix( world); NList<FamilyNode>::Iterator kids(&children); FamilyNode *node; while ((node = kids++) != NULL) { node->SetWorldRecurse( WorldMatrix()); } }
void FamilyNode::SetWorldAll() { ASSERT( statePtr); if (parent) { SetWorldRecurse( parent->WorldMatrix()); return; } // FIXME: multiply by inverse objectMatrix // SetWorldRecurse( WorldMatrix()); }
float3x4 Frustum::ViewMatrix() const { float3x4 world = WorldMatrix(); world.InverseOrthonormal(); return world; }
Rect2F BoneMoveable::TransformToWorld(const Rect2F& val) const { return WorldMatrix().Transform(val); }
Point3F BoneMoveable::TransformToWorld(const Point3F& val) const { return WorldMatrix().Transform(val); }
void DxLight::PointLight(Vertex *src, U32 count) { ASSERT( src ); if (!IsActive()) { return; } Material *material = Manager::curMaterial; // calculate the light's model space position Matrix inverse_world_matrix; inverse_world_matrix.SetInverse(Vid::world_matrix); #ifndef DOBZ2 inverse_world_matrix.Transform(position, WorldMatrix().Position()); #else Vector Centre (CalcSimWorldPosition(Vector (0, 0, 0))); inverse_world_matrix.Transform(position, Centre); #endif // calculate the model space direction direction = position; direction.Normalize(); Bool do_specular = (material->status.specular && Vid::renderState.status.specular && (desc.dwFlags & D3DLIGHT_NO_SPECULAR) != D3DLIGHT_NO_SPECULAR); if (do_specular) { // calculate the halfway vector using the D3D method halfVector = (Vid::model_view_norm + direction); halfVector.Normalize(); } Vertex *in = src; ColorValue *d = &Manager::diffuse[0]; ColorValue *s = &Manager::specular[0]; U32 iv; for (iv = 0; iv < count; iv++ ) { // calculate distance from the light to the vertex direction = position - in->vv; F32 dist = direction.Magnitude(); // if distance is greater than range, then no light reaches the vertex // this could use a Magnitude2() check to avoid the sqrt for verts outside range !!! if ( dist <= desc.dvRange ) { // ASSERT( dist > 0.0f); if (dist <= F32_EPSILON) { dist = F32_EPSILON; } F32 invdist = 1.0f / dist; // normalize the distance dist = (desc.dvRange - dist) * invRange; // calculate the attenuation over that distance F32 a = desc.dvAttenuation0 + dist * desc.dvAttenuation1 + (dist*dist) * desc.dvAttenuation2; if ( a > 0.0f ) { // calculate the model space direction direction.x *= invdist; direction.y *= invdist; direction.z *= invdist; // calculate and scale the attenuated color values ColorValue atten; atten.r = a * desc.dcvColor.r; atten.g = a * desc.dcvColor.g; atten.b = a * desc.dcvColor.b; // calculate the diffuse reflection factor and clamp it to [0,1] // NOTE: both src->nv and light->dvDirection must be normalized vectors F32 diffuse_reflect = in->nv.Dot(direction); // -1.0f <= diffuse_reflect <= 1.0f if ( diffuse_reflect > 0.0f ) { // calculate the diffuse component for the vertex d->r += atten.r * diffuse_reflect * Manager::material_diffuse.r; d->g += atten.g * diffuse_reflect * Manager::material_diffuse.g; d->b += atten.b * diffuse_reflect * Manager::material_diffuse.b; } if ( do_specular ) { // calculate the partial specular reflection factor F32 spec_reflect = in->nv.Dot(halfVector); if ( spec_reflect > SPECULAR_THRESHOLD ) { #if 0 spec_reflect = (F32) pow((double) spec_reflect, (double) material->GetDesc().dvPower); // -1.0f <= spec_reflect <= 1.0f #else // apply the material's power factor to the nearest power of 2 U32 e, ee = material->PowerCount(); for (e = 1; e < ee; e *= 2 ) { spec_reflect = spec_reflect * spec_reflect; } #endif // calculate the diffuse component of the vertex // if vertex color capabilities are added this must be changed s->r += atten.r * spec_reflect * Manager::material_specular.r; s->g += atten.g * spec_reflect * Manager::material_specular.g; s->b += atten.b * spec_reflect * Manager::material_specular.b; } } } // if } // if in++; d++; s++; } // for }
////////////////////////////////////////////////////////////////////////////// // NAME: // ARGUMENTS: // RETURN: // DESCRIPTION: // // NOTE: This function should only be called from DxLight::Manager::Light() ////////////////////////////////////////////////////////////////////////////// void DxLight::DirectLight(VertexL *dst, U32 count) { ASSERT( dst ); if (!IsActive()) { return; } Material *material = Manager::curMaterial; #if 0 if ( count == 0 || (material_diffuse.r + material_diffuse.g + material_diffuse.b + material_diffuse.a) == 0.0f ) { return; } #endif // calculate the vector to the light in model space #ifndef DOBZ2 direction = WorldMatrix().Front(); #else direction = CalcSimWorldDirection(Vector(0, 0, 1)); #endif direction *= -1.0f; Vid::world_matrix.RotateInv(direction); Bool do_specular = (material->status.specular && Vid::renderState.status.specular && (desc.dwFlags & D3DLIGHT_NO_SPECULAR) != D3DLIGHT_NO_SPECULAR); if (do_specular) { // calculate the halfway vector using the D3D method halfVector = (Vid::model_view_norm + direction); halfVector.Normalize(); } VertexL *out = dst; ColorValue *d = &Manager::diffuse[0]; ColorValue *s = &Manager::specular[0]; U32 iv; for (iv = 0; iv < count; iv++ ) { // calculate the diffuse reflection factor and clamp it to [0,1] // NOTE: both src->nv and light->dvDirection must be normalized vectors F32 diffuse_reflect = Manager::norms[iv].Dot(direction); // -1.0f <= diffuse_reflect <= 1.0f if (diffuse_reflect > 0.0f) { // calculate the diffuse component for the vertex d->r += desc.dcvColor.r * diffuse_reflect * Manager::material_diffuse.r; d->g += desc.dcvColor.g * diffuse_reflect * Manager::material_diffuse.g; d->b += desc.dcvColor.b * diffuse_reflect * Manager::material_diffuse.b; } if (do_specular) { // calculate the partial specular reflection factor F32 specular_reflect = Manager::norms[iv].Dot(halfVector); if ( spec_reflect > SPECULAR_THRESHOLD ) { #if 0 spec_reflect = (F32) pow((double) spec_reflect, (double) material->GetDesc().dvPower); // -1.0f <= spec_reflect <= 1.0f #else // apply the material's power factor to the nearest power of 2 U32 e, ee = material->PowerCount(); for (e = 1; e < ee; e *= 2 ) { spec_reflect = spec_reflect * spec_reflect; } #endif // calculate the diffuse component of the vertex // if vertex color capabilities are added this must be changed s->r += desc.dcvColor.r * specular_reflect * Manager::material_specular.r; s->g += desc.dcvColor.g * specular_reflect * Manager::material_specular.g; s->b += desc.dcvColor.b * specular_reflect * Manager::material_specular.b; } } out++; d++; s++; } // for }
////////////////////////////////////////////////////////////////////////////// // NAME: // ARGUMENTS: // RETURN: // DESCRIPTION: // // NOTE: This function should only be called from DxLight::Manager::Light() ////////////////////////////////////////////////////////////////////////////// void DxLight::SpotLight(VertexL *dst, U32 count) { ASSERT( dst ); if (!IsActive()) { return; } Material *material = Manager::curMaterial; // calculate the light's model space position Matrix inverse_world_matrix; inverse_world_matrix.SetInverse(Vid::world_matrix); #ifndef DOBZ2 inverse_world_matrix.Transform(position, WorldMatrix().Position()); #else Vector Centre (CalcSimWorldPosition(Vector (0, 0, 0))); inverse_world_matrix.Transform(position, Centre); #endif // calculate the model space direction direction = position; direction.Normalize(); // get the spot direction vector in model space Vector spot_direction; #ifndef DOBZ2 inverse_world_matrix.Rotate(spot_direction, WorldMatrix().Front()); #else Vector Dir (CalcSimWorldDirection(Vector (0, 0, 1))); inverse_world_matrix.Rotate(spot_direction, Dir); #endif Bool do_specular = (material->status.specular && Vid::renderState.status.specular && (desc.dwFlags & D3DLIGHT_NO_SPECULAR) != D3DLIGHT_NO_SPECULAR); if (do_specular) { // calculate the halfway vector using the D3D method halfVector = (Vid::model_view_norm + direction); halfVector.Normalize(); } VertexL *out = dst; ColorValue *d = &Manager::diffuse[0]; ColorValue *s = &Manager::specular[0]; U32 iv; for (iv = 0; iv < count; iv++ ) { // calculate distance from the light to the vertex direction = position - out->vv; F32 dist = direction.Magnitude(); // if distance is greater than range, then no light reaches the vertex if ( dist <= desc.dvRange ) { // ASSERT( dist > 0.0f); if (dist <= F32_EPSILON) { dist = F32_EPSILON; } F32 invdist = 1.0f / dist; // normalize the distance dist = (desc.dvRange - dist) * invRange; // calculate the attenuation over that distance F32 a = desc.dvAttenuation0 + dist * desc.dvAttenuation1 + (dist*dist) * desc.dvAttenuation2; if ( a > 0.0f ) { // compute the cosine of vectors vert_to_light and the light's model space direction direction *= invdist; F32 cos_dir = -direction.Dot(spot_direction); if ( cos_dir > cosPhi ) { F32 intensity; if ( cos_dir > cosTheta ) // vertex is inside inner cone --> receives full light { intensity = 1.0f; } else // vertex is between inner and outer cone { // intensity = (F32) pow((double) ((cos_dir-cos_phi)/(cos_theta-cos_phi)), (double) desc.dvFalloff); intensity = (cos_dir - cosPhi) * invAngle; } // calculate and scale the attenuated color values ColorValue atten; atten.r = a * desc.dcvColor.r; atten.g = a * desc.dcvColor.g; atten.b = a * desc.dcvColor.b; // calculate the diffuse reflection factor and clamp it to [0,1] // NOTE: both src->nv and light->dvDirection must be normalized vectors F32 diffuse_reflect = Manager::norms[iv].Dot(direction); // -1.0f <= diffuse_reflect <= 1.0f if ( diffuse_reflect > 0.0f ) { diffuse_reflect *= intensity; // calculate the diffuse component for the vertex d->r += atten.r * diffuse_reflect * Manager::material_diffuse.r; d->g += atten.g * diffuse_reflect * Manager::material_diffuse.g; d->b += atten.b * diffuse_reflect * Manager::material_diffuse.b; } if ( do_specular ) { // calculate the partial specular reflection factor F32 spec_reflect = Manager::norms[iv].Dot(halfVector); if ( spec_reflect > SPECULAR_THRESHOLD ) { #if 0 spec_reflect = (F32) pow((double) spec_reflect, (double) material->GetDesc().dvPower); // -1.0f <= spec_reflect <= 1.0f #else // apply the material's power factor to the nearest power of 2 U32 e, ee = material->PowerCount(); for (e = 1; e < ee; e *= 2 ) { spec_reflect = spec_reflect * spec_reflect; } #endif spec_reflect *= intensity; s->r += atten.r * spec_reflect * Manager::material_specular.r; s->g += atten.g * spec_reflect * Manager::material_specular.g; s->b += atten.b * spec_reflect * Manager::material_specular.b; } } } // if } // if } // if out++; d++; s++; } // for }
// // ProjectileObj::ProcessCycle // // Per-cycle processing // void ProjectileObj::ProcessCycle() { PERF_S(("ProjectileObj")) Bool boom = FALSE; // Has a proximity distance been specifed ? F32 proximity2 = ProjectileType()->GetProximity2(); if (proximity2 && GetTarget().Alive()) { // Is the target close enough ? Vector target = GetTarget().GetLocation() - Position(); // Proximity type checks switch (ProjectileType()->GetProximityType()) { case ProjectileObjType::PROXIMITY_NORMAL: if (target.Magnitude2() < proximity2) { boom = TRUE; } break; case ProjectileObjType::PROXIMITY_XZ: if (target.MagnitudeXZ2() < proximity2) { boom = TRUE; } break; case ProjectileObjType::PROXIMITY_Y: if ((GetVelocity().y < 0.0F) && (fabs(target.y) < ProjectileType()->GetProximity())) { boom = TRUE; } break; } if (boom) { // Kaboom Detonate(); } } // Has the fuse expired ? if ( !boom && !ProjectileType()->GetImpact() && GameTime::SimTotalTime() - GetBirthTime() > ProjectileType()->GetFuse() ) { // Kaboom Detonate(); } // Perform type specific physics if (!deathNode.InUse()) { Matrix m = WorldMatrix(); Vector s; ProjectileType()->ProcessProjectilePhysics(*this, m, s); // Update odometer and position distTravelled += s.Magnitude(); m.posit += s; SetSimTarget(m); // Register movement with the collision system CollisionCtrl::AddObject(this); } PERF_E(("ProjectileObj")) // Call base class MapObj::ProcessCycle(); }