| 193 | } |
| 194 | |
| 195 | void ModelInstance::UpdateLightFromControllers(double gameTime) |
| 196 | { |
| 197 | for (const auto & controller : m_lightControllers) |
| 198 | { |
| 199 | auto node = controller->Node; |
| 200 | |
| 201 | // NOTE - this gets frame old world transform - if changing scale at runtime, this won't work and instead it has to be fully updated |
| 202 | float3 scale; |
| 203 | dm::decomposeAffine<float>(node->GetLocalToWorldTransformFloat(), nullptr, nullptr, &scale); |
| 204 | float reallyAverageScale = (scale.x + scale.y + scale.z) / 3.0f; |
| 205 | |
| 206 | Light* light = dynamic_cast<Light*>(node->GetLeaf().get()); |
| 207 | assert( light != nullptr ); |
| 208 | SpotLight* spotLight = dynamic_cast<SpotLight*>(node->GetLeaf().get()); |
| 209 | PointLight* pointLight = dynamic_cast<PointLight*>(node->GetLeaf().get()); |
| 210 | |
| 211 | light->color = controller->Color; |
| 212 | |
| 213 | bool enabled = controller->Enabled; |
| 214 | |
| 215 | if (controller->AutoOffTime != 0 && controller->AutoOnTime != 0) |
| 216 | { |
| 217 | double periodLength = controller->AutoOffTime + controller->AutoOnTime; |
| 218 | double scaledTime = (gameTime+controller->AutoOnOffTimeOffset) / periodLength; |
| 219 | double remainder = dm::saturate<double>(scaledTime - floor(scaledTime)); |
| 220 | enabled &= remainder < (controller->AutoOffTime / periodLength); |
| 221 | } |
| 222 | |
| 223 | float intensity = (enabled)?(controller->Intensity):(0); |
| 224 | |
| 225 | if (spotLight != nullptr) |
| 226 | { |
| 227 | spotLight->radius = reallyAverageScale; |
| 228 | spotLight->intensity = intensity; |
| 229 | |
| 230 | spotLight->outerAngle = abs(controller->OuterAngle); |
| 231 | spotLight->innerAngle = controller->InnerAngle; |
| 232 | |
| 233 | const bool kUseMinSpotlightFalloff = true; |
| 234 | if (kUseMinSpotlightFalloff) |
| 235 | spotLight->outerAngle = -spotLight->outerAngle; // this is a special flag to indicate that, instead of falling off to 0 when angle >= outerAngle, we should clamp to kMinSpotlightFalloff |
| 236 | |
| 237 | } |
| 238 | if (pointLight != nullptr) |
| 239 | { |
| 240 | pointLight->radius = reallyAverageScale; |
| 241 | pointLight->intensity = intensity; |
| 242 | } |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | void ModelInstance::SetTransform(const dm::double3& translation, const dm::dquat& rotation, const dm::double3& scaling) |
| 247 | { |