const Matrix3x4& Light::GetVolumeTransform(Camera* camera) { if (!node_) return Matrix3x4::IDENTITY; switch (lightType_) { case LIGHT_DIRECTIONAL: { Matrix3x4 quadTransform; Vector3 near, far; // Position the directional light quad in halfway between far & near planes to prevent depth clipping camera->GetFrustumSize(near, far); quadTransform.SetTranslation(Vector3(0.0f, 0.0f, (camera->GetNearClip() + camera->GetFarClip()) * 0.5f)); quadTransform.SetScale(Vector3(far.x_, far.y_, 1.0f)); // Will be oversized, but doesn't matter (gets frustum clipped) volumeTransform_ = camera->GetEffectiveWorldTransform() * quadTransform; break; } case LIGHT_SPOT: { float yScale = tanf(fov_ * M_DEGTORAD * 0.5f) * range_; float xScale = aspectRatio_ * yScale; volumeTransform_ = Matrix3x4(node_->GetWorldPosition(), node_->GetWorldRotation(), Vector3(xScale, yScale, range_)); } break; case LIGHT_POINT: volumeTransform_ = Matrix3x4(node_->GetWorldPosition(), Quaternion::IDENTITY, range_); break; } return volumeTransform_; }
void NavArea::DrawDebugGeometry(DebugRenderer* debug, bool depthTest) { if (debug && IsEnabledEffective()) { Matrix3x4 mat; mat.SetTranslation(node_->GetWorldPosition()); debug->AddBoundingBox(boundingBox_, mat, Color::GREEN, depthTest); } }
Matrix3x4 Light::GetFullscreenQuadTransform(Camera* camera) { Matrix3x4 quadTransform; Vector3 near, far; // Position the directional light quad in halfway between far & near planes to prevent depth clipping camera->GetFrustumSize(near, far); quadTransform.SetTranslation(Vector3(0.0f, 0.0f, (camera->GetNearClip() + camera->GetFarClip()) * 0.5f)); quadTransform.SetScale(Vector3(far.x_, far.y_, 1.0f)); // Will be oversized, but doesn't matter (gets frustum clipped) return camera->GetEffectiveWorldTransform() * quadTransform; }
void Skybox::UpdateBatches(const FrameInfo& frame) { distance_ = 0.0f; if (frame.frameNumber_ != lastFrame_) { customWorldTransforms_.Clear(); lastFrame_ = frame.frameNumber_; } // Add camera position to fix the skybox in space. Use effective world transform to take reflection into account Matrix3x4 customWorldTransform = node_->GetWorldTransform(); customWorldTransform.SetTranslation(node_->GetWorldPosition() + frame.camera_->GetEffectiveWorldTransform().Translation()); HashMap<Camera*, Matrix3x4>::Iterator it = customWorldTransforms_.Insert(MakePair(frame.camera_, customWorldTransform)); for (unsigned i = 0; i < batches_.Size(); ++i) { batches_[i].worldTransform_ = &it->second_; batches_[i].distance_ = 0.0f; } }
BoundingBox NavArea::GetWorldBoundingBox() const { Matrix3x4 mat; mat.SetTranslation(node_->GetWorldPosition()); return boundingBox_.Transformed(mat); }
const Matrix3x4& Sprite::GetTransform() const { if (positionDirty_) { Vector2 pos = floatPosition_; Matrix3x4 parentTransform; if (parent_) { Sprite* parentSprite = dynamic_cast<Sprite*>(parent_); if (parentSprite) parentTransform = parentSprite->GetTransform(); else { const IntVector2& parentScreenPos = parent_->GetScreenPosition() + parent_->GetChildOffset(); parentTransform = Matrix3x4::IDENTITY; parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f)); } switch (GetHorizontalAlignment()) { case HA_LEFT: break; case HA_CENTER: pos.x_ += (float)(parent_->GetSize().x_ / 2); break; case HA_RIGHT: pos.x_ += (float)parent_->GetSize().x_; break; } switch (GetVerticalAlignment()) { case VA_TOP: break; case VA_CENTER: pos.y_ += (float)(parent_->GetSize().y_ / 2); break; case VA_BOTTOM: pos.y_ += (float)(parent_->GetSize().y_); break; } } else parentTransform = Matrix3x4::IDENTITY; Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY); hotspotAdjust.SetTranslation(Vector3((float)-hotSpot_.x_, (float)-hotSpot_.y_, 0.0f)); Matrix3x4 mainTransform(Vector3(pos, 0.0f), Quaternion(rotation_, Vector3::FORWARD), Vector3(scale_, 1.0f)); transform_ = parentTransform * mainTransform * hotspotAdjust; positionDirty_ = false; // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements Vector3 topLeftCorner = transform_ * Vector3::ZERO; screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_); } return transform_; }