#include "behavior.h" #include #include #include #include UF_BEHAVIOR_REGISTER_CPP(ext::LightBehavior) #define this (&self) void ext::LightBehavior::initialize( uf::Object& self ) { auto& metadata = this->getComponent(); auto& transform = this->getComponent>(); auto& camera = this->getComponent(); auto& scene = uf::scene::getCurrentScene(); auto& controller = scene.getController(); if ( metadata["light"]["shadows"]["enabled"].as() ) { auto& renderMode = this->getComponent(); std::string name = "RT:" + std::to_string((int) this->getUid()); uf::renderer::addRenderMode( &renderMode, name ); renderMode.blitter.process = false; camera = controller.getComponent(); camera.getTransform() = {}; camera.setStereoscopic(false); if ( metadata["light"]["shadows"]["fov"].is() ) { camera.setFov( metadata["light"]["shadows"]["fov"].as() ); camera.updateProjection(); } if ( ext::json::isArray( metadata["light"]["radius"] ) ) { auto bounds = camera.getBounds(); bounds.x = metadata["light"]["radius"][0].as(); bounds.y = metadata["light"]["radius"][1].as(); camera.setBounds(bounds); } if ( ext::json::isArray( metadata["light"]["shadows"]["resolution"] ) ) { renderMode.width = metadata["light"]["shadows"]["resolution"][0].as(); renderMode.height = metadata["light"]["shadows"]["resolution"][1].as(); auto size = camera.getSize(); size.x = renderMode.width; size.y = renderMode.height; camera.setSize(size); } else { renderMode.width = metadata["light"]["shadows"]["resolution"].as(); renderMode.height = metadata["light"]["shadows"]["resolution"].as(); auto size = camera.getSize(); size.x = renderMode.width; size.y = renderMode.height; camera.setSize(size); } } if ( !metadata["light"]["shadows"]["bias"].is() ) { metadata["light"]["shadows"]["bias"] = 0.00005f; } if ( !ext::json::isArray( metadata["light"]["color"] ) ) { metadata["light"]["color"][0] = 1; //metadata["light"]["color"]["random"].as() ? (rand() % 100) / 100.0 : 1; metadata["light"]["color"][1] = 1; //metadata["light"]["color"]["random"].as() ? (rand() % 100) / 100.0 : 1; metadata["light"]["color"][2] = 1; //metadata["light"]["color"]["random"].as() ? (rand() % 100) / 100.0 : 1; } } void ext::LightBehavior::tick( uf::Object& self ) { auto& metadata = this->getComponent(); if ( this->hasComponent() ) { auto& renderMode = this->getComponent(); renderMode.target = ""; } auto& transform = this->getComponent>(); if ( this->hasComponent() ) { pod::Physics& physics = this->getComponent(); transform = uf::physics::update( transform, physics ); } auto& parent = this->getParent(); auto& parentMetadata = parent.getComponent(); if ( parentMetadata["system"]["name"] == "Light" ) { metadata["light"] = parentMetadata["light"]; } else { if ( ext::json::isObject( metadata["light"]["fade"] ) ) { if ( ext::json::isNull( metadata["light"]["backup"]["power"] ) ) { metadata["light"]["backup"]["power"] = metadata["light"]["power"]; } if ( ext::json::isNull( metadata["light"]["backup"]["color"] ) ) { metadata["light"]["backup"]["color"] = metadata["light"]["color"]; } // fade towards int direction = metadata["light"]["fade"]["increment"].as() ? 1 : -1; metadata["light"]["fade"]["timer"] = metadata["light"]["fade"]["timer"].as() + metadata["light"]["fade"]["rate"].as() * uf::physics::time::delta * direction; // 0 .. delta .. 1 .. (1 + timeout * 0.5) if ( direction == 1 && metadata["light"]["fade"]["timer"].as() >= 0.5f * metadata["light"]["fade"]["timeout"].as() + 1.0f ) { metadata["light"]["fade"]["increment"] = false; } else if ( direction == -1 && metadata["light"]["fade"]["timer"].as() <= -0.5f * metadata["light"]["fade"]["timeout"].as() ) { metadata["light"]["fade"]["increment"] = true; } { float delta = metadata["light"]["fade"]["timer"].as(); delta = std::clamp( delta, 0.f, 1.f ); if ( metadata["light"]["fade"]["power"].is() ) { metadata["light"]["power"] = uf::math::lerp( metadata["light"]["backup"]["power"].as(), metadata["light"]["fade"]["power"].as(), delta ); } if ( ext::json::isArray( metadata["light"]["fade"]["color"] ) ) { pod::Vector3f fadeColor; { fadeColor.x = metadata["light"]["fade"]["color"][0].as(); fadeColor.y = metadata["light"]["fade"]["color"][1].as(); fadeColor.z = metadata["light"]["fade"]["color"][2].as(); } pod::Vector3f origColor; { origColor.x = metadata["light"]["backup"]["color"][0].as(); origColor.y = metadata["light"]["backup"]["color"][1].as(); origColor.z = metadata["light"]["backup"]["color"][2].as(); } pod::Vector3f color = uf::vector::lerp( origColor, fadeColor, delta ); metadata["light"]["color"][0] = color[0]; metadata["light"]["color"][1] = color[1]; metadata["light"]["color"][2] = color[2]; } } } if ( ext::json::isObject( metadata["light"]["flicker"] ) ) { float r = (rand() % 100) / 100.0; float rate = metadata["light"]["flicker"]["rate"].as(); if ( ext::json::isNull( metadata["light"]["backup"]["power"] ) ) { metadata["light"]["backup"]["power"] = metadata["light"]["power"]; } metadata["light"]["flicker"]["timer"] = metadata["light"]["flicker"]["timer"].as() + uf::physics::time::delta; if ( metadata["light"]["flicker"]["timer"].as() >= metadata["light"]["flicker"]["timeout"].as() ) { metadata["light"]["flicker"]["timer"] = 0; metadata["light"]["power"] = (r > rate) ? metadata["light"]["flicker"]["power"].as() : metadata["light"]["backup"]["power"].as(); } } } if ( parentMetadata["system"]["type"] == "Light" ) { auto& parentTransform = parent.getComponent>(); transform.position = parentTransform.position; } else if ( metadata["system"]["track"] == "player" ) { auto& scene = uf::scene::getCurrentScene(); auto& controllerCamera = scene.getController().getComponent().getTransform(); auto& controllerTransform = scene.getController().getComponent>(); transform.position = controllerTransform.position + controllerCamera.position; } if ( ext::json::isNull( metadata["light"]["external update"] ) || (!ext::json::isNull( metadata["light"]["external update"] ) && !metadata["light"]["external update"].as()) ) { auto& camera = this->getComponent(); for ( std::size_t i = 0; i < 2; ++i ) { camera.setView( uf::matrix::inverse( uf::transform::model( transform ) ), i ); } } // render every other frame, maybe if ( false ) { if ( metadata["system"]["renderer"]["limit rendering"]["limiter"].is() && this->hasComponent() ) { auto& limiterMetadata = metadata["system"]["renderer"]["limit rendering"]; auto& renderMode = this->getComponent(); if ( limiterMetadata["timer"].as() > 1.0f / limiterMetadata["limiter"].as() ) { limiterMetadata["timer"] = 0; renderMode.execute = true; } else { limiterMetadata["timer"] = limiterMetadata["timer"].as() + uf::physics::time::delta; renderMode.execute = false; } } } } void ext::LightBehavior::render( uf::Object& self ){ } void ext::LightBehavior::destroy( uf::Object& self ){ if ( this->hasComponent() ) { auto& renderMode = this->getComponent(); uf::renderer::removeRenderMode( &renderMode, false ); this->deleteComponent(); } } #undef this