Commit for 2020.09.27.7z

This commit is contained in:
mrq 2020-09-27 00:00:00 -05:00
parent 0b88b27065
commit a97418d88e
47 changed files with 1251 additions and 1259 deletions

View File

@ -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;
}
*/
}

View File

@ -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));

View 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();\
};

View File

@ -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"

View File

@ -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();
}
}
*/

View File

@ -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());
}
};

View File

@ -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;

View File

@ -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 ) {
}
}
}
*/

View File

@ -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;

View File

@ -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>

View 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();
}
}

View File

@ -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();
}
}
*/

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ) {

View File

@ -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 ) :

View File

@ -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;
}

View File

@ -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" ) {

View File

@ -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
View 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
View 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();
};
}

View 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

View 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& );
};
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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>();

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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();
}

View File

@ -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;
};
}

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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(); {

View File

@ -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;

View File

@ -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();
}

View File

@ -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();

View File

@ -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>();

View File

@ -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,