Commit for 2020.09.27.7z
This commit is contained in:
parent
0b88b27065
commit
a97418d88e
@ -1,7 +1,6 @@
|
||||
#version 450
|
||||
|
||||
#define BASE_LIGHTS_SIZE 16
|
||||
layout (constant_id = 0) const uint LIGHTS = BASE_LIGHTS_SIZE;
|
||||
layout (constant_id = 0) const uint LIGHTS = 32;
|
||||
|
||||
layout (input_attachment_index = 0, binding = 1) uniform subpassInput samplerAlbedo;
|
||||
layout (input_attachment_index = 0, binding = 2) uniform subpassInput samplerNormal;
|
||||
@ -14,6 +13,33 @@ layout (location = 1) in flat uint inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
/*
|
||||
const vec2 poissonDisk[4] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 )
|
||||
);
|
||||
*/
|
||||
|
||||
vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
@ -36,16 +62,25 @@ struct Space {
|
||||
vec3 world;
|
||||
} position, normal, view;
|
||||
|
||||
struct Fog {
|
||||
vec2 range;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec3 ambient;
|
||||
float kexp;
|
||||
Fog fog;
|
||||
Light lights[LIGHTS];
|
||||
} ubo;
|
||||
|
||||
void fog( inout vec3 i ) {
|
||||
vec3 color = vec3( 0.1, 0.1, 0.1 );
|
||||
float inner = 4, outer = 32;
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
vec3 color = ubo.fog.color.rgb;
|
||||
float inner = ubo.fog.range.x;
|
||||
float outer = ubo.fog.range.y;
|
||||
float distance = length(-position.eye);
|
||||
float factor = (distance - inner) / (outer - inner);
|
||||
factor = clamp( factor, 0.0, 1.0 );
|
||||
@ -67,7 +102,7 @@ void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
vec3 L = light.position.xyz - position.eye;
|
||||
float dist = length(L);
|
||||
|
||||
if ( light.radius < dist ) return;
|
||||
if ( light.radius > 0.001 && light.radius < dist ) return;
|
||||
|
||||
vec3 D = normalize(L);
|
||||
float d_dot = max(dot( D, normal.eye ), 0.0);
|
||||
@ -77,6 +112,7 @@ void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
float s_factor = pow( max(dot( R, S ), 0.0), Kexp );
|
||||
|
||||
float attenuation = light.radius / (pow(dist, 2.0) + 1.0);
|
||||
if ( light.radius <= 0.0001 ) attenuation = 1;
|
||||
|
||||
vec3 Ia = La * Ka;
|
||||
vec3 Id = Ld * Kd * d_dot * attenuation;
|
||||
@ -85,53 +121,41 @@ void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
i += Id * light.power;
|
||||
}
|
||||
|
||||
bool debugShadow( Light light, uint i ) {
|
||||
// return false;
|
||||
|
||||
{
|
||||
outFragColor.rgb = texture(samplerShadows[i], inUv).rgb;
|
||||
outFragColor.a = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
vec4 positionClip = light.projection * light.view * vec4(position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
float lightDepth = texture(samplerShadows[i], positionClip.xy * 0.5 + 0.5).r;
|
||||
|
||||
float eyeDepth = positionClip.z;
|
||||
// eyeDepth = lightDepth;
|
||||
float bias = 0.0005;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) eyeDepth = 1;
|
||||
else if ( positionClip.y < -1 || positionClip.y >= 1 ) eyeDepth = 1;
|
||||
else if ( positionClip.z < 0 || positionClip.z >= 1 ) eyeDepth = 1;
|
||||
else eyeDepth /= 0.00526;
|
||||
|
||||
outFragColor.rgb = vec3( 1 - eyeDepth );
|
||||
outFragColor.a = 1;
|
||||
|
||||
return true;
|
||||
float random(vec3 seed, int i){
|
||||
vec4 seed4 = vec4(seed,i);
|
||||
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
|
||||
return fract(sin(dot_product) * 43758.5453);
|
||||
}
|
||||
|
||||
float shadowFactor( Light light, uint i ) {
|
||||
float shadowFactor( Light light, uint shadowMap ) {
|
||||
vec4 positionClip = light.projection * light.view * vec4(position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
float lightDepth = texture(samplerShadows[(i*4)+3], positionClip.xy * 0.5 + 0.5).r;
|
||||
float eyeDepth = positionClip.z;
|
||||
float bias = 0.0005;
|
||||
// bias = max(0.05 * (1.0 - dot(normal.eye, light.position.xyz - position.eye)), bias);
|
||||
|
||||
// eyeDepth /= 0.00526;
|
||||
// lightDepth /= 0.00526;
|
||||
|
||||
eyeDepth = 1 - eyeDepth;
|
||||
lightDepth = 1 - lightDepth;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z < 0 || positionClip.z >= 1 ) return 0.0;
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
float bias = 0.00005;
|
||||
if ( true ) {
|
||||
float cosTheta = clamp(dot(normal.eye, normalize(light.position.xyz - position.eye)), 0, 1);
|
||||
bias = clamp(bias * tan(acos(cosTheta)), 0, 0.01);
|
||||
}
|
||||
|
||||
return eyeDepth - bias < lightDepth ? 1.0 : 0.0;
|
||||
float factor = 1.0;
|
||||
float eyeDepth = positionClip.z;
|
||||
int samples = poissonDisk.length();
|
||||
if ( samples <= 1 ) {
|
||||
return eyeDepth < texture(samplerShadows[shadowMap], uv).r - bias ? 0.0 : factor;
|
||||
}
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
// int index = i;
|
||||
// int index = int( float(samples) * random(gl_FragCoord.xyy, i) ) % samples;
|
||||
int index = int( float(samples) * random(floor(position.world.xyz * 1000.0), i)) % samples;
|
||||
float lightDepth = texture(samplerShadows[shadowMap], uv + poissonDisk[index] / 700.0 ).r;
|
||||
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
@ -183,7 +207,7 @@ void main() {
|
||||
|
||||
vec3 fragColor = albedoSpecular.rgb * ubo.ambient.rgb;
|
||||
bool lit = false;
|
||||
|
||||
uint shadowMap = 0;
|
||||
for ( uint i = 0; i < LIGHTS; ++i ) {
|
||||
Light light = ubo.lights[i];
|
||||
|
||||
@ -192,29 +216,12 @@ void main() {
|
||||
|
||||
light.position.xyz = vec3(ubo.matrices.view[inPushConstantPass] * vec4(light.position.xyz, 1));
|
||||
if ( light.shadowed > 0 ) {
|
||||
float shadowFactor = shadowFactor( light, i );
|
||||
float shadowFactor = shadowFactor( light, shadowMap++ );
|
||||
if ( shadowFactor <= 0.0001 ) continue;
|
||||
}
|
||||
phong( light, albedoSpecular, fragColor );
|
||||
}
|
||||
|
||||
if ( !lit ) fragColor = albedoSpecular.rgb;
|
||||
|
||||
// if ( !lit ) fragColor = albedoSpecular.rgb;
|
||||
fog(fragColor);
|
||||
|
||||
outFragColor = vec4(fragColor,1);
|
||||
/*
|
||||
if ( !false ) {
|
||||
float depth = texture(samplerShadows[0], inUv).r;
|
||||
depth /= 0.00526;
|
||||
outFragColor = vec4( vec3(1 - depth), 1 );
|
||||
return;
|
||||
} else if ( !false ) {
|
||||
outFragColor = vec4( texture(samplerShadows[0], inUv).rgb, 1 );
|
||||
return;
|
||||
} else {
|
||||
outFragColor = vec4( inUv.x, 0, inUv.y, 1 );
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -6,18 +6,15 @@ layout (constant_id = 0) const uint LIGHTS = 16;
|
||||
layout (constant_id = 1) const uint EYES = 2;
|
||||
layout (binding = 0, rgba8) uniform writeonly image2D resultImage[EYES];
|
||||
|
||||
#define RAY_MARCH false
|
||||
#define MARCH_STEPS 32
|
||||
#define EPSILON 0.0001
|
||||
#define MAXLEN 1000.0
|
||||
#define SHADOW 0.5
|
||||
#define SHADOWS true
|
||||
#define RAYBOUNCES 0
|
||||
#define REFLECTION_STRENGTH 0.4
|
||||
#define REFLECTION_FALLOFF 0.5
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint marchingSteps;
|
||||
uint rayBounces;
|
||||
float shadowFactor;
|
||||
float reflectionStrength;
|
||||
float reflectionFalloff;
|
||||
} PushConstant;
|
||||
|
||||
struct Ray {
|
||||
@ -45,9 +42,15 @@ struct State {
|
||||
Result result;
|
||||
} state;
|
||||
|
||||
struct Fog {
|
||||
vec2 range;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout (binding = 2) uniform UBO {
|
||||
mat4 matrices[2];
|
||||
vec4 ambient;
|
||||
Fog fog;
|
||||
Light lights[LIGHTS];
|
||||
} ubo;
|
||||
|
||||
@ -138,7 +141,7 @@ float calcShadow(in vec3 rayO, in vec3 rayD, in int objectID, inout float resT)
|
||||
float tShape = shapeIntersect(rayO, rayD, shape);
|
||||
if ((tShape > EPSILON) && (tShape < resT)) {
|
||||
resT = tShape;
|
||||
return SHADOW;
|
||||
return PushConstant.shadowFactor;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
@ -146,7 +149,7 @@ float calcShadow(in vec3 rayO, in vec3 rayD, in int objectID, inout float resT)
|
||||
// Marching ========================================
|
||||
int intersectMarch( in vec3 rayO, in vec3 rayD, inout float resT ) {
|
||||
resT = 0;
|
||||
for (int i = 0; i < MARCH_STEPS; ++i) {
|
||||
for (int i = 0; i < PushConstant.marchingSteps; ++i) {
|
||||
vec3 position = resT * rayD + rayO;
|
||||
float tNearest = MAXLEN;
|
||||
int objectID = -1;
|
||||
@ -171,7 +174,7 @@ int intersectMarch( in vec3 rayO, in vec3 rayD, inout float resT ) {
|
||||
float calcShadowMarch( in vec3 rayO, in vec3 rayD, in int objectID, inout float resT ) {
|
||||
float distance = resT;
|
||||
resT = 0;
|
||||
for (int i = 0; i < MARCH_STEPS; ++i) {
|
||||
for (int i = 0; i < PushConstant.marchingSteps; ++i) {
|
||||
vec3 position = resT * rayD + rayO;
|
||||
float tNearest = distance;
|
||||
int objectID = -1;
|
||||
@ -186,7 +189,7 @@ float calcShadowMarch( in vec3 rayO, in vec3 rayD, in int objectID, inout float
|
||||
}
|
||||
}
|
||||
if (tNearest < EPSILON) {
|
||||
return SHADOW;
|
||||
return PushConstant.shadowFactor;
|
||||
}
|
||||
if (resT > distance) break;
|
||||
resT += tNearest;
|
||||
@ -195,16 +198,26 @@ float calcShadowMarch( in vec3 rayO, in vec3 rayD, in int objectID, inout float
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
vec3 fog(in float t, in vec3 color) {
|
||||
vec3 fogColor = vec3(0.1);
|
||||
return mix(color, fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0));
|
||||
void fog(inout vec3 i, in float t ) {
|
||||
/*
|
||||
vec3 fogColor = ubo.ambient.rgb;
|
||||
i = mix(i, fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0));
|
||||
*/
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
vec3 color = ubo.fog.color.rgb;
|
||||
float inner = ubo.fog.range.x, outer = ubo.fog.range.y;
|
||||
float factor = (t - inner) / (outer - inner);
|
||||
factor = clamp( factor, 0.0, 1.0 );
|
||||
|
||||
i = mix(i.rgb, color, factor);
|
||||
}
|
||||
|
||||
Result renderScene(inout vec3 rayO, inout vec3 rayD ) {
|
||||
Result result;
|
||||
result.color = vec3(0.0);
|
||||
result.t = MAXLEN;
|
||||
result.id = RAY_MARCH ? intersectMarch(rayO, rayD, result.t) : intersect(rayO, rayD, result.t);
|
||||
result.id = PushConstant.marchingSteps > 0 ? intersectMarch(rayO, rayD, result.t) : intersect(rayO, rayD, result.t);
|
||||
if (result.id == -1) return result;
|
||||
|
||||
Shape shape = shapes[result.id];
|
||||
@ -232,13 +245,13 @@ Result renderScene(inout vec3 rayO, inout vec3 rayD ) {
|
||||
// Shadows
|
||||
float tShadow = dist;
|
||||
float shadowed = 1;
|
||||
if ( SHADOWS )
|
||||
shadowed = RAY_MARCH ? calcShadowMarch(position, D, result.id, tShadow) : calcShadow(position, D, result.id, tShadow);
|
||||
if ( PushConstant.shadowFactor < 1.0 )
|
||||
shadowed = PushConstant.marchingSteps > 0 ? calcShadowMarch(position, D, result.id, tShadow) : calcShadow(position, D, result.id, tShadow);
|
||||
result.color += color * light.power * attenuation * shadowed;
|
||||
}
|
||||
|
||||
// Fog
|
||||
// result.color = fog(t, result.color);
|
||||
// fog(t, result.color);
|
||||
|
||||
// Reflect ray for next render pass
|
||||
reflectRay(rayD, normal);
|
||||
@ -266,13 +279,13 @@ void main() {
|
||||
vec3 finalColor = state.result.color;
|
||||
|
||||
// Reflection
|
||||
float reflectionStrength = REFLECTION_STRENGTH;
|
||||
for (int i = 0; i < RAYBOUNCES; i++) {
|
||||
float reflectionStrength = PushConstant.reflectionStrength;
|
||||
for (int i = 0; i < PushConstant.rayBounces; i++) {
|
||||
Result result = renderScene(state.ray.origin, state.ray.direction);
|
||||
vec3 reflectionColor = result.color;
|
||||
|
||||
finalColor = (1.0 - reflectionStrength) * finalColor + reflectionStrength * mix(reflectionColor, finalColor, 1.0 - reflectionStrength);
|
||||
reflectionStrength *= REFLECTION_FALLOFF;
|
||||
reflectionStrength *= PushConstant.reflectionFalloff;
|
||||
}
|
||||
|
||||
imageStore(resultImage[pass], ivec2(gl_GlobalInvocationID.xy), vec4(finalColor, 1.0));
|
||||
|
||||
70
engine/inc/uf/engine/behavior/behavior.h
Normal file
70
engine/inc/uf/engine/behavior/behavior.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/utils/component/component.h>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <typeindex>
|
||||
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Behavior {
|
||||
typedef std::type_index type_t;
|
||||
typedef std::function<void()> function_t;
|
||||
|
||||
type_t type;
|
||||
function_t initialize;
|
||||
function_t tick;
|
||||
function_t render;
|
||||
function_t destroy;
|
||||
};
|
||||
}
|
||||
|
||||
namespace uf {
|
||||
class UF_API Behaviors : public uf::Component {
|
||||
protected:
|
||||
typedef std::vector<pod::Behavior> container_t;
|
||||
container_t m_behaviors;
|
||||
public:
|
||||
void initialize();
|
||||
void tick();
|
||||
void render();
|
||||
void destroy();
|
||||
|
||||
void addBehavior( const pod::Behavior& );
|
||||
|
||||
template<typename T>
|
||||
static pod::Behavior::type_t getType() {
|
||||
return std::type_index(typeid(T));
|
||||
}
|
||||
template<typename T>
|
||||
void addBehavior() {
|
||||
this->addBehavior(pod::Behavior{
|
||||
.type = getType<T>(),
|
||||
.initialize = T::initialize,
|
||||
.tick = T::tick,
|
||||
.render = T::render,
|
||||
.destroy = T::destroy,
|
||||
});
|
||||
}
|
||||
template<typename T>
|
||||
void removeBehavior() {
|
||||
auto it = this->m_behaviors.begin();
|
||||
while ( it != this->m_behaviors.end() ) {
|
||||
if ( (it++)->type == getType<T>() ) break;
|
||||
}
|
||||
if ( it != this->m_behaviors.end() )
|
||||
this->m_behaviors.erase(it);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define UF_BEHAVIOR_ENTITY_HEADER( OBJ )\
|
||||
class UF_API OBJ ## Behavior {\
|
||||
public:\
|
||||
void initialize();\
|
||||
void tick();\
|
||||
void render();\
|
||||
void destroy();\
|
||||
};
|
||||
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/utils/component/component.h>
|
||||
#include <uf/engine/behavior/behavior.h>
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
@ -9,7 +9,16 @@
|
||||
#include <uf/utils/mempool/mempool.h>
|
||||
|
||||
namespace uf {
|
||||
class UF_API Entity : public uf::Component {
|
||||
/*
|
||||
class UF_API EntityBehavior {
|
||||
public:
|
||||
void initialize();
|
||||
void destroy();
|
||||
void tick();
|
||||
void render();
|
||||
};
|
||||
*/
|
||||
class UF_API Entity : public uf::Behaviors {
|
||||
public:
|
||||
typedef std::vector<uf::Entity*> container_t;
|
||||
protected:
|
||||
@ -25,15 +34,15 @@ namespace uf {
|
||||
static uf::MemoryPool memoryPool;
|
||||
Entity( bool = false );
|
||||
virtual ~Entity();
|
||||
|
||||
// identifiers
|
||||
const std::string& getName() const;
|
||||
std::size_t getUid() const;
|
||||
// parent-child relationship
|
||||
bool hasParent() const;
|
||||
template<typename T=uf::Entity> T& getParent();
|
||||
template<typename T=uf::Entity> T& getRootParent();
|
||||
template<typename T=uf::Entity> const T& getParent() const;
|
||||
template<typename T=uf::Entity> const T& getRootParent() const;
|
||||
const std::string& getName() const;
|
||||
std::size_t getUid() const;
|
||||
|
||||
void setParent();
|
||||
void setParent( uf::Entity& parent );
|
||||
uf::Entity& addChild( uf::Entity& child );
|
||||
@ -41,30 +50,26 @@ namespace uf {
|
||||
void removeChild( uf::Entity& child );
|
||||
uf::Entity::container_t& getChildren();
|
||||
const uf::Entity::container_t& getChildren() const;
|
||||
|
||||
virtual void initialize();
|
||||
virtual void destroy();
|
||||
virtual void tick();
|
||||
virtual void render();
|
||||
|
||||
// use instantiate to allocate
|
||||
void* operator new(size_t, const std::string& = "");
|
||||
void operator delete(void*);
|
||||
|
||||
template<typename T=uf::Entity> void initialize();
|
||||
template<typename T=uf::Entity> void destroy();
|
||||
template<typename T=uf::Entity> void tick();
|
||||
template<typename T=uf::Entity> void render();
|
||||
|
||||
// search
|
||||
uf::Entity* findByName( const std::string& name );
|
||||
uf::Entity* findByUid( std::size_t id );
|
||||
const uf::Entity* findByName( const std::string& name ) const;
|
||||
const uf::Entity* findByUid( std::size_t id ) const;
|
||||
// filters
|
||||
void process( std::function<void(uf::Entity*)> );
|
||||
void process( std::function<void(uf::Entity*, int)>, int depth = 0 );
|
||||
// void process( std::function<void(const uf::Entity*)> ) const ;
|
||||
// void process( std::function<void(const uf::Entity*, int)>, int depth = 0 ) const;
|
||||
// globals
|
||||
static uf::Entity* globalFindByUid( size_t id );
|
||||
static uf::Entity* globalFindByName( const std::string& name );
|
||||
|
||||
// behavior
|
||||
virtual void initialize();
|
||||
virtual void destroy();
|
||||
virtual void tick();
|
||||
virtual void render();
|
||||
};
|
||||
}
|
||||
#include "entity.inl"
|
||||
@ -30,7 +30,7 @@ template<typename T> const T& uf::Entity::getRootParent() const {
|
||||
}
|
||||
return *(const T*) last;
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename T> void uf::Entity::initialize() {
|
||||
static_cast<T*>(this)->initialize();
|
||||
this->initialize();
|
||||
@ -46,4 +46,5 @@ template<typename T> void uf::Entity::tick() {
|
||||
template<typename T> void uf::Entity::render() {
|
||||
static_cast<T*>(this)->render();
|
||||
this->render();
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -12,14 +12,14 @@ namespace uf {
|
||||
virtual void render();
|
||||
virtual void destroy();
|
||||
|
||||
virtual uf::Entity* getController();
|
||||
virtual const uf::Entity* getController() const;
|
||||
virtual uf::Entity& getController();
|
||||
virtual const uf::Entity& getController() const;
|
||||
|
||||
template<typename T> T& getController() {
|
||||
return *((T*) this->getController());
|
||||
return *((T*) &this->getController());
|
||||
}
|
||||
template<typename T> const T& getController() const {
|
||||
return *((const T*) this->getController());
|
||||
return *((const T*) &this->getController());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -27,11 +27,19 @@ namespace ext {
|
||||
VkPhysicalDeviceFeatures2 features2;
|
||||
VkPhysicalDeviceFeatures2 enabledFeatures2;
|
||||
VkPhysicalDeviceMemoryProperties2 memoryProperties2;
|
||||
|
||||
struct {
|
||||
std::vector<VkExtensionProperties> instance;
|
||||
std::vector<VkExtensionProperties> device;
|
||||
} extensionProperties;
|
||||
struct {
|
||||
std::vector<std::string> instance;
|
||||
std::vector<std::string> device;
|
||||
} supportedExtensions;
|
||||
|
||||
VkPipelineCache pipelineCache;
|
||||
|
||||
std::vector<VkQueueFamilyProperties> queueFamilyProperties;
|
||||
std::vector<std::string> supportedExtensions;
|
||||
|
||||
struct {
|
||||
VkQueue graphics;
|
||||
|
||||
@ -9,4 +9,14 @@ namespace pod {
|
||||
namespace {
|
||||
// Sometimes uint isn't declared
|
||||
typedef unsigned int uint;
|
||||
}
|
||||
}
|
||||
/*
|
||||
namespace uf {
|
||||
namespace math {
|
||||
template<typename T>
|
||||
T lerp( const T& from, const T& to, double delta ) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -10,6 +10,7 @@
|
||||
#define UF_MEMORYPOOL_INVALID_MALLOC 0
|
||||
#define UF_MEMORYPOOL_INVALID_FREE 0
|
||||
#define UF_MEMORYPOOL_OVERRIDE_NEW_DELETE 0
|
||||
#define UF_MEMORYPOOL_CACHED_ALLOCATIONS 0
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Userdata;
|
||||
@ -29,6 +30,7 @@ namespace uf {
|
||||
|
||||
typedef std::vector<pod::Allocation> allocations_t;
|
||||
allocations_t m_allocations;
|
||||
allocations_t m_cachedFreeAllocations;
|
||||
public:
|
||||
static bool globalOverride;
|
||||
static bool subPool;
|
||||
|
||||
@ -4,36 +4,6 @@
|
||||
template<typename T>
|
||||
pod::Userdata* uf::userdata::create( const T& data ) {
|
||||
return uf::userdata::create<T>( uf::userdata::memoryPool, data );
|
||||
/*
|
||||
if ( uf::userdata::memoryPool.size() > 0 ) {
|
||||
return uf::userdata::create<T>( uf::userdata::memoryPool, data );
|
||||
} else {
|
||||
#if UF_USERDATA_KLUDGE
|
||||
void* pointer = operator new( sizeof(pod::Userdata) + sizeof data );
|
||||
pod::Userdata* userdata = (pod::Userdata*) pointer;
|
||||
userdata->len = sizeof data;
|
||||
userdata->pointer = NULL;
|
||||
union {
|
||||
uint8_t* from;
|
||||
T* to;
|
||||
} static kludge;
|
||||
kludge.from = userdata->data;
|
||||
::new (kludge.to) T(data);
|
||||
return userdata;
|
||||
#else
|
||||
pod::Userdata* userdata = new pod::Userdata;
|
||||
userdata->len = sizeof data;
|
||||
userdata->data = (uint8_t*) operator new(userdata->len);
|
||||
union {
|
||||
uint8_t* from;
|
||||
T* to;
|
||||
} static kludge;
|
||||
kludge.from = userdata->data;
|
||||
::new (kludge.to) T(data);
|
||||
return userdata;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
}
|
||||
template<typename T>
|
||||
pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, const T& data ) {
|
||||
@ -59,57 +29,6 @@ pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, const
|
||||
kludge.from = userdata->data;
|
||||
::new (kludge.to) T(data);
|
||||
return userdata;
|
||||
/*
|
||||
uf::MemoryPool* memoryPool = NULL;
|
||||
if ( requestedMemoryPool.size() > 0 ) memoryPool = &requestedMemoryPool;
|
||||
else if ( uf::MemoryPool::global.size() > 0 ) memoryPool = &uf::MemoryPool::global;
|
||||
pod::Userdata* userdata;
|
||||
if ( memoryPool )
|
||||
userdata = (pod::Userdata*) memoryPool->alloc( NULL, sizeof(pod::Userdata) + sizeof(data) );
|
||||
else {
|
||||
userdata = uf::userdata::create( requestedMemoryPool, sizeof(data), NULL );
|
||||
}
|
||||
userdata->len = sizeof(data);
|
||||
#if UF_USERDATA_KLUDGE
|
||||
userdata->pointer = NULL;
|
||||
#endif
|
||||
union {
|
||||
uint8_t* from;
|
||||
T* to;
|
||||
} static kludge;
|
||||
kludge.from = userdata->data;
|
||||
::new (kludge.to) T(data);
|
||||
return userdata;
|
||||
*/
|
||||
/*
|
||||
if ( uf::userdata::memoryPool.size() > 0 ) {
|
||||
// pod::Userdata* userdata = uf::userdata::create( memoryPool, sizeof(pod::Userdata) + sizeof(data), NULL );
|
||||
void* pointer = uf::userdata::memoryPool.alloc( NULL, sizeof(pod::Userdata) + sizeof(data) );
|
||||
pod::Userdata* userdata = (pod::Userdata*) pointer;
|
||||
userdata->len = sizeof(data);
|
||||
#if UF_USERDATA_KLUDGE
|
||||
userdata->pointer = NULL;
|
||||
#endif
|
||||
union {
|
||||
uint8_t* from;
|
||||
T* to;
|
||||
} static kludge;
|
||||
kludge.from = userdata->data;
|
||||
::new (kludge.to) T(data);
|
||||
return userdata;
|
||||
} else {
|
||||
if ( memoryPool.size() <= 0 ) return uf::userdata::create<T>(data);
|
||||
pod::Userdata* userdata = new pod::Userdata;
|
||||
auto allocation = memoryPool.allocate( data );
|
||||
userdata->len = allocation.size;
|
||||
#if UF_USERDATA_KLUDGE
|
||||
userdata->pointer = (uint8_t*) allocation.pointer;
|
||||
#else
|
||||
userdata->data = (uint8_t*) allocation.pointer;
|
||||
#endif
|
||||
return userdata;
|
||||
}
|
||||
*/
|
||||
}
|
||||
// Easy way to get the userdata as a reference
|
||||
#include <stdexcept>
|
||||
|
||||
27
engine/src/engine/behavior/behavior.cpp
Normal file
27
engine/src/engine/behavior/behavior.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <uf/engine/behavior/behavior.h>
|
||||
|
||||
void uf::Behaviors::addBehavior( const pod::Behavior& behavior ) {
|
||||
std::cout << "[!!!] behavior attached" << std::endl;
|
||||
this->m_behaviors.emplace_back(behavior);
|
||||
}
|
||||
|
||||
void uf::Behaviors::initialize() {
|
||||
for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) {
|
||||
std::cout << "[!!!] behavior called: initialize" << std::endl;
|
||||
it->initialize();
|
||||
}
|
||||
}
|
||||
void uf::Behaviors::tick() {
|
||||
for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it )
|
||||
it->tick();
|
||||
}
|
||||
void uf::Behaviors::render() {
|
||||
for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it )
|
||||
it->render();
|
||||
}
|
||||
void uf::Behaviors::destroy() {
|
||||
for ( auto it = this->m_behaviors.rbegin(); it != this->m_behaviors.rend(); ++it ) {
|
||||
std::cout << "[!!!] behavior called: destroy" << std::endl;
|
||||
it->destroy();
|
||||
}
|
||||
}
|
||||
@ -49,38 +49,6 @@ const std::string& uf::Entity::getName() const {
|
||||
std::size_t uf::Entity::getUid() const {
|
||||
return this->m_uid;
|
||||
}
|
||||
void uf::Entity::initialize(){
|
||||
if ( this->m_uid == 0 ) this->m_uid = ++uf::Entity::uids;
|
||||
}
|
||||
void uf::Entity::destroy(){
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->destroy();
|
||||
kv->setParent();
|
||||
delete kv;
|
||||
}
|
||||
this->m_children.clear();
|
||||
this->m_uid = 0;
|
||||
/*
|
||||
auto it = std::find(uf::Entity::entities.begin(), uf::Entity::entities.end(), this);
|
||||
if ( it != uf::Entity::entities.end() ) uf::Entity::entities.erase(it);
|
||||
*/
|
||||
}
|
||||
void uf::Entity::tick(){
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->tick();
|
||||
}
|
||||
}
|
||||
void uf::Entity::render(){
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->render();
|
||||
}
|
||||
}
|
||||
|
||||
void* uf::Entity::operator new(size_t size, const std::string& type ) {
|
||||
return type != "" && size == sizeof(uf::Entity) ? uf::instantiator::instantiate( type ) : uf::instantiator::alloc( size );
|
||||
@ -137,22 +105,6 @@ void uf::Entity::process( std::function<void(uf::Entity*, int)> fn, int depth )
|
||||
entity->process(fn, depth + 1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
void uf::Entity::process( std::function<void(const uf::Entity*)> fn ) const {
|
||||
fn(this);
|
||||
for ( uf::Entity* entity : this->getChildren() ) {
|
||||
if ( !entity ) continue;
|
||||
entity->process(fn);
|
||||
}
|
||||
}
|
||||
void uf::Entity::process( std::function<void(const uf::Entity*, int)> fn, int depth ) const {
|
||||
fn(this, depth);
|
||||
for ( uf::Entity* entity : this->getChildren() ) {
|
||||
if ( !entity ) continue;
|
||||
entity->process(fn, depth + 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
uf::Entity* uf::Entity::globalFindByUid( size_t uid ) {
|
||||
for ( auto& allocation : uf::Entity::memoryPool.allocations() ) {
|
||||
uf::Entity* entity = (uf::Entity*) allocation.pointer;
|
||||
@ -166,12 +118,74 @@ uf::Entity* uf::Entity::globalFindByName( const std::string& name ) {
|
||||
if ( entity->getUid() == 0 ) continue;
|
||||
if ( entity->getName() == name ) return entity;
|
||||
}
|
||||
/*
|
||||
for ( uf::Entity* e : uf::Entity::entities ) {
|
||||
if ( !e ) continue;
|
||||
if ( e->getUid() == 0 ) continue;
|
||||
if ( e->getName() == name ) return e;
|
||||
}
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uf::Entity::initialize( ){
|
||||
if ( this->m_uid == 0 ) this->m_uid = ++uf::Entity::uids;
|
||||
|
||||
uf::Behaviors::initialize();
|
||||
}
|
||||
void uf::Entity::tick( ){
|
||||
uf::Behaviors::tick();
|
||||
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->tick();
|
||||
}
|
||||
}
|
||||
void uf::Entity::render( ){
|
||||
uf::Behaviors::render();
|
||||
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->render();
|
||||
}
|
||||
}
|
||||
void uf::Entity::destroy( ){
|
||||
uf::Behaviors::destroy();
|
||||
|
||||
for ( uf::Entity* kv : this->m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->destroy();
|
||||
kv->setParent();
|
||||
delete kv;
|
||||
}
|
||||
this->m_children.clear();
|
||||
this->m_uid = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void uf::EntityBehavior::initialize( uf::Entity& base ){
|
||||
if ( base.m_uid == 0 ) base.m_uid = ++uf::Entity::uids;
|
||||
}
|
||||
void uf::EntityBehavior::destroy( uf::Entity& entity ){
|
||||
for ( uf::Entity* kv : base.m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->destroy();
|
||||
kv->setParent();
|
||||
delete kv;
|
||||
}
|
||||
base.m_children.clear();
|
||||
base.m_uid = 0;
|
||||
}
|
||||
void uf::EntityBehavior::tick( uf::Entity& entity ){
|
||||
for ( uf::Entity* kv : base.m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->tick();
|
||||
}
|
||||
}
|
||||
void uf::EntityBehavior::render( uf::Entity& entity ){
|
||||
for ( uf::Entity* kv : base.m_children ) {
|
||||
if ( !kv ) continue;
|
||||
if ( kv->getUid() == 0 ) continue;
|
||||
kv->render();
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -71,14 +71,10 @@ void uf::Object::destroy() {
|
||||
}
|
||||
void uf::Object::tick() {
|
||||
uf::Entity::tick();
|
||||
|
||||
// listen for metadata file changes
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
if ( metadata["system"]["hot reload"]["enabled"].asBool() ) {
|
||||
/*
|
||||
std::string filename = "./entities/"+metadata["system"]["source"].asString();
|
||||
std::string root = "./data/" + uf::string::directory(filename);
|
||||
size_t mtime = uf::string::mtime( root + uf::string::filename(filename) );
|
||||
*/
|
||||
size_t mtime = uf::string::mtime( metadata["system"]["source"].asString() );
|
||||
if ( metadata["system"]["hot reload"]["mtime"].asUInt64() < mtime ) {
|
||||
std::cout << metadata["system"]["hot reload"]["mtime"] << ": " << mtime << std::endl;
|
||||
@ -115,7 +111,8 @@ void uf::Object::render() {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& camera = scene.getController()->getComponent<uf::Camera>();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
|
||||
if ( !graphic.initialized ) return;
|
||||
|
||||
@ -399,23 +396,45 @@ bool uf::Object::load( const uf::Serializer& json ) {
|
||||
uf::Serializer target = metadata["system"]["lights"];
|
||||
for ( uint i = 0; i < target.size(); ++i ) {
|
||||
uf::Serializer json = target[i];
|
||||
auto* light = this->findByUid(this->loadChild("/light.json", false));
|
||||
if ( !light ) continue;
|
||||
auto& metadata = light->getComponent<uf::Serializer>();
|
||||
auto& transform = light->getComponent<pod::Transform<>>();
|
||||
if ( json["position"].isArray() )
|
||||
for ( uint j = 0; j < 3; ++j ) transform.position[j] = json["position"][j].asFloat();
|
||||
if ( json["orientation"].isArray() )
|
||||
for ( uint j = 0; j < 4; ++j ) transform.orientation[j] = json["orientation"][j].asFloat();
|
||||
std::vector<pod::Vector4f> orientations;
|
||||
if ( json["transform"]["orientation"].isNull() && json["shadows"]["fov"].asFloat() == 0.0f ) {
|
||||
orientations.reserve(6);
|
||||
orientations.push_back({0, 0, 0, -1});
|
||||
orientations.push_back({0, 0.707107, 0, -0.707107});
|
||||
orientations.push_back({0, 1, 0, 0});
|
||||
orientations.push_back({0, 0.707107, 0, 0.707107});
|
||||
orientations.push_back({-0.707107, 0, 0, -0.707107});
|
||||
orientations.push_back({0.707107, 0, 0, -0.707107});
|
||||
json["shadows"]["fov"] = 90.0f;
|
||||
} else {
|
||||
pod::Vector4f orientation;
|
||||
for ( uint j = 0; j < 4; ++j ) orientation[j] = json["transform"]["orientation"][j].asFloat();
|
||||
orientations.push_back(orientation);
|
||||
}
|
||||
uf::Object* target = this;
|
||||
for ( auto& orientation : orientations ) {
|
||||
auto* light = target->findByUid(target->loadChild("/light.json", false));
|
||||
if ( !light ) continue;
|
||||
if ( target == this ) target = (uf::Object*) light;
|
||||
auto& metadata = light->getComponent<uf::Serializer>();
|
||||
auto& transform = light->getComponent<pod::Transform<>>();
|
||||
if ( json["transform"]["position"].isArray() )
|
||||
for ( uint j = 0; j < 3; ++j )
|
||||
transform.position[j] = json["transform"]["position"][j].asFloat();
|
||||
for ( uint j = 0; j < 4; ++j )
|
||||
transform.orientation[j] = orientation[j];
|
||||
|
||||
if ( !json["color"].isNull() ) metadata["light"]["color"] = json["color"];
|
||||
if ( !json["radius"].isNull() ) metadata["light"]["radius"] = json["radius"];
|
||||
if ( !json["power"].isNull() ) metadata["light"]["power"] = json["power"];
|
||||
if ( !json["shadows"].isNull() ) metadata["light"]["shadows"] = json["shadows"];
|
||||
if ( !json["color"].isNull() ) metadata["light"]["color"] = json["color"];
|
||||
if ( !json["radius"].isNull() ) metadata["light"]["radius"] = json["radius"];
|
||||
if ( !json["power"].isNull() ) metadata["light"]["power"] = json["power"];
|
||||
if ( !json["shadows"].isNull() ) metadata["light"]["shadows"] = json["shadows"];
|
||||
if ( !json["flicker"].isNull() ) metadata["light"]["flicker"] = json["flicker"];
|
||||
if ( !json["fade"].isNull() ) metadata["light"]["fade"] = json["fade"];
|
||||
|
||||
light->initialize();
|
||||
if ( !json["system"]["track"].isNull() ) metadata["system"]["track"] = json["system"]["track"];
|
||||
|
||||
// std::cout << json << "\t" << metadata["light"] << std::endl;
|
||||
light->initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,184 +1,17 @@
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/ext/vulkan/vulkan.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
|
||||
#include <uf/ext/vulkan/rendermodes/deferred.h>
|
||||
#include <uf/ext/vulkan/rendermodes/rendertarget.h>
|
||||
#include <uf/ext/vulkan/rendermodes/compute.h>
|
||||
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
|
||||
UF_OBJECT_REGISTER_CPP(Scene)
|
||||
void uf::Scene::initialize() {
|
||||
ext::vulkan::scenes.push_back(this);
|
||||
ext::vulkan::rebuild = true;
|
||||
uf::renderer::scenes.push_back(this);
|
||||
uf::renderer::rebuild = true;
|
||||
|
||||
uf::Object::initialize();
|
||||
}
|
||||
void uf::Scene::tick() {
|
||||
uf::Object::tick();
|
||||
|
||||
if ( uf::scene::getCurrentScene().getUid() == this->getUid() ) {
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
/* Update lights */ if ( metadata["light"]["should"].asBool() ) {
|
||||
// if ( !ext::vulkan::currentRenderMode || ext::vulkan::currentRenderMode->name != "" ) return;
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
||||
std::vector<ext::vulkan::Graphic*> blitters;
|
||||
auto& renderMode = ext::vulkan::getRenderMode("", true);
|
||||
bool hasCompute = ext::vulkan::hasRenderMode("C:RT:" + std::to_string(this->getUid()), true);
|
||||
if ( hasCompute ) {
|
||||
// auto& renderMode = ext::vulkan::getRenderMode("C:RT:" + std::to_string(this->getUid()), true);
|
||||
// auto* renderModePointer = (ext::vulkan::ComputeRenderMode*) &renderMode;
|
||||
// if ( renderModePointer->compute.initialized ) {
|
||||
// blitters.push_back(&renderModePointer->compute);
|
||||
// } else {
|
||||
// hasCompute = false;
|
||||
// }
|
||||
} else if ( renderMode.getType() == "Deferred (Stereoscopic)" ) {
|
||||
auto* renderModePointer = (ext::vulkan::StereoscopicDeferredRenderMode*) &renderMode;
|
||||
blitters.push_back(&renderModePointer->blitters.left);
|
||||
blitters.push_back(&renderModePointer->blitters.right);
|
||||
} else if ( renderMode.getType() == "Deferred" ) {
|
||||
auto* renderModePointer = (ext::vulkan::DeferredRenderMode*) &renderMode;
|
||||
blitters.push_back(&renderModePointer->blitter);
|
||||
}
|
||||
auto& controller = *scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
|
||||
// auto& uniforms = blitter.uniforms;
|
||||
struct UniformDescriptor {
|
||||
struct Matrices {
|
||||
alignas(16) pod::Matrix4f view[2];
|
||||
alignas(16) pod::Matrix4f projection[2];
|
||||
} matrices;
|
||||
alignas(16) pod::Vector4f ambient;
|
||||
struct Light {
|
||||
alignas(16) pod::Vector4f position;
|
||||
alignas(16) pod::Vector4f color;
|
||||
alignas(8) pod::Vector2i type;
|
||||
alignas(16) pod::Matrix4f view;
|
||||
alignas(16) pod::Matrix4f projection;
|
||||
} lights;
|
||||
};
|
||||
|
||||
struct SpecializationConstant {
|
||||
int32_t maxLights = 16;
|
||||
} specializationConstants;
|
||||
|
||||
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
|
||||
auto& blitter = *blitters[_];
|
||||
|
||||
uint8_t* buffer;
|
||||
size_t len;
|
||||
auto* shader = &blitter.material.shaders.front();
|
||||
|
||||
for ( auto& _ : blitter.material.shaders ) {
|
||||
if ( _.uniforms.empty() ) continue;
|
||||
auto& userdata = _.uniforms.front();
|
||||
buffer = (uint8_t*) (void*) userdata;
|
||||
len = userdata.data().len;
|
||||
shader = &_;
|
||||
specializationConstants = _.specializationConstants.get<SpecializationConstant>();
|
||||
}
|
||||
|
||||
if ( !buffer ) continue;
|
||||
|
||||
UniformDescriptor* uniforms = (UniformDescriptor*) buffer;
|
||||
for ( std::size_t i = 0; i < 2; ++i ) {
|
||||
uniforms->matrices.view[i] = camera.getView( i );
|
||||
uniforms->matrices.projection[i] = camera.getProjection( i );
|
||||
}
|
||||
{
|
||||
uniforms->ambient.x = metadata["light"]["ambient"][0].asFloat();
|
||||
uniforms->ambient.y = metadata["light"]["ambient"][1].asFloat();
|
||||
uniforms->ambient.z = metadata["light"]["ambient"][2].asFloat();
|
||||
uniforms->ambient.w = metadata["light"]["kexp"].asFloat();
|
||||
}
|
||||
{
|
||||
std::vector<uf::Entity*> entities;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity || entity->getName() != "Light" ) return;
|
||||
entities.push_back(entity);
|
||||
};
|
||||
for ( uf::Scene* scene : ext::vulkan::scenes ) { if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
}
|
||||
{
|
||||
const pod::Vector3& position = controller.getComponent<pod::Transform<>>().position;
|
||||
std::sort( entities.begin(), entities.end(), [&]( const uf::Entity* l, const uf::Entity* r ){
|
||||
if ( !l ) return false; if ( !r ) return true;
|
||||
if ( !l->hasComponent<pod::Transform<>>() ) return false; if ( !r->hasComponent<pod::Transform<>>() ) return true;
|
||||
return uf::vector::magnitude( uf::vector::subtract( l->getComponent<pod::Transform<>>().position, position ) ) < uf::vector::magnitude( uf::vector::subtract( r->getComponent<pod::Transform<>>().position, position ) );
|
||||
} );
|
||||
}
|
||||
|
||||
{
|
||||
uf::Serializer& metadata = controller.getComponent<uf::Serializer>();
|
||||
if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller);
|
||||
}
|
||||
UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)];
|
||||
for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) {
|
||||
UniformDescriptor::Light& light = lights[i];
|
||||
light.position = { 0, 0, 0, 0 };
|
||||
light.color = { 0, 0, 0, 0 };
|
||||
light.type = { 0, 0 };
|
||||
}
|
||||
|
||||
blitter.material.textures.clear();
|
||||
|
||||
for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) {
|
||||
UniformDescriptor::Light& light = lights[i];
|
||||
uf::Entity* entity = entities[i];
|
||||
|
||||
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
|
||||
uf::Serializer& metadata = entity->getComponent<uf::Serializer>();
|
||||
uf::Camera& camera = entity->getComponent<uf::Camera>();
|
||||
|
||||
light.position.x = transform.position.x;
|
||||
light.position.y = transform.position.y;
|
||||
light.position.z = transform.position.z;
|
||||
|
||||
light.view = camera.getView();
|
||||
light.projection = camera.getProjection();
|
||||
|
||||
if ( entity == &controller ) light.position.y += 2;
|
||||
|
||||
light.position.w = metadata["light"]["radius"].asFloat();
|
||||
|
||||
light.color.x = metadata["light"]["color"][0].asFloat();
|
||||
light.color.y = metadata["light"]["color"][1].asFloat();
|
||||
light.color.z = metadata["light"]["color"][2].asFloat();
|
||||
|
||||
light.color.w = metadata["light"]["power"].asFloat();
|
||||
|
||||
light.type.x = metadata["light"]["type"].asUInt64();
|
||||
light.type.y = metadata["light"]["shadows"]["enabled"].asBool();
|
||||
|
||||
if ( !hasCompute && entity->hasComponent<ext::vulkan::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<ext::vulkan::RenderTargetRenderMode>();
|
||||
auto& renderTarget = renderMode.renderTarget;
|
||||
|
||||
uint8_t i = 0;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
// if ( !(attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
// if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
if ( (attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) ) continue;
|
||||
auto& texture = blitter.material.textures.emplace_back();
|
||||
texture.aliasAttachment(attachment);
|
||||
light.type.y = true;
|
||||
// break;
|
||||
}
|
||||
} else {
|
||||
light.type.y = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
blitter.getPipeline().update( blitter );
|
||||
shader->updateBuffer( (void*) buffer, len, 0, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void uf::Scene::render() {
|
||||
uf::Object::render();
|
||||
@ -188,32 +21,21 @@ void uf::Scene::destroy() {
|
||||
uf::Object::destroy();
|
||||
|
||||
{
|
||||
auto it = std::find(ext::vulkan::scenes.begin(), ext::vulkan::scenes.end(), this);
|
||||
if ( it != ext::vulkan::scenes.end() ) {
|
||||
ext::vulkan::scenes.erase(it);
|
||||
}
|
||||
auto it = std::find(uf::renderer::scenes.begin(), uf::renderer::scenes.end(), this);
|
||||
if ( it != uf::renderer::scenes.end() ) uf::renderer::scenes.erase(it);
|
||||
uf::renderer::rebuild = true;
|
||||
}
|
||||
ext::vulkan::rebuild = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
uf::Entity* uf::Scene::getController() {
|
||||
return this->findByName("Player");
|
||||
}
|
||||
const uf::Entity* uf::Scene::getController() const {
|
||||
return this->findByName("Player");
|
||||
}
|
||||
*/
|
||||
uf::Entity* uf::Scene::getController() {
|
||||
uf::Entity& uf::Scene::getController() {
|
||||
static uf::Entity* cachedController = NULL;
|
||||
if ( ext::vulkan::currentRenderMode ) {
|
||||
static ext::vulkan::RenderMode* cachedRenderMode = NULL;
|
||||
auto& renderMode = *ext::vulkan::currentRenderMode;
|
||||
if ( uf::renderer::currentRenderMode ) {
|
||||
static uf::renderer::RenderMode* cachedRenderMode = NULL;
|
||||
auto& renderMode = *uf::renderer::currentRenderMode;
|
||||
|
||||
if ( cachedRenderMode == &renderMode && cachedController && cachedController->getUid() > 0 ) {
|
||||
return cachedController;
|
||||
return *cachedController;
|
||||
}
|
||||
cachedController = NULL;
|
||||
cachedRenderMode = &renderMode;
|
||||
@ -221,34 +43,17 @@ uf::Entity* uf::Scene::getController() {
|
||||
if ( split.front() == "RT" ) {
|
||||
uint64_t uid = std::stoi( split.back() );
|
||||
uf::Entity* ent = this->findByUid( uid );
|
||||
if ( ent ) return cachedController = ent;
|
||||
if ( ent ) return *(cachedController = ent);
|
||||
}
|
||||
}
|
||||
if ( cachedController && cachedController->getUid() > 0 ) return cachedController;
|
||||
return cachedController = this->findByName("Player");
|
||||
if ( cachedController && cachedController->getUid() > 0 ) return *cachedController;
|
||||
cachedController = this->findByName("Player");
|
||||
return cachedController ? *cachedController : *this;
|
||||
// return this;
|
||||
}
|
||||
const uf::Entity* uf::Scene::getController() const {
|
||||
static const uf::Entity* cachedController = NULL;
|
||||
if ( ext::vulkan::currentRenderMode ) {
|
||||
static ext::vulkan::RenderMode* cachedRenderMode = NULL;
|
||||
auto& renderMode = *ext::vulkan::currentRenderMode;
|
||||
|
||||
if ( cachedRenderMode == &renderMode && cachedController && cachedController->getUid() > 0 ) {
|
||||
return cachedController;
|
||||
}
|
||||
cachedController = NULL;
|
||||
cachedRenderMode = &renderMode;
|
||||
auto split = uf::string::split( renderMode.name, ":" );
|
||||
if ( split.front() == "RT" ) {
|
||||
uint64_t uid = std::stoi( split.back() );
|
||||
const uf::Entity* ent = this->findByUid( uid );
|
||||
if ( ent ) return cachedController = ent;
|
||||
}
|
||||
}
|
||||
if ( cachedController && cachedController->getUid() > 0 ) return cachedController;
|
||||
return cachedController = this->findByName("Player");
|
||||
// return this;
|
||||
const uf::Entity& uf::Scene::getController() const {
|
||||
uf::Scene& scene = *const_cast<uf::Scene*>(this);
|
||||
return scene.getController();
|
||||
}
|
||||
#include <regex>
|
||||
std::vector<uf::Scene*> uf::scene::scenes;
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#define DEBUG_MARKER 0
|
||||
|
||||
vr::IVRSystem* ext::openvr::context;
|
||||
ext::openvr::Driver ext::openvr::driver;
|
||||
uint8_t ext::openvr::renderPass = 0;
|
||||
@ -163,14 +165,14 @@ bool ext::openvr::initialize( int stage ) {
|
||||
uf::Serializer manifest;
|
||||
manifest.readFromFile(ext::openvr::driver.manifest);
|
||||
|
||||
std::cout << ext::openvr::driver.manifest << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << ext::openvr::driver.manifest << std::endl;
|
||||
for ( auto i = 0; i < manifest["action_sets"].size(); ++i ) {
|
||||
std::cout << manifest["action_sets"][i] << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << manifest["action_sets"][i] << std::endl;
|
||||
std::string name = manifest["action_sets"][i]["name"].asString();
|
||||
vr::VRActionSetHandle_t handle;
|
||||
VR_CHECK_INPUT_RESULT( vr::VRInput()->GetActionSetHandle( name.c_str(), &handle ) );
|
||||
handles.actionSets[name] = handle;
|
||||
std::cout << "Registered action set: " << name << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << "Registered action set: " << name << std::endl;
|
||||
// handles.actionSets.push_back(handle);
|
||||
}
|
||||
for ( auto i = 0; i < manifest["actions"].size(); ++i ) {
|
||||
@ -178,7 +180,7 @@ bool ext::openvr::initialize( int stage ) {
|
||||
vr::VRActionHandle_t handle;
|
||||
VR_CHECK_INPUT_RESULT( vr::VRInput()->GetActionHandle( name.c_str(), &handle ) );
|
||||
handles.actions[name] = handle;
|
||||
std::cout << "Registered action: " << name << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << "Registered action: " << name << std::endl;
|
||||
// handles.actions.push_back(handle);
|
||||
|
||||
// add haptics to hooks
|
||||
@ -187,7 +189,7 @@ bool ext::openvr::initialize( int stage ) {
|
||||
std::string shortname = split.back();
|
||||
split = uf::string::split( shortname, "." );
|
||||
if ( split.front() == "hapticVibration" ) {
|
||||
std::cout << "Registered hook for haptic: " << ("VR:Haptics."+split.back()) << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << "Registered hook for haptic: " << ("VR:Haptics."+split.back()) << std::endl;
|
||||
uf::hooks.addHook( "VR:Haptics."+split.back(), [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
if ( vr::VRInputError_None != vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ) )
|
||||
@ -234,7 +236,7 @@ void ext::openvr::tick() {
|
||||
if ( !ext::openvr::context ) return;
|
||||
|
||||
// load render model from api
|
||||
for ( auto pair : ::queuedRenderModels ) {
|
||||
for ( auto& pair : ::queuedRenderModels ) {
|
||||
std::string name = pair.first;
|
||||
auto& queued = pair.second;
|
||||
{
|
||||
@ -243,7 +245,7 @@ void ext::openvr::tick() {
|
||||
if ( status == vr::VRRenderModelError_Loading ) continue;
|
||||
// error'd out
|
||||
if ( status != vr::VRRenderModelError_None ) {
|
||||
std::cout << "Failed to load render model " << name << ": " << vr::VRRenderModels()->GetRenderModelErrorNameFromEnum( status ) << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << "Failed to load render model " << name << ": " << vr::VRRenderModels()->GetRenderModelErrorNameFromEnum( status ) << std::endl;
|
||||
::queuedRenderModels.erase(name);
|
||||
continue;
|
||||
}
|
||||
@ -255,7 +257,7 @@ void ext::openvr::tick() {
|
||||
if ( status == vr::VRRenderModelError_Loading ) continue;
|
||||
// error'd out
|
||||
if ( status != vr::VRRenderModelError_None ) {
|
||||
std::cout << "Failed to load render model " << name << "'s texture: " << vr::VRRenderModels()->GetRenderModelErrorNameFromEnum( status ) << std::endl;
|
||||
if ( DEBUG_MARKER ) std::cout << "Failed to load render model " << name << "'s texture: " << vr::VRRenderModels()->GetRenderModelErrorNameFromEnum( status ) << std::endl;
|
||||
vr::VRRenderModels()->FreeRenderModel( queued.model );
|
||||
::queuedRenderModels.erase(name);
|
||||
continue;
|
||||
@ -430,6 +432,7 @@ void ext::openvr::tick() {
|
||||
}
|
||||
}
|
||||
bool ext::openvr::requestRenderModel( const std::string& name ) {
|
||||
if ( DEBUG_MARKER ) std::cout << "Requesting render model: " << name << std::endl;
|
||||
if ( std::find( renderModelNames.begin(), renderModelNames.end(), name ) == renderModelNames.end() ) return false;
|
||||
if ( renderModels.count(name) == 1 ) return true;
|
||||
::queuedRenderModels[name];
|
||||
@ -466,12 +469,12 @@ void ext::openvr::submit() { bool invert = swapEyes;
|
||||
|
||||
vulkanData.m_nFormat = leftOutputAttachment.format;
|
||||
vulkanData.m_nImage = (uint64_t) (VkImage) leftOutputAttachment.image;
|
||||
// std::cout << leftOutputAttachment.image << std::endl;
|
||||
// if ( DEBUG_MARKER ) std::cout << leftOutputAttachment.image << std::endl;
|
||||
vr::VRCompositor()->Submit( invert ? vr::Eye_Right : vr::Eye_Left, &texture, &bounds );
|
||||
|
||||
vulkanData.m_nFormat = rightOutputAttachment.format;
|
||||
vulkanData.m_nImage = (uint64_t) (VkImage) rightOutputAttachment.image;
|
||||
// std::cout << rightOutputAttachment.image << std::endl;
|
||||
// if ( DEBUG_MARKER ) std::cout << rightOutputAttachment.image << std::endl;
|
||||
vr::VRCompositor()->Submit( invert ? vr::Eye_Left : vr::Eye_Right, &texture, &bounds );
|
||||
|
||||
vr::VRCompositor()->PostPresentHandoff();
|
||||
@ -557,7 +560,7 @@ pod::Matrix4t<> ext::openvr::hmdProjectionMatrix( vr::Hmd_Eye eye, float zNear,
|
||||
frustum.bottom = abs( frustum.bottom );
|
||||
} else {
|
||||
}
|
||||
// std::cout << frustum.left << "\t" << frustum.right << "\t" << frustum.top << "\t" << frustum.bottom << std::endl;
|
||||
// if ( DEBUG_MARKER ) std::cout << frustum.left << "\t" << frustum.right << "\t" << frustum.top << "\t" << frustum.bottom << std::endl;
|
||||
|
||||
/*
|
||||
float fov = this->m_settings.perspective.fov * (3.14159265358f / 180.0f);
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
|
||||
namespace {
|
||||
void VRExtensions( std::vector<std::string>& requested ) {
|
||||
void VRInstanceExtensions( std::vector<std::string>& requested ) {
|
||||
if ( !vr::VRCompositor() ) return;
|
||||
uint32_t nBufferSize = vr::VRCompositor()->GetVulkanInstanceExtensionsRequired( nullptr, 0 );
|
||||
if ( nBufferSize < 0 ) return;
|
||||
@ -19,8 +19,45 @@ namespace {
|
||||
pExtensionStr[0] = 0;
|
||||
vr::VRCompositor()->GetVulkanInstanceExtensionsRequired( pExtensionStr, nBufferSize );
|
||||
std::vector<std::string> extensions = uf::string::split( pExtensionStr, " " );
|
||||
requested.insert( requested.end(), extensions.begin(), extensions.end() );
|
||||
for ( auto& str : extensions ) {
|
||||
// std::cout << str << std::endl;
|
||||
requested.push_back(str);
|
||||
}
|
||||
// requested.insert( requested.end(), extensions.begin(), extensions.end() );
|
||||
}
|
||||
void VRDeviceExtensions( VkPhysicalDevice_T* physicalDevice, std::vector<std::string>& requested ) {
|
||||
if ( !vr::VRCompositor() ) return;
|
||||
uint32_t nBufferSize = vr::VRCompositor()->GetVulkanDeviceExtensionsRequired( physicalDevice, nullptr, 0 );
|
||||
if ( nBufferSize < 0 ) return;
|
||||
char pExtensionStr[nBufferSize];
|
||||
pExtensionStr[0] = 0;
|
||||
vr::VRCompositor()->GetVulkanDeviceExtensionsRequired( physicalDevice , pExtensionStr, nBufferSize );
|
||||
std::vector<std::string> extensions = uf::string::split( pExtensionStr, " " );
|
||||
for ( auto& str : extensions ) requested.push_back(str);
|
||||
// requested.insert( requested.end(), extensions.begin(), extensions.end() );
|
||||
}
|
||||
|
||||
void validateRequestedExtensions( const std::vector<VkExtensionProperties>& extensionProperties, const std::vector<std::string>& requestedExtensions, std::vector<std::string>& supportedExtensions ) {
|
||||
for ( auto& requestedExtension : requestedExtensions ) {
|
||||
bool found = false;
|
||||
for ( auto& extensionProperty : extensionProperties ) {
|
||||
std::string extensionName = extensionProperty.extensionName;
|
||||
if ( requestedExtension != extensionName ) continue;
|
||||
if ( std::find( supportedExtensions.begin(), supportedExtensions.end(), extensionName ) != supportedExtensions.end() ) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if ( found ) break;
|
||||
found = true;
|
||||
supportedExtensions.push_back( extensionName );
|
||||
break;
|
||||
}
|
||||
if ( !found ) {
|
||||
std::cout << "Vulkan missing requested extension: " << requestedExtension << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void enableRequestedDeviceFeatures( ext::vulkan::Device& device ) {
|
||||
uf::Serializer json;
|
||||
|
||||
@ -410,44 +447,29 @@ void ext::vulkan::Device::initialize() {
|
||||
// Load any requested extensions
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::requestedInstanceExtensions.begin(), ext::vulkan::requestedInstanceExtensions.end() );
|
||||
// OpenVR Support
|
||||
if ( ext::openvr::enabled ) VRExtensions(requestedExtensions);
|
||||
if ( ext::openvr::enabled ) VRInstanceExtensions(requestedExtensions);
|
||||
|
||||
{
|
||||
if ( ext::vulkan::validation )
|
||||
for ( auto ext : requestedExtensions ) std::cout << "Requested extension: " << ext << std::endl;
|
||||
for ( auto ext : requestedExtensions )
|
||||
std::cout << "Requested instance extension: " << ext << std::endl;
|
||||
|
||||
uint32_t extensionsCount = 0;
|
||||
uint32_t enabledExtensionsCount = 0;
|
||||
|
||||
VK_CHECK_RESULT(vkEnumerateInstanceExtensionProperties( NULL, &extensionsCount, NULL ));
|
||||
extensionProperties.instance.resize(extensionsCount);
|
||||
VK_CHECK_RESULT( vkEnumerateInstanceExtensionProperties( NULL, &extensionsCount, extensionProperties.instance.data() ) );
|
||||
|
||||
std::vector<VkExtensionProperties> extensionProperties(extensionsCount);
|
||||
VK_CHECK_RESULT( vkEnumerateInstanceExtensionProperties( NULL, &extensionsCount, &extensionProperties[0] ) );
|
||||
|
||||
for ( size_t i = 0; i < requestedExtensions.size(); ++i ) {
|
||||
bool found = false; uint32_t index = 0;
|
||||
for ( index = 0; index < extensionsCount; index++ ) {
|
||||
if ( strcmp( requestedExtensions[i].c_str(), extensionProperties[index].extensionName ) == 0 ) {
|
||||
for ( auto& alreadyAdded : supportedExtensions ) {
|
||||
if ( requestedExtensions[i] == alreadyAdded ) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( found ) break;
|
||||
found = true;
|
||||
supportedExtensions.push_back(extensionProperties[index].extensionName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !found ) std::cout << "Vulkan missing requested extension " << requestedExtensions[index] << std::endl;
|
||||
}
|
||||
validateRequestedExtensions( extensionProperties.instance, requestedExtensions, supportedExtensions.instance );
|
||||
}
|
||||
// Create instance
|
||||
{
|
||||
std::vector<const char*> extensions;
|
||||
for ( auto& s : supportedExtensions ) {
|
||||
if ( ext::vulkan::validation ) std::cout << "Enabled extension: " << s << std::endl;
|
||||
extensions.push_back( s.c_str() );
|
||||
std::vector<const char*> instanceExtensions;
|
||||
for ( auto& s : supportedExtensions.instance ) {
|
||||
if ( ext::vulkan::validation )
|
||||
std::cout << "Enabled instance extension: " << s << std::endl;
|
||||
instanceExtensions.push_back( s.c_str() );
|
||||
}
|
||||
|
||||
VkApplicationInfo appInfo = {};
|
||||
@ -462,8 +484,8 @@ void ext::vulkan::Device::initialize() {
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
createInfo.pApplicationInfo = &appInfo;
|
||||
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||
createInfo.ppEnabledExtensionNames = extensions.data();
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(instanceExtensions.size());
|
||||
createInfo.ppEnabledExtensionNames = instanceExtensions.data();
|
||||
|
||||
if ( ext::vulkan::validation ) {
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
||||
@ -536,45 +558,31 @@ void ext::vulkan::Device::initialize() {
|
||||
bool useSwapChain = true;
|
||||
VkQueueFlags requestedQueueTypes = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT;
|
||||
std::vector<std::string> requestedExtensions;
|
||||
std::vector<const char*> deviceExtensions = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::requestedInstanceExtensions.begin(), ext::vulkan::requestedInstanceExtensions.end() );
|
||||
/* OpenVR support */ if ( ext::openvr::enabled && vr::VRCompositor() ) {
|
||||
uint32_t nBufferSize = vr::VRCompositor()->GetVulkanDeviceExtensionsRequired( ( VkPhysicalDevice_T * ) this->physicalDevice, nullptr, 0 );
|
||||
if ( nBufferSize > 0 ) {
|
||||
char pExtensionStr[nBufferSize];
|
||||
pExtensionStr[0] = 0;
|
||||
vr::VRCompositor()->GetVulkanDeviceExtensionsRequired( ( VkPhysicalDevice_T * ) this->physicalDevice, pExtensionStr, nBufferSize );
|
||||
std::vector<std::string> vrExtensions = uf::string::split( pExtensionStr, " " );
|
||||
requestedExtensions.insert( requestedExtensions.end(), vrExtensions.begin(), vrExtensions.end() );
|
||||
}
|
||||
requestedExtensions.insert( requestedExtensions.end(), ext::vulkan::requestedDeviceExtensions.begin(), ext::vulkan::requestedDeviceExtensions.end() );
|
||||
// OpenVR Support
|
||||
if ( ext::openvr::enabled ) {
|
||||
VRDeviceExtensions( this->physicalDevice, requestedExtensions);
|
||||
}
|
||||
{
|
||||
// Allocate enough ExtensionProperties to support all extensions being enabled
|
||||
if ( ext::vulkan::validation )
|
||||
for ( auto ext : requestedExtensions ) std::cout << "Requested device extension: " << ext << std::endl;
|
||||
|
||||
uint32_t extensionsCount = 0;
|
||||
uint32_t enabledExtensionsCount = 0;
|
||||
|
||||
VK_CHECK_RESULT(vkEnumerateDeviceExtensionProperties( this->physicalDevice, NULL, &extensionsCount, NULL ));
|
||||
std::vector<VkExtensionProperties> extensionProperties(extensionsCount);
|
||||
VK_CHECK_RESULT( vkEnumerateDeviceExtensionProperties( this->physicalDevice, NULL, &extensionsCount, &extensionProperties[0] ) );
|
||||
extensionProperties.device.resize( extensionsCount );
|
||||
VK_CHECK_RESULT( vkEnumerateDeviceExtensionProperties( this->physicalDevice, NULL, &extensionsCount, extensionProperties.device.data() ) );
|
||||
|
||||
for ( size_t i = 0; i < requestedExtensions.size(); ++i ) {
|
||||
bool found = false;
|
||||
uint32_t index = 0;
|
||||
for ( index = 0; index < extensionsCount; index++ ) {
|
||||
if ( strcmp( requestedExtensions[i].c_str(), extensionProperties[index].extensionName ) == 0 ) {
|
||||
for ( auto alreadyAdded : deviceExtensions ) {
|
||||
if ( strcmp( requestedExtensions[i].c_str(), alreadyAdded ) == 0 ) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( found ) break;
|
||||
found = true;
|
||||
deviceExtensions.push_back(extensionProperties[index].extensionName);
|
||||
}
|
||||
}
|
||||
if ( !found ) std::cout << "Vulkan missing requested extension " << requestedExtensions[index] << std::endl;
|
||||
}
|
||||
validateRequestedExtensions( extensionProperties.device, requestedExtensions, supportedExtensions.device );
|
||||
}
|
||||
std::vector<const char*> deviceExtensions = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
for ( auto& s : supportedExtensions.device ) {
|
||||
if ( ext::vulkan::validation ) std::cout << "Enabled device extension: " << s << std::endl;
|
||||
deviceExtensions.push_back( s.c_str() );
|
||||
}
|
||||
|
||||
// Desired queues need to be requested upon logical device creation
|
||||
|
||||
@ -426,9 +426,42 @@ void ext::vulkan::Pipeline::record( Graphic& graphic, VkCommandBuffer commandBuf
|
||||
}
|
||||
size_t offset = 0;
|
||||
for ( auto& pushConstant : shader.pushConstants ) {
|
||||
size_t len = 0;
|
||||
void* pointer = NULL;
|
||||
if ( bindPoint == VK_PIPELINE_BIND_POINT_COMPUTE ) {
|
||||
len = pushConstant.data().len;
|
||||
pointer = pushConstant.data().data;
|
||||
} else {
|
||||
struct Stereo {
|
||||
uint32_t pass;
|
||||
};
|
||||
static Stereo stereo;
|
||||
stereo.pass = ext::openvr::renderPass;
|
||||
|
||||
len = sizeof(stereo);
|
||||
pointer = &stereo;
|
||||
}
|
||||
if ( len > 0 && pointer )
|
||||
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, 0, len, pointer );
|
||||
/*
|
||||
size_t len = pushConstant.data().len;
|
||||
void* pointer = pushConstant.data().data;
|
||||
std::cout << pointer << ": " << len << std::endl;
|
||||
if ( len == 4 ) {
|
||||
struct Stereo {
|
||||
uint32_t pass;
|
||||
};
|
||||
auto& stereo = pushConstant.get<Stereo>();
|
||||
std::cout << pointer << ": Got " << stereo.pass << std::endl;
|
||||
}
|
||||
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, 0, len, pointer );
|
||||
*/
|
||||
/*
|
||||
struct PushConstant {
|
||||
uint32_t pass;
|
||||
} p = { ext::openvr::renderPass };
|
||||
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, 0, sizeof(p), &p );
|
||||
*/
|
||||
/*
|
||||
pod::Userdata& userdata = pushConstant.data();
|
||||
{
|
||||
@ -437,7 +470,6 @@ void ext::vulkan::Pipeline::record( Graphic& graphic, VkCommandBuffer commandBuf
|
||||
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, offset, userdata.len, userdata.data );
|
||||
offset += userdata.len;
|
||||
*/
|
||||
vkCmdPushConstants( commandBuffer, pipelineLayout, shader.descriptor.stage, 0, sizeof(p), &p );
|
||||
}
|
||||
}
|
||||
// Bind descriptor sets describing shader binding points
|
||||
|
||||
@ -237,21 +237,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
// transition layers for read
|
||||
for ( auto layer : layers ) {
|
||||
layer->pipelineBarrier( commands[i], 0 );
|
||||
/*
|
||||
if ( layer->getName() == "" ) continue;
|
||||
RenderTarget& renderTarget = layer->renderTarget;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.oldLayout = attachment.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
attachment.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
@ -260,6 +245,20 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
for ( auto graphic : graphics ) {
|
||||
// only draw graphics that are assigned to this type of render mode
|
||||
if ( graphic->descriptor.renderMode != this->getName() ) continue;
|
||||
// update push constants
|
||||
/*
|
||||
auto& shaders = graphic->material.shaders;
|
||||
for ( auto& shader : shaders ) {
|
||||
for ( auto& pushConstant : shader.pushConstants ) {
|
||||
struct Stereo {
|
||||
uint32_t pass;
|
||||
};
|
||||
auto& stereo = pushConstant.get<Stereo>();
|
||||
stereo.pass = ext::openvr::renderPass;
|
||||
std::cout << pushConstant.data().data << ": Expecting " << stereo.pass << std::endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
graphic->record(commands[i] );
|
||||
}
|
||||
// render gui layer
|
||||
@ -290,21 +289,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
|
||||
for ( auto layer : layers ) {
|
||||
layer->pipelineBarrier( commands[i], 1 );
|
||||
/*
|
||||
if ( layer->getName() == "" ) continue;
|
||||
RenderTarget& renderTarget = layer->renderTarget;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
|
||||
if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = attachment.layout;
|
||||
imageMemoryBarrier.newLayout = attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
attachment.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
// Blit eye to swapchain
|
||||
|
||||
@ -177,6 +177,7 @@ ext::vulkan::RenderMode& ext::vulkan::addRenderMode( ext::vulkan::RenderMode* mo
|
||||
renderModes.push_back(mode);
|
||||
std::cout << "Adding RenderMode: " << name << ": " << mode->getType() << std::endl;
|
||||
// reorder
|
||||
ext::vulkan::rebuild = true;
|
||||
return *mode;
|
||||
}
|
||||
ext::vulkan::RenderMode& ext::vulkan::getRenderMode( const std::string& name, bool isName ) {
|
||||
@ -216,6 +217,7 @@ void ext::vulkan::removeRenderMode( ext::vulkan::RenderMode* mode, bool free ) {
|
||||
renderModes.erase( std::remove( renderModes.begin(), renderModes.end(), mode ), renderModes.end() );
|
||||
mode->destroy();
|
||||
if ( free ) delete mode;
|
||||
ext::vulkan::rebuild = true;
|
||||
}
|
||||
|
||||
void ext::vulkan::initialize( uint8_t stage ) {
|
||||
@ -292,7 +294,10 @@ void ext::vulkan::tick() {
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode->device ) renderMode->initialize(ext::vulkan::device);
|
||||
if ( !renderMode->device ) {
|
||||
renderMode->initialize(ext::vulkan::device);
|
||||
ext::vulkan::rebuild = true;
|
||||
}
|
||||
renderMode->tick();
|
||||
}
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
|
||||
@ -23,7 +23,7 @@ uf::Camera::Camera() :
|
||||
this->setProjection(uf::matrix::identity());
|
||||
|
||||
this->m_transform = uf::transform::initialize(this->m_transform);
|
||||
this->m_transform.position = {0,1.725,0};
|
||||
this->m_transform.position = {0, 0, 0};
|
||||
}
|
||||
/*
|
||||
uf::Camera::Camera( const pod::Math::num_t& fov, const pod::Vector2& size, const pod::Vector2& bounds, const pod::Vector3& offset, const pod::Vector2& tops ) :
|
||||
|
||||
@ -43,8 +43,7 @@ std::string uf::MemoryPool::stats() const {
|
||||
metadata["free"] = size - allocated;
|
||||
metadata["objects"] = this->m_allocations.size();
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << (void*) this->m_pool;
|
||||
std::stringstream ss; ss << std::hex << (void*) this->m_pool;
|
||||
metadata["pool"] = ss.str();
|
||||
}
|
||||
|
||||
@ -53,20 +52,16 @@ std::string uf::MemoryPool::stats() const {
|
||||
void uf::MemoryPool::initialize( size_t size ) {
|
||||
if ( size <= 0 ) return;
|
||||
if ( this->size() > 0 ) this->destroy();
|
||||
// this->m_pool = (uint8_t*) malloc( size );
|
||||
// this->m_allocations.reserve( 128 );
|
||||
this->m_size = size;
|
||||
if ( uf::MemoryPool::subPool && uf::MemoryPool::global.size() > 0 && this != &uf::MemoryPool::global ) {
|
||||
this->m_pool = (uint8_t*) uf::MemoryPool::global.alloc( NULL, size );
|
||||
} else {
|
||||
this->m_pool = (uint8_t*) malloc( size );
|
||||
}
|
||||
// this->m_pool = (uint8_t*) operator new( size );
|
||||
memset( this->m_pool, 0, size );
|
||||
}
|
||||
void uf::MemoryPool::destroy() {
|
||||
if ( this->size() <= 0 ) return;
|
||||
// ::free(this->m_pool);
|
||||
if ( uf::MemoryPool::subPool && this != &uf::MemoryPool::global ) {
|
||||
uf::MemoryPool::global.free( this->m_pool );
|
||||
} else {
|
||||
@ -79,32 +74,87 @@ void uf::MemoryPool::destroy() {
|
||||
pod::Allocation uf::MemoryPool::allocate( void* data, size_t size ) {
|
||||
if ( UF_MEMORYPOOL_MUTEX ) this->m_mutex.lock();
|
||||
// find next available allocation
|
||||
// RLE-esque
|
||||
size_t index = 0;
|
||||
size_t len = this->size();
|
||||
pod::Allocation allocation;
|
||||
// pool not initialized
|
||||
if ( len <= 0 ) {
|
||||
if ( DEBUG_PRINT ) std::cout << "CANNOT MALLOC: " << size << ", POOL NOT INITIALIZED" << std::endl;
|
||||
goto MANUAL_MALLOC;
|
||||
}
|
||||
// find any availble spots in-between existing allocations
|
||||
|
||||
// an optimization by quickly reusing free'd allocations seemed like a good idea
|
||||
// but still have to iterate through allocation information
|
||||
// to keep allocation information in order
|
||||
|
||||
// check our cache of first
|
||||
#if UF_MEMORYPOOL_CACHED_ALLOCATIONS
|
||||
if ( !this->m_cachedFreeAllocations.empty() ) {
|
||||
auto it = this->m_cachedFreeAllocations.begin();
|
||||
// check if any recently free'd allocation is big enough for our new allocation
|
||||
for ( ; it != this->m_cachedFreeAllocations.end(); ++it ) {
|
||||
if ( it->size < size ) break;
|
||||
}
|
||||
// found a suitable allocation, use it
|
||||
if ( it != this->m_cachedFreeAllocations.end() ) {
|
||||
index = it->index;
|
||||
// find where to insert in our allocation table
|
||||
auto next = this->m_allocations.begin();
|
||||
while ( next != this->m_allocations.end() ) {
|
||||
if ( index + size < next->index ) break;
|
||||
++next;
|
||||
}
|
||||
// check if it was actually valid
|
||||
if ( next != this->m_allocations.end() ) {
|
||||
// initialize allocation info
|
||||
allocation.index = index;
|
||||
allocation.size = size;
|
||||
allocation.pointer = &this->m_pool[0] + index;
|
||||
|
||||
// security
|
||||
if ( data ) memcpy( allocation.pointer, data, size );
|
||||
else memset( allocation.pointer, 0, size );
|
||||
|
||||
// overrides if we're overloading global new/delete
|
||||
IGNORE_GLOBAL_MEMORYPOOL = true;
|
||||
// register as allocated
|
||||
this->m_allocations.insert(next, allocation);
|
||||
IGNORE_GLOBAL_MEMORYPOOL = false;
|
||||
|
||||
goto RETURN;
|
||||
}
|
||||
// remove from cache
|
||||
this->m_cachedFreeAllocations.erase(it);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// find any availble spots in-between existing allocations
|
||||
auto next = this->m_allocations.begin();
|
||||
for ( auto it = next; it != this->m_allocations.end(); ++it ) {
|
||||
index = it->index + it->size;
|
||||
if ( ++next == this->m_allocations.end() ) break;
|
||||
// target index is behind next allocated space, use it
|
||||
if ( index < next->index ) break;
|
||||
}
|
||||
// no allocation found, OOM
|
||||
if ( index + size > len ) {
|
||||
std::cout << "MemoryPool: " << this << ": Out of Memory!" << std::endl;
|
||||
goto MANUAL_MALLOC;
|
||||
}
|
||||
|
||||
// initialize allocation info
|
||||
allocation.index = index;
|
||||
allocation.size = size;
|
||||
allocation.pointer = &this->m_pool[0] + index;
|
||||
|
||||
// security
|
||||
if ( data ) memcpy( allocation.pointer, data, size );
|
||||
else memset( allocation.pointer, 0, size );
|
||||
|
||||
// overrides if we're overloading global new/delete
|
||||
IGNORE_GLOBAL_MEMORYPOOL = true;
|
||||
// register as allocated
|
||||
this->m_allocations.insert(next, allocation);
|
||||
IGNORE_GLOBAL_MEMORYPOOL = false;
|
||||
}
|
||||
@ -149,31 +199,40 @@ bool uf::MemoryPool::exists( void* pointer, size_t size ) {
|
||||
}
|
||||
bool uf::MemoryPool::free( void* pointer, size_t size ) {
|
||||
if ( UF_MEMORYPOOL_MUTEX ) this->m_mutex.lock();
|
||||
// fail if uninitialized or pointer is outside of our pool
|
||||
if ( this->m_size <= 0 || pointer < &this->m_pool[0] || pointer >= &this->m_pool[0] + this->m_size ) {
|
||||
if ( DEBUG_PRINT ) std::cout << "CANNOT FREE: " << pointer << ", ERROR: " << (this->m_size <= 0) << " " << (pointer < &this->m_pool[0]) << " " << (pointer >= &this->m_pool[0] + this->m_size) << std::endl;
|
||||
goto MANUAL_FREE;
|
||||
}
|
||||
{
|
||||
// pointer arithmatic
|
||||
size_t index = (uint8_t*) pointer - &this->m_pool[0];
|
||||
auto it = this->m_allocations.begin();
|
||||
pod::Allocation allocation;
|
||||
// find our allocation in the allocation pool
|
||||
for ( ; it != this->m_allocations.end(); ++it ) {
|
||||
if ( it->index == index ) {
|
||||
allocation = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if ( allocation.index != index || (size > 0 && allocation.size != size) ) {
|
||||
// pointer isn't actually allocated
|
||||
if ( allocation.index != index ) {
|
||||
if ( DEBUG_PRINT ) std::cout << "CANNOT FREE: " << pointer << ", NOT FOUND" << std::endl;
|
||||
goto MANUAL_FREE;
|
||||
}
|
||||
// size validation mismatch, do not free
|
||||
if (size > 0 && allocation.size != size) {
|
||||
if ( DEBUG_PRINT ) std::cout << "CANNOT FREE: " << pointer << ", MISMATCHED SIZES (" << size << " != " << allocation.size << ")" << std::endl;
|
||||
goto MANUAL_FREE;
|
||||
}
|
||||
if ( DEBUG_PRINT ) std::cout << "FREE'D ALLOCATION: " << pointer << ", " << size << "\t" << allocation.pointer << ", " << allocation.size << ", " << allocation.index << std::endl;
|
||||
// remove from our allocation table...
|
||||
this->m_allocations.erase(it);
|
||||
// ...but add it to our free'd allocation cache
|
||||
#if UF_MEMORYPOOL_CACHED_ALLOCATIONS
|
||||
this->m_cachedFreeAllocations.push_back(allocation);
|
||||
#endif
|
||||
if ( UF_MEMORYPOOL_MUTEX ) this->m_mutex.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ void ext::Gui::initialize() {
|
||||
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& metadata = controller.getComponent<uf::Serializer>();
|
||||
|
||||
if ( metadata["overlay"]["cursor"]["type"].asString() == "mouse" ) {
|
||||
@ -816,7 +816,8 @@ void ext::Gui::render() {
|
||||
auto& scene = this->getRootParent<uf::Scene>();
|
||||
auto& mesh = this->getComponent<uf::GuiMesh>();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& camera = scene.getController()->getComponent<uf::Camera>();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
if ( !graphic.initialized ) return;
|
||||
|
||||
@ -892,7 +893,8 @@ void ext::Gui::render() {
|
||||
for ( std::size_t i = 0; i < 2; ++i ) {
|
||||
if ( metadata["text settings"]["world"].asBool() ) {
|
||||
auto& scene = this->getRootParent<uf::Scene>();
|
||||
auto& camera = scene.getController()->getComponent<uf::Camera>();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
|
||||
pod::Transform<> flatten = uf::transform::flatten( this->getComponent<pod::Transform<>>() );
|
||||
auto model = uf::transform::model( flatten );
|
||||
@ -965,7 +967,8 @@ void ext::Gui::render() {
|
||||
uniforms.matrices.model[i] = ::matrix * rotation;
|
||||
*/
|
||||
auto& scene = this->getRootParent<uf::Scene>();
|
||||
auto& camera = scene.getController()->getComponent<uf::Camera>();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
|
||||
pod::Transform<> flatten = uf::transform::flatten( this->getComponent<pod::Transform<>>() );
|
||||
auto model = uf::transform::model( flatten );
|
||||
@ -1018,7 +1021,7 @@ void ext::Gui::render() {
|
||||
{
|
||||
/* Update GUI panel */ {
|
||||
auto& scene = this->getRootParent<uf::Scene>();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto* renderMode = (uf::renderer::RenderTargetRenderMode*) &uf::renderer::getRenderMode("Gui");
|
||||
if ( renderMode->getName() == "Gui" ) {
|
||||
|
||||
@ -321,8 +321,8 @@ void EXT_API ext::tick() {
|
||||
if ( !timer.running() ) timer.start();
|
||||
if ( uf::Window::isKeyPressed("Z") && timer.elapsed().asDouble() >= 1 ) { timer.reset();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto* controller = scene.getController();
|
||||
auto& camera = controller->getComponent<uf::Camera>();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto& t = camera.getTransform(); //controller->getComponent<pod::Transform<>>();
|
||||
uf::iostream << "Viewport position: (" << t.position.x << ", " << t.position.y << ", " << t.position.z << ") (" << t.orientation.x << ", " << t.orientation.y << ", " << t.orientation.z << ", " << t.orientation.w << ")";
|
||||
uf::iostream << "\n";
|
||||
|
||||
377
ext/scenes/base.cpp
Normal file
377
ext/scenes/base.cpp
Normal file
@ -0,0 +1,377 @@
|
||||
#include "base.h"
|
||||
|
||||
#include <uf/utils/time/time.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
#include <uf/utils/math/transform.h>
|
||||
#include <uf/utils/window/window.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
|
||||
#include <uf/utils/audio/audio.h>
|
||||
#include <uf/utils/thread/thread.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
|
||||
#include <uf/engine/asset/asset.h>
|
||||
#include <uf/engine/asset/masterdata.h>
|
||||
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
|
||||
#include <uf/ext/gltf/gltf.h>
|
||||
|
||||
#include <uf/utils/math/collision.h>
|
||||
|
||||
#include "../ext.h"
|
||||
#include "../gui/gui.h"
|
||||
|
||||
void ext::Scene::initialize() {
|
||||
uf::Scene::initialize();
|
||||
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
|
||||
this->addHook( "system:Quit.%UID%", [&](const std::string& event)->std::string{
|
||||
std::cout << event << std::endl;
|
||||
ext::ready = false;
|
||||
return "true";
|
||||
});
|
||||
|
||||
this->addHook( "world:Music.LoadPrevious.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
if ( metadata["previous bgm"]["filename"] == "" ) return "false";
|
||||
|
||||
std::string filename = metadata["previous bgm"]["filename"].asString();
|
||||
float timestamp = metadata["previous bgm"]["timestamp"].asFloat();
|
||||
|
||||
// std::cout << metadata["previous bgm"] << std::endl;
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) {
|
||||
metadata["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadata["previous bgm"]["timestamp"] = audio.getTime();
|
||||
audio.stop();
|
||||
}
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
|
||||
audio.setTime(timestamp);
|
||||
audio.play();
|
||||
|
||||
return "true";
|
||||
});
|
||||
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::string filename = json["filename"].asString();
|
||||
|
||||
if ( uf::string::extension(filename) != "ogg" ) return "false";
|
||||
const uf::Audio* audioPointer = NULL;
|
||||
try { audioPointer = &assetLoader.get<uf::Audio>(filename); } catch ( ... ) {}
|
||||
if ( !audioPointer ) return "false";
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) audio.stop();
|
||||
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
|
||||
audio.play();
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
||||
this->addHook( "menu:Pause", [&](const std::string& event)->std::string{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
if ( timer.elapsed().asDouble() < 1 ) return "false";
|
||||
timer.reset();
|
||||
|
||||
uf::Serializer json = event;
|
||||
ext::Gui* manager = (ext::Gui*) this->findByName("Gui Manager");
|
||||
if ( !manager ) return "false";
|
||||
uf::Serializer payload;
|
||||
ext::Gui* gui = (ext::Gui*) manager->findByUid( (payload["uid"] = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() );
|
||||
uf::Serializer& metadata = gui->getComponent<uf::Serializer>();
|
||||
metadata["menu"] = json["menu"];
|
||||
gui->initialize();
|
||||
return payload;
|
||||
});
|
||||
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
std::string asset = json["asset"].asString();
|
||||
std::string uid = json["uid"].asString();
|
||||
|
||||
assetLoader.load(asset, "asset:Load." + uid);
|
||||
|
||||
return "true";
|
||||
});
|
||||
/* store viewport size */ {
|
||||
metadata["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["window"]["size"]["y"] = uf::renderer::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].asUInt64();
|
||||
size.y = json["window"]["size"]["y"].asUInt64();
|
||||
}
|
||||
|
||||
metadata["window"] = json["window"];
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
void ext::Scene::tick() {
|
||||
uf::Scene::tick();
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
/* check if audio needs to loop */ try {
|
||||
uf::Audio& bgm = this->getComponent<uf::Audio>();
|
||||
float current = bgm.getTime();
|
||||
float end = bgm.getDuration();
|
||||
float epsilon = 0.005f;
|
||||
if ( current + epsilon >= end || !bgm.playing() ) {
|
||||
// intro to main transition
|
||||
std::string filename = bgm.getFilename();
|
||||
filename = assetLoader.getOriginal(filename);
|
||||
if ( filename.find("_intro") != std::string::npos ) {
|
||||
assetLoader.load(uf::string::replace( filename, "_intro", "" ), "asset:Load." + std::to_string(this->getUid()));
|
||||
// loop
|
||||
} else {
|
||||
bgm.setTime(0);
|
||||
if ( !bgm.playing() ) bgm.play();
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {
|
||||
|
||||
}
|
||||
|
||||
/* Regain control if nothing requests it */ {
|
||||
ext::Gui* menu = (ext::Gui*) this->findByName("Gui: Menu");
|
||||
if ( !menu ) {
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Entity Information */ {
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
if ( uf::Window::isKeyPressed("U") && timer.elapsed().asDouble() >= 1 ) { timer.reset();
|
||||
auto& allocations = uf::Entity::memoryPool.allocations();
|
||||
uf::iostream << "Current size: " << allocations.size() << " | UIDs: " << uf::Entity::uids << "\n";
|
||||
uint orphans = 0;
|
||||
uint empty = 0;
|
||||
for ( auto& allocation : allocations ) {
|
||||
uf::Entity* e = (uf::Entity*) allocation.pointer;
|
||||
if ( !e->hasParent() ) {
|
||||
++orphans;
|
||||
uf::iostream << "Orphan: " << e->getName() << ": " << e << "\n";
|
||||
}
|
||||
}
|
||||
uf::iostream << "Orphans: " << orphans << "\n";
|
||||
uf::iostream << "Empty: " << empty << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Updates Sound Listener */ {
|
||||
auto& controller = this->getController();
|
||||
auto& transform = controller.getComponent<pod::Transform<>>();
|
||||
|
||||
ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } );
|
||||
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
|
||||
ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } );
|
||||
}
|
||||
|
||||
if ( uf::scene::getCurrentScene().getUid() == this->getUid() ) {
|
||||
/* Update lights */ if ( metadata["light"]["should"].asBool() ) {
|
||||
// if ( !uf::renderer::currentRenderMode || uf::renderer::currentRenderMode->name != "" ) return;
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
||||
std::vector<uf::Graphic*> blitters;
|
||||
auto& renderMode = uf::renderer::getRenderMode("", true);
|
||||
bool hasCompute = uf::renderer::hasRenderMode("C:RT:" + std::to_string(this->getUid()), true);
|
||||
if ( hasCompute ) {
|
||||
// auto& renderMode = uf::renderer::getRenderMode("C:RT:" + std::to_string(this->getUid()), true);
|
||||
// auto* renderModePointer = (uf::renderer::ComputeRenderMode*) &renderMode;
|
||||
// if ( renderModePointer->compute.initialized ) {
|
||||
// blitters.push_back(&renderModePointer->compute);
|
||||
// } else {
|
||||
// hasCompute = false;
|
||||
// }
|
||||
} else if ( renderMode.getType() == "Deferred (Stereoscopic)" ) {
|
||||
auto* renderModePointer = (uf::renderer::StereoscopicDeferredRenderMode*) &renderMode;
|
||||
blitters.push_back(&renderModePointer->blitters.left);
|
||||
blitters.push_back(&renderModePointer->blitters.right);
|
||||
} else if ( renderMode.getType() == "Deferred" ) {
|
||||
auto* renderModePointer = (uf::renderer::DeferredRenderMode*) &renderMode;
|
||||
blitters.push_back(&renderModePointer->blitter);
|
||||
}
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
|
||||
// auto& uniforms = blitter.uniforms;
|
||||
struct UniformDescriptor {
|
||||
struct Matrices {
|
||||
alignas(16) pod::Matrix4f view[2];
|
||||
alignas(16) pod::Matrix4f projection[2];
|
||||
} matrices;
|
||||
alignas(16) pod::Vector4f ambient;
|
||||
struct {
|
||||
alignas(8) pod::Vector2f range;
|
||||
alignas(16) pod::Vector4f color;
|
||||
} fog;
|
||||
struct Light {
|
||||
alignas(16) pod::Vector4f position;
|
||||
alignas(16) pod::Vector4f color;
|
||||
alignas(8) pod::Vector2i type;
|
||||
alignas(16) pod::Matrix4f view;
|
||||
alignas(16) pod::Matrix4f projection;
|
||||
} lights;
|
||||
};
|
||||
|
||||
struct SpecializationConstant {
|
||||
int32_t maxLights = 32;
|
||||
} specializationConstants;
|
||||
|
||||
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
|
||||
auto& blitter = *blitters[_];
|
||||
|
||||
uint8_t* buffer;
|
||||
size_t len;
|
||||
auto* shader = &blitter.material.shaders.front();
|
||||
|
||||
for ( auto& _ : blitter.material.shaders ) {
|
||||
if ( _.uniforms.empty() ) continue;
|
||||
auto& userdata = _.uniforms.front();
|
||||
buffer = (uint8_t*) (void*) userdata;
|
||||
len = userdata.data().len;
|
||||
shader = &_;
|
||||
specializationConstants = _.specializationConstants.get<SpecializationConstant>();
|
||||
}
|
||||
|
||||
if ( !buffer ) continue;
|
||||
|
||||
UniformDescriptor* uniforms = (UniformDescriptor*) buffer;
|
||||
for ( std::size_t i = 0; i < 2; ++i ) {
|
||||
uniforms->matrices.view[i] = camera.getView( i );
|
||||
uniforms->matrices.projection[i] = camera.getProjection( i );
|
||||
}
|
||||
{
|
||||
uniforms->ambient.x = metadata["light"]["ambient"][0].asFloat();
|
||||
uniforms->ambient.y = metadata["light"]["ambient"][1].asFloat();
|
||||
uniforms->ambient.z = metadata["light"]["ambient"][2].asFloat();
|
||||
uniforms->ambient.w = metadata["light"]["kexp"].asFloat();
|
||||
}
|
||||
{
|
||||
uniforms->fog.color.x = metadata["light"]["fog"]["color"][0].asFloat();
|
||||
uniforms->fog.color.y = metadata["light"]["fog"]["color"][1].asFloat();
|
||||
uniforms->fog.color.z = metadata["light"]["fog"]["color"][2].asFloat();
|
||||
|
||||
uniforms->fog.range.x = metadata["light"]["fog"]["range"][0].asFloat();
|
||||
uniforms->fog.range.y = metadata["light"]["fog"]["range"][1].asFloat();
|
||||
}
|
||||
{
|
||||
std::vector<uf::Entity*> entities;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity || entity->getName() != "Light" ) return;
|
||||
entities.push_back(entity);
|
||||
};
|
||||
for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
}
|
||||
{
|
||||
const pod::Vector3& position = controller.getComponent<pod::Transform<>>().position;
|
||||
std::sort( entities.begin(), entities.end(), [&]( const uf::Entity* l, const uf::Entity* r ){
|
||||
if ( !l ) return false; if ( !r ) return true;
|
||||
if ( !l->hasComponent<pod::Transform<>>() ) return false; if ( !r->hasComponent<pod::Transform<>>() ) return true;
|
||||
return uf::vector::magnitude( uf::vector::subtract( l->getComponent<pod::Transform<>>().position, position ) ) < uf::vector::magnitude( uf::vector::subtract( r->getComponent<pod::Transform<>>().position, position ) );
|
||||
} );
|
||||
}
|
||||
|
||||
{
|
||||
uf::Serializer& metadata = controller.getComponent<uf::Serializer>();
|
||||
if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller);
|
||||
}
|
||||
UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)];
|
||||
for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) {
|
||||
UniformDescriptor::Light& light = lights[i];
|
||||
light.position = { 0, 0, 0, 0 };
|
||||
light.color = { 0, 0, 0, 0 };
|
||||
light.type = { 0, 0 };
|
||||
}
|
||||
|
||||
blitter.material.textures.clear();
|
||||
|
||||
for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) {
|
||||
UniformDescriptor::Light& light = lights[i];
|
||||
uf::Entity* entity = entities[i];
|
||||
|
||||
pod::Transform<>& transform = entity->getComponent<pod::Transform<>>();
|
||||
uf::Serializer& metadata = entity->getComponent<uf::Serializer>();
|
||||
uf::Camera& camera = entity->getComponent<uf::Camera>();
|
||||
|
||||
light.position.x = transform.position.x;
|
||||
light.position.y = transform.position.y;
|
||||
light.position.z = transform.position.z;
|
||||
|
||||
light.view = camera.getView();
|
||||
light.projection = camera.getProjection();
|
||||
|
||||
if ( entity == &controller ) light.position.y += 2;
|
||||
|
||||
light.position.w = metadata["light"]["radius"][1].asFloat();
|
||||
|
||||
light.color.x = metadata["light"]["color"][0].asFloat();
|
||||
light.color.y = metadata["light"]["color"][1].asFloat();
|
||||
light.color.z = metadata["light"]["color"][2].asFloat();
|
||||
|
||||
light.color.w = metadata["light"]["power"].asFloat();
|
||||
|
||||
light.type.x = metadata["light"]["type"].asUInt64();
|
||||
light.type.y = metadata["light"]["shadows"]["enabled"].asBool();
|
||||
|
||||
if ( !hasCompute && entity->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = entity->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
auto& renderTarget = renderMode.renderTarget;
|
||||
|
||||
uint8_t i = 0;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
// if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
if ( (attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) ) continue;
|
||||
auto& texture = blitter.material.textures.emplace_back();
|
||||
texture.aliasAttachment(attachment);
|
||||
light.type.y = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
light.type.y = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
blitter.getPipeline().update( blitter );
|
||||
shader->updateBuffer( (void*) buffer, len, 0, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void ext::Scene::render() {
|
||||
uf::Scene::render();
|
||||
}
|
||||
void ext::Scene::destroy() {
|
||||
uf::Scene::destroy();
|
||||
}
|
||||
16
ext/scenes/base.h
Normal file
16
ext/scenes/base.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API Scene : public uf::Scene {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual void tick();
|
||||
virtual void render();
|
||||
virtual void destroy();
|
||||
};
|
||||
}
|
||||
35
ext/scenes/map/behavior_test.cpp
Normal file
35
ext/scenes/map/behavior_test.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "behavior_test.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define this (&self)
|
||||
void ext::TestBehavior::attach( uf::Object& self ) {
|
||||
self.addBehavior({
|
||||
.type = uf::Behaviors::getType<ext::TestBehavior>(),
|
||||
.initialize = [&]() {
|
||||
ext::TestBehavior::initialize( self );
|
||||
},
|
||||
.tick = [&]() {
|
||||
ext::TestBehavior::tick( self );
|
||||
},
|
||||
.render = [&]() {
|
||||
ext::TestBehavior::render( self );
|
||||
},
|
||||
.destroy = [&]() {
|
||||
ext::TestBehavior::destroy( self );
|
||||
},
|
||||
});
|
||||
}
|
||||
void ext::TestBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void ext::TestBehavior::tick( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void ext::TestBehavior::render( uf::Object& self ) {
|
||||
|
||||
}
|
||||
void ext::TestBehavior::destroy( uf::Object& self ) {
|
||||
|
||||
}
|
||||
#undef this
|
||||
15
ext/scenes/map/behavior_test.h
Normal file
15
ext/scenes/map/behavior_test.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "../base.h"
|
||||
|
||||
namespace ext {
|
||||
class EXT_API TestBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
}
|
||||
@ -22,104 +22,30 @@
|
||||
#include "../../ext.h"
|
||||
#include "../../gui/gui.h"
|
||||
|
||||
#include "behavior_test.h"
|
||||
|
||||
EXT_OBJECT_REGISTER_CPP(TestScene_Map)
|
||||
void ext::TestScene_Map::initialize() {
|
||||
uf::Scene::initialize();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
ext::Scene::initialize();
|
||||
|
||||
this->addHook( "system:Quit.%UID%", [&](const std::string& event)->std::string{
|
||||
std::cout << event << std::endl;
|
||||
ext::ready = false;
|
||||
return "true";
|
||||
});
|
||||
{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
uf::Object* object = new uf::Object;
|
||||
this->addChild(*object);
|
||||
ext::TestBehavior::attach( *object );
|
||||
|
||||
std::string asset = json["asset"].asString();
|
||||
std::string uid = json["uid"].asString();
|
||||
|
||||
assetLoader.load(asset, "asset:Load." + uid);
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "menu:Pause", [&](const std::string& event)->std::string{
|
||||
if ( timer.elapsed().asDouble() < 1 ) return "false";
|
||||
timer.reset();
|
||||
|
||||
uf::Serializer json = event;
|
||||
ext::Gui* manager = (ext::Gui*) this->findByName("Gui Manager");
|
||||
if ( !manager ) return "false";
|
||||
uf::Serializer payload;
|
||||
ext::Gui* gui = (ext::Gui*) manager->findByUid( (payload["uid"] = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() );
|
||||
uf::Serializer& metadata = gui->getComponent<uf::Serializer>();
|
||||
metadata["menu"] = json["menu"];
|
||||
gui->initialize();
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
|
||||
/* store viewport size */ {
|
||||
metadata["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["window"]["size"]["y"] = uf::renderer::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].asUInt64();
|
||||
size.y = json["window"]["size"]["y"].asUInt64();
|
||||
}
|
||||
|
||||
metadata["window"] = json["window"];
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
payload["state"] = true;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
object->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void ext::TestScene_Map::render() {
|
||||
uf::Scene::render();
|
||||
ext::Scene::render();
|
||||
}
|
||||
void ext::TestScene_Map::tick() {
|
||||
uf::Scene::tick();
|
||||
ext::Scene::tick();
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
/* Regain control if nothing requests it */ {
|
||||
ext::Gui* menu = (ext::Gui*) this->findByName("Gui: Menu");
|
||||
if ( !menu ) {
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
/* Updates Sound Listener */ {
|
||||
pod::Transform<>& transform = this->getController()->getComponent<pod::Transform<>>();
|
||||
|
||||
ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } );
|
||||
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
|
||||
ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } );
|
||||
}
|
||||
|
||||
/* Collision */ {
|
||||
bool local = false;
|
||||
bool sort = false;
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/object/object.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include "../base.h"
|
||||
|
||||
namespace ext {
|
||||
class EXT_API TestScene_Map : public uf::Scene {
|
||||
class EXT_API TestScene_Map : public ext::Scene {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual void tick();
|
||||
|
||||
@ -22,101 +22,14 @@
|
||||
|
||||
EXT_OBJECT_REGISTER_CPP(TestScene_MarchingCubes)
|
||||
void ext::TestScene_MarchingCubes::initialize() {
|
||||
uf::Scene::initialize();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
this->addHook( "system:Quit.%UID%", [&](const std::string& event)->std::string{
|
||||
std::cout << event << std::endl;
|
||||
ext::ready = false;
|
||||
return "true";
|
||||
});
|
||||
{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
std::string asset = json["asset"].asString();
|
||||
std::string uid = json["uid"].asString();
|
||||
|
||||
assetLoader.load(asset, "asset:Load." + uid);
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "menu:Pause", [&](const std::string& event)->std::string{
|
||||
if ( timer.elapsed().asDouble() < 1 ) return "false";
|
||||
timer.reset();
|
||||
|
||||
uf::Serializer json = event;
|
||||
ext::Gui* manager = (ext::Gui*) this->findByName("Gui Manager");
|
||||
if ( !manager ) return "false";
|
||||
uf::Serializer payload;
|
||||
ext::Gui* gui = (ext::Gui*) manager->findByUid( (payload["uid"] = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() );
|
||||
uf::Serializer& metadata = gui->getComponent<uf::Serializer>();
|
||||
metadata["menu"] = json["menu"];
|
||||
gui->initialize();
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
|
||||
/* store viewport size */ {
|
||||
metadata["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["window"]["size"]["y"] = uf::renderer::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].asUInt64();
|
||||
size.y = json["window"]["size"]["y"].asUInt64();
|
||||
}
|
||||
|
||||
metadata["window"] = json["window"];
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
payload["state"] = true;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
ext::Scene::initialize();
|
||||
}
|
||||
|
||||
void ext::TestScene_MarchingCubes::render() {
|
||||
uf::Scene::render();
|
||||
ext::Scene::render();
|
||||
}
|
||||
void ext::TestScene_MarchingCubes::tick() {
|
||||
uf::Scene::tick();
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
/* Regain control if nothing requests it */ {
|
||||
ext::Gui* menu = (ext::Gui*) this->findByName("Gui: Menu");
|
||||
if ( !menu ) {
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
/* Updates Sound Listener */ {
|
||||
pod::Transform<>& transform = this->getController()->getComponent<pod::Transform<>>();
|
||||
|
||||
ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } );
|
||||
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
|
||||
ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } );
|
||||
}
|
||||
ext::Scene::tick();
|
||||
|
||||
/* Collision */ {
|
||||
bool local = false;
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/object/object.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include "../base.h"
|
||||
|
||||
namespace ext {
|
||||
class EXT_API TestScene_MarchingCubes : public uf::Scene {
|
||||
class EXT_API TestScene_MarchingCubes : public ext::Scene {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual void tick();
|
||||
|
||||
@ -121,10 +121,10 @@ void ext::Heightmap::render() {
|
||||
/* Update uniforms */ if ( this->hasComponent<MESH_TYPE>() ) {
|
||||
auto& mesh = this->getComponent<MESH_TYPE>();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& root = this->getRootParent<uf::Scene>();
|
||||
auto& player = *root.getController();
|
||||
auto& camera = player.getComponent<uf::Camera>();
|
||||
auto& transform = player.getComponent<pod::Transform<>>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto& transform = controller.getComponent<pod::Transform<>>();
|
||||
auto& model = this->getComponent<pod::Transform<>>();
|
||||
if ( !graphic.initialized ) return;
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
|
||||
@ -517,9 +517,9 @@ void ext::Marching::render() {
|
||||
/* Update uniforms */ if ( this->hasComponent<MESH_TYPE>() ) {
|
||||
auto& mesh = this->getComponent<MESH_TYPE>();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& root = this->getRootParent<uf::Scene>();
|
||||
auto& player = *root.getController();
|
||||
auto& camera = player.getComponent<uf::Camera>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& model = this->getComponent<pod::Transform<>>();
|
||||
if ( !graphic.initialized ) return;
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
EXT_OBJECT_REGISTER_CPP(TestScene_RayTracing)
|
||||
void ext::TestScene_RayTracing::initialize() {
|
||||
uf::Scene::initialize();
|
||||
ext::Scene::initialize();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
@ -72,84 +72,20 @@ void ext::TestScene_RayTracing::initialize() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this->addHook( "system:Quit.%UID%", [&](const std::string& event)->std::string{
|
||||
std::cout << event << std::endl;
|
||||
ext::ready = false;
|
||||
return "true";
|
||||
});
|
||||
{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
std::string asset = json["asset"].asString();
|
||||
std::string uid = json["uid"].asString();
|
||||
|
||||
assetLoader.load(asset, "asset:Load." + uid);
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
{
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "menu:Pause", [&](const std::string& event)->std::string{
|
||||
if ( timer.elapsed().asDouble() < 1 ) return "false";
|
||||
timer.reset();
|
||||
|
||||
uf::Serializer json = event;
|
||||
ext::Gui* manager = (ext::Gui*) this->findByName("Gui Manager");
|
||||
if ( !manager ) return "false";
|
||||
uf::Serializer payload;
|
||||
ext::Gui* gui = (ext::Gui*) manager->findByUid( (payload["uid"] = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() );
|
||||
uf::Serializer& metadata = gui->getComponent<uf::Serializer>();
|
||||
metadata["menu"] = json["menu"];
|
||||
gui->initialize();
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
|
||||
/* store viewport size */ {
|
||||
metadata["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["window"]["size"]["y"] = uf::renderer::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].asUInt64();
|
||||
size.y = json["window"]["size"]["y"].asUInt64();
|
||||
}
|
||||
|
||||
metadata["window"] = json["window"];
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
payload["state"] = true;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
void ext::TestScene_RayTracing::render() {
|
||||
uf::Scene::render();
|
||||
ext::Scene::render();
|
||||
}
|
||||
void ext::TestScene_RayTracing::destroy() {
|
||||
if ( this->hasComponent<uf::renderer::ComputeRenderMode>() ) {
|
||||
auto& renderMode = this->getComponent<uf::renderer::ComputeRenderMode>();
|
||||
uf::renderer::removeRenderMode( &renderMode, false );
|
||||
}
|
||||
uf::Scene::destroy();
|
||||
ext::Scene::destroy();
|
||||
}
|
||||
void ext::TestScene_RayTracing::tick() {
|
||||
uf::Scene::tick();
|
||||
ext::Scene::tick();
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
@ -160,6 +96,10 @@ void ext::TestScene_RayTracing::tick() {
|
||||
struct UniformDescriptor {
|
||||
alignas(16) pod::Matrix4f matrices[2];
|
||||
alignas(16) pod::Vector4f ambient;
|
||||
struct {
|
||||
alignas(8) pod::Vector2f range;
|
||||
alignas(16) pod::Vector4f color;
|
||||
} fog;
|
||||
struct Light {
|
||||
alignas(16) pod::Vector4f position;
|
||||
alignas(16) pod::Vector4f color;
|
||||
@ -177,8 +117,22 @@ void ext::TestScene_RayTracing::tick() {
|
||||
auto& shader = renderMode.compute.material.shaders.front();
|
||||
specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
|
||||
|
||||
struct PushConstant {
|
||||
uint32_t marchingSteps;
|
||||
uint32_t rayBounces;
|
||||
float shadowFactor;
|
||||
float reflectionStrength;
|
||||
float reflectionFalloff;
|
||||
};
|
||||
auto& pushConstant = shader.pushConstants.front().get<PushConstant>();
|
||||
pushConstant.marchingSteps = metadata["rays"]["marching steps"].asUInt64();
|
||||
pushConstant.rayBounces = metadata["rays"]["ray bounces"].asUInt64();
|
||||
pushConstant.shadowFactor = metadata["rays"]["shadow factor"].asFloat();
|
||||
pushConstant.reflectionStrength = metadata["rays"]["reflection"]["strength"].asFloat();
|
||||
pushConstant.reflectionFalloff = metadata["rays"]["reflection"]["falloff"].asFloat();
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto& transform = controller.getComponent<pod::Transform<>>();
|
||||
|
||||
@ -190,8 +144,20 @@ void ext::TestScene_RayTracing::tick() {
|
||||
uniforms->matrices[i] = uf::matrix::inverse( camera.getProjection(i) * camera.getView(i) );
|
||||
}
|
||||
|
||||
// uniforms->lights.position = { 0, 0, 0, 32 };
|
||||
// uniforms->lights.color = { 1, 1, 1, 1 };
|
||||
{
|
||||
uniforms->ambient.x = metadata["light"]["ambient"][0].asFloat();
|
||||
uniforms->ambient.y = metadata["light"]["ambient"][1].asFloat();
|
||||
uniforms->ambient.z = metadata["light"]["ambient"][2].asFloat();
|
||||
uniforms->ambient.w = metadata["light"]["kexp"].asFloat();
|
||||
}
|
||||
{
|
||||
uniforms->fog.color.x = metadata["light"]["fog"]["color"][0].asFloat();
|
||||
uniforms->fog.color.y = metadata["light"]["fog"]["color"][1].asFloat();
|
||||
uniforms->fog.color.z = metadata["light"]["fog"]["color"][2].asFloat();
|
||||
|
||||
uniforms->fog.range.x = metadata["light"]["fog"]["range"][0].asFloat();
|
||||
uniforms->fog.range.y = metadata["light"]["fog"]["range"][1].asFloat();
|
||||
}
|
||||
|
||||
std::vector<uf::Entity*> entities;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
@ -229,7 +195,7 @@ void ext::TestScene_RayTracing::tick() {
|
||||
|
||||
if ( entity == &controller ) light.position.y += 2;
|
||||
|
||||
light.position.w = metadata["light"]["radius"].asFloat();
|
||||
light.position.w = metadata["light"]["radius"][1].asFloat();
|
||||
|
||||
light.color.x = metadata["light"]["color"][0].asFloat();
|
||||
light.color.y = metadata["light"]["color"][1].asFloat();
|
||||
@ -243,23 +209,6 @@ void ext::TestScene_RayTracing::tick() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Regain control if nothing requests it */ {
|
||||
ext::Gui* menu = (ext::Gui*) this->findByName("Gui: Menu");
|
||||
if ( !menu ) {
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
/* Updates Sound Listener */ {
|
||||
pod::Transform<>& transform = this->getController()->getComponent<pod::Transform<>>();
|
||||
|
||||
ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } );
|
||||
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
|
||||
ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } );
|
||||
}
|
||||
|
||||
/* Collision */ {
|
||||
bool local = false;
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/object/object.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include "../base.h"
|
||||
|
||||
namespace ext {
|
||||
class EXT_API TestScene_RayTracing : public uf::Scene {
|
||||
class EXT_API TestScene_RayTracing : public ext::Scene {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual void tick();
|
||||
|
||||
@ -19,124 +19,25 @@
|
||||
#include "../../gui/gui.h"
|
||||
|
||||
namespace {
|
||||
uf::Object controller;
|
||||
|
||||
ext::Gui* circleIn;
|
||||
ext::Gui* circleOut;
|
||||
}
|
||||
|
||||
uf::Entity* ext::StartMenu::getController() {
|
||||
return (uf::Entity*) &controller;
|
||||
uf::Entity& ext::StartMenu::getController() {
|
||||
return *this;
|
||||
}
|
||||
const uf::Entity* ext::StartMenu::getController() const {
|
||||
return (uf::Entity*) &controller;
|
||||
const uf::Entity& ext::StartMenu::getController() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
EXT_OBJECT_REGISTER_CPP(StartMenu)
|
||||
void ext::StartMenu::initialize() {
|
||||
uf::Scene::initialize();
|
||||
ext::Scene::initialize();
|
||||
this->m_name = "Main Menu";
|
||||
// this->load("./scenes/start/scene.json");
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
this->addHook( "system:Quit.%UID%", [&](const std::string& event)->std::string{
|
||||
std::cout << event << std::endl;
|
||||
ext::ready = false;
|
||||
return "true";
|
||||
});
|
||||
this->addHook( "world:Music.LoadPrevious.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
if ( metadata["previous bgm"]["filename"] == "" ) return "false";
|
||||
|
||||
std::string filename = metadata["previous bgm"]["filename"].asString();
|
||||
float timestamp = metadata["previous bgm"]["timestamp"].asFloat();
|
||||
|
||||
// std::cout << metadata["previous bgm"] << std::endl;
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) {
|
||||
metadata["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadata["previous bgm"]["timestamp"] = audio.getTime();
|
||||
audio.stop();
|
||||
}
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
|
||||
audio.setTime(timestamp);
|
||||
audio.play();
|
||||
|
||||
return "true";
|
||||
});
|
||||
this->addHook( "asset:Load." + std::to_string(this->getUid()), [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::string filename = json["filename"].asString();
|
||||
|
||||
if ( uf::string::extension(filename) != "ogg" ) return "false";
|
||||
const uf::Audio* audioPointer = NULL;
|
||||
try { audioPointer = &assetLoader.get<uf::Audio>(filename); } catch ( ... ) {}
|
||||
if ( !audioPointer ) return "false";
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) {
|
||||
/*
|
||||
if ( filename.find("_intro") == std::string::npos ) {
|
||||
metadata["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadata["previous bgm"]["timestamp"] = audio.getTime();
|
||||
}
|
||||
*/
|
||||
audio.stop();
|
||||
}
|
||||
|
||||
// std::cout << metadata["previous bgm"] << std::endl;
|
||||
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
|
||||
audio.play();
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
|
||||
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
std::string asset = json["asset"].asString();
|
||||
std::string uid = json["uid"].asString();
|
||||
|
||||
assetLoader.load(asset, "asset:Load." + uid);
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
||||
/* store viewport size */ {
|
||||
metadata["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["window"]["size"]["y"] = uf::renderer::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].asUInt64();
|
||||
size.y = json["window"]["size"]["y"].asUInt64();
|
||||
}
|
||||
|
||||
metadata["window"] = json["window"];
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
payload["state"] = true;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
|
||||
/* Magic Circle Outter */ {
|
||||
circleOut = (ext::Gui*) this->findByUid( this->loadChild("./gui/mainmenu/circle-out.json", true) );
|
||||
}
|
||||
@ -145,6 +46,7 @@ void ext::StartMenu::initialize() {
|
||||
}
|
||||
// update camera
|
||||
{
|
||||
auto& controller = this->getController();
|
||||
controller.getComponent<uf::Camera>().update(true);
|
||||
pod::Transform<>& transform = controller.getComponent<pod::Transform<>>();
|
||||
|
||||
@ -155,32 +57,11 @@ void ext::StartMenu::initialize() {
|
||||
}
|
||||
|
||||
void ext::StartMenu::tick() {
|
||||
uf::Scene::tick();
|
||||
ext::Scene::tick();
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
/* check if audio needs to loop */ try {
|
||||
uf::Audio& bgm = this->getComponent<uf::Audio>();
|
||||
float current = bgm.getTime();
|
||||
float end = bgm.getDuration();
|
||||
float epsilon = 0.005f;
|
||||
if ( current + epsilon >= end || !bgm.playing() ) {
|
||||
// intro to main transition
|
||||
std::string filename = bgm.getFilename();
|
||||
filename = assetLoader.getOriginal(filename);
|
||||
if ( filename.find("_intro") != std::string::npos ) {
|
||||
assetLoader.load(uf::string::replace( filename, "_intro", "" ), "asset:Load." + std::to_string(this->getUid()));
|
||||
// loop
|
||||
} else {
|
||||
bgm.setTime(0);
|
||||
if ( !bgm.playing() ) bgm.play();
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {
|
||||
|
||||
}
|
||||
|
||||
if ( circleIn ) {
|
||||
pod::Transform<>& transform = circleIn->getComponent<pod::Transform<>>();
|
||||
static float time = 0.0f;
|
||||
@ -224,22 +105,13 @@ void ext::StartMenu::tick() {
|
||||
// metadata["color"][3] = alpha;
|
||||
}
|
||||
|
||||
// check on controller position
|
||||
/*
|
||||
{
|
||||
pod::Vector3f position = ext::openvr::controllerPosition( vr::Controller_Hand::Hand_Right );
|
||||
pod::Quaternion<> orientation = ext::openvr::controllerQuaternion( vr::Controller_Hand::Hand_Right );
|
||||
std::cout << "Right hand:\n";
|
||||
std::cout << "\tPosition: " << position.x << ", " << position.y << ", " << position.z << "\n";
|
||||
std::cout << "\tOrientation: " << orientation.x << ", " << orientation.y << ", " << orientation.z << ", " << orientation.w << std::endl;
|
||||
}
|
||||
*/
|
||||
{
|
||||
auto& controller = this->getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
camera.updateView();
|
||||
}
|
||||
}
|
||||
|
||||
void ext::StartMenu::render() {
|
||||
uf::Scene::render();
|
||||
ext::Scene::render();
|
||||
}
|
||||
@ -1,18 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include "../base.h"
|
||||
|
||||
namespace ext {
|
||||
class EXT_API StartMenu : public uf::Scene {
|
||||
class EXT_API StartMenu : public ext::Scene {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual void tick();
|
||||
virtual void render();
|
||||
virtual uf::Entity* getController();
|
||||
virtual const uf::Entity* getController() const;
|
||||
|
||||
virtual uf::Entity& getController();
|
||||
virtual const uf::Entity& getController() const;
|
||||
};
|
||||
}
|
||||
@ -111,7 +111,7 @@ void ext::Craeture::initialize() {
|
||||
if ( filename == "" ) return "false";
|
||||
uf::Audio& sfx = this->getComponent<uf::SoundEmitter>().add(filename);
|
||||
sfx.setVolume(masterdata["volumes"]["sfx"].asFloat());
|
||||
auto& pTransform = world.getController()->getComponent<pod::Transform<>>();
|
||||
auto& pTransform = world.getController().getComponent<pod::Transform<>>();
|
||||
sfx.setPosition( transform.position );
|
||||
sfx.play();
|
||||
|
||||
@ -169,7 +169,7 @@ void ext::Craeture::tick() {
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Scene& world = uf::scene::getCurrentScene();
|
||||
uf::Serializer& pMetadata = world.getController()->getComponent<uf::Serializer>();
|
||||
uf::Serializer& pMetadata = world.getController().getComponent<uf::Serializer>();
|
||||
|
||||
if ( !pMetadata["system"]["control"].asBool() ) return;
|
||||
|
||||
|
||||
@ -118,7 +118,7 @@ void ext::GuiWorldPauseMenu::initialize() {
|
||||
}
|
||||
/* set sprite order */ {
|
||||
metadata["portraits"]["i"] = 0;
|
||||
uf::Serializer& pMetadata = scene.getController()->getComponent<uf::Serializer>();
|
||||
uf::Serializer& pMetadata = scene.getController().getComponent<uf::Serializer>();
|
||||
int i = 0;
|
||||
for ( auto& k : pMetadata[""]["party"] ) {
|
||||
std::string id = k.asString();
|
||||
|
||||
@ -132,10 +132,10 @@ void ext::HousamoSprite::render() {
|
||||
ext::Craeture::render();
|
||||
/* Update uniforms */ if ( this->hasComponent<uf::Graphic>() ) {
|
||||
auto& mesh = this->getComponent<uf::Mesh>();
|
||||
auto& scene = this->getRootParent<uf::Scene>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& camera = scene.getController()->getComponent<uf::Camera>();
|
||||
auto& camera = scene.getController().getComponent<uf::Camera>();
|
||||
if ( !graphic.initialized ) return;
|
||||
// auto& uniforms = graphic.uniforms<uf::StereoMeshDescriptor>();
|
||||
auto& uniforms = graphic.material.shaders.front().uniforms.front().get<uf::StereoMeshDescriptor>();
|
||||
@ -147,7 +147,7 @@ void ext::HousamoSprite::render() {
|
||||
/*
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
if ( !graphic.initialized ) return;
|
||||
|
||||
@ -16,16 +16,9 @@ void ext::Light::initialize() {
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
std::string name = "RT:" + std::to_string((int) this->getUid());
|
||||
uf::renderer::addRenderMode( &renderMode, name );
|
||||
if ( metadata["light"]["shadows"]["resolution"].isArray() ) {
|
||||
renderMode.width = metadata["light"]["shadows"]["resolution"][0].asUInt64();
|
||||
renderMode.height = metadata["light"]["shadows"]["resolution"][1].asUInt64();
|
||||
} else {
|
||||
renderMode.width = metadata["light"]["shadows"]["resolution"].asUInt64();
|
||||
renderMode.height = metadata["light"]["shadows"]["resolution"].asUInt64();
|
||||
}
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
|
||||
camera = controller.getComponent<uf::Camera>();
|
||||
camera.getTransform() = {};
|
||||
@ -34,17 +27,37 @@ void ext::Light::initialize() {
|
||||
camera.setFov( metadata["light"]["shadows"]["fov"].asFloat() );
|
||||
camera.updateProjection();
|
||||
}
|
||||
if ( metadata["light"]["radius"].isArray() ) {
|
||||
auto bounds = camera.getBounds();
|
||||
bounds.x = metadata["light"]["radius"][0].asFloat();
|
||||
bounds.y = metadata["light"]["radius"][1].asFloat();
|
||||
camera.setBounds(bounds);
|
||||
}
|
||||
}
|
||||
if ( metadata["light"]["shadows"]["resolution"].isArray() ) {
|
||||
renderMode.width = metadata["light"]["shadows"]["resolution"][0].asUInt64();
|
||||
renderMode.height = metadata["light"]["shadows"]["resolution"][1].asUInt64();
|
||||
auto size = camera.getSize();
|
||||
size.x = renderMode.width;
|
||||
size.y = renderMode.height;
|
||||
camera.setSize(size);
|
||||
} else {
|
||||
renderMode.width = metadata["light"]["shadows"]["resolution"].asUInt64();
|
||||
renderMode.height = metadata["light"]["shadows"]["resolution"].asUInt64();
|
||||
auto size = camera.getSize();
|
||||
size.x = renderMode.width;
|
||||
size.y = renderMode.height;
|
||||
camera.setSize(size);
|
||||
}
|
||||
}
|
||||
if ( !metadata["light"].isArray() ) {
|
||||
if ( !metadata["light"]["color"].isArray() ) {
|
||||
metadata["light"]["color"][0] = 1; //metadata["light"]["color"]["random"].asBool() ? (rand() % 100) / 100.0 : 1;
|
||||
metadata["light"]["color"][1] = 1; //metadata["light"]["color"]["random"].asBool() ? (rand() % 100) / 100.0 : 1;
|
||||
metadata["light"]["color"][2] = 1; //metadata["light"]["color"]["random"].asBool() ? (rand() % 100) / 100.0 : 1;
|
||||
}
|
||||
}
|
||||
void ext::Light::tick() {
|
||||
uf::Object::tick();
|
||||
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
if ( this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
||||
renderMode.target = "";
|
||||
@ -55,16 +68,86 @@ void ext::Light::tick() {
|
||||
pod::Physics& physics = this->getComponent<pod::Physics>();
|
||||
transform = uf::physics::update( transform, physics );
|
||||
}
|
||||
{
|
||||
uf::transform::rotate( transform, {0, 1, 0}, uf::physics::time::delta );
|
||||
|
||||
auto& parent = this->getParent();
|
||||
auto& parentMetadata = parent.getComponent<uf::Serializer>();
|
||||
if ( parentMetadata["system"]["type"] == "Light" ) {
|
||||
metadata["light"] = parentMetadata["light"];
|
||||
} else {
|
||||
if ( metadata["light"]["fade"].isObject() ) {
|
||||
if ( metadata["light"]["backup"]["power"].isNull() ) {
|
||||
metadata["light"]["backup"]["power"] = metadata["light"]["power"];
|
||||
}
|
||||
if ( metadata["light"]["backup"]["color"].isNull() ) {
|
||||
metadata["light"]["backup"]["color"] = metadata["light"]["color"];
|
||||
}
|
||||
// fade towards
|
||||
int direction = metadata["light"]["fade"]["increment"].asBool() ? 1 : -1;
|
||||
metadata["light"]["fade"]["timer"] = metadata["light"]["fade"]["timer"].asFloat() + metadata["light"]["fade"]["rate"].asFloat() * uf::physics::time::delta * direction;
|
||||
|
||||
// 0 .. delta .. 1 .. (1 + timeout * 0.5)
|
||||
|
||||
if ( direction == 1 && metadata["light"]["fade"]["timer"].asFloat() >= 0.5f * metadata["light"]["fade"]["timeout"].asFloat() + 1.0f ) {
|
||||
metadata["light"]["fade"]["increment"] = false;
|
||||
} else if ( direction == -1 && metadata["light"]["fade"]["timer"].asFloat() <= -0.5f * metadata["light"]["fade"]["timeout"].asFloat() ) {
|
||||
metadata["light"]["fade"]["increment"] = true;
|
||||
}
|
||||
{
|
||||
float delta = metadata["light"]["fade"]["timer"].asFloat();
|
||||
delta = std::clamp( delta, 0.f, 1.f );
|
||||
if ( metadata["light"]["fade"]["power"].isNumeric() ) {
|
||||
metadata["light"]["power"] = std::lerp( metadata["light"]["backup"]["power"].asFloat(), metadata["light"]["fade"]["power"].asFloat(), delta );
|
||||
}
|
||||
if ( metadata["light"]["fade"]["color"].isArray() ) {
|
||||
pod::Vector3f fadeColor; {
|
||||
fadeColor.x = metadata["light"]["fade"]["color"][0].asFloat();
|
||||
fadeColor.y = metadata["light"]["fade"]["color"][1].asFloat();
|
||||
fadeColor.z = metadata["light"]["fade"]["color"][2].asFloat();
|
||||
}
|
||||
pod::Vector3f origColor; {
|
||||
origColor.x = metadata["light"]["backup"]["color"][0].asFloat();
|
||||
origColor.y = metadata["light"]["backup"]["color"][1].asFloat();
|
||||
origColor.z = metadata["light"]["backup"]["color"][2].asFloat();
|
||||
}
|
||||
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 ( metadata["light"]["flicker"].isObject() ) {
|
||||
float r = (rand() % 100) / 100.0;
|
||||
float rate = metadata["light"]["flicker"]["rate"].asFloat();
|
||||
if ( metadata["light"]["backup"]["power"].isNull() ) {
|
||||
metadata["light"]["backup"]["power"] = metadata["light"]["power"];
|
||||
}
|
||||
metadata["light"]["flicker"]["timer"] = metadata["light"]["flicker"]["timer"].asFloat() + uf::physics::time::delta;
|
||||
if ( metadata["light"]["flicker"]["timer"].asFloat() >= metadata["light"]["flicker"]["timeout"].asFloat() ) {
|
||||
metadata["light"]["flicker"]["timer"] = 0;
|
||||
metadata["light"]["power"] = (r > rate) ? metadata["light"]["flicker"]["power"].asFloat() : metadata["light"]["backup"]["power"];
|
||||
}
|
||||
}
|
||||
}
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
// if ( metadata["light"]["external update"].isNull() || (!metadata["light"]["external update"].isNull() && !metadata["light"]["external update"].asBool()) ) {
|
||||
|
||||
if ( parentMetadata["system"]["type"] == "Light" ) {
|
||||
auto& parentTransform = parent.getComponent<pod::Transform<>>();
|
||||
transform.position = parentTransform.position;
|
||||
} else if ( metadata["system"]["track"] == "player" ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controllerCamera = scene.getController().getComponent<uf::Camera>().getTransform();
|
||||
auto& controllerTransform = scene.getController().getComponent<pod::Transform<>>();
|
||||
transform.position = controllerTransform.position + controllerCamera.position;
|
||||
}
|
||||
if ( metadata["light"]["external update"].isNull() || (!metadata["light"]["external update"].isNull() && !metadata["light"]["external update"].asBool()) ) {
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
for ( std::size_t i = 0; i < 2; ++i ) {
|
||||
camera.setView( uf::matrix::inverse( uf::transform::model( transform ) ), i );
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
uf::Object::tick();
|
||||
}
|
||||
void ext::Light::render() {
|
||||
uf::Object::render();
|
||||
|
||||
@ -181,7 +181,7 @@ void ext::Hands::initialize() {
|
||||
void ext::Hands::tick() {
|
||||
uf::Object::tick();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& controllerCamera = controller.getComponent<uf::Camera>();
|
||||
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
|
||||
auto& controllerCameraTransform = controllerCamera.getTransform();
|
||||
@ -442,7 +442,7 @@ void ext::Hands::render() {
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = controller.getComponent<uf::Camera>();
|
||||
|
||||
pod::Matrix4f playerModel = uf::matrix::identity(); {
|
||||
|
||||
@ -62,7 +62,7 @@ void ext::Portal::initialize() {
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
// copies camera settings
|
||||
camera = controller.getComponent<uf::Camera>();
|
||||
}
|
||||
@ -88,7 +88,7 @@ void ext::Portal::tick() {
|
||||
renderMode.target = "";
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
/*
|
||||
@ -128,7 +128,7 @@ void ext::Portal::render() {
|
||||
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = *scene.getController();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
auto& controllerCamera = controller.getComponent<uf::Camera>();
|
||||
if ( !blitter.initialized ) return;
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
EXT_OBJECT_REGISTER_CPP(TestScene_WorldScape)
|
||||
void ext::TestScene_WorldScape::initialize() {
|
||||
uf::Scene::initialize();
|
||||
ext::Scene::initialize();
|
||||
this->m_name = "World";
|
||||
// this->load("./scenes/world/scene.json");
|
||||
|
||||
@ -49,89 +49,14 @@ void ext::TestScene_WorldScape::initialize() {
|
||||
metadata["system"]["mastertable"][table] = data.load(table);
|
||||
}
|
||||
}
|
||||
|
||||
this->addHook( "world:Music.LoadPrevious.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
if ( metadata["previous bgm"]["filename"] == "" ) return "false";
|
||||
|
||||
std::string filename = metadata["previous bgm"]["filename"].asString();
|
||||
float timestamp = metadata["previous bgm"]["timestamp"].asFloat();
|
||||
|
||||
// std::cout << metadata["previous bgm"] << std::endl;
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) {
|
||||
metadata["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadata["previous bgm"]["timestamp"] = audio.getTime();
|
||||
audio.stop();
|
||||
}
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
|
||||
audio.setTime(timestamp);
|
||||
audio.play();
|
||||
|
||||
return "true";
|
||||
});
|
||||
this->addHook( "asset:Load." + std::to_string(this->getUid()), [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::string filename = json["filename"].asString();
|
||||
|
||||
if ( uf::string::extension(filename) != "ogg" ) return "false";
|
||||
const uf::Audio* audioPointer = NULL;
|
||||
try { audioPointer = &assetLoader.get<uf::Audio>(filename); } catch ( ... ) {}
|
||||
if ( !audioPointer ) return "false";
|
||||
|
||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||
if ( audio.playing() ) {
|
||||
/*
|
||||
if ( filename.find("_intro") == std::string::npos ) {
|
||||
metadata["previous bgm"]["filename"] = audio.getFilename();
|
||||
metadata["previous bgm"]["timestamp"] = audio.getTime();
|
||||
}
|
||||
*/
|
||||
audio.stop();
|
||||
}
|
||||
|
||||
// std::cout << metadata["previous bgm"] << std::endl;
|
||||
|
||||
audio.load(filename);
|
||||
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
|
||||
audio.play();
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
this->addHook( "menu:Pause", [&](const std::string& event)->std::string{
|
||||
if ( timer.elapsed().asDouble() < 1 ) return "false";
|
||||
timer.reset();
|
||||
|
||||
uf::Serializer json = event;
|
||||
ext::Gui* manager = (ext::Gui*) this->findByName("Gui Manager");
|
||||
if ( !manager ) return "false";
|
||||
uf::Serializer payload;
|
||||
ext::Gui* gui = (ext::Gui*) manager->findByUid( (payload["uid"] = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() );
|
||||
uf::Serializer& metadata = gui->getComponent<uf::Serializer>();
|
||||
metadata["menu"] = json["menu"];
|
||||
gui->initialize();
|
||||
return payload;
|
||||
});
|
||||
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
std::string asset = json["asset"].asString();
|
||||
std::string uid = json["uid"].asString();
|
||||
|
||||
assetLoader.load(asset, "asset:Load." + uid);
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
||||
this->addHook( "world:Battle.Prepare", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
uf::Entity& player = *this->getController();
|
||||
uf::Entity& player = this->getController();
|
||||
uf::Serializer& pMetadata = player.getComponent<uf::Serializer>();
|
||||
|
||||
uf::Serializer payload;
|
||||
@ -200,109 +125,12 @@ void ext::TestScene_WorldScape::initialize() {
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
||||
/* store viewport size */ {
|
||||
metadata["window"]["size"]["x"] = uf::renderer::width;
|
||||
metadata["window"]["size"]["y"] = uf::renderer::height;
|
||||
|
||||
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
|
||||
pod::Vector2ui size; {
|
||||
size.x = json["window"]["size"]["x"].asUInt64();
|
||||
size.y = json["window"]["size"]["y"].asUInt64();
|
||||
}
|
||||
|
||||
metadata["window"] = json["window"];
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
|
||||
// lock control
|
||||
{
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
void ext::TestScene_WorldScape::tick() {
|
||||
uf::Scene::tick();
|
||||
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
|
||||
|
||||
/* check if audio needs to loop */ try {
|
||||
uf::Audio& bgm = this->getComponent<uf::Audio>();
|
||||
float current = bgm.getTime();
|
||||
float end = bgm.getDuration();
|
||||
float epsilon = 0.005f;
|
||||
if ( current + epsilon >= end || !bgm.playing() ) {
|
||||
// intro to main transition
|
||||
std::string filename = bgm.getFilename();
|
||||
filename = assetLoader.getOriginal(filename);
|
||||
if ( filename.find("_intro") != std::string::npos ) {
|
||||
assetLoader.load(uf::string::replace( filename, "_intro", "" ), "asset:Load." + std::to_string(this->getUid()));
|
||||
// loop
|
||||
} else {
|
||||
bgm.setTime(0);
|
||||
if ( !bgm.playing() ) bgm.play();
|
||||
}
|
||||
}
|
||||
} catch ( ... ) {
|
||||
|
||||
}
|
||||
|
||||
/* Regain control if nothing requests it */ {
|
||||
ext::Gui* menu = (ext::Gui*) this->findByName("Gui: Menu");
|
||||
if ( !menu ) {
|
||||
uf::Serializer payload;
|
||||
payload["state"] = false;
|
||||
uf::hooks.call("window:Mouse.CursorVisibility", payload);
|
||||
uf::hooks.call("window:Mouse.Lock");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Entity Information */ {
|
||||
static uf::Timer<long long> timer(false);
|
||||
if ( !timer.running() ) timer.start();
|
||||
if ( uf::Window::isKeyPressed("U") && timer.elapsed().asDouble() >= 1 ) { timer.reset();
|
||||
auto& allocations = uf::Entity::memoryPool.allocations();
|
||||
uf::iostream << "Current size: " << allocations.size() << " | UIDs: " << uf::Entity::uids << "\n";
|
||||
uint orphans = 0;
|
||||
uint empty = 0;
|
||||
for ( auto& allocation : allocations ) {
|
||||
uf::Entity* e = (uf::Entity*) allocation.pointer;
|
||||
if ( !e->hasParent() ) {
|
||||
++orphans;
|
||||
uf::iostream << "Orphan: " << e->getName() << ": " << e << "\n";
|
||||
}
|
||||
}
|
||||
/*
|
||||
for ( uf::Entity* e : uf::Entity::entities ) {
|
||||
if ( e && !e->hasParent() ) {
|
||||
++orphans;
|
||||
uf::iostream << "Orphan: " << e->getName() << ": " << e << "\n";
|
||||
}
|
||||
if ( !e ) ++empty;
|
||||
}
|
||||
*/
|
||||
uf::iostream << "Orphans: " << orphans << "\n";
|
||||
uf::iostream << "Empty: " << empty << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Updates Sound Listener */ {
|
||||
pod::Transform<>& transform = this->getController()->getComponent<pod::Transform<>>();
|
||||
|
||||
ext::oal.listener( "POSITION", { transform.position.x, transform.position.y, transform.position.z } );
|
||||
ext::oal.listener( "VELOCITY", { 0, 0, 0 } );
|
||||
ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } );
|
||||
}
|
||||
ext::Scene::tick();
|
||||
}
|
||||
|
||||
void ext::TestScene_WorldScape::render() {
|
||||
uf::Scene::render();
|
||||
ext::Scene::render();
|
||||
}
|
||||
@ -1,13 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include "../base.h"
|
||||
|
||||
namespace ext {
|
||||
class EXT_API TestScene_WorldScape : public uf::Scene {
|
||||
class EXT_API TestScene_WorldScape : public ext::Scene {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual void tick();
|
||||
|
||||
@ -433,10 +433,10 @@ void ext::Region::render( ) {
|
||||
|
||||
if ( !metadata["region"]["rasterized"].asBool() ) return;
|
||||
/* Update uniforms */ if ( this->hasComponent<uf::Graphic>() ) {
|
||||
auto& scene = this->getRootParent<uf::Scene>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& mesh = this->getComponent<ext::TerrainGenerator::mesh_t>();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& camera = scene.getController()->getComponent<uf::Camera>();
|
||||
auto& camera = scene.getController().getComponent<uf::Camera>();
|
||||
if ( !graphic.initialized ) return;
|
||||
// auto& uniforms = graphic.uniforms<uf::StereoMeshDescriptor>();
|
||||
auto& uniforms = graphic.material.shaders.front().uniforms.front().get<uf::StereoMeshDescriptor>();
|
||||
|
||||
@ -100,8 +100,8 @@ void ext::Terrain::initialize() {
|
||||
void ext::Terrain::tick() {
|
||||
uf::Object::tick();
|
||||
|
||||
uf::Scene& root = this->getRootParent<uf::Scene>();
|
||||
uf::Object& controller = root.getController<uf::Object>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
uf::Object& controller = scene.getController<uf::Object>();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
pod::Thread& mainThread = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false, true );
|
||||
// lambda to transition from a resolving state
|
||||
@ -132,7 +132,7 @@ void ext::Terrain::tick() {
|
||||
};
|
||||
// generate initial terrain
|
||||
if ( metadata["system"]["state"] == "preinit" ) {
|
||||
uf::Entity* controller = root.findByName("Player");
|
||||
uf::Entity* controller = scene.findByName("Player");
|
||||
if ( controller ) {
|
||||
transitionState(*this, "initialize", true);
|
||||
this->generate(true);
|
||||
@ -415,9 +415,9 @@ void ext::Terrain::render() {
|
||||
}
|
||||
|
||||
void ext::Terrain::relocateChildren() {
|
||||
uf::Scene& root = this->getRootParent<uf::Scene>();
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
std::vector<uf::Entity*> entities;
|
||||
root.process( [&]( uf::Entity* entity ) {
|
||||
scene.process( [&]( uf::Entity* entity ) {
|
||||
if ( !entity || entity->getUid() == 0 ) return;
|
||||
uf::Serializer& metadata = entity->getComponent<uf::Serializer>();
|
||||
if ( metadata["region"].isObject() && metadata["region"]["track"].asBool() ) {
|
||||
@ -485,7 +485,7 @@ bool ext::Terrain::exists( const pod::Vector3i& position ) const {
|
||||
|
||||
bool ext::Terrain::inBounds( const pod::Vector3i& position ) const {
|
||||
const uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
const pod::Transform<>& player = scene.getController()->getComponent<pod::Transform<>>();
|
||||
const pod::Transform<>& player = scene.getController().getComponent<pod::Transform<>>();
|
||||
const uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
pod::Vector3ui size = {
|
||||
metadata["region"]["size"][0].asUInt(),
|
||||
@ -521,7 +521,7 @@ void ext::Terrain::generate( bool single ) {
|
||||
};
|
||||
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
const pod::Transform<>& player = scene.getController()->getComponent<pod::Transform<>>();
|
||||
const pod::Transform<>& player = scene.getController().getComponent<pod::Transform<>>();
|
||||
pod::Vector3i location = {
|
||||
(int) player.position.x / size.x,
|
||||
(int) player.position.y / size.y,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user