diff --git a/Makefile b/Makefile index a9b3f728..93c98a6b 100644 --- a/Makefile +++ b/Makefile @@ -44,8 +44,9 @@ EXT_LIB_NAME += ext #VULKAN_SDK_PATH += /c/VulkanSDK/1.3.204.1/ #VULKAN_SDK_PATH += /c/VulkanSDK/1.3.211.0/ #VULKAN_SDK_PATH += /c/VulkanSDK/1.3.216.0/ -VULKAN_SDK_PATH += /c/VulkanSDK/1.3.224.1/ -#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.231.1/ +#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.224.1/ +VULKAN_SDK_PATH += /c/VulkanSDK/1.3.231.1/ +#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.261.1/ GLSLC += $(VULKAN_SDK_PATH)/Bin/glslc SPV_OPTIMIZER += $(VULKAN_SDK_PATH)/Bin/spirv-opt diff --git a/bin/data/config.json b/bin/data/config.json index 1e253eea..b376a33e 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -5,7 +5,7 @@ "matrix": { "reverseInfinite": true }, "meshes": { "interleaved": false }, "lights": { "enabled": true, - "useLightmaps": true, + "useLightmaps": false, "max": 32, "shadows": { "enabled": true, @@ -29,9 +29,9 @@ } }, "vxgi": { + // "limiter": 0, "limiter": 0.125, - // "limiter": 0.125, - "size": 192, + "size": 256, "dispatch": 8, "cascades": 3, "cascadePower": 1.5, @@ -41,8 +41,8 @@ "traceStartOffsetFactor": 1, "shadows": 0, "extents": { - "min": [ -4, -4, -4 ], - "max": [ 4, 4, 4 ] + "min": [ -8, -8, -8 ], + "max": [ 8, 8, 8 ] } }, "rt": { @@ -91,8 +91,8 @@ // "size": [ 960, 540 ] // "size": [ 640, 480 ] }, - "gpu": 7817, // 2060 - // "gpu": 29631, // 6800XT + // "gpu": 7817, // 2060 + "gpu": 29631, // 6800XT "experimental": { "rebuild on tick begin": false, "batch queue submissions": true, @@ -204,7 +204,7 @@ ,"VK_KHR_ray_query" // ,"VK_AMD_shader_explicit_vertex_parameter" - // ,"VK_KHR_fragment_shader_barycentric" + ,"VK_KHR_fragment_shader_barycentric" ] }, "features": [ @@ -292,7 +292,7 @@ "debug draw": { "enabled": false, "line width": 8, - // "layer": "Gui", + "layer": "Gui", "rate": 0.0125 } }, diff --git a/bin/data/entities/model.json b/bin/data/entities/model.json index a245e19b..c1eef406 100644 --- a/bin/data/entities/model.json +++ b/bin/data/entities/model.json @@ -61,7 +61,7 @@ "renderer": { "front face": "auto", "cull mode": "back", - "filter": "linear", + "filter": "nearest", "atlas": false, "invert": true, diff --git a/bin/data/entities/player.json b/bin/data/entities/player.json index d03fdc72..aeef1a5a 100644 --- a/bin/data/entities/player.json +++ b/bin/data/entities/player.json @@ -6,7 +6,7 @@ "SoundEmitterBehavior" ], "ignore": false, -/* + /* "transform": { "position": [ 0, 0, 0 ], "rotation": { @@ -15,7 +15,7 @@ }, "scale": [ 1, 1, 1 ] }, -*/ + */ "assets": [ // { "filename": "./playerModel.json", "delay": 0 }, "./playerModel.json", @@ -55,10 +55,11 @@ } }, "movement": { - "walk": 1, - "move": 4, + "walk": 8, + "move": 8, "run": 16, - "rotate": 1.5, + // "rotate": 1.5, + "rotate": 4, "air": 0.1, "crouch": 1, @@ -69,7 +70,8 @@ // "floor": [ 0, -0.5, 0 ], "floor": [ 0, -1.0, 0 ], "print": false - } + }, + "strafe": false }, "physics": { "gravity": [ 0, -9.81, 0 ], @@ -86,19 +88,18 @@ "shared": false }, "camera": { - "offset": [ 0, 0, 0 ], + "offset": [ 0, 5, 3 ], + "orientation": [ 0, 0.894427, -0.447214, 0 ], "position" : [ 0, 1.8, 0 ], "scale": [ 1, 1, 1 ], "invert": [ false, false, false ], "limit": { - // "minima": [ null, -1.57079633, null ], - // "maxima": [ null, 1.57079633, null ], - "minima": [ null, -1.0, null ], "maxima": [ null, 1.0, null ], "current":[ null, 0, null ] }, "settings": { + "fixed": true, "fov" : 90.0, "clip" : [ 0.1, 64.0 ], "size" : [ 0, 0 ] diff --git a/bin/data/entities/playerModel.json b/bin/data/entities/playerModel.json index c8f1796e..2df8755c 100644 --- a/bin/data/entities/playerModel.json +++ b/bin/data/entities/playerModel.json @@ -1,7 +1,7 @@ { "type": "Object", "name": "Player: Model", - "ignore": true, + "ignore": false, "import": "/model.json", "assets": [ "/player/bear.glb" @@ -27,7 +27,7 @@ }, "metadata": { "track": true, - "hide": true, + "hide": false, "graph": { "debug": { "print": { @@ -42,14 +42,12 @@ "baking": { "enabled": false }, - "renderer": { - "cull mode": "back", - "filter": "linear" - }, "lights": { "lightmap": false }, "renderer": { + "cull mode": "front", + "filter": "linear", "flip textures": false, "invert": false, "skinned": true diff --git a/bin/data/scenes/sourceengine/animal_crossing.json b/bin/data/scenes/sourceengine/animal_crossing.json new file mode 100644 index 00000000..4feeef38 --- /dev/null +++ b/bin/data/scenes/sourceengine/animal_crossing.json @@ -0,0 +1,53 @@ +{ + "import": "./base_sourceengine.json", + "assets": [ + // { "filename": "./models/animal_crossing.glb" } + { "filename": "./models/animal_crossing/graph.json" } + // { "filename": "/burger.json", "delay": 1 } + ], + "metadata": { + "graph": { + "assets": [ + "./audio/music/5pm.ogg" + ], + "tags": { + // exact matches + // "func_door_rotating_5473": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } }, + // "func_door_rotating_5509": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } }, + // "func_door_rotating_5568": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } }, + // "func_door_rotating_5584": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } }, + + // regex matches + // "/^prop_physics_override/": { "action": "load", "payload": { "import": "/prop.json", "metadata": { "physics": { "gravity": [ 0, 0, 0 ] } } } }, + // "/^prop_physics_[^o]/": { "action": "load", "payload": { "import": "/prop.json" } }, + "light_environment": { "ignore": false, + "transform": { + "position": [250.3781, 148.704, 202.286] + }, + "light": { + "color": [0.95, 0.25, 0.25], + "power": 1000000, + "global": true, + "bias": { + "constant": 0, + "slope": 5, + "shader": 0.0000175 + }, + "radius": [0.9999999, 0], + "resolution": 4096 + } + }, + "/^tools\\/toolsnodraw/": { "material": { + "base": [ 1.0, 1.0, 1.0, 1.0 ], + "emissive": [ 0.0, 0.0, 0.0, 0.0 ], + "fMetallic": 0.0, + "fRoughness": 0.10000000149011612, + "fOcclusion": 1.0, + "fAlphaCutoff": 0.5, + "iAlbedo": 27, + "modeAlpha": 1 + } } + } + } + } +} \ No newline at end of file diff --git a/bin/data/scenes/sourceengine/base_sourceengine.json b/bin/data/scenes/sourceengine/base_sourceengine.json index c2207110..0007334c 100644 --- a/bin/data/scenes/sourceengine/base_sourceengine.json +++ b/bin/data/scenes/sourceengine/base_sourceengine.json @@ -18,17 +18,17 @@ "optimize mesh": { "simplify": 0 } }, "info_player_spawn": { "action": "attach", "filename": "./player.json", "transform": { "orientation": [ 0, 1, 0, 0 ] } }, - "light_environment": { "ignore": true, "transform": { "orientation": [0,0,0,1] }, "light": { + "light_environment": { "ignore": false, "light": { // "color": [0.1, 0.1, 0.1], - "power": 10000, + "power": 1000000, "global": true, "bias": { - "constant": 1.25, - "slope": 1.75, - "shader": 0.000000000005 + "constant": 0, + "slope": 5, + "shader": 0.000025 }, - "radius": [8, 0], - "resolution": 1024 + "radius": [0.9999999, 0], + "resolution": 4096 } }, // "/^light_[^e]/": { "ignore": true }, diff --git a/bin/data/scenes/sourceengine/scene.json b/bin/data/scenes/sourceengine/scene.json index d8328c78..b1e69379 100644 --- a/bin/data/scenes/sourceengine/scene.json +++ b/bin/data/scenes/sourceengine/scene.json @@ -6,9 +6,9 @@ ], "metadata": { "light": { - "ambient": [ 0, 0, 0 ], + // "ambient": [ 0, 0, 0 ], // "ambient": [ 0.05, 0.05, 0.05 ], - // "ambient": [ 0.15, 0.15, 0.15 ], + "ambient": [ 0.15, 0.15, 0.15 ], // "ambient": [ 0.5, 0.5, 0.5 ], // "ambient": [ 0.8, 0.8, 0.8 ], // "ambient": [ 0.1, 0.1, 0.2 ], @@ -24,13 +24,13 @@ "samples": 4 }, - "fog-": { + "fog": { // "color": [ 0.1, 0.1, 0.1 ], // "color": [ 0.2, 0.2, 0.2 ], "color": [ 0.3, 0.3, 0.3 ], "range": [ 64, 256 ], "step scale": 4, - "absorbtion": 0.0125, + "absorbtion": 0.125, "density": { "threshold": 0.35, "multiplier": 2.0, diff --git a/bin/data/scenes/sourceengine/sourceengine.json b/bin/data/scenes/sourceengine/sourceengine.json index 74277413..0ca77b5c 100644 --- a/bin/data/scenes/sourceengine/sourceengine.json +++ b/bin/data/scenes/sourceengine/sourceengine.json @@ -1,7 +1,8 @@ { // "import": "./rp_downtown_v2.json" - "import": "./ss2_medsci1.json" +// "import": "./ss2_medsci1.json" // "import": "./sh2_mcdonalds.json" + "import": "./animal_crossing.json" // "import": "./mds_mcdonalds.json" // "import": "./gm_construct.json" } \ No newline at end of file diff --git a/bin/data/shaders/common/macros.h b/bin/data/shaders/common/macros.h index 03e97e50..f5b31fbb 100644 --- a/bin/data/shaders/common/macros.h +++ b/bin/data/shaders/common/macros.h @@ -75,12 +75,15 @@ // easy and accessible in one place #ifndef BARYCENTRIC - #define BARYCENTRIC 0 + #define BARYCENTRIC 1 #endif #if BARYCENTRIC #ifndef BARYCENTRIC_CALCULATE #define BARYCENTRIC_CALCULATE 0 #endif + #ifndef BUFFER_REFERENCE + #define BUFFER_REFERENCE 1 + #endif #endif #if BUFFER_REFERENCE diff --git a/engine/inc/uf/utils/math/vector.h b/engine/inc/uf/utils/math/vector.h index a11e5af3..1fa78eaf 100644 --- a/engine/inc/uf/utils/math/vector.h +++ b/engine/inc/uf/utils/math/vector.h @@ -141,8 +141,9 @@ namespace uf { template T /*UF_API*/ round( const T& vector ); // // Complex arithmetic template typename T::type_t /*UF_API*/ dot( const T& left, const T& right ); // Compute the dot product between two vectors - template pod::Angle /*UF_API*/ angle( const T& a, const T& b ); // Compute the angle between two vectors - template T /*UF_API*/ cross( const T& a, const T& b ); // Compute the angle between two vectors + template float /*UF_API*/ angle( const T& a, const T& b ); // Compute the angle between two vectors + template float /*UF_API*/ signedAngle( const T& a, const T& b, const T& axis ); // Compute the signed angle between two vectors + template T /*UF_API*/ cross( const T& a, const T& b ); // Compute the cross product between two vectors template T /*UF_API*/ lerp( const T& from, const T& to, double, bool = true ); // Linearly interpolate between two vectors template T /*UF_API*/ lerp( const T& from, const T& to, const T&, bool = true ); // Linearly interpolate between two vectors @@ -220,7 +221,7 @@ namespace uf { inline uf::Vector& negate(); // Flip sign of all components // Complex arithmetic inline T dot( const Vector right ) const; // Compute the dot product between two vectors - inline pod::Angle angle( const Vector& b ) const; // Compute the angle between two vectors + inline float angle( const Vector& b ) const; // Compute the angle between two vectors inline uf::Vector lerp( const Vector to, double delta ) const; // Linearly interpolate between two vectors inline uf::Vector slerp( const Vector to, double delta ) const; // Spherically interpolate between two vectors diff --git a/engine/inc/uf/utils/math/vector/class.inl b/engine/inc/uf/utils/math/vector/class.inl index 7013ed95..650ebf3d 100644 --- a/engine/inc/uf/utils/math/vector/class.inl +++ b/engine/inc/uf/utils/math/vector/class.inl @@ -111,7 +111,7 @@ inline T uf::Vector::dot( const Vector right ) const { return uf::vector::dot( this->m_pod, right ); } template // Compute the angle between two vectors -inline pod::Angle uf::Vector::angle( const Vector& b ) const { +inline float uf::Vector::angle( const Vector& b ) const { return uf::vector::angle( this->m_pod, b ); } diff --git a/engine/inc/uf/utils/math/vector/pod.inl b/engine/inc/uf/utils/math/vector/pod.inl index 7fdf6c10..71dc5b2a 100644 --- a/engine/inc/uf/utils/math/vector/pod.inl +++ b/engine/inc/uf/utils/math/vector/pod.inl @@ -314,8 +314,20 @@ typename T::type_t /*UF_API*/ uf::vector::dot( const T& left, const T& right ) { return uf::vector::sum(uf::vector::multiply(left, right)); } template // Compute the angle between two vectors -pod::Angle /*UF_API*/ uf::vector::angle( const T& a, const T& b ) { - return acos(uf::vector::dot(a, b)); +float /*UF_API*/ uf::vector::angle( const T& a, const T& b ) { + auto dot = uf::vector::dot(a, b); + if ( dot < -1.0f ) dot = -1.0f; + if ( dot > 1.0f ) dot = 1.0f; + return acos(dot); +} +template // Compute the angle between two vectors +float /*UF_API*/ uf::vector::signedAngle( const T& a, const T& b, const T& axis ) { + auto unsignedAngle = uf::vector::angle(a, b); + float cross_x = a.y * b.z - a.z * b.y; + float cross_y = a.z * b.x - a.x * b.z; + float cross_z = a.x * b.y - a.y * b.x; + float sign = (axis.x * cross_x + axis.y * cross_y + axis.z * cross_z) >= 0.0f ? 1.0f : -1.0f; + return unsignedAngle * sign; } template // Linearly interpolate between two vectors T /*UF_API*/ uf::vector::lerp( const T& from, const T& to, double delta, bool clamp ) { diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index fcefa391..68e85674 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -15,7 +15,7 @@ #include #include -#define BARYCENTRIC 0 +#define BARYCENTRIC 1 #if BARYCENTRIC #ifndef BARYCENTRIC_CALCULATE #define BARYCENTRIC_CALCULATE 0 diff --git a/engine/src/ext/vulkan/shader.cpp b/engine/src/ext/vulkan/shader.cpp index 4664a9ca..4b516cc7 100644 --- a/engine/src/ext/vulkan/shader.cpp +++ b/engine/src/ext/vulkan/shader.cpp @@ -309,6 +309,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl moduleCreateInfo.pCode = (uint32_t*) spirv.data(); VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &module)); + //UF_MSG_DEBUG("Shader: {}", filename); } { diff --git a/ext/behaviors/light/behavior.cpp b/ext/behaviors/light/behavior.cpp index 2edcafb4..1eec13b9 100644 --- a/ext/behaviors/light/behavior.cpp +++ b/ext/behaviors/light/behavior.cpp @@ -92,9 +92,9 @@ void ext::LightBehavior::initialize( uf::Object& self ) { } else { size = pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height }; } - if ( radius.y < radius.x ) radius.y = 256; + if ( radius.y < radius.x ) radius.y = 2048; camera.setProjection( uf::matrix::perspective( fov, (float) size.x / (float) size.y, radius.x, radius.y ) ); - // camera.update(true); + camera.update(true); uf::stl::string name = "RT:" + std::to_string((int) this->getUid()); renderMode.blitter.process = false; diff --git a/ext/behaviors/player/behavior.cpp b/ext/behaviors/player/behavior.cpp index c4ac15d8..4782249e 100644 --- a/ext/behaviors/player/behavior.cpp +++ b/ext/behaviors/player/behavior.cpp @@ -39,10 +39,14 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) { cameraTransform.position = uf::vector::decode( metadataJson["camera"]["position"], cameraTransform.position ); cameraTransform.scale = uf::vector::decode( metadataJson["camera"]["scale"], cameraTransform.scale ); - cameraTransform.reference = &transform; + cameraTransform.orientation = uf::vector::decode( metadataJson["camera"]["orientation"], cameraTransform.orientation ); + + cameraTransform.reference = metadata.camera.fixed ? NULL : &transform; auto cameraSettingsJson = metadataJson["camera"]["settings"]; + metadata.camera.offset = uf::vector::decode( metadataJson["camera"]["offset"], metadata.camera.offset ); + if ( metadataJson["camera"]["ortho"].as() ) { float l = cameraSettingsJson["left"].as(); float r = cameraSettingsJson["right"].as(); @@ -124,6 +128,14 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { auto& physics = this->getComponent(); auto& scene = uf::scene::getCurrentScene(); + { + static bool first = false; + if ( !first ) { + first = true; + uf::transform::rotate( transform, {0, 1, 0}, 3.1415926f ); + } + } + struct { bool forward = false; bool backwards = false; @@ -132,6 +144,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { bool lookLeft = false; bool lookRight = false; + bool lookUp = false; + bool lookDown = false; bool running = false; bool walk = false; bool jump = false; @@ -150,6 +164,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { .right = uf::inputs::kbm::states::D, .lookLeft = uf::inputs::kbm::states::Left, .lookRight = uf::inputs::kbm::states::Right, + .lookUp = uf::inputs::kbm::states::Up, + .lookDown = uf::inputs::kbm::states::Down, .running = uf::inputs::kbm::states::LShift, .walk = uf::inputs::kbm::states::LAlt, .jump = uf::inputs::kbm::states::Space, @@ -345,7 +361,11 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { #endif // un-flatted if noclipped - if ( stats.noclipped || collider.stats.gravity == pod::Vector3f{0,0,0} ){ + if ( metadata.camera.fixed ) { + translator = cameraTransform; + translator.forward.y = 0; + translator.forward = uf::vector::normalize( translator.forward ); + } else if ( stats.noclipped || collider.stats.gravity == pod::Vector3f{0,0,0} ){ translator.forward.y += cameraTransform.forward.y; translator.forward = uf::vector::normalize( translator.forward ); } @@ -373,15 +393,24 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { physics.linear.velocity *= { speed.friction, 1, speed.friction }; stats.walking = (keys.forward ^ keys.backwards) || (keys.left ^ keys.right); + if ( stats.walking ) { float factor = stats.floored ? 1.0f : speed.air; if ( stats.noclipped ) { physics.linear.velocity += target * speed.move; } else { - // float delta = collider.body ? uf::physics::impl::timescale : uf::physics::time::delta; - float delta = uf::physics::time::delta; + physics.linear.velocity += target * std::clamp( speed.move * factor - uf::vector::dot( physics.linear.velocity, target ), 0.0f, speed.move * 10 * uf::physics::time::delta ); + } - physics.linear.velocity += target * std::clamp( speed.move * factor - uf::vector::dot( physics.linear.velocity, target ), 0.0f, speed.move * 10 * delta ); + auto dot = uf::vector::dot( transform.forward, target ); + if ( !metadata.movement.strafe && dot < 1.0f ) { + // auto cross = uf::vector::normalize( uf::vector::cross( transform.forward, target ) ); + // auto axis = cross == pod::Vector3f{0, 0, 0} ? transform.up : cross; + auto axis = transform.up; + float angle = uf::vector::signedAngle( transform.forward, target, axis ) * uf::physics::time::delta * 4; // speed.rotate; + + if ( collider.body ) uf::physics::impl::applyRotation( collider, axis, angle ); else + uf::transform::rotate( transform, axis, angle ); } } if ( !stats.floored ) stats.walking = false; @@ -406,7 +435,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { { const pod::Vector2ui deadZone{0, 0}; const auto& mouseDelta = uf::inputs::kbm::states::Mouse; - bool shouldnt = (mouseDelta.x == 0 && mouseDelta.y == 0) || !metadata.system.control; + bool shouldnt = (mouseDelta.x == 0 && mouseDelta.y == 0) || !metadata.system.control || metadata.camera.fixed; if ( !shouldnt ) { pod::Vector2f delta = { (float) metadata.mouse.sensitivity.x * (abs(mouseDelta.x) < deadZone.x ? 0 : mouseDelta.x), @@ -417,30 +446,50 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { } #endif - if ( metadata.camera.queued.x != 0 || metadata.camera.queued.y != 0 ) { - auto lookDelta = metadata.camera.queued; - if ( abs(lookDelta.x) > uf::physics::time::delta / metadata.mouse.smoothing.x ) lookDelta.x *= uf::physics::time::delta * metadata.mouse.smoothing.x; - if ( abs(lookDelta.y) > uf::physics::time::delta / metadata.mouse.smoothing.y ) lookDelta.y *= uf::physics::time::delta * metadata.mouse.smoothing.y; - metadata.camera.queued -= lookDelta; - if ( lookDelta.x != 0 ) { - if ( metadata.camera.invert.x ) lookDelta.x *= -1; - metadata.camera.limit.current.x += lookDelta.x; - if ( metadata.camera.limit.current.x != metadata.camera.limit.current.x || ( metadata.camera.limit.current.x < metadata.camera.limit.max.x && metadata.camera.limit.current.x > metadata.camera.limit.min.x ) ) { - if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, lookDelta.x ); else - uf::transform::rotate( transform, transform.up, lookDelta.x ); - } else metadata.camera.limit.current.x -= lookDelta.x; + if ( !metadata.camera.fixed ) { + if ( metadata.camera.queued.x != 0 || metadata.camera.queued.y != 0 ) { + auto lookDelta = metadata.camera.queued; + if ( abs(lookDelta.x) > uf::physics::time::delta / metadata.mouse.smoothing.x ) lookDelta.x *= uf::physics::time::delta * metadata.mouse.smoothing.x; + if ( abs(lookDelta.y) > uf::physics::time::delta / metadata.mouse.smoothing.y ) lookDelta.y *= uf::physics::time::delta * metadata.mouse.smoothing.y; + metadata.camera.queued -= lookDelta; + if ( lookDelta.x != 0 ) { + if ( metadata.camera.invert.x ) lookDelta.x *= -1; + metadata.camera.limit.current.x += lookDelta.x; + if ( metadata.camera.limit.current.x != metadata.camera.limit.current.x || ( metadata.camera.limit.current.x < metadata.camera.limit.max.x && metadata.camera.limit.current.x > metadata.camera.limit.min.x ) ) { + if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, lookDelta.x ); else + uf::transform::rotate( transform, transform.up, lookDelta.x ); + } else metadata.camera.limit.current.x -= lookDelta.x; + } + if ( lookDelta.y != 0 ) { + if ( metadata.camera.invert.y ) lookDelta.y *= -1; + metadata.camera.limit.current.y += lookDelta.y; + if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) { + // if ( collider.body && !collider.shared ) uf::physics::impl::applyRotation( collider, cameraTransform.right, lookDelta.y ); else + uf::transform::rotate( cameraTransform, cameraTransform.right, lookDelta.y ); + } else metadata.camera.limit.current.y -= lookDelta.y; + } + } else { + if ( keys.lookRight ^ keys.lookLeft ) { + if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); else + uf::transform::rotate( transform, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); + } + if ( keys.lookUp ^ keys.lookDown ) { + float direction = keys.lookUp ? 1 : -1; + if ( metadata.camera.invert.y ) direction *= -1; + uf::transform::rotate( cameraTransform, cameraTransform.right, speed.rotate * direction ); + } + } + } else { + if ( keys.lookRight ^ keys.lookLeft ) { + // auto rotation = uf::quaternion::axisAngle( cameraTransform.up, uf::physics::time::delta * (keys.lookRight ? 1 : -1) ); + // cameraTransform.position = uf::quaternion::rotate( rotation, cameraTransform.position - transform.position ); } - if ( lookDelta.y != 0 ) { - if ( metadata.camera.invert.y ) lookDelta.y *= -1; - metadata.camera.limit.current.y += lookDelta.y; - if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) { - // if ( collider.body && !collider.shared ) uf::physics::impl::applyRotation( collider, cameraTransform.right, lookDelta.y ); else - uf::transform::rotate( cameraTransform, cameraTransform.right, lookDelta.y ); - } else metadata.camera.limit.current.y -= lookDelta.y; + if ( keys.lookUp ^ keys.lookDown ) { + // if ( collider.body && !collider.shared ) uf::physics::impl::applyRotation( collider, cameraTransform.right, lookDelta.y ); else + float direction = keys.lookUp ? 1 : -1; + if ( metadata.camera.invert.y ) direction *= -1; + uf::transform::rotate( cameraTransform, cameraTransform.right, speed.rotate * direction ); } - } else if ( keys.lookRight ^ keys.lookLeft ) { - if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); else - uf::transform::rotate( transform, transform.up, speed.rotate * (keys.lookRight ? 1 : -1) ); } { if ( collider.body ) uf::physics::impl::setVelocity( collider, physics.linear.velocity ); else @@ -448,10 +497,25 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { } - if ( stats.deltaCrouch ) { - float delta = metadata.movement.crouch; - if ( metadata.system.crouching ) cameraTransform.position.y -= delta; - else cameraTransform.position.y += delta; + if ( metadata.camera.fixed ) { + cameraTransform.reference = NULL; + cameraTransform.position = transform.position + metadata.camera.offset; + // cameraTransform.orientation = uf::vector::decode( metadataJson["camera"]["orientation"], uf::quaternion::identity() ); + cameraTransform = uf::transform::reorient( cameraTransform ); + } else { + if ( metadata.camera.offset != pod::Vector3f{0,0,0} ) { + //auto flattened = uf::transform::flatten( cameraTransform ); + auto& flattened = transform; + metadata.camera.intermediary.position = uf::quaternion::rotate( flattened.orientation, metadata.camera.offset ); + + metadata.camera.intermediary.reference = &transform; + cameraTransform.reference = &metadata.camera.intermediary; + } + if ( stats.deltaCrouch ) { + float delta = metadata.movement.crouch; + if ( metadata.system.crouching ) cameraTransform.position.y -= delta; + else cameraTransform.position.y += delta; + } } #if UF_USE_OPENAL @@ -550,6 +614,7 @@ void ext::PlayerBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& auto& serializerAudioFootstep = serializer["audio"]["footstep"]; auto& serializerCamera = serializer["camera"]; auto& serializerCameraLimit = serializerCamera["limit"]; + auto& serializerCameraSettings = serializerCamera["settings"]; serializerSystem["menu"] = /*this->*/system.menu; serializerSystem["control"] = /*this->*/system.control; @@ -561,6 +626,7 @@ void ext::PlayerBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializerMovement["run"] = /*this->*/movement.run; serializerMovement["walk"] = /*this->*/movement.walk; serializerMovement["air"] = /*this->*/movement.air; + serializerMovement["strafe"] = /*this->*/movement.strafe; serializerMovement["jump"] = uf::vector::encode(/*this->*/movement.jump); serializerMovement["floored"]["feet"] = uf::vector::encode(/*this->*/movement.floored.feet); serializerMovement["floored"]["floor"] = uf::vector::encode(/*this->*/movement.floored.floor); @@ -573,6 +639,7 @@ void ext::PlayerBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializerCameraLimit["current"] = uf::vector::encode(/*this->*/camera.limit.current); serializerCameraLimit["minima"] = uf::vector::encode(/*this->*/camera.limit.min); serializerCameraLimit["maxima"] = uf::vector::encode(/*this->*/camera.limit.max); + serializerCameraSettings["fixed"] = camera.fixed; serializer["use"]["length"] = /*this->*/use.length; } @@ -583,6 +650,7 @@ void ext::PlayerBehavior::Metadata::deserialize( uf::Object& self, uf::Serialize auto& serializerMovement = serializer["movement"]; auto& serializerCamera = serializer["camera"]; auto& serializerCameraLimit = serializerCamera["limit"]; + auto& serializerCameraSettings = serializerCamera["settings"]; /*this->*/system.menu = serializerSystem["menu"].as(/*this->*/system.menu); /*this->*/system.control = serializerSystem["control"].as(/*this->*/system.control); @@ -594,6 +662,7 @@ void ext::PlayerBehavior::Metadata::deserialize( uf::Object& self, uf::Serialize /*this->*/movement.run = serializerMovement["run"].as(/*this->*/movement.run); /*this->*/movement.walk = serializerMovement["walk"].as(/*this->*/movement.walk); /*this->*/movement.air = serializerMovement["air"].as(/*this->*/movement.air); + /*this->*/movement.strafe = serializerMovement["strafe"].as(/*this->*/movement.strafe); /*this->*/movement.jump = uf::vector::decode(serializerMovement["jump"], /*this->*/movement.jump); /*this->*/movement.floored.feet = uf::vector::decode(serializerMovement["floored"]["feet"], /*this->*/movement.floored.feet); /*this->*/movement.floored.floor = uf::vector::decode(serializerMovement["floored"]["floor"], /*this->*/movement.floored.floor); @@ -609,6 +678,7 @@ void ext::PlayerBehavior::Metadata::deserialize( uf::Object& self, uf::Serialize /*this->*/camera.limit.current = uf::vector::decode( serializerCameraLimit["current"], /*this->*/camera.limit.current ); /*this->*/camera.limit.min = uf::vector::decode( serializerCameraLimit["minima"], /*this->*/camera.limit.min ); /*this->*/camera.limit.max = uf::vector::decode( serializerCameraLimit["maxima"], /*this->*/camera.limit.max ); + /*this->*/camera.fixed = serializerCameraSettings["fixed"].as( /*this->*/camera.fixed ); /*this->*/use.length = serializer["use"]["length"].as(/*this->*/use.length); } diff --git a/ext/behaviors/player/behavior.h b/ext/behaviors/player/behavior.h index bd9e672c..5e3a1a9d 100644 --- a/ext/behaviors/player/behavior.h +++ b/ext/behaviors/player/behavior.h @@ -26,6 +26,7 @@ namespace ext { float walk = 1.0f; float friction = 0.8f; float air = 1.0f; + bool strafe = true; pod::Vector3f jump = {0,8,0}; struct { pod::Vector3f feet = {0,-1.5,0}; @@ -41,6 +42,11 @@ namespace ext { } limit; pod::Vector3t invert; pod::Vector2f queued; + + pod::Vector3f offset; + pod::Transform<> intermediary; + + bool fixed = false; } camera; struct { pod::Vector2f sensitivity = {1,1}; diff --git a/ext/behaviors/scene/behavior.cpp b/ext/behaviors/scene/behavior.cpp index 59a6beda..4ffac320 100644 --- a/ext/behaviors/scene/behavior.cpp +++ b/ext/behaviors/scene/behavior.cpp @@ -343,9 +343,13 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) { pod::Transform<> transform = controller.getComponent>(); if ( controller.hasComponent() ) { auto& camera = controller.getComponent(); + transform = camera.getTransform(); + /* transform.position += camera.getTransform().position; transform = uf::transform::reorient( transform ); + */ } + transform = uf::transform::flatten( transform ); transform.forward *= -1; ext::al::listener( transform ); diff --git a/ext/main.cpp b/ext/main.cpp index e5884c31..cbcae1ac 100644 --- a/ext/main.cpp +++ b/ext/main.cpp @@ -885,12 +885,12 @@ void EXT_API ext::tick() { /* Update physics timer */ { uf::physics::tick(); } - /* Update graph */ { - uf::graph::tick(); - } /* Update entities */ { uf::scene::tick(); } + /* Update graph */ { + uf::graph::tick(); + } /* Tick Main Thread Queue */ { uf::thread::process( uf::thread::get(uf::thread::mainThreadName) );