diff --git a/.dir-locals.el b/.dir-locals.el index 1ef497b..e37598b 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -2,8 +2,8 @@ ((string-equal system-type "windows-nt") ; Microsoft Windows (progn ((c-mode . - ((company-clang-arguments . ("-IE:/Projects/symmerty/include" "-IE:\\Projects\\symmerty\\third_party\\windows\\SDL2-2.0.5\\include")) - (flycheck-clang-include-path . ("E:/Projects/symmerty/include"))) + ((company-clang-arguments . ("-IW:/include")) + (flycheck-clang-include-path . ("W:/include"))) ) ((c++-mode . ((mode . c)))) ) diff --git a/README.md b/README.md index 702ea8a..7e3eeff 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,7 @@ - Console fix bug when enabled in editor mode - Console command history - Console command help + - Space partitioning and scene handling - NPR and cross-hatching - Move Gui_State and Editor_State into game_state and modify usage as needed - Remove model and replace all usages with static mesh @@ -416,4 +417,4 @@ * Console log output * Console error/warning output * Implemented Auto scrolling to the bottom in console - * Implemented screen coordinate to ray conversion and ray-sphere collision \ No newline at end of file + * Implemented screen coordinate to ray conversion and ray-sphere collision diff --git a/src/common/hashmap.c b/src/common/hashmap.c index aa4228e..5843673 100644 --- a/src/common/hashmap.c +++ b/src/common/hashmap.c @@ -9,14 +9,14 @@ struct Hashmap_Entry { - char* key; - struct Variant value; + char* key; + struct Variant value; }; struct Hashmap { - struct Hashmap_Entry* buckets[HASH_MAP_NUM_BUCKETS]; - int iter_bucket, iter_index; + struct Hashmap_Entry* buckets[HASH_MAP_NUM_BUCKETS]; + int iter_bucket, iter_index; }; static unsigned int hashmap_generate_hash(const char* key); @@ -24,337 +24,337 @@ static struct Hashmap_Entry* hashmap_entry_new(struct Hashmap* hashmap, const ch static struct Hashmap_Entry* hashmap_entry_new(struct Hashmap* hashmap, const char* key) { - unsigned int index = hashmap_generate_hash(key); - struct Hashmap_Entry* new_entry = NULL; - for(int i = 0; i < array_len(hashmap->buckets[index]); i++) /* Look for duplicates and over-write if found */ + unsigned int index = hashmap_generate_hash(key); + struct Hashmap_Entry* new_entry = NULL; + for(int i = 0; i < array_len(hashmap->buckets[index]); i++) /* Look for duplicates and over-write if found */ + { + if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0) { - if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0) - { - new_entry = &hashmap->buckets[index][i]; - if(new_entry->key) free(new_entry->key); - break; - } + new_entry = &hashmap->buckets[index][i]; + if(new_entry->key) free(new_entry->key); + break; } - if(!new_entry) new_entry = array_grow(hashmap->buckets[index], struct Hashmap_Entry); - new_entry->key = str_new(key); - new_entry->value.type = VT_NONE; - variant_free(&new_entry->value); - return new_entry; + } + if(!new_entry) new_entry = array_grow(hashmap->buckets[index], struct Hashmap_Entry); + new_entry->key = str_new(key); + new_entry->value.type = VT_NONE; + variant_free(&new_entry->value); + return new_entry; } unsigned int hashmap_generate_hash(const char* key) { - unsigned int index = 0; - const int multiplier = 51; - for(int i = 0; i < (int)strlen(key); i++) - index = index * multiplier + key[i]; - return index % HASH_MAP_NUM_BUCKETS; + unsigned int index = 0; + const int multiplier = 51; + for(int i = 0; i < (int)strlen(key); i++) + index = index * multiplier + key[i]; + return index % HASH_MAP_NUM_BUCKETS; } struct Hashmap* hashmap_new(void) { - struct Hashmap* hashmap = malloc(sizeof(*hashmap)); - if(!hashmap) - return NULL; - for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) - hashmap->buckets[i] = array_new(struct Hashmap_Entry); - hashmap->iter_bucket = 0; - hashmap->iter_index = -1; - return hashmap; + struct Hashmap* hashmap = malloc(sizeof(*hashmap)); + if(!hashmap) + return NULL; + for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) + hashmap->buckets[i] = array_new(struct Hashmap_Entry); + hashmap->iter_bucket = 0; + hashmap->iter_index = -1; + return hashmap; } void hashmap_free(struct Hashmap* hashmap) { - if(!hashmap) return; - for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) + if(!hashmap) return; + for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) + { + for(int j = 0; j < array_len(hashmap->buckets[i]); j++) { - for(int j = 0; j < array_len(hashmap->buckets[i]); j++) - { - struct Hashmap_Entry* entry = &hashmap->buckets[i][j]; - if(entry->key) - { - free(entry->key); - entry->key = NULL; - } - variant_free(&entry->value); - } - array_free(hashmap->buckets[i]); - hashmap->buckets[i] = NULL; + struct Hashmap_Entry* entry = &hashmap->buckets[i][j]; + if(entry->key) + { + free(entry->key); + entry->key = NULL; + } + variant_free(&entry->value); } - free(hashmap); - hashmap = NULL; + array_free(hashmap->buckets[i]); + hashmap->buckets[i] = NULL; + } + free(hashmap); + hashmap = NULL; } void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value) { - if(!hashmap || !key || !value) return; - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_copy(&new_entry->value, value); + if(!hashmap || !key || !value) return; + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_copy(&new_entry->value, value); } struct Variant* hashmap_value_get(const struct Hashmap* hashmap, const char* key) { - if(!hashmap || !key) return NULL; - struct Variant* value = NULL; - unsigned int index = hashmap_generate_hash(key); - int key_len = strlen(key); - int compare_len = key_len < HASH_MAX_KEY_LEN ? key_len : HASH_MAX_KEY_LEN; - for(int i = 0; i < array_len(hashmap->buckets[index]); i++) + if(!hashmap || !key) return NULL; + struct Variant* value = NULL; + unsigned int index = hashmap_generate_hash(key); + int key_len = (int)strlen(key); + int compare_len = key_len < HASH_MAX_KEY_LEN ? key_len : HASH_MAX_KEY_LEN; + for(int i = 0; i < array_len(hashmap->buckets[index]); i++) + { + if(strncmp(key, hashmap->buckets[index][i].key, compare_len) == 0) { - if(strncmp(key, hashmap->buckets[index][i].key, compare_len) == 0) - { - value = &hashmap->buckets[index][i].value; - break; - } + value = &hashmap->buckets[index][i].value; + break; } - return value; + } + return value; } void hashmap_value_remove(struct Hashmap* hashmap, const char* key) { - if(!hashmap || !key) return; - unsigned int index = hashmap_generate_hash(key); - int index_to_remove = -1; - for(int i = 0; i < array_len(hashmap->buckets[index]); i++) + if(!hashmap || !key) return; + unsigned int index = hashmap_generate_hash(key); + int index_to_remove = -1; + for(int i = 0; i < array_len(hashmap->buckets[index]); i++) + { + if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0) { - if(strncmp(key, hashmap->buckets[index][i].key, HASH_MAX_KEY_LEN) == 0) - { - index_to_remove = i; - break; - } + index_to_remove = i; + break; } - if(index_to_remove != -1) array_remove_at(hashmap->buckets[index], index_to_remove); + } + if(index_to_remove != -1) array_remove_at(hashmap->buckets[index], index_to_remove); } bool hashmap_value_exists(struct Hashmap * hashmap, const char * key) { - return hashmap_value_get(hashmap, key); + return hashmap_value_get(hashmap, key); } void hashmap_float_set(struct Hashmap* hashmap, const char* key, const float value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_float(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_float(&new_entry->value, value); } void hashmap_int_set(struct Hashmap* hashmap, const char* key, const int value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_int(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_int(&new_entry->value, value); } void hashmap_double_set(struct Hashmap* hashmap, const char* key, const double value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_double(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_double(&new_entry->value, value); } void hashmap_bool_set(struct Hashmap* hashmap, const char* key, const bool value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_bool(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_bool(&new_entry->value, value); } void hashmap_vec2_set(struct Hashmap* hashmap, const char* key, const vec2* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_vec2(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_vec2(&new_entry->value, value); } void hashmap_vec3_set(struct Hashmap* hashmap, const char* key, const vec3* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_vec3(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_vec3(&new_entry->value, value); } void hashmap_vec4_set(struct Hashmap* hashmap, const char* key, const vec4* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_vec4(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_vec4(&new_entry->value, value); } void hashmap_quat_set(struct Hashmap* hashmap, const char* key, const quat* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_quat(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_quat(&new_entry->value, value); } void hashmap_vec2_setf(struct Hashmap* hashmap, const char* key, const float x, const float y) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_vec2f(&new_entry->value, x, y); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_vec2f(&new_entry->value, x, y); } void hashmap_vec3_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_vec3f(&new_entry->value, x, y, z); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_vec3f(&new_entry->value, x, y, z); } void hashmap_vec4_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z, const float w) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_vec4f(&new_entry->value, x, y, z, w); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_vec4f(&new_entry->value, x, y, z, w); } void hashmap_quat_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z, const float w) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_quatf(&new_entry->value, x, y, z, w); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_quatf(&new_entry->value, x, y, z, w); } void hashmap_mat4_set(struct Hashmap* hashmap, const char* key, const mat4* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_mat4(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_mat4(&new_entry->value, value); } void hashmap_str_set(struct Hashmap* hashmap, const char* key, const char* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_str(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_str(&new_entry->value, value); } void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value) { - struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); - variant_assign_ptr(&new_entry->value, value); + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_ptr(&new_entry->value, value); } float hashmap_float_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_FLOAT); - return variant->val_float; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_FLOAT); + return variant->val_float; } int hashmap_int_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_INT); - return variant->val_int; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_INT); + return variant->val_int; } double hashmap_double_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_DOUBLE); - return variant->val_double; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_DOUBLE); + return variant->val_double; } bool hashmap_bool_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_BOOL); - return variant->val_bool; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_BOOL); + return variant->val_bool; } vec2 hashmap_vec2_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_VEC2); - return variant->val_vec2; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_VEC2); + return variant->val_vec2; } vec3 hashmap_vec3_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_VEC3); - return variant->val_vec3; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_VEC3); + return variant->val_vec3; } vec4 hashmap_vec4_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_VEC4); - return variant->val_vec4; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_VEC4); + return variant->val_vec4; } quat hashmap_quat_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_QUAT); - return variant->val_quat; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_QUAT); + return variant->val_quat; } const mat4* hashmap_mat4_get(const struct Hashmap* hashmap, const char* key) { - struct Variant* variant = hashmap_value_get(hashmap, key); - if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_MAT4); - return variant->val_mat4; + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_MAT4); + return variant->val_mat4; } const char* hashmap_str_get(const struct Hashmap* hashmap, const char* key) { - const struct Variant* variant = hashmap_value_get(hashmap, key); - return variant->val_str; + const struct Variant* variant = hashmap_value_get(hashmap, key); + return variant->val_str; } void* hashmap_ptr_get(const struct Hashmap* hashmap, const char* key) { - const struct Variant* variant = hashmap_value_get(hashmap, key); - return variant->val_voidptr; + const struct Variant* variant = hashmap_value_get(hashmap, key); + return variant->val_voidptr; } void hashmap_debug_print(const struct Hashmap* hashmap) { - if(!hashmap) return; - static char str[128]; - memset(str, '\0', 128); - for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) + if(!hashmap) return; + static char str[128]; + memset(str, '\0', 128); + for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) + { + log_message("Bucket : %d", i); + log_message("Bucket len : %d", array_len(hashmap->buckets[i])); + for(int j = 0; j < array_len(hashmap->buckets[i]); j++) { - log_message("Bucket : %d", i); - log_message("Bucket len : %d", array_len(hashmap->buckets[i])); - for(int j = 0; j < array_len(hashmap->buckets[i]); j++) - { - struct Hashmap_Entry* entry = &hashmap->buckets[i][j]; - const struct Variant* value = &entry->value; - const char* key = entry->key; - log_message("Key : %s", key); - variant_to_str(value, str, 128); - log_message("Value : %s", str); - memset(str, '\0', 128); - } + struct Hashmap_Entry* entry = &hashmap->buckets[i][j]; + const struct Variant* value = &entry->value; + const char* key = entry->key; + log_message("Key : %s", key); + variant_to_str(value, str, 128); + log_message("Value : %s", str); + memset(str, '\0', 128); } + } } void hashmap_iter_begin(struct Hashmap* hashmap) { - assert(hashmap); - hashmap->iter_bucket = 0; - hashmap->iter_index = -1; + assert(hashmap); + hashmap->iter_bucket = 0; + hashmap->iter_index = -1; } int hashmap_iter_next(struct Hashmap* hashmap, char** key, struct Variant** value) { - assert(hashmap); - for(;hashmap->iter_bucket < HASH_MAP_NUM_BUCKETS; hashmap->iter_bucket++) + assert(hashmap); + for(;hashmap->iter_bucket < HASH_MAP_NUM_BUCKETS; hashmap->iter_bucket++) + { + if(hashmap->buckets[hashmap->iter_bucket]) { - if(hashmap->buckets[hashmap->iter_bucket]) - { - if(++hashmap->iter_index < array_len(hashmap->buckets[hashmap->iter_bucket])) - { - *key = hashmap->buckets[hashmap->iter_bucket][hashmap->iter_index].key; - *value = &hashmap->buckets[hashmap->iter_bucket][hashmap->iter_index].value; - return 1; - } - else - { - hashmap->iter_index = -1; - } - } + if(++hashmap->iter_index < array_len(hashmap->buckets[hashmap->iter_bucket])) + { + *key = hashmap->buckets[hashmap->iter_bucket][hashmap->iter_index].key; + *value = &hashmap->buckets[hashmap->iter_bucket][hashmap->iter_index].value; + return 1; + } + else + { + hashmap->iter_index = -1; + } } - return 0; + } + return 0; } void hashmap_copy(struct Hashmap* from, struct Hashmap* to) { - struct Variant* from_val = NULL; - char* from_key = NULL; + struct Variant* from_val = NULL; + char* from_key = NULL; - HASHMAP_FOREACH(from, from_key, from_val) - { - hashmap_value_set(to, from_key, from_val); - } + HASHMAP_FOREACH(from, from_key, from_val) + { + hashmap_value_set(to, from_key, from_val); + } } diff --git a/src/common/hashmap.h b/src/common/hashmap.h index 74ac218..ae73dce 100644 --- a/src/common/hashmap.h +++ b/src/common/hashmap.h @@ -11,46 +11,46 @@ struct Hashmap; struct Variant; -struct Hashmap* hashmap_new(void); -void hashmap_free(struct Hashmap* hashmap); -void hashmap_copy(struct Hashmap* from, struct Hashmap* to); -void hashmap_value_remove(struct Hashmap* hashmap, const char* key); -bool hashmap_value_exists(struct Hashmap* hashmap, const char* key); -void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value); -struct Variant* hashmap_value_get(const struct Hashmap* hashmap, const char* key); - -void hashmap_float_set(struct Hashmap* hashmap, const char* key, const float value); -void hashmap_int_set(struct Hashmap* hashmap, const char* key, const int value); -void hashmap_double_set(struct Hashmap* hashmap, const char* key, const double value); -void hashmap_bool_set(struct Hashmap* hashmap, const char* key, const bool value); -void hashmap_vec2_set(struct Hashmap* hashmap, const char* key, const vec2* value); -void hashmap_vec3_set(struct Hashmap* hashmap, const char* key, const vec3* value); -void hashmap_vec4_set(struct Hashmap* hashmap, const char* key, const vec4* value); -void hashmap_quat_set(struct Hashmap* hashmap, const char* key, const quat* value); -void hashmap_vec2_setf(struct Hashmap* hashmap, const char* key, const float x, const float y); -void hashmap_vec3_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z); -void hashmap_vec4_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z, const float w); -void hashmap_quat_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z, const float w); -void hashmap_mat4_set(struct Hashmap* hashmap, const char* key, const mat4* value); -void hashmap_str_set(struct Hashmap* hashmap, const char* key, const char* value); -void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value); - -float hashmap_float_get(const struct Hashmap* hashmap, const char* key); -int hashmap_int_get(const struct Hashmap* hashmap, const char* key); -double hashmap_double_get(const struct Hashmap* hashmap, const char* key); -bool hashmap_bool_get(const struct Hashmap* hashmap, const char* key); -vec2 hashmap_vec2_get(const struct Hashmap* hashmap, const char* key); -vec3 hashmap_vec3_get(const struct Hashmap* hashmap, const char* key); -vec4 hashmap_vec4_get(const struct Hashmap* hashmap, const char* key); -quat hashmap_quat_get(const struct Hashmap* hashmap, const char* key); -const mat4* hashmap_mat4_get(const struct Hashmap* hashmap, const char* key); -const char* hashmap_str_get(const struct Hashmap* hashmap, const char* key); -void* hashmap_ptr_get(const struct Hashmap* hashmap, const char* key); - -void hashmap_debug_print(const struct Hashmap* hashmap); +struct Hashmap* hashmap_new(void); +void hashmap_free(struct Hashmap* hashmap); +void hashmap_copy(struct Hashmap* from, struct Hashmap* to); +void hashmap_value_remove(struct Hashmap* hashmap, const char* key); +bool hashmap_value_exists(struct Hashmap* hashmap, const char* key); +void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value); +struct Variant* hashmap_value_get(const struct Hashmap* hashmap, const char* key); + +void hashmap_float_set(struct Hashmap* hashmap, const char* key, const float value); +void hashmap_int_set(struct Hashmap* hashmap, const char* key, const int value); +void hashmap_double_set(struct Hashmap* hashmap, const char* key, const double value); +void hashmap_bool_set(struct Hashmap* hashmap, const char* key, const bool value); +void hashmap_vec2_set(struct Hashmap* hashmap, const char* key, const vec2* value); +void hashmap_vec3_set(struct Hashmap* hashmap, const char* key, const vec3* value); +void hashmap_vec4_set(struct Hashmap* hashmap, const char* key, const vec4* value); +void hashmap_quat_set(struct Hashmap* hashmap, const char* key, const quat* value); +void hashmap_vec2_setf(struct Hashmap* hashmap, const char* key, const float x, const float y); +void hashmap_vec3_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z); +void hashmap_vec4_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z, const float w); +void hashmap_quat_setf(struct Hashmap* hashmap, const char* key, const float x, const float y, const float z, const float w); +void hashmap_mat4_set(struct Hashmap* hashmap, const char* key, const mat4* value); +void hashmap_str_set(struct Hashmap* hashmap, const char* key, const char* value); +void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value); + +float hashmap_float_get(const struct Hashmap* hashmap, const char* key); +int hashmap_int_get(const struct Hashmap* hashmap, const char* key); +double hashmap_double_get(const struct Hashmap* hashmap, const char* key); +bool hashmap_bool_get(const struct Hashmap* hashmap, const char* key); +vec2 hashmap_vec2_get(const struct Hashmap* hashmap, const char* key); +vec3 hashmap_vec3_get(const struct Hashmap* hashmap, const char* key); +vec4 hashmap_vec4_get(const struct Hashmap* hashmap, const char* key); +quat hashmap_quat_get(const struct Hashmap* hashmap, const char* key); +const mat4* hashmap_mat4_get(const struct Hashmap* hashmap, const char* key); +const char* hashmap_str_get(const struct Hashmap* hashmap, const char* key); +void* hashmap_ptr_get(const struct Hashmap* hashmap, const char* key); + +void hashmap_debug_print(const struct Hashmap* hashmap); /* Only used during iteration */ -void hashmap_iter_begin(struct Hashmap* hashmap); -int hashmap_iter_next(struct Hashmap* hashmap, char** key, struct Variant** value); +void hashmap_iter_begin(struct Hashmap* hashmap); +int hashmap_iter_next(struct Hashmap* hashmap, char** key, struct Variant** value); #define HASHMAP_FOREACH(hashmap, key, value) \ hashmap_iter_begin(hashmap); \ diff --git a/src/common/linmath.c b/src/common/linmath.c index 16dcbaf..ea0383e 100644 --- a/src/common/linmath.c +++ b/src/common/linmath.c @@ -15,130 +15,130 @@ const vec3 UNIT_Z_NEG = {.x = 0, .y = 0, .z = -1}; void vec2_fill(vec2* res, float x, float y) { - res->x = x; - res->y = y; + res->x = x; + res->y = y; } void vec2_add(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x + v2->x; - res->y = v1->y + v2->y; + res->x = v1->x + v2->x; + res->y = v1->y + v2->y; } void vec2_sub(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x - v2->x; - res->y = v1->y - v2->y; + res->x = v1->x - v2->x; + res->y = v1->y - v2->y; } void vec2_assign(vec2* res, const vec2* val) { - res->x = val->x; - res->y = val->y; + res->x = val->x; + res->y = val->y; } float vec2_len(vec2* val) { - return sqrtf((val->x * val->x) + (val->y * val->y)); + return sqrtf((val->x * val->x) + (val->y * val->y)); } void vec2_norm(vec2* res, vec2* val) { - if (!val->x && !val->y) - { - vec2_assign(res, val); - return; - } + if (!val->x && !val->y) + { + vec2_assign(res, val); + return; + } - float l = 1.0f / vec2_len(val); - vec2 v; - v.x = val->x * l; - v.y = val->y * l; + float l = 1.0f / vec2_len(val); + vec2 v; + v.x = val->x * l; + v.y = val->y * l; - res->x = v.x; - res->y = v.y; + res->x = v.x; + res->y = v.y; } void vec2_mul(vec2* res, vec2* v1, vec2* v2) { - res->x = v1->x * v2->x; - res->y = v1->y * v2->y; + res->x = v1->x * v2->x; + res->y = v1->y * v2->y; } void vec3_fill(vec3* res, float x, float y, float z) { - res->x = x; - res->y = y; - res->z = z; + res->x = x; + res->y = y; + res->z = z; } void vec3_add(vec3* res, const vec3* v1, const vec3* v3) { - res->x = v1->x + v3->x; - res->y = v1->y + v3->y; - res->z = v1->z + v3->z; + res->x = v1->x + v3->x; + res->y = v1->y + v3->y; + res->z = v1->z + v3->z; } void vec3_sub(vec3* res, const vec3* v1, const vec3* v3) { - res->x = v1->x - v3->x; - res->y = v1->y - v3->y; - res->z = v1->z - v3->z; + res->x = v1->x - v3->x; + res->y = v1->y - v3->y; + res->z = v1->z - v3->z; } void vec3_assign(vec3* res, const vec3* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; + res->x = val->x; + res->y = val->y; + res->z = val->z; } void vec3_cross(vec3* res, const vec3* v1, const vec3* v2) { - vec3 v; - v.x = (v1->y * v2->z) - (v1->z * v2->y); - v.y = (v1->z * v2->x) - (v1->x * v2->z); - v.z = (v1->x * v2->y) - (v1->y * v2->x); + vec3 v; + v.x = (v1->y * v2->z) - (v1->z * v2->y); + v.y = (v1->z * v2->x) - (v1->x * v2->z); + v.z = (v1->x * v2->y) - (v1->y * v2->x); - res->x = v.x; - res->y = v.y; - res->z = v.z; + res->x = v.x; + res->y = v.y; + res->z = v.z; } float vec3_len(vec3* val) { - return sqrtf((val->x * val->x) + (val->y * val->y) + (val->z * val->z)); + return sqrtf((val->x * val->x) + (val->y * val->y) + (val->z * val->z)); } void vec3_norm(vec3* res, vec3* val) { - if (!val->x && !val->y && !val->z) - { - vec3_assign(res, val); - return; - } - - float l = 1.0f / vec3_len(val); - vec3 v; - v.x = val->x * l; - v.y = val->y * l; - v.z = val->z * l; + if (!val->x && !val->y && !val->z) + { + vec3_assign(res, val); + return; + } + + float l = 1.0f / vec3_len(val); + vec3 v; + v.x = val->x * l; + v.y = val->y * l; + v.z = val->z * l; - res->x = v.x; - res->y = v.y; - res->z = v.z; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void vec3_mul(vec3* res, vec3* v1, vec3* v3) { - res->x = v1->x * v3->x; - res->y = v1->y * v3->y; - res->z = v1->z * v3->z; + res->x = v1->x * v3->x; + res->y = v1->y * v3->y; + res->z = v1->z * v3->z; } void vec3_mul_mat4(vec3* res, vec3* val, mat4* mat) { - vec3 v; + vec3 v; v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + mat->mat[12]; v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + mat->mat[13]; v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + mat->mat[14]; @@ -149,126 +149,126 @@ void vec3_mul_mat4(vec3* res, vec3* val, mat4* mat) void vec3_scale(vec3* res, const vec3* val, float s) { - res->x = val->x * s; - res->y = val->y * s; - res->z = val->z * s; + res->x = val->x * s; + res->y = val->y * s; + res->z = val->z * s; } int vec3_equals(vec3* v1, vec3* v2) { - if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && - (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && - (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON))) - return 1; + if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && + (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON))) + return 1; - return 0; + return 0; } void vec3_transform_norm(vec3* res, const vec3* val, const mat4* mat) { - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) - Omits the translation, only scaling + rotating*/ - vec3 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + Omits the translation, only scaling + rotating*/ + vec3 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } float vec3_dot(vec3* v1, vec3* v2) { - return (v1->x * v2->x + - v1->y * v2->y + - v1->z * v2->z); + return (v1->x * v2->x + + v1->y * v2->y + + v1->z * v2->z); } void vec4_fill(vec4* res, float x, float y, float z, float w) { - res->x = x; - res->y = y; - res->z = z; - res->w = w; + res->x = x; + res->y = y; + res->z = z; + res->w = w; } void vec4_fill_vec3(vec4* res, const vec3* v, float w) { - res->x = v->x; - res->y = v->y; - res->z = v->z; - res->w = w; + res->x = v->x; + res->y = v->y; + res->z = v->z; + res->w = w; } void vec4_add(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x + v4->x; - res->y = v1->y + v4->y; - res->z = v1->z + v4->z; - res->w = v1->w + v4->w; + res->x = v1->x + v4->x; + res->y = v1->y + v4->y; + res->z = v1->z + v4->z; + res->w = v1->w + v4->w; } void vec4_sub(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x - v4->x; - res->y = v1->y - v4->y; - res->z = v1->z - v4->z; - res->w = v1->w - v4->w; + res->x = v1->x - v4->x; + res->y = v1->y - v4->y; + res->z = v1->z - v4->z; + res->w = v1->w - v4->w; } void vec4_assign(vec4* res, const vec4* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; - res->w = val->w; + res->x = val->x; + res->y = val->y; + res->z = val->z; + res->w = val->w; } float vec4_len(vec4* val) { - return sqrtf((val->x * val->x) + - (val->y * val->y) + - (val->z * val->z) + - (val->w * val->w)); + return sqrtf((val->x * val->x) + + (val->y * val->y) + + (val->z * val->z) + + (val->w * val->w)); } void vec4_norm(vec4* res, vec4* val) { - if (!val->x && !val->y && !val->z && !val->w) - { - vec4_assign(res, val); - return; - } - - float l = 1.0f / vec4_len(val); - vec4 v; - v.x = val->x * l; - v.y = val->y * l; - v.z = val->z * l; - v.w = val->w * l; + if (!val->x && !val->y && !val->z && !val->w) + { + vec4_assign(res, val); + return; + } + + float l = 1.0f / vec4_len(val); + vec4 v; + v.x = val->x * l; + v.y = val->y * l; + v.z = val->z * l; + v.w = val->w * l; - res->x = v.x; - res->y = v.y; - res->z = v.z; - res->w = v.w; + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; } void vec4_mul(vec4* res, vec4* v1, vec4* v4) { - res->x = v1->x * v4->x; - res->y = v1->y * v4->y; - res->z = v1->z * v4->z; - res->w = v1->w * v4->w; + res->x = v1->x * v4->x; + res->y = v1->y * v4->y; + res->z = v1->z * v4->z; + res->w = v1->w * v4->w; } void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat) { - vec4 v; + vec4 v; v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8] + val->w * mat->mat[12]; v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9] + val->w * mat->mat[13]; v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10] + val->w * mat->mat[14]; @@ -281,77 +281,77 @@ void vec4_mul_mat4(vec4* res, vec4* val, mat4* mat) void vec4_scale(vec4* res, const vec4* val, float s) { - res->x = val->x * s; - res->y = val->y * s; - res->z = val->z * s; - res->w = val->w * s; + res->x = val->x * s; + res->y = val->y * s; + res->z = val->z * s; + res->w = val->w * s; } int vec4_equals(vec4* v1, vec4* v2) { - if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && - (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && - (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON)) && - (v1->w < (v2->w + EPSILON) && v1->w > (v2->w - EPSILON))) - return 1; + if ((v1->x < (v2->x + EPSILON) && v1->x > (v2->x - EPSILON)) && + (v1->y < (v2->y + EPSILON) && v1->y > (v2->y - EPSILON)) && + (v1->z < (v2->z + EPSILON) && v1->z > (v2->z - EPSILON)) && + (v1->w < (v2->w + EPSILON) && v1->w > (v2->w - EPSILON))) + return 1; - return 0; + return 0; } void vec4_transform_norm(vec4* res, const vec4* val, const mat4* mat) { - /* - a = (Vx, Vy, Vz, 0) - b = (a×M)T - Out = (bx, by, bz) + /* + a = (Vx, Vy, Vz, 0) + b = (a×M)T + Out = (bx, by, bz) - Omits the translation, only scaling + rotating*/ - vec4 v; - v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; - v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; - v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; - res->x = v.x; - res->y = v.y; - res->z = v.z; + Omits the translation, only scaling + rotating*/ + vec4 v; + v.x = val->x * mat->mat[0] + val->y * mat->mat[4] + val->z * mat->mat[8]; + v.y = val->x * mat->mat[1] + val->y * mat->mat[5] + val->z * mat->mat[9]; + v.z = val->x * mat->mat[2] + val->y * mat->mat[6] + val->z * mat->mat[10]; + res->x = v.x; + res->y = v.y; + res->z = v.z; } void mat4_identity(mat4* res) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = res->mat[5] = res->mat[10] = res->mat[15] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = res->mat[5] = res->mat[10] = res->mat[15] = 1.0f; } void mat4_mul(mat4* res, const mat4* mat1, const mat4* mat2) { - float mat[16]; - const float *m1 = mat1->mat, *m2 = mat2->mat; + float mat[16]; + const float *m1 = mat1->mat, *m2 = mat2->mat; - mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; - mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; - mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; - mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; + mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]; + mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]; + mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]; + mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]; - mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; - mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; - mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; - mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; + mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]; + mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]; + mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]; + mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]; - mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; - mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; - mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; - mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; + mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]; + mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]; + mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]; + mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]; - mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; - mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; - mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; - mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; + mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]; + mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]; + mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]; + mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]; - memcpy(res->mat, mat, sizeof(float)*16); + memcpy(res->mat, mat, sizeof(float)*16); } void mat4_translate(mat4* res, float x, float y, float z) { - memset(res->mat, 0, sizeof(float) * 16); + memset(res->mat, 0, sizeof(float) * 16); res->mat[0] = 1.0f; res->mat[5] = 1.0f; res->mat[10] = 1.0f; @@ -364,7 +364,7 @@ void mat4_translate(mat4* res, float x, float y, float z) void mat4_lookat(mat4* res, const vec3* eye, const vec3* center, const vec3* up_vec) { - vec3 f, up, s, u; + vec3 f, up, s, u; mat4 translate; vec3_sub(&f, center, eye); @@ -399,63 +399,63 @@ void mat4_lookat(mat4* res, const vec3* eye, const vec3* center, const vec3* up_ void mat4_perspective(mat4* res, float fov, float aspect, float nearz, float farz ) { - float r = TO_RADIANS(fov / 2); - float deltaz = farz - nearz; - float s = sin(r); + float r = TO_RADIANS(fov / 2); + float deltaz = farz - nearz; + float s = (float)sin(r); float cotangent = 0; - if (deltaz == 0 || s == 0 || aspect == 0) - return; + if (deltaz == 0 || s == 0 || aspect == 0) + return; - cotangent = cos(r) / s; - mat4_identity(res); - res->mat[0] = cotangent / aspect; - res->mat[5] = cotangent; - res->mat[10] = -(farz + nearz) / deltaz; - res->mat[11] = -1; - res->mat[14] = -2 * nearz * farz / deltaz; - res->mat[15] = 0; + cotangent = (float)cos(r) / s; + mat4_identity(res); + res->mat[0] = cotangent / aspect; + res->mat[5] = cotangent; + res->mat[10] = -(farz + nearz) / deltaz; + res->mat[11] = -1; + res->mat[14] = -2 * nearz * farz / deltaz; + res->mat[15] = 0; } void mat4_ortho(mat4* res, - float left, float right, - float bottom, float top, - float nearz, float farz) -{ - float tx = -((right + left) / (right - left)); - float ty = -((top + bottom) / (top - bottom)); - float tz = -((farz + nearz) / (farz - nearz)); - mat4_identity(res); - res->mat[0] = 2 / (right - left); - res->mat[5] = 2 / (top - bottom); - res->mat[10] = -2 / (farz - nearz); - res->mat[12] = tx; - res->mat[13] = ty; - res->mat[14] = tz; + float left, float right, + float bottom, float top, + float nearz, float farz) +{ + float tx = -((right + left) / (right - left)); + float ty = -((top + bottom) / (top - bottom)); + float tz = -((farz + nearz) / (farz - nearz)); + mat4_identity(res); + res->mat[0] = 2 / (right - left); + res->mat[5] = 2 / (top - bottom); + res->mat[10] = -2 / (farz - nearz); + res->mat[12] = tx; + res->mat[13] = ty; + res->mat[14] = tz; } void mat4_scale(mat4* res, float x, float y, float z) { - memset(res->mat, 0, sizeof(float) * 16); - res->mat[0] = x; - res->mat[5] = y; - res->mat[10] = z; - res->mat[15] = 1.0f; + memset(res->mat, 0, sizeof(float) * 16); + res->mat[0] = x; + res->mat[5] = y; + res->mat[10] = z; + res->mat[15] = 1.0f; } void mat4_from_quat(mat4* res, const quat* q) { - double xx = q->x * q->x; - double xy = q->x * q->y; - double xz = q->x * q->z; - double xw = q->x * q->w; + float xx = q->x * q->x; + float xy = q->x * q->y; + float xz = q->x * q->z; + float xw = q->x * q->w; - double yy = q->y * q->y; - double yz = q->y * q->z; - double yw = q->y * q->w; + float yy = q->y * q->y; + float yz = q->y * q->z; + float yw = q->y * q->w; - double zz = q->z * q->z; - double zw = q->z * q->w; + float zz = q->z * q->z; + float zw = q->z * q->w; res->mat[0] = 1 - 2 * (yy + zz); res->mat[1] = 2 * (xy + zw); @@ -480,210 +480,210 @@ void mat4_from_quat(mat4* res, const quat* q) void mat4_rot_x(mat4* res, const float angle) { - res->mat[0] = 1.0f; - res->mat[1] = 0.0f; - res->mat[2] = 0.0f; - res->mat[3] = 0.0f; - - res->mat[4] = 0.0f; - res->mat[5] = cosf(angle); - res->mat[6] = sinf(angle); - res->mat[7] = 0.0f; - - res->mat[8] = 0.0f; - res->mat[9] = -sinf(angle); - res->mat[10] = cosf(angle); - res->mat[11] = 0.0f; - - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[0] = 1.0f; + res->mat[1] = 0.0f; + res->mat[2] = 0.0f; + res->mat[3] = 0.0f; + + res->mat[4] = 0.0f; + res->mat[5] = cosf(angle); + res->mat[6] = sinf(angle); + res->mat[7] = 0.0f; + + res->mat[8] = 0.0f; + res->mat[9] = -sinf(angle); + res->mat[10] = cosf(angle); + res->mat[11] = 0.0f; + + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_rot_y(mat4* res, float angle) { - res->mat[0] = cosf(angle); - res->mat[1] = 0.0f; - res->mat[2] = -sinf(angle); - res->mat[3] = 0.0f; + res->mat[0] = cosf(angle); + res->mat[1] = 0.0f; + res->mat[2] = -sinf(angle); + res->mat[3] = 0.0f; - res->mat[4] = 0.0f; - res->mat[5] = 1.0f; - res->mat[6] = 0.0f; - res->mat[7] = 0.0f; + res->mat[4] = 0.0f; + res->mat[5] = 1.0f; + res->mat[6] = 0.0f; + res->mat[7] = 0.0f; - res->mat[8] = sinf(angle); - res->mat[9] = 0.0f; - res->mat[10] = cosf(angle); - res->mat[11] = 0.0f; + res->mat[8] = sinf(angle); + res->mat[9] = 0.0f; + res->mat[10] = cosf(angle); + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_rot_z(mat4* res, float angle) { - res->mat[0] = cosf(angle); - res->mat[1] = sinf(angle); - res->mat[2] = 0.0f; - res->mat[3] = 0.0f; + res->mat[0] = cosf(angle); + res->mat[1] = sinf(angle); + res->mat[2] = 0.0f; + res->mat[3] = 0.0f; - res->mat[4] = -sinf(angle); - res->mat[5] = cosf(angle); - res->mat[6] = 0.0f; - res->mat[7] = 0.0f; + res->mat[4] = -sinf(angle); + res->mat[5] = cosf(angle); + res->mat[6] = 0.0f; + res->mat[7] = 0.0f; - res->mat[8] = 0.0f; - res->mat[9] = 0.0f; - res->mat[10] = 1.0f; - res->mat[11] = 0.0f; + res->mat[8] = 0.0f; + res->mat[9] = 0.0f; + res->mat[10] = 1.0f; + res->mat[11] = 0.0f; - res->mat[12] = 0.0f; - res->mat[13] = 0.0f; - res->mat[14] = 0.0f; - res->mat[15] = 1.0f; + res->mat[12] = 0.0f; + res->mat[13] = 0.0f; + res->mat[14] = 0.0f; + res->mat[15] = 1.0f; } void mat4_assign(mat4* res, const mat4* m) { - if(res == m) - return; - memcpy(res->mat, m->mat, sizeof(float) * 16); + if(res == m) + return; + memcpy(res->mat, m->mat, sizeof(float) * 16); } void mat4_inverse(mat4* res, mat4* mat) { - mat4 tmp; - float det; - int i; - - tmp.mat[0] = mat->mat[5] * mat->mat[10] * mat->mat[15] - - mat->mat[5] * mat->mat[11] * mat->mat[14] - - mat->mat[9] * mat->mat[6] * mat->mat[15] + - mat->mat[9] * mat->mat[7] * mat->mat[14] + - mat->mat[13] * mat->mat[6] * mat->mat[11] - - mat->mat[13] * mat->mat[7] * mat->mat[10]; - - tmp.mat[4] = -mat->mat[4] * mat->mat[10] * mat->mat[15] + - mat->mat[4] * mat->mat[11] * mat->mat[14] + - mat->mat[8] * mat->mat[6] * mat->mat[15] - - mat->mat[8] * mat->mat[7] * mat->mat[14] - - mat->mat[12] * mat->mat[6] * mat->mat[11] + - mat->mat[12] * mat->mat[7] * mat->mat[10]; - - tmp.mat[8] = mat->mat[4] * mat->mat[9] * mat->mat[15] - - mat->mat[4] * mat->mat[11] * mat->mat[13] - - mat->mat[8] * mat->mat[5] * mat->mat[15] + - mat->mat[8] * mat->mat[7] * mat->mat[13] + - mat->mat[12] * mat->mat[5] * mat->mat[11] - - mat->mat[12] * mat->mat[7] * mat->mat[9]; - - tmp.mat[12] = -mat->mat[4] * mat->mat[9] * mat->mat[14] + - mat->mat[4] * mat->mat[10] * mat->mat[13] + - mat->mat[8] * mat->mat[5] * mat->mat[14] - - mat->mat[8] * mat->mat[6] * mat->mat[13] - - mat->mat[12] * mat->mat[5] * mat->mat[10] + - mat->mat[12] * mat->mat[6] * mat->mat[9]; - - tmp.mat[1] = -mat->mat[1] * mat->mat[10] * mat->mat[15] + - mat->mat[1] * mat->mat[11] * mat->mat[14] + - mat->mat[9] * mat->mat[2] * mat->mat[15] - - mat->mat[9] * mat->mat[3] * mat->mat[14] - - mat->mat[13] * mat->mat[2] * mat->mat[11] + - mat->mat[13] * mat->mat[3] * mat->mat[10]; - - tmp.mat[5] = mat->mat[0] * mat->mat[10] * mat->mat[15] - - mat->mat[0] * mat->mat[11] * mat->mat[14] - - mat->mat[8] * mat->mat[2] * mat->mat[15] + - mat->mat[8] * mat->mat[3] * mat->mat[14] + - mat->mat[12] * mat->mat[2] * mat->mat[11] - - mat->mat[12] * mat->mat[3] * mat->mat[10]; - - tmp.mat[9] = -mat->mat[0] * mat->mat[9] * mat->mat[15] + - mat->mat[0] * mat->mat[11] * mat->mat[13] + - mat->mat[8] * mat->mat[1] * mat->mat[15] - - mat->mat[8] * mat->mat[3] * mat->mat[13] - - mat->mat[12] * mat->mat[1] * mat->mat[11] + - mat->mat[12] * mat->mat[3] * mat->mat[9]; - - tmp.mat[13] = mat->mat[0] * mat->mat[9] * mat->mat[14] - - mat->mat[0] * mat->mat[10] * mat->mat[13] - - mat->mat[8] * mat->mat[1] * mat->mat[14] + - mat->mat[8] * mat->mat[2] * mat->mat[13] + - mat->mat[12] * mat->mat[1] * mat->mat[10] - - mat->mat[12] * mat->mat[2] * mat->mat[9]; - - tmp.mat[2] = mat->mat[1] * mat->mat[6] * mat->mat[15] - - mat->mat[1] * mat->mat[7] * mat->mat[14] - - mat->mat[5] * mat->mat[2] * mat->mat[15] + - mat->mat[5] * mat->mat[3] * mat->mat[14] + - mat->mat[13] * mat->mat[2] * mat->mat[7] - - mat->mat[13] * mat->mat[3] * mat->mat[6]; - - tmp.mat[6] = -mat->mat[0] * mat->mat[6] * mat->mat[15] + - mat->mat[0] * mat->mat[7] * mat->mat[14] + - mat->mat[4] * mat->mat[2] * mat->mat[15] - - mat->mat[4] * mat->mat[3] * mat->mat[14] - - mat->mat[12] * mat->mat[2] * mat->mat[7] + - mat->mat[12] * mat->mat[3] * mat->mat[6]; - - tmp.mat[10] = mat->mat[0] * mat->mat[5] * mat->mat[15] - - mat->mat[0] * mat->mat[7] * mat->mat[13] - - mat->mat[4] * mat->mat[1] * mat->mat[15] + - mat->mat[4] * mat->mat[3] * mat->mat[13] + - mat->mat[12] * mat->mat[1] * mat->mat[7] - - mat->mat[12] * mat->mat[3] * mat->mat[5]; - - tmp.mat[14] = -mat->mat[0] * mat->mat[5] * mat->mat[14] + - mat->mat[0] * mat->mat[6] * mat->mat[13] + - mat->mat[4] * mat->mat[1] * mat->mat[14] - - mat->mat[4] * mat->mat[2] * mat->mat[13] - - mat->mat[12] * mat->mat[1] * mat->mat[6] + - mat->mat[12] * mat->mat[2] * mat->mat[5]; - - tmp.mat[3] = -mat->mat[1] * mat->mat[6] * mat->mat[11] + - mat->mat[1] * mat->mat[7] * mat->mat[10] + - mat->mat[5] * mat->mat[2] * mat->mat[11] - - mat->mat[5] * mat->mat[3] * mat->mat[10] - - mat->mat[9] * mat->mat[2] * mat->mat[7] + - mat->mat[9] * mat->mat[3] * mat->mat[6]; - - tmp.mat[7] = mat->mat[0] * mat->mat[6] * mat->mat[11] - - mat->mat[0] * mat->mat[7] * mat->mat[10] - - mat->mat[4] * mat->mat[2] * mat->mat[11] + - mat->mat[4] * mat->mat[3] * mat->mat[10] + - mat->mat[8] * mat->mat[2] * mat->mat[7] - - mat->mat[8] * mat->mat[3] * mat->mat[6]; - - tmp.mat[11] = -mat->mat[0] * mat->mat[5] * mat->mat[11] + - mat->mat[0] * mat->mat[7] * mat->mat[9] + - mat->mat[4] * mat->mat[1] * mat->mat[11] - - mat->mat[4] * mat->mat[3] * mat->mat[9] - - mat->mat[8] * mat->mat[1] * mat->mat[7] + - mat->mat[8] * mat->mat[3] * mat->mat[5]; - - tmp.mat[15] = mat->mat[0] * mat->mat[5] * mat->mat[10] - - mat->mat[0] * mat->mat[6] * mat->mat[9] - - mat->mat[4] * mat->mat[1] * mat->mat[10] + - mat->mat[4] * mat->mat[2] * mat->mat[9] + - mat->mat[8] * mat->mat[1] * mat->mat[6] - - mat->mat[8] * mat->mat[2] * mat->mat[5]; - - det = mat->mat[0] * tmp.mat[0] + mat->mat[1] * tmp.mat[4] + mat->mat[2] * tmp.mat[8] + mat->mat[3] * tmp.mat[12]; - - if (det == 0) { - return; - } - - det = 1.0 / det; - - for (i = 0; i < 16; i++) { - res->mat[i] = tmp.mat[i] * det; - } + mat4 tmp; + float det; + int i; + + tmp.mat[0] = mat->mat[5] * mat->mat[10] * mat->mat[15] - + mat->mat[5] * mat->mat[11] * mat->mat[14] - + mat->mat[9] * mat->mat[6] * mat->mat[15] + + mat->mat[9] * mat->mat[7] * mat->mat[14] + + mat->mat[13] * mat->mat[6] * mat->mat[11] - + mat->mat[13] * mat->mat[7] * mat->mat[10]; + + tmp.mat[4] = -mat->mat[4] * mat->mat[10] * mat->mat[15] + + mat->mat[4] * mat->mat[11] * mat->mat[14] + + mat->mat[8] * mat->mat[6] * mat->mat[15] - + mat->mat[8] * mat->mat[7] * mat->mat[14] - + mat->mat[12] * mat->mat[6] * mat->mat[11] + + mat->mat[12] * mat->mat[7] * mat->mat[10]; + + tmp.mat[8] = mat->mat[4] * mat->mat[9] * mat->mat[15] - + mat->mat[4] * mat->mat[11] * mat->mat[13] - + mat->mat[8] * mat->mat[5] * mat->mat[15] + + mat->mat[8] * mat->mat[7] * mat->mat[13] + + mat->mat[12] * mat->mat[5] * mat->mat[11] - + mat->mat[12] * mat->mat[7] * mat->mat[9]; + + tmp.mat[12] = -mat->mat[4] * mat->mat[9] * mat->mat[14] + + mat->mat[4] * mat->mat[10] * mat->mat[13] + + mat->mat[8] * mat->mat[5] * mat->mat[14] - + mat->mat[8] * mat->mat[6] * mat->mat[13] - + mat->mat[12] * mat->mat[5] * mat->mat[10] + + mat->mat[12] * mat->mat[6] * mat->mat[9]; + + tmp.mat[1] = -mat->mat[1] * mat->mat[10] * mat->mat[15] + + mat->mat[1] * mat->mat[11] * mat->mat[14] + + mat->mat[9] * mat->mat[2] * mat->mat[15] - + mat->mat[9] * mat->mat[3] * mat->mat[14] - + mat->mat[13] * mat->mat[2] * mat->mat[11] + + mat->mat[13] * mat->mat[3] * mat->mat[10]; + + tmp.mat[5] = mat->mat[0] * mat->mat[10] * mat->mat[15] - + mat->mat[0] * mat->mat[11] * mat->mat[14] - + mat->mat[8] * mat->mat[2] * mat->mat[15] + + mat->mat[8] * mat->mat[3] * mat->mat[14] + + mat->mat[12] * mat->mat[2] * mat->mat[11] - + mat->mat[12] * mat->mat[3] * mat->mat[10]; + + tmp.mat[9] = -mat->mat[0] * mat->mat[9] * mat->mat[15] + + mat->mat[0] * mat->mat[11] * mat->mat[13] + + mat->mat[8] * mat->mat[1] * mat->mat[15] - + mat->mat[8] * mat->mat[3] * mat->mat[13] - + mat->mat[12] * mat->mat[1] * mat->mat[11] + + mat->mat[12] * mat->mat[3] * mat->mat[9]; + + tmp.mat[13] = mat->mat[0] * mat->mat[9] * mat->mat[14] - + mat->mat[0] * mat->mat[10] * mat->mat[13] - + mat->mat[8] * mat->mat[1] * mat->mat[14] + + mat->mat[8] * mat->mat[2] * mat->mat[13] + + mat->mat[12] * mat->mat[1] * mat->mat[10] - + mat->mat[12] * mat->mat[2] * mat->mat[9]; + + tmp.mat[2] = mat->mat[1] * mat->mat[6] * mat->mat[15] - + mat->mat[1] * mat->mat[7] * mat->mat[14] - + mat->mat[5] * mat->mat[2] * mat->mat[15] + + mat->mat[5] * mat->mat[3] * mat->mat[14] + + mat->mat[13] * mat->mat[2] * mat->mat[7] - + mat->mat[13] * mat->mat[3] * mat->mat[6]; + + tmp.mat[6] = -mat->mat[0] * mat->mat[6] * mat->mat[15] + + mat->mat[0] * mat->mat[7] * mat->mat[14] + + mat->mat[4] * mat->mat[2] * mat->mat[15] - + mat->mat[4] * mat->mat[3] * mat->mat[14] - + mat->mat[12] * mat->mat[2] * mat->mat[7] + + mat->mat[12] * mat->mat[3] * mat->mat[6]; + + tmp.mat[10] = mat->mat[0] * mat->mat[5] * mat->mat[15] - + mat->mat[0] * mat->mat[7] * mat->mat[13] - + mat->mat[4] * mat->mat[1] * mat->mat[15] + + mat->mat[4] * mat->mat[3] * mat->mat[13] + + mat->mat[12] * mat->mat[1] * mat->mat[7] - + mat->mat[12] * mat->mat[3] * mat->mat[5]; + + tmp.mat[14] = -mat->mat[0] * mat->mat[5] * mat->mat[14] + + mat->mat[0] * mat->mat[6] * mat->mat[13] + + mat->mat[4] * mat->mat[1] * mat->mat[14] - + mat->mat[4] * mat->mat[2] * mat->mat[13] - + mat->mat[12] * mat->mat[1] * mat->mat[6] + + mat->mat[12] * mat->mat[2] * mat->mat[5]; + + tmp.mat[3] = -mat->mat[1] * mat->mat[6] * mat->mat[11] + + mat->mat[1] * mat->mat[7] * mat->mat[10] + + mat->mat[5] * mat->mat[2] * mat->mat[11] - + mat->mat[5] * mat->mat[3] * mat->mat[10] - + mat->mat[9] * mat->mat[2] * mat->mat[7] + + mat->mat[9] * mat->mat[3] * mat->mat[6]; + + tmp.mat[7] = mat->mat[0] * mat->mat[6] * mat->mat[11] - + mat->mat[0] * mat->mat[7] * mat->mat[10] - + mat->mat[4] * mat->mat[2] * mat->mat[11] + + mat->mat[4] * mat->mat[3] * mat->mat[10] + + mat->mat[8] * mat->mat[2] * mat->mat[7] - + mat->mat[8] * mat->mat[3] * mat->mat[6]; + + tmp.mat[11] = -mat->mat[0] * mat->mat[5] * mat->mat[11] + + mat->mat[0] * mat->mat[7] * mat->mat[9] + + mat->mat[4] * mat->mat[1] * mat->mat[11] - + mat->mat[4] * mat->mat[3] * mat->mat[9] - + mat->mat[8] * mat->mat[1] * mat->mat[7] + + mat->mat[8] * mat->mat[3] * mat->mat[5]; + + tmp.mat[15] = mat->mat[0] * mat->mat[5] * mat->mat[10] - + mat->mat[0] * mat->mat[6] * mat->mat[9] - + mat->mat[4] * mat->mat[1] * mat->mat[10] + + mat->mat[4] * mat->mat[2] * mat->mat[9] + + mat->mat[8] * mat->mat[1] * mat->mat[6] - + mat->mat[8] * mat->mat[2] * mat->mat[5]; + + det = mat->mat[0] * tmp.mat[0] + mat->mat[1] * tmp.mat[4] + mat->mat[2] * tmp.mat[8] + mat->mat[3] * tmp.mat[12]; + + if (det == 0) { + return; + } + + det = 1.f / det; + + for (i = 0; i < 16; i++) { + res->mat[i] = tmp.mat[i] * det; + } } @@ -691,120 +691,120 @@ void mat4_inverse(mat4* res, mat4* mat) void quat_fill(quat* res, float x, float y, float z, float w) { - res->x = x; - res->y = y; - res->z = z; - res->w = w; + res->x = x; + res->y = y; + res->z = z; + res->w = w; } void quat_identity(quat* res) { - res->x = 0.0; - res->y = 0.0; - res->z = 0.0; - res->w = 1.0; + res->x = 0.0; + res->y = 0.0; + res->z = 0.0; + res->w = 1.0; } void quat_mul_vec3(vec3* res, const quat* q, const vec3* v) { - vec3 uv, uuv, qvec; - qvec.x = q->x; - qvec.y = q->y; - qvec.z = q->z; + vec3 uv, uuv, qvec; + qvec.x = q->x; + qvec.y = q->y; + qvec.z = q->z; - vec3_cross(&uv, &qvec, v); - vec3_cross(&uuv, &qvec, &uv); + vec3_cross(&uv, &qvec, v); + vec3_cross(&uuv, &qvec, &uv); - vec3_scale(&uv, &uv, (2.0f * q->w)); - vec3_scale(&uuv, &uuv, 2.0f); + vec3_scale(&uv, &uv, (2.0f * q->w)); + vec3_scale(&uuv, &uuv, 2.0f); - vec3_add(res, v, &uv); - vec3_add(res, res, &uuv); + vec3_add(res, v, &uv); + vec3_add(res, res, &uuv); } void quat_assign(quat* res, const quat* val) { - res->x = val->x; - res->y = val->y; - res->z = val->z; - res->w = val->w; + res->x = val->x; + res->y = val->y; + res->z = val->z; + res->w = val->w; } void quat_mul(quat* res, const quat* q1, const quat* q2) { - quat tmp1, tmp2; - quat_assign(&tmp1, q1); - quat_assign(&tmp2, q2); + quat tmp1, tmp2; + quat_assign(&tmp1, q1); + quat_assign(&tmp2, q2); - res->x = tmp1.w * tmp2.x + tmp1.x * tmp2.w + tmp1.y * tmp2.z - tmp1.z * tmp2.y; - res->y = tmp1.w * tmp2.y + tmp1.y * tmp2.w + tmp1.z * tmp2.x - tmp1.x * tmp2.z; - res->z = tmp1.w * tmp2.z + tmp1.z * tmp2.w + tmp1.x * tmp2.y - tmp1.y * tmp2.x; + res->x = tmp1.w * tmp2.x + tmp1.x * tmp2.w + tmp1.y * tmp2.z - tmp1.z * tmp2.y; + res->y = tmp1.w * tmp2.y + tmp1.y * tmp2.w + tmp1.z * tmp2.x - tmp1.x * tmp2.z; + res->z = tmp1.w * tmp2.z + tmp1.z * tmp2.w + tmp1.x * tmp2.y - tmp1.y * tmp2.x; res->w = tmp1.w * tmp2.w - tmp1.x * tmp2.x - tmp1.y * tmp2.y - tmp1.z * tmp2.z; } float quat_len_sq(const quat* q) { - return (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); + return (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); } float quat_len(const quat* q) { - return sqrt(quat_len_sq(q)); + return (float)sqrt(quat_len_sq(q)); } void quat_norm(quat* res, const quat* val) { - float length = quat_len(val); - if(fabs(length) < EPSILON) - { - quat_fill(res, 0.0f, 0.0f, 0.0f, 0.0f); - return; - } + float length = quat_len(val); + if(fabs(length) < EPSILON) + { + quat_fill(res, 0.0f, 0.0f, 0.0f, 0.0f); + return; + } - quat_fill(res, res->x / length, res->y / length, res->z / length, res->w / length); + quat_fill(res, res->x / length, res->y / length, res->z / length, res->w / length); } void quat_axis_angle(quat* res, const vec3* v, float angle) { - float half_angle = angle * 0.5f; - float scale = sinf(half_angle); + float half_angle = angle * 0.5f; + float scale = sinf(half_angle); - res->x = v->x * scale; - res->y = v->y * scale; - res->z = v->z * scale; - res->w = cosf(half_angle); - quat_norm(res, res); + res->x = v->x * scale; + res->y = v->y * scale; + res->z = v->z * scale; + res->w = cosf(half_angle); + quat_norm(res, res); } void quat_get_forward_rh(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Z_NEG); + quat_mul_vec3(res, q, &UNIT_Z_NEG); } void quat_get_forward_lh(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Z); + quat_mul_vec3(res, q, &UNIT_Z); } void quat_get_up(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_Y); + quat_mul_vec3(res, q, &UNIT_Y); } void quat_get_right(vec3* res, const quat* q) { - quat_mul_vec3(res, q, &UNIT_X); + quat_mul_vec3(res, q, &UNIT_X); } float quat_get_pitch(const quat* q) { - float result = atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); + float result = (float)atan2(2 * (q->y * q->z + q->w * q->x), q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z); return result; } float quat_get_yaw(const quat* q) { - float result = asin(-2 * (q->x * q->z - q->w * q->y)); + float result = (float)asin(-2 * (q->x * q->z - q->w * q->y)); return result; } @@ -813,3 +813,14 @@ float quat_get_roll(const quat* q) float result = atan2(2 * (q->x * q->y + q->w * q->z), q->w * q->w + q->x * q->x - q->y * q->y - q->z * q->z); return result; } + +void quat_mul_mat4(quat* res, quat* val, mat4* mat) +{ + vec4 v; + vec4_fill(&v, val->x, val->y, val->z, val->w); + vec4_mul_mat4(&v, &v, mat); + res->x = v.x; + res->y = v.y; + res->z = v.z; + res->w = v.w; +} diff --git a/src/common/linmath.h b/src/common/linmath.h index ffb6ceb..f82b81a 100644 --- a/src/common/linmath.h +++ b/src/common/linmath.h @@ -11,7 +11,7 @@ i'll make my own additions like SIMD etc later on. /* conversions */ #ifndef M_PI - #define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846f #endif #define EPSILON 0.0001 #define TO_RADIANS(degrees) ((degrees * M_PI) / 180.0) @@ -132,5 +132,6 @@ void quat_mul_vec3(vec3* res, const quat* q, const vec3* v); void quat_assign(quat* res, const quat* val); void quat_identity(quat* res); void quat_fill(quat* res, float x, float y, float z, float w); +void quat_mul_mat4(quat* res, quat* val, mat4* mat); #endif diff --git a/src/common/parser.c b/src/common/parser.c index b75ed09..384c312 100644 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -15,70 +15,70 @@ bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line) { - if(!file) - { - log_error("parser:load", "Invalid file handle for file %s", filename); - return false; - } + if(!file) + { + log_error("parser:load", "Invalid file handle for file %s", filename); + return false; + } - if(!assign_func) - { - log_error("parser:load", "No assign function provided to load file %s", filename); - return false; - } + if(!assign_func) + { + log_error("parser:load", "No assign function provided to load file %s", filename); + return false; + } - /* Read line by line, ignore comments */ - char format_str[64]; - char key_str[HASH_MAX_KEY_LEN]; - char value_str[MAX_VALUE_LEN]; - char line_buffer[MAX_LINE_LEN]; - memset(key_str, '\0', HASH_MAX_KEY_LEN); - memset(line_buffer, '\0', MAX_LINE_LEN); + /* Read line by line, ignore comments */ + char format_str[64]; + char key_str[HASH_MAX_KEY_LEN]; + char value_str[MAX_VALUE_LEN]; + char line_buffer[MAX_LINE_LEN]; + memset(key_str, '\0', HASH_MAX_KEY_LEN); + memset(line_buffer, '\0', MAX_LINE_LEN); memset(format_str, '\0', 64); - snprintf(format_str, 64, " %%%d[^: ] : %%%d[^\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN); + snprintf(format_str, 64, " %%%d[^: ] : %%%d[^\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN); - while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) - { - current_line++; - memset(key_str, '\0', HASH_MAX_KEY_LEN); - memset(value_str, '\0', HASH_MAX_KEY_LEN); + while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + { + current_line++; + memset(key_str, '\0', HASH_MAX_KEY_LEN); + memset(value_str, '\0', HASH_MAX_KEY_LEN); - if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0) - { - if(return_on_emptyline) - return true; - else - continue; - } + if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0) + { + if(return_on_emptyline) + return true; + else + continue; + } - if(line_buffer[0] == '#') - continue; + if(line_buffer[0] == '#') + continue; - if(sscanf(line_buffer, format_str, key_str, value_str) != 2) - { - log_warning("Malformed value in config file %s, line %d", filename, current_line); - continue; - } - - assign_func(key_str, value_str, filename, current_line); + if(sscanf(line_buffer, format_str, key_str, value_str) != 2) + { + log_warning("Malformed value in config file %s, line %d", filename, current_line); + continue; } - return true; + + assign_func(key_str, value_str, filename, current_line); + } + return true; } struct Parser* parser_load_objects(FILE* file, const char* filename) { - /* Note, this is isn't really a proper parser and might have lurking bugs, it just has to be - good enough for my needs. For example, multiple opening and closing braces on them - same line are fine but opening brace on the same line as type is NOT fine. There - are probably several others that i don't know of yet. This is just a temporary solution, - i may completely change the format in the future or switch to binary or use something like - JSON or TOML etc. */ + /* Note, this is isn't really a proper parser and might have lurking bugs, it just has to be + good enough for my needs. For example, multiple opening and closing braces on them + same line are fine but opening brace on the same line as type is NOT fine. There + are probably several others that i don't know of yet. This is just a temporary solution, + i may completely change the format in the future or switch to binary or use something like + JSON or TOML etc. */ - if(!file) - { - log_error("parser:load_objects", "Invalid file handle for file %s", filename); - return false; - } + if(!file) + { + log_error("parser:load_objects", "Invalid file handle for file %s", filename); + return false; + } struct Parser* parser = malloc(sizeof(*parser)); if(!parser) @@ -89,109 +89,109 @@ struct Parser* parser_load_objects(FILE* file, const char* filename) parser->objects = array_new(struct Parser_Object); - int current_line = 0; - char line_buffer[MAX_LINE_LEN]; - char type_str[HASH_MAX_KEY_LEN]; - char obj_str[1024]; + int current_line = 0; + char line_buffer[MAX_LINE_LEN]; + char type_str[HASH_MAX_KEY_LEN]; + char obj_str[1024]; - while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) - { - current_line++; - memset(type_str, '\0', HASH_MAX_KEY_LEN); + while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + { + current_line++; + memset(type_str, '\0', HASH_MAX_KEY_LEN); - if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0) - { - continue; - } + if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0) + { + continue; + } - if(line_buffer[0] == '#') - continue; + if(line_buffer[0] == '#') + continue; - /* Object type */ - if(sscanf(line_buffer, "%s", type_str) != 1) - { - log_warning("Malformed line in config file %s, line %d", filename, current_line); - continue; - } + /* Object type */ + if(sscanf(line_buffer, "%s", type_str) != 1) + { + log_warning("Malformed line in config file %s, line %d", filename, current_line); + continue; + } - // Check if type string is valid - int type_str_len = strnlen(type_str, HASH_MAX_KEY_LEN); - if(type_str_len < 3 || strncmp(type_str, "{", HASH_MAX_KEY_LEN) == 0 || strncmp(type_str, "}", HASH_MAX_KEY_LEN) == 0) - { - log_warning("Invalid object type '%s' on line %d", type_str, current_line); - continue; - } + // Check if type string is valid + size_t type_str_len = strnlen(type_str, HASH_MAX_KEY_LEN); + if(type_str_len < 3 || strncmp(type_str, "{", HASH_MAX_KEY_LEN) == 0 || strncmp(type_str, "}", HASH_MAX_KEY_LEN) == 0) + { + log_warning("Invalid object type '%s' on line %d", type_str, current_line); + continue; + } - long obj_beginning = -1; - long obj_ending = -1; - int obj_begin_expexted_at = current_line; - bool found_next_before_current_ended = false; + long obj_beginning = -1; + long obj_ending = -1; + int obj_begin_expexted_at = current_line; + bool found_next_before_current_ended = false; - /* Opening brace and closing brace */ - char c = ' '; - int line_len = strnlen(line_buffer, MAX_LINE_LEN); - int seek_amount = line_len - type_str_len; - fseek(file, -seek_amount, SEEK_CUR); + /* Opening brace and closing brace */ + char c = ' '; + size_t line_len = strnlen(line_buffer, MAX_LINE_LEN); + size_t seek_amount = line_len - type_str_len; + fseek(file, -seek_amount, SEEK_CUR); + while(!feof(file)) + { + c = fgetc(file); + if(c == '\n') + { + current_line++; + continue; + } + + if(c == '{') + { + obj_beginning = ftell(file); + c = ' '; while(!feof(file)) { - c = fgetc(file); - if(c == '\n') - { - current_line++; - continue; - } - - if(c == '{') - { - obj_beginning = ftell(file); - c = ' '; - while(!feof(file)) - { - c = fgetc(file); - if(c == '\n') - { - current_line++; - continue; - } + c = fgetc(file); + if(c == '\n') + { + current_line++; + continue; + } - /* check if we found opening brace of next object, - if this is true then it means that this object is missing - it's closing brace and we should stop */ - if(c == '{') - { - found_next_before_current_ended = true; - break; - } - - if(c == '}') - { + /* check if we found opening brace of next object, + if this is true then it means that this object is missing + it's closing brace and we should stop */ + if(c == '{') + { + found_next_before_current_ended = true; + break; + } + + if(c == '}') + { obj_ending = ftell(file) - 1; - break; - } - } - if(obj_ending != -1) break; - } + break; + } } + if(obj_ending != -1) break; + } + } - if(obj_beginning == -1) - { - log_error("parser:load_object", "Syntax error while loading %s, expected '{' at line %d", filename, obj_begin_expexted_at); - return false; - } + if(obj_beginning == -1) + { + log_error("parser:load_object", "Syntax error while loading %s, expected '{' at line %d", filename, obj_begin_expexted_at); + return false; + } - if(obj_ending == -1) - { - if(found_next_before_current_ended) - log_error("parser:load_object", "Syntax error while loading %s, expected '}' before line %d but found '{'", filename, current_line); - else - log_error("parser:load_object", "Syntax error while loading %s, expected '}' at line %d", filename, current_line); - return false; - } + if(obj_ending == -1) + { + if(found_next_before_current_ended) + log_error("parser:load_object", "Syntax error while loading %s, expected '}' before line %d but found '{'", filename, current_line); + else + log_error("parser:load_object", "Syntax error while loading %s, expected '}' at line %d", filename, current_line); + return false; + } - memset(obj_str, '\0', 1024); - memset(line_buffer, '\0', MAX_LINE_LEN); - fseek(file, obj_beginning, SEEK_SET); - fread(obj_str, obj_ending - obj_beginning, 1, file); + memset(obj_str, '\0', 1024); + memset(line_buffer, '\0', MAX_LINE_LEN); + fseek(file, obj_beginning, SEEK_SET); + fread(obj_str, obj_ending - obj_beginning, 1, file); fseek(file, obj_ending + 1, SEEK_SET); // Position cursor after closing brace '}' // Read into intermediate parser object and add it to the objects list @@ -229,7 +229,7 @@ struct Parser* parser_load_objects(FILE* file, const char* filename) while((line = strtok(NULL, "\r\n")) != NULL); //log_to_stdout("Object found\nType: %s\n%s\n\n", type_str, obj_str); - } + } return parser; } @@ -240,25 +240,25 @@ int parser_object_type_from_str(const char* str) if(strncmp(str, "Entity", HASH_MAX_KEY_LEN) == 0) object_type = PO_ENTITY; else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL; - else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL; - else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG; - else if(strncmp(str, "Key", HASH_MAX_KEY_LEN) == 0) object_type = PO_KEY; + else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL; + else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG; + else if(strncmp(str, "Key", HASH_MAX_KEY_LEN) == 0) object_type = PO_KEY; return object_type; } const char* parser_object_type_to_str(int type) { - switch(type) - { - case PO_ENTITY: return "Entity"; - case PO_MODEL: return "Model"; - case PO_MATERIAL: return "Material"; - case PO_CONFIG: return "Config"; - case PO_KEY: return "Key"; - case PO_UNKNOWN: return "Unknown"; - default: return "Unknown"; - } + switch(type) + { + case PO_ENTITY: return "Entity"; + case PO_MODEL: return "Model"; + case PO_MATERIAL: return "Material"; + case PO_CONFIG: return "Config"; + case PO_KEY: return "Key"; + case PO_UNKNOWN: return "Unknown"; + default: return "Unknown"; + } } void parser_free(struct Parser *parser) @@ -276,68 +276,68 @@ void parser_free(struct Parser *parser) struct Parser* parser_new(void) { - struct Parser* parser = NULL; - parser = malloc(sizeof(*parser)); - if(!parser) - { - log_error("parser:new", "Out of memory"); - return NULL; - } + struct Parser* parser = NULL; + parser = malloc(sizeof(*parser)); + if(!parser) + { + log_error("parser:new", "Out of memory"); + return NULL; + } - parser->objects = array_new(struct Parser_Object); - if(!parser->objects) - { - log_error("parser:new", "Could not create objects array for parser"); - free(parser); - return NULL; - } + parser->objects = array_new(struct Parser_Object); + if(!parser->objects) + { + log_error("parser:new", "Could not create objects array for parser"); + free(parser); + return NULL; + } - return parser; + return parser; } struct Parser_Object* parser_object_new(struct Parser* parser, int type) { - assert(parser); - struct Parser_Object* object = array_grow(parser->objects, struct Parser_Object); - if(!object) - { - log_error("parser:object_new", "Failed to add new parser object"); - return NULL; - } + assert(parser); + struct Parser_Object* object = array_grow(parser->objects, struct Parser_Object); + if(!object) + { + log_error("parser:object_new", "Failed to add new parser object"); + return NULL; + } object->type = type; - object->data = hashmap_new(); + object->data = hashmap_new(); - return object; + return object; } bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename) { - assert(parser); - char value_str[MAX_VALUE_LEN]; - int counter = 0; - for(int i = 0; i < array_len(parser->objects); i++) + assert(parser); + char value_str[MAX_VALUE_LEN]; + int counter = 0; + for(int i = 0; i < array_len(parser->objects); i++) + { + struct Parser_Object* object = &parser->objects[i]; + if(object->type == PO_UNKNOWN) { - struct Parser_Object* object = &parser->objects[i]; - if(object->type == PO_UNKNOWN) - { - log_warning("Unknown object type, cannot write to %s", filename); - continue; - } + log_warning("Unknown object type, cannot write to %s", filename); + continue; + } - fprintf(file, "%s\n{\n", parser_object_type_to_str(object->type)); + fprintf(file, "%s\n{\n", parser_object_type_to_str(object->type)); - char* key = NULL; - struct Variant* value = NULL; - HASHMAP_FOREACH(object->data, key, value) - { - memset(value_str, '\0', MAX_VALUE_LEN); + char* key = NULL; + struct Variant* value = NULL; + HASHMAP_FOREACH(object->data, key, value) + { + memset(value_str, '\0', MAX_VALUE_LEN); variant_to_str(value, &value_str[0], MAX_VALUE_LEN); - fprintf(file, "\t%s : %s\n", key, value_str); - } - fprintf(file, "}\n\n"); - counter++; + fprintf(file, "\t%s : %s\n", key, value_str); } + fprintf(file, "}\n\n"); + counter++; + } - log_message("%d objects written to %s", counter, filename); - return true; + log_message("%d objects written to %s", counter, filename); + return true; } diff --git a/src/common/string_utils.c b/src/common/string_utils.c index 5cbb988..98fa482 100644 --- a/src/common/string_utils.c +++ b/src/common/string_utils.c @@ -61,73 +61,73 @@ char* str_concat(char* string, const char* str_to_concat) char* str_replace(char* string, const char* pattern, const char* replacement) { - int* indices = array_new(int); - size_t string_len = strlen(string); + int* indices = array_new(int); + size_t string_len = strlen(string); - /* Calculate size of new string and allocate new memory */ - size_t pattern_len = strlen(pattern); - size_t replacement_len = strlen(replacement); + /* Calculate size of new string and allocate new memory */ + size_t pattern_len = strlen(pattern); + size_t replacement_len = strlen(replacement); - int done = 0; - char* remaining_string = string; - while(!done) + int done = 0; + char* remaining_string = string; + while(!done) + { + char* location = strstr(remaining_string, pattern); + if(location) { - char* location = strstr(remaining_string, pattern); - if(location) - { - int index = location - string; - array_push(indices, index, int); - remaining_string = location + pattern_len; /* Find the next occurance in the remaining string */ - } - else - { - done = 1; - } + int index = (int)(location - string); + array_push(indices, index, int); + remaining_string = location + pattern_len; /* Find the next occurance in the remaining string */ } - - int num_indices = array_len(indices); - if(num_indices > 0) + else { - size_t string_len_without_pattern = string_len - (pattern_len * num_indices); - size_t new_string_len = string_len_without_pattern + (replacement_len * num_indices); - char* new_string = malloc(new_string_len); + done = 1; + } + } - if(new_string) - { - done = 0; - int count = 0; - int index = indices[count]; - unsigned int prev_index = 0; - while(!done) - { - char* source_beg = string + prev_index; - char* source_end = string + index; + int num_indices = array_len(indices); + if(num_indices > 0) + { + size_t string_len_without_pattern = string_len - (pattern_len * num_indices); + size_t new_string_len = string_len_without_pattern + (replacement_len * num_indices); + char* new_string = malloc(new_string_len); + + if(new_string) + { + done = 0; + int count = 0; + int index = indices[count]; + int prev_index = 0; + while(!done) + { + char* source_beg = string + prev_index; + char* source_end = string + index; - strncat(new_string, source_beg, (source_end - source_beg)); - strcat(new_string, replacement); + strncat(new_string, source_beg, (source_end - source_beg)); + strcat(new_string, replacement); - count++; - prev_index = index + pattern_len; + count++; + prev_index = index + pattern_len; - if(count == array_len(indices)) - { - done = 1; - source_beg = string + prev_index; - strcat(new_string, source_beg); - } - else - { - index = indices[count]; - } - } - free(string); + if(count == array_len(indices)) + { + done = 1; + source_beg = string + prev_index; + strcat(new_string, source_beg); } - - array_free(indices); - return new_string; - } - else - { - return NULL; + else + { + index = indices[count]; + } + } + free(string); } + + array_free(indices); + return new_string; + } + else + { + return NULL; + } } diff --git a/src/game/config_vars.c b/src/game/config_vars.c index d6bb6da..8186d08 100644 --- a/src/game/config_vars.c +++ b/src/game/config_vars.c @@ -16,46 +16,46 @@ static struct Hashmap* cvars = NULL; void config_vars_init(void) { - cvars = hashmap_new(); - /* Initialize with default values incase there is no config file */ - hashmap_int_set(cvars, "render_width", 1024); - hashmap_int_set(cvars, "render_height", 768); - hashmap_int_set(cvars, "fog_mode", 0); - hashmap_vec3_setf(cvars, "fog_color", 0.9f, 0.2f, 0.2f); - hashmap_float_set(cvars, "fog_density", 0.1); - hashmap_float_set(cvars, "fog_start_dist", 10.f); - hashmap_float_set(cvars, "fog_max_dist", 50.f); - hashmap_vec3_setf(cvars, "ambient_light", 0.1f, 0.1f, 0.1f); - hashmap_bool_set(cvars, "msaa_enabled", 1); - hashmap_int_set(cvars, "msaa_levels", 4); - hashmap_bool_set(cvars, "debug_draw_enabled", true); - hashmap_bool_set(cvars, "debug_draw_physics", true); + cvars = hashmap_new(); + /* Initialize with default values incase there is no config file */ + hashmap_int_set(cvars, "render_width", 1024); + hashmap_int_set(cvars, "render_height", 768); + hashmap_int_set(cvars, "fog_mode", 0); + hashmap_vec3_setf(cvars, "fog_color", 0.9f, 0.2f, 0.2f); + hashmap_float_set(cvars, "fog_density", 0.1f); + hashmap_float_set(cvars, "fog_start_dist", 10.f); + hashmap_float_set(cvars, "fog_max_dist", 50.f); + hashmap_vec3_setf(cvars, "ambient_light", 0.1f, 0.1f, 0.1f); + hashmap_bool_set(cvars, "msaa_enabled", 1); + hashmap_int_set(cvars, "msaa_levels", 4); + hashmap_bool_set(cvars, "debug_draw_enabled", true); + hashmap_bool_set(cvars, "debug_draw_physics", true); hashmap_int_set(cvars, "video_driver_linux", VD_WAYLAND); - hashmap_int_set(cvars, "debug_draw_mode", 0); + hashmap_int_set(cvars, "debug_draw_mode", 0); hashmap_vec4_setf(cvars, "debug_draw_color", 1.f, 0.f, 0.f, 1.f); - hashmap_float_set(cvars, "player_move_speed", 10.f); - hashmap_float_set(cvars, "player_move_speed_multiplier", 2.f); - hashmap_float_set(cvars, "player_turn_speed", 5.f); + hashmap_float_set(cvars, "player_move_speed", 10.f); + hashmap_float_set(cvars, "player_move_speed_multiplier", 2.f); + hashmap_float_set(cvars, "player_turn_speed", 5.f); } void config_vars_cleanup(void) { - hashmap_free(cvars); + hashmap_free(cvars); } struct Hashmap* config_vars_get(void) { - return cvars; + return cvars; } bool config_vars_load(const char* filename, int directory_type) { - FILE* config_file = io_file_open(directory_type, filename, "rb"); - if(!config_file) - { - log_error("config:vars_load", "Could not open %s", filename); - return false; - } + FILE* config_file = io_file_open(directory_type, filename, "rb"); + if(!config_file) + { + log_error("config:vars_load", "Could not open %s", filename); + return false; + } struct Parser* parser = parser_load_objects(config_file, filename); if(!parser) @@ -65,74 +65,73 @@ bool config_vars_load(const char* filename, int directory_type) return false; } - bool config_loaded = false; + bool config_loaded = false; for(int i = 0; i < array_len(parser->objects); i++) { struct Parser_Object* object = &parser->objects[i]; - if(object->type != PO_CONFIG) - { - log_warning("Unexpected config object type %s in %s", parser_object_type_to_str(object->type), filename); - continue; - } - - config_loaded = true; - char* key = NULL; - struct Variant* value = NULL; - char variant_str[MAX_VARIANT_STR_LEN]; - HASHMAP_FOREACH(object->data, key, value) - { - struct Variant* existing_val = hashmap_value_get(cvars, key); - if(!existing_val) - { - log_warning("Unkown key '%s' in config file %s", key, filename); - continue; - } - - variant_copy(existing_val, value); - } - } - - if(config_loaded) log_message("Loaded config from %s", filename); - fclose(config_file); - return config_loaded; -} - -bool config_vars_save(const char* filename, int directory_type) -{ - bool success = false; - FILE* config_file = io_file_open(directory_type, filename, "w"); - if(!config_file) + if(object->type != PO_CONFIG) { - log_error("config:vars_save", "Failed to open config file %s for writing"); - return success; + log_warning("Unexpected config object type %s in %s", parser_object_type_to_str(object->type), filename); + continue; } - struct Parser* parser = parser_new(); - if(!parser) + config_loaded = true; + char* key = NULL; + struct Variant* value = NULL; + HASHMAP_FOREACH(object->data, key, value) { - log_error("config_vars:save", "Could not create Parser for %s", filename); - fclose(config_file); - return false; + struct Variant* existing_val = hashmap_value_get(cvars, key); + if(!existing_val) + { + log_warning("Unkown key '%s' in config file %s", key, filename); + continue; + } + + variant_copy(existing_val, value); } + } - struct Parser_Object* object = parser_object_new(parser, PO_CONFIG); - if(!object) - { - log_error("config_vars:save", "Could not create Parser_Object for %s", filename); - parser_free(parser); - fclose(config_file); - return false; - } + if(config_loaded) log_message("Loaded config from %s", filename); + fclose(config_file); + return config_loaded; +} - hashmap_copy(cvars, object->data); +bool config_vars_save(const char* filename, int directory_type) +{ + bool success = false; + FILE* config_file = io_file_open(directory_type, filename, "w"); + if(!config_file) + { + log_error("config:vars_save", "Failed to open config file %s for writing"); + return success; + } - if(!parser_write_objects(parser, config_file, filename)) - { - log_error("config_vars:save", "Failed to write config to '%s'", filename); - success = false; - } + struct Parser* parser = parser_new(); + if(!parser) + { + log_error("config_vars:save", "Could not create Parser for %s", filename); + fclose(config_file); + return false; + } + struct Parser_Object* object = parser_object_new(parser, PO_CONFIG); + if(!object) + { + log_error("config_vars:save", "Could not create Parser_Object for %s", filename); parser_free(parser); fclose(config_file); - return success; + return false; + } + + hashmap_copy(cvars, object->data); + + if(!parser_write_objects(parser, config_file, filename)) + { + log_error("config_vars:save", "Failed to write config to '%s'", filename); + success = false; + } + + parser_free(parser); + fclose(config_file); + return success; } diff --git a/src/game/physics.c b/src/game/physics.c index 190c03d..bf74c66 100644 --- a/src/game/physics.c +++ b/src/game/physics.c @@ -6,533 +6,533 @@ static struct { - dWorldID world; - dSpaceID space; - dJointGroupID contact_group; - double step_size; - RigidbodyColCB on_collision; - RigidbodyMoveCB on_move; + dWorldID world; + dSpaceID space; + dJointGroupID contact_group; + double step_size; + RigidbodyColCB on_collision; + RigidbodyMoveCB on_move; } -Physics; + Physics; static void physics_near_callback(void* data, dGeomID body1, dGeomID body2); static void physics_cs_ray_hit_callback(void* data, dGeomID geom1, dGeomID geom2); void physics_init(void) { - if(dInitODE2(0) == 0) - { - log_error("physics:init", "Failed to initialize ode"); - return; - } - - dAllocateODEDataForThread(dAllocateMaskAll); - Physics.world = dWorldCreate(); - if(!Physics.world) - { - log_error("physics:init", "Physics world created!"); - } - else - { - log_message("Physics world created"); - Physics.space = dHashSpaceCreate(0); - Physics.contact_group = dJointGroupCreate(0); - Physics.step_size = 0.016; - dWorldSetCFM(Physics.world,1e-5); - dWorldSetAutoDisableFlag(Physics.world, 1); - dWorldSetLinearDamping(Physics.world, 0.00001); - dWorldSetAngularDamping(Physics.world, 0.005); - dWorldSetMaxAngularSpeed(Physics.world, 200); - dWorldSetContactMaxCorrectingVel(Physics.world,0.1); - dWorldSetContactSurfaceLayer(Physics.world,0.001); - } + if(dInitODE2(0) == 0) + { + log_error("physics:init", "Failed to initialize ode"); + return; + } + + dAllocateODEDataForThread(dAllocateMaskAll); + Physics.world = dWorldCreate(); + if(!Physics.world) + { + log_error("physics:init", "Physics world created!"); + } + else + { + log_message("Physics world created"); + Physics.space = dHashSpaceCreate(0); + Physics.contact_group = dJointGroupCreate(0); + Physics.step_size = 0.016; + dWorldSetCFM(Physics.world,1e-5); + dWorldSetAutoDisableFlag(Physics.world, 1); + dWorldSetLinearDamping(Physics.world, 0.00001); + dWorldSetAngularDamping(Physics.world, 0.005); + dWorldSetMaxAngularSpeed(Physics.world, 200); + dWorldSetContactMaxCorrectingVel(Physics.world,0.1); + dWorldSetContactSurfaceLayer(Physics.world,0.001); + } } void physics_cleanup(void) { - dJointGroupDestroy(Physics.contact_group); - dSpaceDestroy(Physics.space); - if(Physics.world) - { - dWorldDestroy(Physics.world); - } - dCleanupODEAllDataForThread(); - dCloseODE(); + dJointGroupDestroy(Physics.contact_group); + dSpaceDestroy(Physics.space); + if(Physics.world) + { + dWorldDestroy(Physics.world); + } + dCleanupODEAllDataForThread(); + dCloseODE(); } void physics_step(float delta_time) { - int steps = (int)ceilf(delta_time / Physics.step_size); - for(int i = 0; i < steps; i++) - { - dSpaceCollide(Physics.space, NULL, physics_near_callback); - dWorldQuickStep(Physics.world, Physics.step_size); - dJointGroupEmpty(Physics.contact_group); - } + int steps = (int)ceilf(delta_time / (float)Physics.step_size); + for(int i = 0; i < steps; i++) + { + dSpaceCollide(Physics.space, NULL, physics_near_callback); + dWorldQuickStep(Physics.world, Physics.step_size); + dJointGroupEmpty(Physics.contact_group); + } } void physics_gravity_set(float x, float y, float z) { - dWorldSetGravity(Physics.world, x, y, z); + dWorldSetGravity(Physics.world, x, y, z); } void physics_gravity_get(float * x, float * y, float * z) { - assert(x && y && z); - dVector3 gravity; - dWorldGetGravity(Physics.world, gravity); - *x = gravity[0]; - *y = gravity[1]; - *z = gravity[2]; + assert(x && y && z); + dVector3 gravity; + dWorldGetGravity(Physics.world, gravity); + *x = (float)gravity[0]; + *y = (float)gravity[1]; + *z = (float)gravity[2]; } void physics_body_position_get(Rigidbody body, float * x, float * y, float * z) { - assert(x && y && z); - const dReal* position = dBodyGetPosition(body); - *x = position[0]; - *y = position[1]; - *z = position[2]; + assert(x && y && z); + const dReal* position = dBodyGetPosition(body); + *x = (float)position[0]; + *y = (float)position[1]; + *z = (float)position[2]; } void physics_body_position_set(Rigidbody body, float x, float y, float z) { - dBodySetPosition(body, x, y, z); - dBodyEnable(body); + dBodySetPosition(body, x, y, z); + dBodyEnable(body); } void physics_body_rotation_get(Rigidbody body, float * x, float * y, float * z, float * w) { - assert(x && y && z && w); - const dReal* rotation = dBodyGetQuaternion(body); - *x = rotation[1]; - *y = rotation[2]; - *z = rotation[3]; - *w = rotation[0]; + assert(x && y && z && w); + const dReal* rotation = dBodyGetQuaternion(body); + *x = (float)rotation[1]; + *y = (float)rotation[2]; + *z = (float)rotation[3]; + *w = (float)rotation[0]; } void physics_body_rotation_set(Rigidbody body, float x, float y, float z, float w) { - dReal rotation[4] = { 0.f }; - rotation[1] = x; - rotation[2] = y; - rotation[3] = z; - rotation[0] = w; - dBodySetQuaternion(body, &rotation[0]); - dBodyEnable(body); + dReal rotation[4] = { 0.f }; + rotation[1] = x; + rotation[2] = y; + rotation[3] = z; + rotation[0] = w; + dBodySetQuaternion(body, &rotation[0]); + dBodyEnable(body); } void physics_near_callback(void* data, dGeomID o1, dGeomID o2) { - assert(o1); - assert(o2); + assert(o1); + assert(o2); - //if(dGeomIsSpace(o1) || dGeomIsSpace(o2)) - //{ - // fprintf(stderr, "testing space %p %p\n", (void*)o1, (void*)o2); - // // colliding a space with something - // dSpaceCollide2(o1, o2, data, &physics_near_callback); - // // Note we do not want to test intersections within a space, - // // only between spaces. - // return; - //} + //if(dGeomIsSpace(o1) || dGeomIsSpace(o2)) + //{ + // fprintf(stderr, "testing space %p %p\n", (void*)o1, (void*)o2); + // // colliding a space with something + // dSpaceCollide2(o1, o2, data, &physics_near_callback); + // // Note we do not want to test intersections within a space, + // // only between spaces. + // return; + //} - // fprintf(stderr,"testing geoms %p %p\n", o1, o2); + // fprintf(stderr,"testing geoms %p %p\n", o1, o2); - // exit without doing anything if the two bodies are connected by a joint - dBodyID b1 = dGeomGetBody(o1); - dBodyID b2 = dGeomGetBody(o2); + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); - if (b1 && b2 && dAreConnectedExcluding(b1,b2,dJointTypeContact)) - return; + if (b1 && b2 && dAreConnectedExcluding(b1,b2,dJointTypeContact)) + return; - if(o1 == o2) - log_message("same body!"); + if(o1 == o2) + log_message("same body!"); #define MAX_CONTACTS 8 - dContact contact[MAX_CONTACTS]; - for (int i = 0; i < MAX_CONTACTS; i++) - { - //contact[i].surface.mode = dContactBounce | dContactSoftCFM; - contact[i].surface.mode = dContactBounce | dContactSoftCFM; - contact[i].surface.mu = dInfinity; - contact[i].surface.mu2 = 0; - contact[i].surface.bounce = 0.1; - contact[i].surface.bounce_vel = 0.1; - contact[i].surface.soft_cfm = 0.01; - } - - int n = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(dContact)); - if(n > 0) - { - Physics.on_collision(b1, b2); - for(int i = 0; i < n; i++) - { - //contact[i].surface.slip1 = 0.7; - //contact[i].surface.slip2 = 0.7; - //contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2; - //contact[i].surface.mu = 50.0; // was: dInfinity - //contact[i].surface.soft_erp = 0.96; - //contact[i].surface.soft_cfm = 0.04; - - dJointID c = dJointCreateContact(Physics.world, Physics.contact_group, &contact[i]); - dJointAttach(c, b1, b2); - /*dGeomGetBody(contact[i].geom.g1), - dGeomGetBody(contact[i].geom.g2));*/ - } + dContact contact[MAX_CONTACTS]; + for (int i = 0; i < MAX_CONTACTS; i++) + { + //contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + + int n = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(dContact)); + if(n > 0) + { + Physics.on_collision(b1, b2); + for(int i = 0; i < n; i++) + { + //contact[i].surface.slip1 = 0.7; + //contact[i].surface.slip2 = 0.7; + //contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2; + //contact[i].surface.mu = 50.0; // was: dInfinity + //contact[i].surface.soft_erp = 0.96; + //contact[i].surface.soft_cfm = 0.04; + + dJointID c = dJointCreateContact(Physics.world, Physics.contact_group, &contact[i]); + dJointAttach(c, b1, b2); + /*dGeomGetBody(contact[i].geom.g1), + dGeomGetBody(contact[i].geom.g2));*/ } + } } Collision_Shape physics_body_cs_get(Rigidbody body) { - return dBodyGetFirstGeom(body); + return dBodyGetFirstGeom(body); } void physics_body_cs_set(Rigidbody body, Collision_Shape shape) { - dGeomSetBody(shape, body); + dGeomSetBody(shape, body); } Collision_Shape physics_cs_plane_create(float a, float b, float c, float d) { - dGeomID plane = dCreatePlane(Physics.space, a, b, c, d); - return plane; + dGeomID plane = dCreatePlane(Physics.space, a, b, c, d); + return plane; } void physics_cs_plane_params_set(Collision_Shape shape, float a, float b, float c, float d) { - dGeomPlaneSetParams(shape, a, b, c, d); + dGeomPlaneSetParams(shape, a, b, c, d); } void physics_cs_plane_params_get(Collision_Shape shape, float* a, float* b, float* c, float* d) { - assert(a && b && c && d); - *a = *b = *c = *d = 0.f; - float result[4] = { 0.f }; - dGeomPlaneGetParams(shape, result); - *a = result[0]; - *b = result[1]; - *c = result[2]; - *d = result[3]; + assert(a && b && c && d); + *a = *b = *c = *d = 0.f; + float result[4] = { 0.f }; + dGeomPlaneGetParams(shape, result); + *a = result[0]; + *b = result[1]; + *c = result[2]; + *d = result[3]; } Collision_Shape physics_cs_box_create(float x, float y, float z) { - dGeomID box = dCreateBox(Physics.space, x, y, z); - if(!box) - { - log_error("physics:cs_box_create", "Failed to create box collision shape"); - } - return box; + dGeomID box = dCreateBox(Physics.space, x, y, z); + if(!box) + { + log_error("physics:cs_box_create", "Failed to create box collision shape"); + } + return box; } int physics_cs_type_get(Collision_Shape shape) { - int geom_class = dGeomGetClass(shape); - switch(geom_class) - { - case dBoxClass: return CST_BOX; - case dSphereClass: return CST_SPHERE; - case dCylinderClass: return CST_CYLINDER; - case dTriMeshClass: return CST_TRIMESH; - case dPlaneClass: return CST_PLANE; - default: return CST_UNKNOWN; - } + int geom_class = dGeomGetClass(shape); + switch(geom_class) + { + case dBoxClass: return CST_BOX; + case dSphereClass: return CST_SPHERE; + case dCylinderClass: return CST_CYLINDER; + case dTriMeshClass: return CST_TRIMESH; + case dPlaneClass: return CST_PLANE; + default: return CST_UNKNOWN; + } } void physics_cs_box_params_get(Collision_Shape shape, float* x, float* y, float* z) { - assert(x && y && z); - *x = *y = *z = 0.f; - dReal lengths[3] = { 0 }; - dGeomBoxGetLengths(shape, &lengths[0]); - *x = lengths[0]; - *y = lengths[1]; - *z = lengths[2]; + assert(x && y && z); + *x = *y = *z = 0.f; + dReal lengths[3] = { 0 }; + dGeomBoxGetLengths(shape, &lengths[0]); + *x = lengths[0]; + *y = lengths[1]; + *z = lengths[2]; } void physics_cs_box_params_set(Collision_Shape shape, float x, float y, float z) { - dGeomBoxSetLengths(shape, x, y, z); + dGeomBoxSetLengths(shape, x, y, z); } Collision_Shape physics_cs_sphere_create(float radius) { - dGeomID sphere = dCreateSphere(Physics.space, radius); - if(!sphere) - { - log_error("physics:cs_sphere_create", "Failed to create sphere collision shape"); - } - return sphere; + dGeomID sphere = dCreateSphere(Physics.space, radius); + if(!sphere) + { + log_error("physics:cs_sphere_create", "Failed to create sphere collision shape"); + } + return sphere; } float physics_cs_sphere_radius_get(Collision_Shape shape) { - return dGeomSphereGetRadius(shape); + return dGeomSphereGetRadius(shape); } void physics_cs_sphere_radius_set(Collision_Shape shape, float radius) { - dGeomSphereSetRadius(shape, radius); + dGeomSphereSetRadius(shape, radius); } Collision_Shape physics_cs_capsule_create(float radius, float length) { - dGeomID capsule = dCreateCapsule(Physics.space, radius, length); - if(!capsule) - { - log_error("physics:cs_capsule_create", "Failed to create capsule collision shape"); - } - return capsule; + dGeomID capsule = dCreateCapsule(Physics.space, radius, length); + if(!capsule) + { + log_error("physics:cs_capsule_create", "Failed to create capsule collision shape"); + } + return capsule; } void physics_cs_capsule_params_get(Collision_Shape shape, float* radius, float* length) { - assert(radius && length); - *radius = *length = 0.f; - dGeomCapsuleGetParams(shape, radius, length); + assert(radius && length); + *radius = *length = 0.f; + dGeomCapsuleGetParams(shape, radius, length); } void physics_cs_capsule_params_set(Collision_Shape shape, float radius, float length) { - dGeomCapsuleSetParams(shape, radius, length); + dGeomCapsuleSetParams(shape, radius, length); } void physics_box_params_get(Rigidbody body, float* x, float* y, float* z) { - assert(x && y && z); - *x = *y = *z = 0.f; - dGeomID box = dBodyGetFirstGeom(body); - if(box == 0) - { - log_error("physics:box_get_params", "Body has invalid geometry"); - return; - } - float lengths[3] = { 0.f }; - dGeomBoxGetLengths(box, lengths); - *x = lengths[0]; - *y = lengths[1]; - *z = lengths[2]; + assert(x && y && z); + *x = *y = *z = 0.f; + dGeomID box = dBodyGetFirstGeom(body); + if(box == 0) + { + log_error("physics:box_get_params", "Body has invalid geometry"); + return; + } + float lengths[3] = { 0.f }; + dGeomBoxGetLengths(box, lengths); + *x = lengths[0]; + *y = lengths[1]; + *z = lengths[2]; } void physics_box_params_set(Rigidbody body, float x, float y, float z) { - assert(x && y && z); - dGeomID box = dBodyGetFirstGeom(body); - if(box == 0) - { - log_error("physics:box_get_params", "Body has invalid geometry"); - return; - } - dGeomBoxSetLengths(box, x, y, z); + assert(x && y && z); + dGeomID box = dBodyGetFirstGeom(body); + if(box == 0) + { + log_error("physics:box_get_params", "Body has invalid geometry"); + return; + } + dGeomBoxSetLengths(box, x, y, z); } Rigidbody physics_body_box_create(float x, float y, float z) { - Rigidbody body = NULL; - Collision_Shape box = physics_cs_box_create(x, y, z); - if(box) - { - body = dBodyCreate(Physics.world); - physics_body_cs_set(body, box); - dBodySetMovedCallback(body, Physics.on_move); - } + Rigidbody body = NULL; + Collision_Shape box = physics_cs_box_create(x, y, z); + if(box) + { + body = dBodyCreate(Physics.world); + physics_body_cs_set(body, box); + dBodySetMovedCallback(body, Physics.on_move); + } - return body; + return body; } Rigidbody physics_body_sphere_create(float radius) { - Rigidbody body = NULL; - Collision_Shape sphere = physics_cs_sphere_create(radius); - if(sphere) - { - body = dBodyCreate(Physics.world); - physics_body_cs_set(body, sphere); - dBodySetMovedCallback(body, Physics.on_move); - } + Rigidbody body = NULL; + Collision_Shape sphere = physics_cs_sphere_create(radius); + if(sphere) + { + body = dBodyCreate(Physics.world); + physics_body_cs_set(body, sphere); + dBodySetMovedCallback(body, Physics.on_move); + } - return body; + return body; } Rigidbody physics_body_capsule_create(float radius, float length) { - Rigidbody body = NULL; - Collision_Shape capsule = physics_cs_capsule_create(radius, length); - if(capsule) - { - body = dBodyCreate(Physics.world); - physics_body_cs_set(body, capsule); - dBodySetMovedCallback(body, Physics.on_move); - } + Rigidbody body = NULL; + Collision_Shape capsule = physics_cs_capsule_create(radius, length); + if(capsule) + { + body = dBodyCreate(Physics.world); + physics_body_cs_set(body, capsule); + dBodySetMovedCallback(body, Physics.on_move); + } - return body; + return body; } void physics_body_force_add(Rigidbody body, float fx, float fy, float fz) { - dBodyAddForce(body, fx, fy, fz); + dBodyAddForce(body, fx, fy, fz); } void physics_body_set_moved_callback(RigidbodyMoveCB callback) { - Physics.on_move = callback; + Physics.on_move = callback; } void physics_body_set_collision_callback(RigidbodyColCB callback) { - Physics.on_collision = callback; + Physics.on_collision = callback; } float physics_body_mass_get(Rigidbody body) { - return 0.0f; + return 0.0f; } void physics_body_mass_set(Rigidbody body, float mass) { - /*dMass dmass; - dMassAdjust(&dmass, mass); - dBodySetMass(body, &dmass);*/ + /*dMass dmass; + dMassAdjust(&dmass, mass); + dBodySetMass(body, &dmass);*/ } void physics_body_data_set(Rigidbody body, void * data) { - dBodySetData(body, data); + dBodySetData(body, data); } void * physics_body_data_get(Rigidbody body) { - return dBodyGetData(body); + return dBodyGetData(body); } void physics_body_kinematic_set(Rigidbody body) { - dBodySetKinematic(body); + dBodySetKinematic(body); } void physics_cs_ray_hit_callback(void* data, dGeomID geom1, dGeomID geom2) { - dContact contact; - if(dCollide(geom1, geom2, 1, &contact.geom, sizeof(contact)) == 1) + dContact contact; + if(dCollide(geom1, geom2, 1, &contact.geom, sizeof(contact)) == 1) + { + struct Raycast_Hit* rayhit = (struct Raycast_Hit*)data; + Rigidbody body = dGeomGetBody(geom2); + if(body) + { + int entity_id = (int)dBodyGetData(body); + if(entity_id != 0) rayhit->entity_id = entity_id; + } + else { - struct Raycast_Hit* rayhit = (struct Raycast_Hit*)data; - Rigidbody body = dGeomGetBody(geom2); - if(body) - { - int entity_id = (int)dBodyGetData(body); - if(entity_id != 0) rayhit->entity_id = entity_id; - } - else - { - int entity_id = (int)dGeomGetData(geom2); - if(entity_id != 0) rayhit->entity_id = entity_id; - } + int entity_id = (int)dGeomGetData(geom2); + if(entity_id != 0) rayhit->entity_id = entity_id; } + } } bool physics_cs_ray_cast(Collision_Shape ray, - struct Raycast_Hit* out_rayhit, - float pos_x, float pos_y, float pos_z, - float dir_x, float dir_y, float dir_z) + struct Raycast_Hit* out_rayhit, + float pos_x, float pos_y, float pos_z, + float dir_x, float dir_y, float dir_z) { - assert(out_rayhit); - out_rayhit->entity_id = -1; - dGeomRaySet(ray, pos_x, pos_y, pos_z, dir_x, dir_y, dir_z); - dSpaceCollide2(ray, Physics.space, (void*)out_rayhit, &physics_cs_ray_hit_callback); - return out_rayhit->entity_id == -1 ? false : true; + assert(out_rayhit); + out_rayhit->entity_id = -1; + dGeomRaySet(ray, pos_x, pos_y, pos_z, dir_x, dir_y, dir_z); + dSpaceCollide2(ray, Physics.space, (void*)out_rayhit, &physics_cs_ray_hit_callback); + return out_rayhit->entity_id == -1 ? false : true; } void physics_cs_position_get(Collision_Shape shape, float * x, float * y, float * z) { - assert(x && y && z); - if(dGeomGetClass(shape) == dPlaneClass) - { - *x = 0.f; - *y = 0.f; - *z = 0.f; - return; - } + assert(x && y && z); + if(dGeomGetClass(shape) == dPlaneClass) + { + *x = 0.f; + *y = 0.f; + *z = 0.f; + return; + } - const dReal* pos = dGeomGetPosition(shape); - *x = pos[0]; - *y = pos[1]; - *z = pos[2]; + const dReal* pos = dGeomGetPosition(shape); + *x = pos[0]; + *y = pos[1]; + *z = pos[2]; } void physics_cs_position_set(Collision_Shape shape, float x, float y, float z) { - if(dGeomGetClass(shape) == dPlaneClass) - return; + if(dGeomGetClass(shape) == dPlaneClass) + return; - dGeomSetPosition(shape, x, y, z); + dGeomSetPosition(shape, x, y, z); } void physics_cs_rotation_get(Collision_Shape shape, float* x, float* y, float* z, float* w) { - assert(x && y && z && w); + assert(x && y && z && w); - if(dGeomGetClass(shape) == dPlaneClass) - { - *x = 0.f; - *y = 0.f; - *z = 0.f; - *w = 1.f; - return; - } + if(dGeomGetClass(shape) == dPlaneClass) + { + *x = 0.f; + *y = 0.f; + *z = 0.f; + *w = 1.f; + return; + } - dReal rotation[4] = { 1, 0, 0, 0 }; - dGeomGetQuaternion(shape, &rotation[0]); - *x = rotation[1]; - *y = rotation[2]; - *z = rotation[3]; - *w = rotation[0]; + dReal rotation[4] = { 1, 0, 0, 0 }; + dGeomGetQuaternion(shape, &rotation[0]); + *x = rotation[1]; + *y = rotation[2]; + *z = rotation[3]; + *w = rotation[0]; } void physics_cs_rotation_set(Collision_Shape shape, float x, float y, float z, float w) { - if(dGeomGetClass(shape) == dPlaneClass) - return; + if(dGeomGetClass(shape) == dPlaneClass) + return; - dReal rotation[4] = { 0.f }; - rotation[1] = x; - rotation[2] = y; - rotation[3] = z; - rotation[0] = w; - dGeomSetQuaternion(shape, &rotation[0]); + dReal rotation[4] = { 0.f }; + rotation[1] = x; + rotation[2] = y; + rotation[3] = z; + rotation[0] = w; + dGeomSetQuaternion(shape, &rotation[0]); } Collision_Shape physics_cs_ray_create(float length, bool first_contact, bool backface_cull) { - dGeomID ray = dCreateRay(Physics.space, length); - dGeomRaySetParams(ray, first_contact, backface_cull); - return ray; + dGeomID ray = dCreateRay(Physics.space, length); + dGeomRaySetParams(ray, first_contact, backface_cull); + return ray; } void physics_body_remove(Rigidbody body) { - dGeomID shape = dBodyGetFirstGeom(body); - if(shape) - physics_cs_remove(shape); - dBodyDestroy(body); + dGeomID shape = dBodyGetFirstGeom(body); + if(shape) + physics_cs_remove(shape); + dBodyDestroy(body); } void physics_cs_remove(Collision_Shape shape) { - dGeomDestroy(shape); + dGeomDestroy(shape); } void physics_cs_data_set(Collision_Shape shape, void* data) { - assert(shape); - dGeomSetData(shape, data); + assert(shape); + dGeomSetData(shape, data); } void* physics_cs_data_get(Collision_Shape shape) { - assert(shape); - return dGeomGetData(shape); -} \ No newline at end of file + assert(shape); + return dGeomGetData(shape); +} diff --git a/src/game/platform.c b/src/game/platform.c index 516629f..2a68cef 100644 --- a/src/game/platform.c +++ b/src/game/platform.c @@ -13,19 +13,19 @@ struct Window { - void* sdl_window; - SDL_GLContext gl_context; - int is_fullscreen; + void* sdl_window; + SDL_GLContext gl_context; + int is_fullscreen; }; struct Platform_State { - Keyboard_Event_Func on_keyboard_func; - Mousebutton_Event_Func on_mousebutton_func; - Mousemotion_Event_Func on_mousemotion_func; - Mousewheel_Event_Func on_mousewheel_func; - Windowresize_Event_Func on_windowresize_func; - Textinput_Event_Func on_textinput_func; + Keyboard_Event_Func on_keyboard_func; + Mousebutton_Event_Func on_mousebutton_func; + Mousemotion_Event_Func on_mousemotion_func; + Mousewheel_Event_Func on_mousewheel_func; + Windowresize_Event_Func on_windowresize_func; + Textinput_Event_Func on_textinput_func; }; /* TODO: Find a better way to handle internal state */ @@ -33,176 +33,176 @@ static struct Platform_State* platform_state = NULL; struct Window* window_create(const char* title, int width, int height, int msaa, int msaa_levels) { - struct Window* new_window = NULL; + struct Window* new_window = NULL; + if(!new_window) + { + new_window = malloc(sizeof(*new_window)); if(!new_window) { - new_window = malloc(sizeof(*new_window)); - if(!new_window) - { - log_error("window_create", "Out of memory"); - return NULL; - } - new_window->sdl_window = NULL; - new_window->gl_context = NULL; - new_window->is_fullscreen = 0; + log_error("window_create", "Out of memory"); + return NULL; } + new_window->sdl_window = NULL; + new_window->gl_context = NULL; + new_window->is_fullscreen = 0; + } - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if(msaa) - { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaa); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_levels); - } - SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - //SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if(msaa) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaa); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_levels); + } + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + //SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); #ifdef GL_DEBUG_CONTEXT - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); #endif - SDL_Window* sdl_window = SDL_CreateWindow(title, - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - width, height, - SDL_WINDOW_OPENGL | - SDL_WINDOW_RESIZABLE | - SDL_WINDOW_INPUT_FOCUS | - SDL_WINDOW_MOUSE_FOCUS); - if(!sdl_window) - { - log_error("window_create:SDL_CreateWindow", "Could not create window : %s", SDL_GetError()); - free(new_window); - new_window = NULL; - return new_window; - } + SDL_Window* sdl_window = SDL_CreateWindow(title, + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, + SDL_WINDOW_OPENGL | + SDL_WINDOW_RESIZABLE | + SDL_WINDOW_INPUT_FOCUS | + SDL_WINDOW_MOUSE_FOCUS); + if(!sdl_window) + { + log_error("window_create:SDL_CreateWindow", "Could not create window : %s", SDL_GetError()); + free(new_window); + new_window = NULL; + return new_window; + } - new_window->sdl_window = sdl_window; - SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window); - if(!gl_context) - { - log_error("window_create:SDL_GL_CreateContext", "Failed to create GL context : %s", SDL_GetError()); + new_window->sdl_window = sdl_window; + SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window); + if(!gl_context) + { + log_error("window_create:SDL_GL_CreateContext", "Failed to create GL context : %s", SDL_GetError()); window_destroy(new_window); - free(new_window); - new_window = NULL; - return new_window; - } - - new_window->gl_context = gl_context; - SDL_Window* current_window = SDL_GL_GetCurrentWindow(); - SDL_GLContext current_context = SDL_GL_GetCurrentContext(); - SDL_GL_MakeCurrent((SDL_Window*)new_window->sdl_window, new_window->gl_context); - SDL_GL_SetSwapInterval(1); /* 0: Vsync disabled, 1: Vsync enabled*/ - if(current_window && current_context) SDL_GL_MakeCurrent(current_window, current_context); - - int major = 0, minor = 0; - SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); - SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); - log_message("Window created and initialized with opengl core context %d.%d", major, minor); + free(new_window); + new_window = NULL; return new_window; + } + + new_window->gl_context = gl_context; + SDL_Window* current_window = SDL_GL_GetCurrentWindow(); + SDL_GLContext current_context = SDL_GL_GetCurrentContext(); + SDL_GL_MakeCurrent((SDL_Window*)new_window->sdl_window, new_window->gl_context); + SDL_GL_SetSwapInterval(1); /* 0: Vsync disabled, 1: Vsync enabled*/ + if(current_window && current_context) SDL_GL_MakeCurrent(current_window, current_context); + + int major = 0, minor = 0; + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); + log_message("Window created and initialized with opengl core context %d.%d", major, minor); + return new_window; } int window_fullscreen_set(struct Window* window, int fullscreen) { - int success = 0; - int rc = SDL_SetWindowFullscreen(window->sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - if(rc == 0) - { - window->is_fullscreen = fullscreen ? 1 : 0; - success = 1; - log_message("Window set to %s mode", fullscreen ? "fullscreen" : "windowed"); - int w, h; - window_get_size(window, &w, &h); - log_message("Window size : %dx%d", w, h); - window_get_drawable_size(window, &w, &h); - log_message("Drawable size : %dx%d", w, h); - } - else - { - log_error("platform:window_fullscreen", "window_fullscreen_set failed, %s", SDL_GetError()); - } - return success; + int success = 0; + int rc = SDL_SetWindowFullscreen(window->sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + if(rc == 0) + { + window->is_fullscreen = fullscreen ? 1 : 0; + success = 1; + log_message("Window set to %s mode", fullscreen ? "fullscreen" : "windowed"); + int w, h; + window_get_size(window, &w, &h); + log_message("Window size : %dx%d", w, h); + window_get_drawable_size(window, &w, &h); + log_message("Drawable size : %dx%d", w, h); + } + else + { + log_error("platform:window_fullscreen", "window_fullscreen_set failed, %s", SDL_GetError()); + } + return success; } void window_make_context_current(struct Window* window) { - SDL_GL_MakeCurrent((SDL_Window*)window->sdl_window, window->gl_context); + SDL_GL_MakeCurrent((SDL_Window*)window->sdl_window, window->gl_context); } void window_show(struct Window* window) { - SDL_ShowWindow((SDL_Window*)window->sdl_window); + SDL_ShowWindow((SDL_Window*)window->sdl_window); } void window_hide(struct Window* window) { - SDL_HideWindow((SDL_Window*)window->sdl_window); + SDL_HideWindow((SDL_Window*)window->sdl_window); } void window_raise(struct Window* window) { - SDL_RaiseWindow((SDL_Window*)window->sdl_window); + SDL_RaiseWindow((SDL_Window*)window->sdl_window); } void window_destroy(struct Window* window) { - if(window->gl_context) SDL_GL_DeleteContext(window->gl_context); - SDL_DestroyWindow((SDL_Window*)window->sdl_window); + if(window->gl_context) SDL_GL_DeleteContext(window->gl_context); + SDL_DestroyWindow((SDL_Window*)window->sdl_window); } void window_set_size(struct Window* window, int width, int height) { - SDL_SetWindowSize((SDL_Window*)window->sdl_window, width, height); + SDL_SetWindowSize((SDL_Window*)window->sdl_window, width, height); } void window_get_size(struct Window* window, int* out_width, int* out_height) { - SDL_GetWindowSize((SDL_Window*)window->sdl_window, out_width, out_height); + SDL_GetWindowSize((SDL_Window*)window->sdl_window, out_width, out_height); } void window_get_drawable_size(struct Window* window, int* out_width, int* out_height) { - SDL_GL_GetDrawableSize((SDL_Window*)window->sdl_window, out_width, out_height); + SDL_GL_GetDrawableSize((SDL_Window*)window->sdl_window, out_width, out_height); } void window_swap_buffers(struct Window* window) { - SDL_GL_SwapWindow(window->sdl_window); + SDL_GL_SwapWindow(window->sdl_window); } bool platform_init(void) { bool success = true; if(SDL_Init(SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0) - { + { success = false; - if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init failed", SDL_GetError(), NULL) != 0) - log_to_stdout("platform_init", "SDL Init failed : %s", SDL_GetError()); + if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init failed", SDL_GetError(), NULL) != 0) + log_to_stdout("platform_init", "SDL Init failed : %s", SDL_GetError()); + } + else + { + platform_state = malloc(sizeof(*platform_state)); + if(!platform_state) + { + if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Allocation Failure", "Memory allocation failed, out of memory!", NULL) != 0) + log_to_stdout("platform_init", "Could not create platform state, out of memory"); + success = false; } else { - platform_state = malloc(sizeof(*platform_state)); - if(!platform_state) - { - if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Allocation Failure", "Memory allocation failed, out of memory!", NULL) != 0) - log_to_stdout("platform_init", "Could not create platform state, out of memory"); - success = false; - } - else - { - platform_state->on_keyboard_func = NULL; - platform_state->on_mousebutton_func = NULL; - platform_state->on_mousemotion_func = NULL; - platform_state->on_mousewheel_func = NULL; - platform_state->on_textinput_func = NULL; - platform_state->on_windowresize_func = NULL; - } + platform_state->on_keyboard_func = NULL; + platform_state->on_mousebutton_func = NULL; + platform_state->on_mousemotion_func = NULL; + platform_state->on_mousewheel_func = NULL; + platform_state->on_textinput_func = NULL; + platform_state->on_windowresize_func = NULL; } - return success; + } + return success; } bool platform_init_video() @@ -234,228 +234,228 @@ bool platform_init_video() void platform_cleanup(void) { - if(platform_state) free(platform_state); - platform_state = NULL; + if(platform_state) free(platform_state); + platform_state = NULL; SDL_VideoQuit(); - SDL_Quit(); + SDL_Quit(); } void platform_poll_events(bool* out_quit) { - static SDL_Event event; - while(SDL_PollEvent(&event) != 0) + static SDL_Event event; + while(SDL_PollEvent(&event) != 0) + { + switch(event.type) + { + case SDL_QUIT: + *out_quit = 1; + break; + case SDL_KEYDOWN: case SDL_KEYUP: + { + int scancode = event.key.keysym.scancode; + int key = event.key.keysym.sym; + int state = event.key.state; + int repeat = event.key.repeat; + int mod_ctrl = (event.key.keysym.mod & KMOD_CTRL) ? 1 : 0; + int mod_shift = (event.key.keysym.mod & KMOD_SHIFT) ? 1 : 0; + int mod_alt = (event.key.keysym.mod & KMOD_ALT) ? 1 : 0; + platform_state->on_keyboard_func(key, scancode, state, repeat, mod_ctrl, mod_shift, mod_alt); + //log_message("Key name : %s", SDL_GetKeyName(key)); + break; + } + case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: + { + int button = event.button.button; + int state = event.button.state; + int num_clicks = event.button.clicks; + int x = event.button.x; + int y = event.button.y; + platform_state->on_mousebutton_func(button, state, x, y, num_clicks); + break; + } + case SDL_MOUSEMOTION: { - switch(event.type) - { - case SDL_QUIT: - *out_quit = 1; - break; - case SDL_KEYDOWN: case SDL_KEYUP: - { - int scancode = event.key.keysym.scancode; - int key = event.key.keysym.sym; - int state = event.key.state; - int repeat = event.key.repeat; - int mod_ctrl = (event.key.keysym.mod & KMOD_CTRL) ? 1 : 0; - int mod_shift = (event.key.keysym.mod & KMOD_SHIFT) ? 1 : 0; - int mod_alt = (event.key.keysym.mod & KMOD_ALT) ? 1 : 0; - platform_state->on_keyboard_func(key, scancode, state, repeat, mod_ctrl, mod_shift, mod_alt); - //log_message("Key name : %s", SDL_GetKeyName(key)); - break; - } - case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: - { - int button = event.button.button; - int state = event.button.state; - int num_clicks = event.button.clicks; - int x = event.button.x; - int y = event.button.y; - platform_state->on_mousebutton_func(button, state, x, y, num_clicks); - break; - } - case SDL_MOUSEMOTION: - { - int xrel = event.motion.xrel; - int yrel = event.motion.yrel; - int x = event.motion.x; - int y = event.motion.y; - platform_state->on_mousemotion_func(x, y, xrel, yrel); - break; - } - case SDL_MOUSEWHEEL: - { - int x = event.wheel.x; - int y = event.wheel.y; - platform_state->on_mousewheel_func(x, y); - break; - } - case SDL_TEXTINPUT: - { - platform_state->on_textinput_func(event.text.text); - break; - } - case SDL_WINDOWEVENT: - { - if(event.window.event == SDL_WINDOWEVENT_RESIZED) - { - platform_state->on_windowresize_func(event.window.data1, event.window.data2); - } - } - break; - } + int xrel = event.motion.xrel; + int yrel = event.motion.yrel; + int x = event.motion.x; + int y = event.motion.y; + platform_state->on_mousemotion_func(x, y, xrel, yrel); + break; } + case SDL_MOUSEWHEEL: + { + int x = event.wheel.x; + int y = event.wheel.y; + platform_state->on_mousewheel_func(x, y); + break; + } + case SDL_TEXTINPUT: + { + platform_state->on_textinput_func(event.text.text); + break; + } + case SDL_WINDOWEVENT: + { + if(event.window.event == SDL_WINDOWEVENT_RESIZED) + { + platform_state->on_windowresize_func(event.window.data1, event.window.data2); + } + } + break; + } + } } void platform_keyboard_callback_set(Keyboard_Event_Func func) { - platform_state->on_keyboard_func = func; + platform_state->on_keyboard_func = func; } void platform_mousebutton_callback_set(Mousebutton_Event_Func func) { - platform_state->on_mousebutton_func = func; + platform_state->on_mousebutton_func = func; } void platform_mousemotion_callback_set(Mousemotion_Event_Func func) { - platform_state->on_mousemotion_func = func; + platform_state->on_mousemotion_func = func; } void platform_mousewheel_callback_set(Mousewheel_Event_Func func) { - platform_state->on_mousewheel_func = func; + platform_state->on_mousewheel_func = func; } void platform_textinput_callback_set(Textinput_Event_Func func) { - platform_state->on_textinput_func = func; + platform_state->on_textinput_func = func; } void platform_windowresize_callback_set(Windowresize_Event_Func func) { - platform_state->on_windowresize_func = func; + platform_state->on_windowresize_func = func; } int platform_is_key_pressed(int key) { - /* Returns 1 if key is pressed, 0 otherwise */ - const Uint8* keyboard_state = SDL_GetKeyboardState(NULL); - return keyboard_state[SDL_GetScancodeFromKey(key)]; + /* Returns 1 if key is pressed, 0 otherwise */ + const Uint8* keyboard_state = SDL_GetKeyboardState(NULL); + return keyboard_state[SDL_GetScancodeFromKey(key)]; } int platform_mousebutton_state_get(uint button) { - int pressed = 0; - uint32 current_button_state = SDL_GetMouseState(NULL, NULL); - if((current_button_state & SDL_BUTTON(button))) pressed = 1; - return pressed; + int pressed = 0; + uint32 current_button_state = SDL_GetMouseState(NULL, NULL); + if((current_button_state & SDL_BUTTON(button))) pressed = 1; + return pressed; } void platform_mouse_position_get(int* x, int* y) { - SDL_GetMouseState(x, y); + SDL_GetMouseState(x, y); } void platform_mouse_position_set(struct Window* window, int x, int y) { - SDL_WarpMouseInWindow(window->sdl_window, x, y); + SDL_WarpMouseInWindow(window->sdl_window, x, y); } void platform_mouse_global_position_set(int x, int y) { - SDL_WarpMouseGlobal(x, y); + SDL_WarpMouseGlobal(x, y); } void platform_mouse_relative_mode_set(int relative_mode) { - SDL_SetRelativeMouseMode(relative_mode ? SDL_TRUE : SDL_FALSE); + SDL_SetRelativeMouseMode(relative_mode ? SDL_TRUE : SDL_FALSE); } int platform_mouse_relative_mode_get(void) { - return SDL_GetRelativeMouseMode() == SDL_TRUE ? 1 : 0; + return SDL_GetRelativeMouseMode() == SDL_TRUE ? 1 : 0; } uint32 platform_ticks_get(void) { - return SDL_GetTicks(); + return SDL_GetTicks(); } void platform_mouse_delta_get(int* x, int* y) { - SDL_GetRelativeMouseState(x, y); + SDL_GetRelativeMouseState(x, y); } char* platform_install_directory_get(void) { - char* returned_path = SDL_GetBasePath(); - char* path = NULL; - if(returned_path) - { - path = str_new(returned_path); - SDL_free(returned_path); - } - return path; + char* returned_path = SDL_GetBasePath(); + char* path = NULL; + if(returned_path) + { + path = str_new(returned_path); + SDL_free(returned_path); + } + return path; } void platform_clipboard_text_set(const char* text) { - SDL_SetClipboardText(text); + SDL_SetClipboardText(text); } char* platform_clipboard_text_get(void) { - char* returned_text = SDL_GetClipboardText(); - char* text = NULL; - if(returned_text) - { - text = str_new(returned_text); - SDL_free(returned_text); - } - return text; + char* returned_text = SDL_GetClipboardText(); + char* text = NULL; + if(returned_text) + { + text = str_new(returned_text); + SDL_free(returned_text); + } + return text; } int platform_key_from_name(const char* key_name) { - if(!key_name || strlen(key_name) == 0) return SDLK_UNKNOWN; + if(!key_name || strlen(key_name) == 0) return SDLK_UNKNOWN; - /* Remove leading/trailing spaces, preserve spaces in-between */ - #define max_name_len 30 - char trimmed_key_name[max_name_len] = {'\0'}; + /* Remove leading/trailing spaces, preserve spaces in-between */ +#define max_name_len 30 + char trimmed_key_name[max_name_len] = {'\0'}; - int start = 0; - while(isspace(key_name[start]) != 0) start++; + int start = 0; + while(isspace(key_name[start]) != 0) start++; - int end = strlen(key_name) - 1; - while(isspace(key_name[end]) != 0) end--; + size_t end = strlen(key_name) - 1; + while(isspace(key_name[end]) != 0) end--; - strncpy(trimmed_key_name, &key_name[start], (end - start) + 1); - int key = SDL_GetKeyFromName(trimmed_key_name); - /*if(key == SDLK_UNKNOWN) - log_error("platform:key_from_name", "Unrecognized key '%s', SDL (%s)", trimmed_key_name, SDL_GetError());*/ - return key; + strncpy(trimmed_key_name, &key_name[start], (end - start) + 1); + int key = SDL_GetKeyFromName(trimmed_key_name); + /*if(key == SDLK_UNKNOWN) + log_error("platform:key_from_name", "Unrecognized key '%s', SDL (%s)", trimmed_key_name, SDL_GetError());*/ + return key; } const char* platform_key_name_get(int key) { - if(key < 0) return "SDLK_UNKNOWN"; - return SDL_GetKeyName(key); + if(key < 0) return "SDLK_UNKNOWN"; + return SDL_GetKeyName(key); } char* platform_user_directory_get(const char* organization, const char* application) { - char* user_directory = NULL; - char* temp_path = SDL_GetPrefPath(organization, application); - if(temp_path) - { - user_directory = str_new(temp_path); - SDL_free(temp_path); - } - else - { + char* user_directory = NULL; + char* temp_path = SDL_GetPrefPath(organization, application); + if(temp_path) + { + user_directory = str_new(temp_path); + SDL_free(temp_path); + } + else + { log_to_stdout("ERR(platform:user_directory_get) Error getting user directory, %s", SDL_GetError()); - } - return user_directory; + } + return user_directory; } void* platform_load_library(const char *name) @@ -469,7 +469,7 @@ void* platform_load_library(const char *name) #elif defined(_MSC_VER) snprintf(lib_name, MAX_LIB_NAME_LEN, "%s.dll", name); #elif defined(__MING32__) || defined(__MINGW64__) - snprintf(lib_name, MAX_LIB_NAME_LEN, "./%s.dll", name); + snprintf(lib_name, MAX_LIB_NAME_LEN, "./%s.dll", name); #endif void* lib_handle = SDL_LoadObject(lib_name); if(!lib_handle) log_error("platform:load_library", "Failed to load library '%s', SDL : (%s)", lib_name, SDL_GetError()); diff --git a/src/libsymmetry/camera.c b/src/libsymmetry/camera.c index 4ccb63d..8eb8395 100644 --- a/src/libsymmetry/camera.c +++ b/src/libsymmetry/camera.c @@ -21,224 +21,224 @@ static void update_frustum(struct Camera* camera); void camera_reset(struct Camera* camera) { - if(camera->fbo != -1) framebuffer_remove(camera->fbo); - if(camera->render_tex != -1) texture_remove(camera->render_tex); - if(camera->depth_tex != -1) texture_remove(camera->depth_tex); - camera->fbo = camera->render_tex = camera->depth_tex = -1; - camera->ortho = camera->resizeable = false; - camera->fov = camera->aspect_ratio = camera->nearz = camera->farz = 0.f; - mat4_identity(&camera->view_mat); - mat4_identity(&camera->proj_mat); - mat4_identity(&camera->view_proj_mat); - for(int i = 0; i < FP_NUM_PLANES; i++) - vec4_fill(&camera->frustum[i], 0.f, 0.f, 0.f, 0.f); - vec4_fill(&camera->clear_color, 0.f, 1.f, 0.f, 1.0); + if(camera->fbo != -1) framebuffer_remove(camera->fbo); + if(camera->render_tex != -1) texture_remove(camera->render_tex); + if(camera->depth_tex != -1) texture_remove(camera->depth_tex); + camera->fbo = camera->render_tex = camera->depth_tex = -1; + camera->ortho = camera->resizeable = false; + camera->fov = camera->aspect_ratio = camera->nearz = camera->farz = 0.f; + mat4_identity(&camera->view_mat); + mat4_identity(&camera->proj_mat); + mat4_identity(&camera->view_proj_mat); + for(int i = 0; i < FP_NUM_PLANES; i++) + vec4_fill(&camera->frustum[i], 0.f, 0.f, 0.f, 0.f); + vec4_fill(&camera->clear_color, 0.f, 1.f, 0.f, 1.0); } void camera_init(struct Camera* camera, int width, int height) { - camera->base.type = ET_CAMERA; - camera->fbo = -1; - camera->render_tex = -1; - camera->depth_tex = -1; - camera->farz = 1000.f; - camera->nearz = 0.1f; - camera->fov = 60.f; - camera->ortho = false; - camera->resizeable = true; - camera->zoom = 1.f; - float aspect_ratio = (float)width / (float)height; - camera->aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio; - mat4_identity(&camera->view_mat); - mat4_identity(&camera->proj_mat); - mat4_identity(&camera->view_proj_mat); - for(int i = 0; i < FP_NUM_PLANES; i++) - vec4_fill(&camera->frustum[i], 0.f, 0.f, 0.f, 0.f); - camera_update_view(camera); - camera_update_proj(camera); - vec4_fill(&camera->clear_color, 1.f, 1.f, 1.f, 1.f); + camera->base.type = ET_CAMERA; + camera->fbo = -1; + camera->render_tex = -1; + camera->depth_tex = -1; + camera->farz = 1000.f; + camera->nearz = 0.1f; + camera->fov = 60.f; + camera->ortho = false; + camera->resizeable = true; + camera->zoom = 1.f; + float aspect_ratio = (float)width / (float)height; + camera->aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio; + mat4_identity(&camera->view_mat); + mat4_identity(&camera->proj_mat); + mat4_identity(&camera->view_proj_mat); + for(int i = 0; i < FP_NUM_PLANES; i++) + vec4_fill(&camera->frustum[i], 0.f, 0.f, 0.f, 0.f); + camera_update_view(camera); + camera_update_proj(camera); + vec4_fill(&camera->clear_color, 1.f, 1.f, 1.f, 1.f); } void camera_update_view_proj(struct Camera* camera) { - mat4_identity(&camera->view_proj_mat); - mat4_mul(&camera->view_proj_mat, &camera->proj_mat, &camera->view_mat); - update_frustum(camera); + mat4_identity(&camera->view_proj_mat); + mat4_mul(&camera->view_proj_mat, &camera->proj_mat, &camera->view_mat); + update_frustum(camera); } void camera_update_view(struct Camera* camera) { - vec3 lookat = {0.f, 0.f, 0.f}; - vec3 up = {0.f, 0.f, 0.f}; - vec3 position = {0.f, 0.f, 0.f}; - transform_get_absolute_lookat(&camera->base, &lookat); - transform_get_absolute_up(&camera->base, &up); - transform_get_absolute_position(&camera->base, &position); - mat4_lookat(&camera->view_mat, &position, &lookat, &up); - camera_update_view_proj(&camera->base); + vec3 lookat = {0.f, 0.f, 0.f}; + vec3 up = {0.f, 0.f, 0.f}; + vec3 position = {0.f, 0.f, 0.f}; + transform_get_absolute_lookat(&camera->base, &lookat); + transform_get_absolute_up(&camera->base, &up); + transform_get_absolute_position(&camera->base, &position); + mat4_lookat(&camera->view_mat, &position, &lookat, &up); + camera_update_view_proj(camera); } void camera_update_proj(struct Camera* camera) { - if(!camera->ortho) - { - mat4_perspective(&camera->proj_mat, - camera->fov / camera->zoom, - camera->aspect_ratio, - camera->nearz, - camera->farz); - } - else - { - int width, height; - struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); - mat4_ortho(&camera->proj_mat, - -width / camera->zoom, - width / camera->zoom, - height / camera->zoom, - -height / camera->zoom, - camera->nearz, - camera->farz); - } - camera_update_view_proj(camera); + if(!camera->ortho) + { + mat4_perspective(&camera->proj_mat, + camera->fov / camera->zoom, + camera->aspect_ratio, + camera->nearz, + camera->farz); + } + else + { + int width, height; + struct Game_State* game_state = game_state_get(); + platform->window.get_size(game_state->window, &width, &height); + mat4_ortho(&camera->proj_mat, + -width / camera->zoom, + width / camera->zoom, + height / camera->zoom, + -height / camera->zoom, + camera->nearz, + camera->farz); + } + camera_update_view_proj(camera); } void camera_attach_fbo(struct Camera* camera, - int width, - int height, - bool has_depth, - bool has_color, - bool resizeable) + int width, + int height, + bool has_depth, + bool has_color, + bool resizeable) { - assert(width > 0 && height > 0); - if(camera->fbo != -1) - { - log_error("camera:attach_fbo", "Camera already has fbo attached!"); - return; - } - camera->fbo = framebuffer_create(width, height, has_depth, 0, resizeable); - if(camera->fbo > -1) + assert(width > 0 && height > 0); + if(camera->fbo != -1) + { + log_error("camera:attach_fbo", "Camera already has fbo attached!"); + return; + } + camera->fbo = framebuffer_create(width, height, has_depth, 0, resizeable); + if(camera->fbo > -1) + { + if(has_color) { - if(has_color) - { - camera->render_tex = texture_create(NULL, - TU_DIFFUSE, - width, height, - GL_RGBA, - GL_RGBA8, - GL_UNSIGNED_BYTE, - NULL); - texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - texture_set_param(camera->render_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - texture_set_param(camera->render_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - framebuffer_texture_set(camera->fbo, camera->render_tex, FA_COLOR_ATTACHMENT0); - } - - if(has_depth) - { - camera->depth_tex = texture_create(NULL, - TU_SHADOWMAP1, - width, height, - GL_DEPTH_COMPONENT, - GL_DEPTH_COMPONENT, - GL_UNSIGNED_BYTE, - NULL); - texture_set_param(camera->depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - texture_set_param(camera->depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - texture_set_param(camera->depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - texture_set_param(camera->depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - framebuffer_texture_set(camera->fbo, camera->depth_tex, FA_DEPTH_ATTACHMENT); - } + camera->render_tex = texture_create(NULL, + TU_DIFFUSE, + width, height, + GL_RGBA, + GL_RGBA8, + GL_UNSIGNED_BYTE, + NULL); + texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + texture_set_param(camera->render_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + texture_set_param(camera->render_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + framebuffer_texture_set(camera->fbo, camera->render_tex, FA_COLOR_ATTACHMENT0); } - else + + if(has_depth) { - log_error("camera:attach_fbo", "Framebuffer not attached to camera!"); + camera->depth_tex = texture_create(NULL, + TU_SHADOWMAP1, + width, height, + GL_DEPTH_COMPONENT, + GL_DEPTH_COMPONENT, + GL_UNSIGNED_BYTE, + NULL); + texture_set_param(camera->depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + texture_set_param(camera->depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + texture_set_param(camera->depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + texture_set_param(camera->depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + framebuffer_texture_set(camera->fbo, camera->depth_tex, FA_DEPTH_ATTACHMENT); } + } + else + { + log_error("camera:attach_fbo", "Framebuffer not attached to camera!"); + } } static void update_frustum(struct Camera* camera) { - assert(camera); - float* mvp = &camera->view_proj_mat.mat[0]; + assert(camera); + float* mvp = &camera->view_proj_mat.mat[0]; - camera->frustum[FP_LEFT].x = mvp[3] + mvp[0]; - camera->frustum[FP_LEFT].y = mvp[7] + mvp[4]; - camera->frustum[FP_LEFT].z = mvp[11] + mvp[2]; - camera->frustum[FP_LEFT].w = mvp[15] + mvp[12]; + camera->frustum[FP_LEFT].x = mvp[3] + mvp[0]; + camera->frustum[FP_LEFT].y = mvp[7] + mvp[4]; + camera->frustum[FP_LEFT].z = mvp[11] + mvp[2]; + camera->frustum[FP_LEFT].w = mvp[15] + mvp[12]; - camera->frustum[FP_RIGHT].x = mvp[3] - mvp[0]; - camera->frustum[FP_RIGHT].y = mvp[7] - mvp[4]; - camera->frustum[FP_RIGHT].z = mvp[11] - mvp[8]; - camera->frustum[FP_RIGHT].w = mvp[15] - mvp[12]; + camera->frustum[FP_RIGHT].x = mvp[3] - mvp[0]; + camera->frustum[FP_RIGHT].y = mvp[7] - mvp[4]; + camera->frustum[FP_RIGHT].z = mvp[11] - mvp[8]; + camera->frustum[FP_RIGHT].w = mvp[15] - mvp[12]; - camera->frustum[FP_BOTTOM].x = mvp[3] + mvp[1]; - camera->frustum[FP_BOTTOM].y = mvp[11] + mvp[5]; - camera->frustum[FP_BOTTOM].z = mvp[11] + mvp[9]; - camera->frustum[FP_BOTTOM].w = mvp[15] + mvp[13]; + camera->frustum[FP_BOTTOM].x = mvp[3] + mvp[1]; + camera->frustum[FP_BOTTOM].y = mvp[11] + mvp[5]; + camera->frustum[FP_BOTTOM].z = mvp[11] + mvp[9]; + camera->frustum[FP_BOTTOM].w = mvp[15] + mvp[13]; - camera->frustum[FP_TOP].x = mvp[3] - mvp[1]; - camera->frustum[FP_TOP].y = mvp[7] - mvp[5]; - camera->frustum[FP_TOP].z = mvp[11] - mvp[9]; - camera->frustum[FP_TOP].w = mvp[15] - mvp[13]; + camera->frustum[FP_TOP].x = mvp[3] - mvp[1]; + camera->frustum[FP_TOP].y = mvp[7] - mvp[5]; + camera->frustum[FP_TOP].z = mvp[11] - mvp[9]; + camera->frustum[FP_TOP].w = mvp[15] - mvp[13]; - camera->frustum[FP_NEAR].x = mvp[3] + mvp[2]; - camera->frustum[FP_NEAR].y = mvp[7] + mvp[6]; - camera->frustum[FP_NEAR].z = mvp[11] + mvp[10]; - camera->frustum[FP_NEAR].w = mvp[15] + mvp[14]; + camera->frustum[FP_NEAR].x = mvp[3] + mvp[2]; + camera->frustum[FP_NEAR].y = mvp[7] + mvp[6]; + camera->frustum[FP_NEAR].z = mvp[11] + mvp[10]; + camera->frustum[FP_NEAR].w = mvp[15] + mvp[14]; - camera->frustum[FP_FAR].x = mvp[3] - mvp[2]; - camera->frustum[FP_FAR].y = mvp[7] - mvp[6]; - camera->frustum[FP_FAR].z = mvp[11] - mvp[10]; - camera->frustum[FP_FAR].w = mvp[15] - mvp[14]; - - for(int i = 0; i < FP_NUM_PLANES; i++) - { - vec3 plane_xyz = {camera->frustum[i].x, camera->frustum[i].y, camera->frustum[i].z}; - float length = fabsf(vec3_len(&plane_xyz)); - vec4_scale(&camera->frustum[i], &camera->frustum[i], (1.f / length)); - } + camera->frustum[FP_FAR].x = mvp[3] - mvp[2]; + camera->frustum[FP_FAR].y = mvp[7] - mvp[6]; + camera->frustum[FP_FAR].z = mvp[11] - mvp[10]; + camera->frustum[FP_FAR].w = mvp[15] - mvp[14]; + + for(int i = 0; i < FP_NUM_PLANES; i++) + { + vec3 plane_xyz = {camera->frustum[i].x, camera->frustum[i].y, camera->frustum[i].z}; + float length = fabsf(vec3_len(&plane_xyz)); + vec4_scale(&camera->frustum[i], &camera->frustum[i], (1.f / length)); + } } struct Ray camera_screen_coord_to_ray(struct Camera* camera, int mouse_x, int mouse_y) { - struct Ray ray; + struct Ray ray; - int win_width = 0, win_height = 0; - struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &win_width, &win_height); + int win_width = 0, win_height = 0; + struct Game_State* game_state = game_state_get(); + platform->window.get_size(game_state->window, &win_width, &win_height); - float normalized_x = (2.f * (float)mouse_x) / (float)win_width - 1.f; - float normalized_y = 1.f - (2.f * (float)mouse_y) / (float)win_height; + float normalized_x = (2.f * (float)mouse_x) / (float)win_width - 1.f; + float normalized_y = 1.f - (2.f * (float)mouse_y) / (float)win_height; - vec3 near_point = {0.f}; - vec3 far_point = {0.f}; + vec3 near_point = {0.f}; + vec3 far_point = {0.f}; - mat4 inverse_view_proj_mat; - mat4_identity(&inverse_view_proj_mat); - mat4_inverse(&inverse_view_proj_mat, &camera->view_proj_mat); + mat4 inverse_view_proj_mat; + mat4_identity(&inverse_view_proj_mat); + mat4_inverse(&inverse_view_proj_mat, &camera->view_proj_mat); - //Project the near point - quat rot_near = {normalized_x, normalized_y, 0.f, 1.f}; - vec4_mul_mat4(&rot_near, &rot_near, &inverse_view_proj_mat); - near_point.x = rot_near.x / rot_near.w; - near_point.y = rot_near.y / rot_near.w; - near_point.z = rot_near.z / rot_near.w; + //Project the near point + quat rot_near = {normalized_x, normalized_y, 0.f, 1.f}; + quat_mul_mat4(&rot_near, &rot_near, &inverse_view_proj_mat); + near_point.x = rot_near.x / rot_near.w; + near_point.y = rot_near.y / rot_near.w; + near_point.z = rot_near.z / rot_near.w; - //Project far point - quat rot_far = {normalized_x, normalized_y, 1.f, 1.f}; - vec4_mul_mat4(&rot_far, &rot_far, &inverse_view_proj_mat); - far_point.x = rot_far.x / rot_far.w; - far_point.y = rot_far.y / rot_far.w; - far_point.z = rot_far.z / rot_far.w; + //Project far point + quat rot_far = {normalized_x, normalized_y, 1.f, 1.f}; + quat_mul_mat4(&rot_far, &rot_far, &inverse_view_proj_mat); + far_point.x = rot_far.x / rot_far.w; + far_point.y = rot_far.y / rot_far.w; + far_point.z = rot_far.z / rot_far.w; - vec3_sub(&ray.direction, &far_point, &near_point); - vec3_norm(&ray.direction, &ray.direction); + vec3_sub(&ray.direction, &far_point, &near_point); + vec3_norm(&ray.direction, &ray.direction); - transform_get_absolute_position(&camera->base, &ray.origin); + transform_get_absolute_position(&camera->base, &ray.origin); - return ray; -} \ No newline at end of file + return ray; +} diff --git a/src/libsymmetry/console.c b/src/libsymmetry/console.c index c5b0684..84b41bd 100644 --- a/src/libsymmetry/console.c +++ b/src/libsymmetry/console.c @@ -14,82 +14,82 @@ static int console_filter(const struct nk_text_edit *box, nk_rune unicode); void console_init(struct Console* console) { - assert(console); + assert(console); - console_message_color[CMT_MESSAGE] = nk_rgb(255, 255, 255); - console_message_color[CMT_WARNING] = nk_rgb(255, 255, 0); - console_message_color[CMT_ERROR] = nk_rgb(255, 0, 0); - console_message_color[CMT_COMMAND] = nk_rgb(114, 173, 224); - console_message_color[CMT_NONE] = nk_rgb(255, 0, 255); + console_message_color[CMT_MESSAGE] = nk_rgb(255, 255, 255); + console_message_color[CMT_WARNING] = nk_rgb(255, 255, 0); + console_message_color[CMT_ERROR] = nk_rgb(255, 0, 0); + console_message_color[CMT_COMMAND] = nk_rgb(114, 173, 224); + console_message_color[CMT_NONE] = nk_rgb(255, 0, 255); - console->visible = false; - console->scroll_to_bottom = true; - console->text_region_height = 22.f; - console->line_height = 20.f; - console->current_message_index = -1; - - memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); - for(int i = 0; i < MAX_CONSOLE_MESSAGES; i++) - { - memset(console->console_messages[i].message, '\0', MAX_CONSOLE_MESSAGE_LEN); - console->console_messages[i].type = CMT_NONE; - } + console->visible = false; + console->scroll_to_bottom = true; + console->text_region_height = 22.f; + console->line_height = 20.f; + console->current_message_index = -1; + + memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); + for(int i = 0; i < MAX_CONSOLE_MESSAGES; i++) + { + memset(console->console_messages[i].message, '\0', MAX_CONSOLE_MESSAGE_LEN); + console->console_messages[i].type = CMT_NONE; + } } void console_toggle(struct Console* console) { - if(!console->visible) console->scroll_to_bottom = true; - console->visible = !console->visible; + console->visible = !console->visible; + if(console->visible) console->scroll_to_bottom = true; } void console_update(struct Console* console, struct Gui_State* gui_state, float dt) { - if(!console->visible) return; + if(!console->visible) return; - struct nk_context* context = &gui_state->context; - struct Game_State* game_state = game_state_get(); + struct nk_context* context = &gui_state->context; + struct Game_State* game_state = game_state_get(); - int win_width = 0, win_height = 0; - platform->window.get_drawable_size(game_state->window, &win_width, &win_height); - int half_height = win_height / 2; + int win_width = 0, win_height = 0; + platform->window.get_drawable_size(game_state->window, &win_width, &win_height); + int half_height = win_height / 2; - if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE)) + if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE)) + { + nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1); + if(nk_group_begin(context, "Log", NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1); - if(nk_group_begin(context, "Log", NK_WINDOW_BORDER)) - { - for(int i = 0; i <= console->current_message_index; i++) - { - nk_layout_row_dynamic(context, console->line_height, 1); - nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, console_message_color[console->console_messages[i].type], console->console_messages[i].message); - } - - if(console->scroll_to_bottom == true) // scroll console message area to the bottom if required - { - *context->current->layout->offset_y = context->current->layout->at_y; - console->scroll_to_bottom = false; - } + for(int i = 0; i <= console->current_message_index; i++) + { + nk_layout_row_dynamic(context, console->line_height, 1); + nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, console_message_color[console->console_messages[i].type], console->console_messages[i].message); + } + + if(console->scroll_to_bottom == true) // scroll console message area to the bottom if required + { + *context->current->layout->offset_y = (nk_uint)context->current->layout->at_y; + console->scroll_to_bottom = false; + } - nk_group_end(context); - } - - //Edit-string/Textfield for command - nk_layout_row_dynamic(context, console->text_region_height, 1); - int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER; - nk_edit_focus(context, edit_flags); - int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_MESSAGE_LEN, console_filter); - if(edit_state & NK_EDIT_COMMITED) - { - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; + nk_group_end(context); + } + + //Edit-string/Textfield for command + nk_layout_row_dynamic(context, console->text_region_height, 1); + int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER; + nk_edit_focus(context, edit_flags); + int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_MESSAGE_LEN, console_filter); + if(edit_state & NK_EDIT_COMMITED) + { + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; - snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "> %s", console->console_command_text); - console->console_messages[console->current_message_index].type = CMT_COMMAND; - memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); - console->scroll_to_bottom = true; - } + snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "> %s", console->console_command_text); + console->console_messages[console->current_message_index].type = CMT_COMMAND; + memset(console->console_command_text, '\0', MAX_CONSOLE_MESSAGE_LEN); + console->scroll_to_bottom = true; } - nk_end(context); + } + nk_end(context); } void console_destroy(struct Console* console) @@ -99,37 +99,37 @@ void console_destroy(struct Console* console) int console_filter(const struct nk_text_edit *box, nk_rune unicode) { - NK_UNUSED(box); - if(unicode > 128 || unicode == 96) // Ignore tilde or anything other than ascii - return nk_false; - else - return nk_true; + NK_UNUSED(box); + if(unicode > 128 || unicode == 96) // Ignore tilde or anything other than ascii + return nk_false; + else + return nk_true; } void console_on_log_message(struct Console* console, const char* message, va_list args) { - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; - vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, message, args); - console->console_messages[console->current_message_index].type = CMT_MESSAGE; - console->scroll_to_bottom = true; + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; + vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, message, args); + console->console_messages[console->current_message_index].type = CMT_MESSAGE; + console->scroll_to_bottom = true; } void console_on_log_warning(struct Console* console, const char* warning_message, va_list args) { - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; - vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args); - console->console_messages[console->current_message_index].type = CMT_WARNING; - console->scroll_to_bottom = true; + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; + vsnprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, warning_message, args); + console->console_messages[console->current_message_index].type = CMT_WARNING; + console->scroll_to_bottom = true; } void console_on_log_error(struct Console* console, const char* context, const char* error, va_list args) { - if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) - console->current_message_index = 0; - int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context); - vsnprintf(console->console_messages[console->current_message_index].message + loc, MAX_CONSOLE_MESSAGE_LEN, error, args); - console->console_messages[console->current_message_index].type = CMT_ERROR; - console->scroll_to_bottom = true; + if(++console->current_message_index >= MAX_CONSOLE_MESSAGES) + console->current_message_index = 0; + int loc = snprintf(console->console_messages[console->current_message_index].message, MAX_CONSOLE_MESSAGE_LEN, "(%s)", context); + vsnprintf(console->console_messages[console->current_message_index].message + loc, MAX_CONSOLE_MESSAGE_LEN, error, args); + console->console_messages[console->current_message_index].type = CMT_ERROR; + console->scroll_to_bottom = true; } diff --git a/src/libsymmetry/editor.c b/src/libsymmetry/editor.c index bf7a1cb..d03b855 100644 --- a/src/libsymmetry/editor.c +++ b/src/libsymmetry/editor.c @@ -7,6 +7,7 @@ #include "texture.h" #include "framebuffer.h" #include "../common/array.h" +#include "../common/hashmap.h" #include "shader.h" #include "../common/num_types.h" #include "light.h" @@ -33,19 +34,19 @@ struct Editor_State { - bool enabled; - bool renderer_settings_window; - struct Entity* selected_entity; - int top_panel_height; - float camera_turn_speed; - float camera_move_speed; - float camera_sprint_multiplier; + bool enabled; + bool renderer_settings_window; + struct Entity* selected_entity; + int top_panel_height; + float camera_turn_speed; + float camera_move_speed; + float camera_sprint_multiplier; }; struct Debug_Variable { - struct Variant data; - char* name; + struct Variant data; + char* name; }; static struct Editor_State editor_state; @@ -57,718 +58,716 @@ static void editor_show_entity_in_list(struct nk_context* context, struct Scene* static void editor_widget_color_combov3(struct nk_context* context, vec3* color, int width, int height); static void editor_widget_color_combov4(struct nk_context* context, vec4* color, int width, int height); static bool editor_widget_v3(struct nk_context* context, - vec3* value, - const char* name_x, - const char* name_y, - const char* name_z, - float min, - float max, - float step, - float inc_per_pixel, - int row_height); + vec3* value, + const char* name_x, + const char* name_y, + const char* name_z, + float min, + float max, + float step, + float inc_per_pixel, + int row_height); void editor_init(void) { - editor_state.enabled = true; - editor_state.renderer_settings_window = false; - editor_state.selected_entity = NULL; - editor_state.top_panel_height = 20; - editor_state.camera_turn_speed = 50.f; - editor_state.camera_move_speed = 20.f; - editor_state.camera_sprint_multiplier = 2.f; - debug_vars_list = array_new(struct Debug_Variable); - empty_indices = array_new(int); + editor_state.enabled = true; + editor_state.renderer_settings_window = false; + editor_state.selected_entity = NULL; + editor_state.top_panel_height = 20; + editor_state.camera_turn_speed = 50.f; + editor_state.camera_move_speed = 20.f; + editor_state.camera_sprint_multiplier = 2.f; + debug_vars_list = array_new(struct Debug_Variable); + empty_indices = array_new(int); } void editor_init_camera(void) { - struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; - entity_rename(editor_camera, "Editor_Camera"); - editor_camera->base.active = true; - editor_camera->clear_color.x = 0.3f; - editor_camera->clear_color.y = 0.6f; - editor_camera->clear_color.z = 0.9f; - editor_camera->clear_color.w = 1.f; - - - struct Hashmap* config = platform->config.get(); - int render_width = hashmap_int_get(config, "render_width"); - int render_height = hashmap_int_get(config, "render_height"); - camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); - - vec3 cam_pos = {5.f, 20.f, 50.f}; - transform_translate(editor_camera, &cam_pos, TS_WORLD); + struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; + entity_rename(editor_camera, "Editor_Camera"); + editor_camera->base.active = true; + editor_camera->clear_color.x = 0.3f; + editor_camera->clear_color.y = 0.6f; + editor_camera->clear_color.z = 0.9f; + editor_camera->clear_color.w = 1.f; + + struct Hashmap* config = platform->config.get(); + int render_width = hashmap_int_get(config, "render_width"); + int render_height = hashmap_int_get(config, "render_height"); + camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); + + vec3 cam_pos = {5.f, 20.f, 50.f}; + transform_translate(editor_camera, &cam_pos, TS_WORLD); } int editor_debugvar_slot_create(const char* name, int value_type) { - int index = -1; - struct Debug_Variable* debug_var = NULL; - if(array_len(empty_indices) > 0) - { - index = *array_get_last(empty_indices, int); - array_pop(empty_indices); - debug_var = &debug_vars_list[index]; - } - else - { - debug_var = array_grow(debug_vars_list, struct Debug_Variable); - index = array_len(debug_vars_list) - 1; - } - debug_var->name = str_new(name); - debug_var->data.type = value_type; + int index = -1; + struct Debug_Variable* debug_var = NULL; + if(array_len(empty_indices) > 0) + { + index = *array_get_last(empty_indices, int); + array_pop(empty_indices); + debug_var = &debug_vars_list[index]; + } + else + { + debug_var = array_grow(debug_vars_list, struct Debug_Variable); + index = array_len(debug_vars_list) - 1; + } + debug_var->name = str_new(name); + debug_var->data.type = value_type; - return index; + return index; } void editor_debugvar_slot_remove(int index) { - assert(index > -1 && index < array_len(debug_vars_list)); - struct Debug_Variable* debug_var = &debug_vars_list[index]; - variant_free(&debug_var->data); - if(debug_var->name) free(debug_var->name); - debug_var->name = NULL; - debug_var->data.type = VT_NONE; + assert(index > -1 && index < array_len(debug_vars_list)); + struct Debug_Variable* debug_var = &debug_vars_list[index]; + variant_free(&debug_var->data); + if(debug_var->name) free(debug_var->name); + debug_var->name = NULL; + debug_var->data.type = VT_NONE; } void editor_debugvar_slot_set_float(int index, float value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_float(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_float(&debug_vars_list[index].data, value); } void editor_debugvar_slot_set_int(int index, int value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_int(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_int(&debug_vars_list[index].data, value); } void editor_debugvar_slot_set_double(int index, double value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_double(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_double(&debug_vars_list[index].data, value); } void editor_debugvar_slot_set_vec2(int index, vec2* value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_vec2(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_vec2(&debug_vars_list[index].data, value); } void editor_debugvar_slot_set_vec3(int index, vec3* value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_vec3(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_vec3(&debug_vars_list[index].data, value); } void editor_debugvar_slot_set_vec4(int index, vec4* value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_vec4(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_vec4(&debug_vars_list[index].data, value); } void editor_debugvar_slot_set_quat(int index, quat* value) { - assert(index > -1 && index < array_len(debug_vars_list)); - variant_assign_quat(&debug_vars_list[index].data, value); + assert(index > -1 && index < array_len(debug_vars_list)); + variant_assign_quat(&debug_vars_list[index].data, value); } void editor_update(float dt) { - if(!editor_state.enabled) return; + if(!editor_state.enabled) return; - editor_camera_update(dt); + editor_camera_update(dt); - struct Game_State* game_state = game_state_get(); - struct Gui_State* gui_state = gui_state_get(); - struct nk_context* context = &gui_state->context; - int win_width = 0, win_height = 0; + struct Game_State* game_state = game_state_get(); + struct Gui_State* gui_state = gui_state_get(); + struct nk_context* context = &gui_state->context; + int win_width = 0, win_height = 0; platform->window.get_drawable_size(game_state->window, &win_width, &win_height); - int half_width = win_width / 2, half_height = win_height / 2; - static int window_flags = NK_WINDOW_BORDER | - NK_WINDOW_CLOSABLE | - NK_WINDOW_MOVABLE | - NK_WINDOW_SCROLL_AUTO_HIDE | - NK_WINDOW_SCALABLE; - - /* Main enacapsulating window */ - struct nk_style_item default_background = context->style.window.fixed_background; - struct nk_vec2 default_padding = context->style.window.padding; - context->style.window.padding = nk_vec2(0.f, 0.f); - context->style.window.fixed_background = nk_style_item_hide(); - if(nk_begin(context, "Editor", nk_recti(0, 0, win_width, win_height), NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND)) + int half_width = win_width / 2, half_height = win_height / 2; + static int window_flags = NK_WINDOW_BORDER | + NK_WINDOW_CLOSABLE | + NK_WINDOW_MOVABLE | + NK_WINDOW_SCROLL_AUTO_HIDE | + NK_WINDOW_SCALABLE; + + /* Main enacapsulating window */ + struct nk_style_item default_background = context->style.window.fixed_background; + struct nk_vec2 default_padding = context->style.window.padding; + context->style.window.padding = nk_vec2(0.f, 0.f); + context->style.window.fixed_background = nk_style_item_hide(); + if(nk_begin(context, "Editor", nk_recti(0, 0, win_width, win_height), NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND)) + { + context->style.window.fixed_background = default_background; + /* Top Panel */ + nk_layout_row_dynamic(context, editor_state.top_panel_height + 10.f, 1); + nk_group_begin(context, "Menubar", NK_WINDOW_NO_SCROLLBAR); { - context->style.window.fixed_background = default_background; - /* Top Panel */ - nk_layout_row_dynamic(context, editor_state.top_panel_height + 10, 1); - nk_group_begin(context, "Menubar", NK_WINDOW_NO_SCROLLBAR); - { - static float top_panel_ratios[] = {0.1f, 0.1f, 0.7f, 0.1f}; - static int frames = 0; - static int fps = 0; - static float seconds = 0.f; - seconds += dt; - frames++; - if(seconds >= 1.f) - { - fps = frames; - seconds = 0.f; - frames = 0; - } - - nk_layout_row(context, NK_DYNAMIC, editor_state.top_panel_height, sizeof(top_panel_ratios) / sizeof(float), top_panel_ratios); - if(nk_button_label(context, "Render Settings")) - editor_state.renderer_settings_window = !editor_state.renderer_settings_window; - if(nk_button_label(context, "Save config")) + static float top_panel_ratios[] = {0.1f, 0.1f, 0.7f, 0.1f}; + static int frames = 0; + static int fps = 0; + static float seconds = 0.f; + seconds += dt; + frames++; + if(seconds >= 1.f) + { + fps = frames; + seconds = 0.f; + frames = 0; + } + + nk_layout_row(context, NK_DYNAMIC, editor_state.top_panel_height, sizeof(top_panel_ratios) / sizeof(float), top_panel_ratios); + if(nk_button_label(context, "Render Settings")) + editor_state.renderer_settings_window = !editor_state.renderer_settings_window; + if(nk_button_label(context, "Save config")) platform->config.save("config.cfg", DIRT_USER); - nk_spacing(context, 1); - nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps); - nk_group_end(context); - } + nk_spacing(context, 1); + nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps); + nk_group_end(context); + } - static float main_editor_ratios[] = {0.2f, 0.6f, 0.2f}; + static float main_editor_ratios[] = {0.2f, 0.6f, 0.2f}; nk_layout_row(context, NK_DYNAMIC, win_height - editor_state.top_panel_height, sizeof(main_editor_ratios) / sizeof(float), main_editor_ratios); - /* Left */ - if(nk_group_begin(context, "Editor Left", NK_WINDOW_SCROLL_AUTO_HIDE)) + /* Left */ + if(nk_group_begin(context, "Editor Left", NK_WINDOW_SCROLL_AUTO_HIDE)) + { + /* Entities List */ + struct Scene* scene = game_state_get()->scene; + if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED)) + { + nk_layout_row_dynamic(context, 250, 1); + if(nk_group_begin(context, "Entity Name", NK_WINDOW_SCROLL_AUTO_HIDE)) { - /* Entities List */ - struct Scene* scene = game_state_get()->scene; - if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED)) - { - nk_layout_row_dynamic(context, 250, 1); - if(nk_group_begin(context, "Entity Name", NK_WINDOW_SCROLL_AUTO_HIDE)) - { - for(int i = 0; i < MAX_ENTITIES; i++) editor_show_entity_in_list(context, scene, &scene->entities[i]); - for(int i = 0; i < MAX_CAMERAS; i++) editor_show_entity_in_list(context, scene, &scene->cameras[i]); - for(int i = 0; i < MAX_LIGHTS; i++) editor_show_entity_in_list(context, scene, &scene->lights[i]); - for(int i = 0; i < MAX_STATIC_MESHES; i++) editor_show_entity_in_list(context, scene, &scene->static_meshes[i]); + for(int i = 0; i < MAX_ENTITIES; i++) editor_show_entity_in_list(context, scene, &scene->entities[i]); + for(int i = 0; i < MAX_CAMERAS; i++) editor_show_entity_in_list(context, scene, &scene->cameras[i]); + for(int i = 0; i < MAX_LIGHTS; i++) editor_show_entity_in_list(context, scene, &scene->lights[i]); + for(int i = 0; i < MAX_STATIC_MESHES; i++) editor_show_entity_in_list(context, scene, &scene->static_meshes[i]); - nk_group_end(context); - } - nk_tree_pop(context); - } - - /* Debug Variables */ - if(nk_tree_push(context, NK_TREE_TAB, "Debug Variables", NK_MAXIMIZED)) - { - static char variant_str[MAX_VARIANT_STR_LEN] = {'\0'}; - nk_layout_row_dynamic(context, 250, 1); - if(nk_group_begin(context, "Name", NK_WINDOW_SCROLL_AUTO_HIDE)) - { - for(int i = 0; i < array_len(debug_vars_list); i++) - { - struct Debug_Variable* debug_var = &debug_vars_list[i]; - if(debug_var->data.type == VT_NONE) continue; - nk_layout_row_dynamic(context, 20, 2); - nk_label(context, debug_var->name, NK_TEXT_ALIGN_LEFT); - variant_to_str(&debug_var->data, variant_str, MAX_VARIANT_STR_LEN); - nk_label(context, variant_str, NK_TEXT_ALIGN_RIGHT); - memset(variant_str, '\0', MAX_VARIANT_STR_LEN); - } - nk_group_end(context); - } - nk_tree_pop(context); - } - - nk_group_end(context); + nk_group_end(context); } - - /* Empty Space in the center */ - nk_spacing(context, 1); - - /* Right */ - if(nk_group_begin(context, "Editor Right", NK_WINDOW_NO_SCROLLBAR)) + nk_tree_pop(context); + } + + /* Debug Variables */ + if(nk_tree_push(context, NK_TREE_TAB, "Debug Variables", NK_MAXIMIZED)) + { + static char variant_str[MAX_VARIANT_STR_LEN] = {'\0'}; + nk_layout_row_dynamic(context, 250, 1); + if(nk_group_begin(context, "Name", NK_WINDOW_SCROLL_AUTO_HIDE)) { - /* Entity Inspector */ - if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED)) - { - const int row_height = 18; - if(editor_state.selected_entity) - { - struct Scene* scene = game_state_get()->scene; - struct Entity* entity = editor_state.selected_entity; - - struct Entity* parent_ent = entity->transform.parent; - nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT); - nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); - nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity->editor_selected ? "True" : "False"); - nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); - nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); - - /* Transform */ - { - nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Position", NK_TEXT_ALIGN_CENTERED); - vec3 abs_pos = {0.f, 0.f, 0.f}; - transform_get_absolute_position(entity, &abs_pos); - if(editor_widget_v3(context, &abs_pos, "Px", "Py", "Pz", -FLT_MAX, FLT_MAX, 5.f, 1.f, row_height)) transform_set_position(entity, &abs_pos); - - nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Rotation", NK_TEXT_ALIGN_CENTERED); - quat abs_rot = {0.f, 0.f, 0.f, 1.f}; - transform_get_absolute_rot(entity, &abs_rot); - vec3 rot_angles = {0.f, 0.f, 0.f}; - rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot)); - rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot)); - rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot)); - vec3 curr_rot = {rot_angles.x, rot_angles.y, rot_angles.z}; - - nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rx", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f); - nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Ry", -FLT_MAX, &curr_rot.y, FLT_MAX, 5.f, 1.f); - nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rz", -FLT_MAX, &curr_rot.z, FLT_MAX, 5.f, 1.f); - - vec3 delta = {0.f, 0.f, 0.f}; - vec3_sub(&delta, &rot_angles, &curr_rot); - - vec3 AXIS_X = {1.f, 0.f, 0.f}; - vec3 AXIS_Y = {0.f, 1.f, 0.f}; - vec3 AXIS_Z = {0.f, 0.f, 1.f}; - - const float epsilon = 0.0001f; - if(fabsf(delta.x) > epsilon) transform_rotate(entity, &AXIS_X, delta.x, TS_WORLD); - if(fabsf(delta.y) > epsilon) transform_rotate(entity, &AXIS_Y, delta.y, TS_WORLD); - if(fabsf(delta.z) > epsilon) transform_rotate(entity, &AXIS_Z, delta.z, TS_WORLD); - - nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Scale", NK_TEXT_ALIGN_CENTERED); - vec3 abs_scale = {0.f, 0.f, 0.f}; - transform_get_absolute_scale(entity, &abs_scale); - if(editor_widget_v3(context, &abs_scale, "SX", "SY", "SZ", 0.1f, FLT_MAX, 1.f, 0.1f, row_height)) - { - entity->transform.scale = abs_scale; - transform_update_transmat(entity); - } - } - - /* Light */ - if(entity->type == ET_LIGHT) - { - if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED)) - { - struct Light* light = (struct Light*)entity; - if(light->type > LT_POINT) - { - nk_layout_row_dynamic(context, row_height, 1); - nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED); - } - else - { - static const char* light_types[] = {"Spot", "Directional", "Point"}; - float combo_width = nk_widget_width(context), combo_height = row_height * (LT_MAX); - - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Light Type", NK_TEXT_ALIGN_LEFT); - nk_combobox(context, light_types, LT_MAX - 1, &light->type, row_height, nk_vec2(combo_width, combo_height)); - - nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED); - nk_layout_row_dynamic(context, row_height, 1); - editor_widget_color_combov3(context, &light->color, 200, 300); - - nk_layout_row_dynamic(context, row_height, 1); - nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f); - - if(light->type != LT_DIR) - { - nk_layout_row_dynamic(context, row_height, 1); - light->outer_angle = TO_RADIANS(nk_propertyf(context, "Outer Angle", TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 360, 1.f, 0.5f)); - - nk_layout_row_dynamic(context, row_height, 1); - light->inner_angle = TO_RADIANS(nk_propertyf(context, "Inner Angle", 1.f, TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 1.f, 0.5f)); - - nk_layout_row_dynamic(context, row_height, 1); - nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 1); - - nk_layout_row_dynamic(context, row_height, 1); - nk_property_float(context, "Falloff", 0.f, &light->falloff, 100.f, 0.1f, 0.05f); - } - } - nk_tree_pop(context); - } - } - - /* Camera */ - if(entity->type == ET_CAMERA) - { - if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED)) - { - bool update = false; - struct Camera* camera = (struct Camera*)entity; - - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - bool ortho = nk_checkbox_label(context, "", &camera->ortho); - if(ortho != camera->ortho) - { - update = true; - } - - - if(!camera->ortho) - { - nk_layout_row_dynamic(context, row_height, 1); - float new_fov = nk_propertyf(context, "Fov", 30.f, camera->fov, 90.f, 0.1f, 1.f); - if(new_fov != camera->fov) - { - camera->fov = new_fov; - update = true; - } - - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio); - } - - nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Clear Color", NK_TEXT_ALIGN_CENTERED); - nk_layout_row_dynamic(context, row_height, 1); - editor_widget_color_combov4(context, &camera->clear_color, 200, 300); - - nk_layout_row_dynamic(context, row_height, 1); - float new_zoom = nk_propertyf(context, "Zoom", 1.f, camera->zoom, FLT_MAX, 0.1f, 1.f); - if(new_zoom != camera->zoom) - { - camera->zoom = new_zoom; - update = true; - } - - nk_layout_row_dynamic(context, row_height, 1); - float new_near_z = nk_propertyf(context, "NearZ", -FLT_MAX, camera->nearz, camera->farz, 0.1f, 1.f); - if(new_near_z != camera->nearz) - { - camera->nearz = new_near_z; - update = true; - } - - nk_layout_row_dynamic(context, row_height, 1); - float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f); - if(new_far_z != camera->farz) - { - camera->farz = new_far_z; - update = true; - } - - if(update) - { - camera_update_view(entity); - camera_update_proj(entity); - } - - nk_tree_pop(context); - } - } - } - else - { - nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED); - } - nk_tree_pop(context); - } - - nk_group_end(context); + for(int i = 0; i < array_len(debug_vars_list); i++) + { + struct Debug_Variable* debug_var = &debug_vars_list[i]; + if(debug_var->data.type == VT_NONE) continue; + nk_layout_row_dynamic(context, 20, 2); + nk_label(context, debug_var->name, NK_TEXT_ALIGN_LEFT); + variant_to_str(&debug_var->data, variant_str, MAX_VARIANT_STR_LEN); + nk_label(context, variant_str, NK_TEXT_ALIGN_RIGHT); + memset(variant_str, '\0', MAX_VARIANT_STR_LEN); + } + nk_group_end(context); } + nk_tree_pop(context); + } + + nk_group_end(context); } - nk_end(context); - context->style.window.padding = default_padding; - /* Render Settings Window */ - if(editor_state.renderer_settings_window) + /* Empty Space in the center */ + nk_spacing(context, 1); + + /* Right */ + if(nk_group_begin(context, "Editor Right", NK_WINDOW_NO_SCROLLBAR)) { - const int row_height = 25; - if(nk_begin_titled(context, "Renderer_Settings_Window", "Renderer Settings", nk_rect(half_width, half_height, 300, 350), window_flags)) + /* Entity Inspector */ + if(nk_tree_push(context, NK_TREE_TAB, "Inspector", NK_MAXIMIZED)) + { + const int row_height = 18; + if(editor_state.selected_entity) { - static struct Render_Settings render_settings; - renderer_settings_get(&render_settings); - if(nk_tree_push(context, NK_TREE_TAB, "Debug", NK_MAXIMIZED)) + struct Scene* scene = game_state_get()->scene; + struct Entity* entity = editor_state.selected_entity; + + struct Entity* parent_ent = entity->transform.parent; + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Name", NK_TEXT_ALIGN_LEFT); nk_label(context, entity->name, NK_TEXT_ALIGN_RIGHT); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "ID", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%d", entity->id); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Selected", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity->editor_selected ? "True" : "False"); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Entity Type", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%s", entity_type_name_get(entity)); + nk_layout_row_dynamic(context, row_height, 2); nk_label(context, "Parent Name", NK_TEXT_ALIGN_LEFT); nk_label(context, parent_ent ? parent_ent->name : "NONE", NK_TEXT_ALIGN_RIGHT); + + /* Transform */ + { + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Position", NK_TEXT_ALIGN_CENTERED); + vec3 abs_pos = {0.f, 0.f, 0.f}; + transform_get_absolute_position(entity, &abs_pos); + if(editor_widget_v3(context, &abs_pos, "Px", "Py", "Pz", -FLT_MAX, FLT_MAX, 5.f, 1.f, row_height)) transform_set_position(entity, &abs_pos); + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Rotation", NK_TEXT_ALIGN_CENTERED); + quat abs_rot = {0.f, 0.f, 0.f, 1.f}; + transform_get_absolute_rot(entity, &abs_rot); + vec3 rot_angles = {0.f, 0.f, 0.f}; + rot_angles.x = TO_DEGREES(quat_get_pitch(&abs_rot)); + rot_angles.y = TO_DEGREES(quat_get_yaw(&abs_rot)); + rot_angles.z = TO_DEGREES(quat_get_roll(&abs_rot)); + vec3 curr_rot = {rot_angles.x, rot_angles.y, rot_angles.z}; + + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rx", -FLT_MAX, &curr_rot.x, FLT_MAX, 5.f, 1.f); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Ry", -FLT_MAX, &curr_rot.y, FLT_MAX, 5.f, 1.f); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, "Rz", -FLT_MAX, &curr_rot.z, FLT_MAX, 5.f, 1.f); + + vec3 delta = {0.f, 0.f, 0.f}; + vec3_sub(&delta, &rot_angles, &curr_rot); + + vec3 AXIS_X = {1.f, 0.f, 0.f}; + vec3 AXIS_Y = {0.f, 1.f, 0.f}; + vec3 AXIS_Z = {0.f, 0.f, 1.f}; + + const float epsilon = 0.0001f; + if(fabsf(delta.x) > epsilon) transform_rotate(entity, &AXIS_X, delta.x, TS_WORLD); + if(fabsf(delta.y) > epsilon) transform_rotate(entity, &AXIS_Y, delta.y, TS_WORLD); + if(fabsf(delta.z) > epsilon) transform_rotate(entity, &AXIS_Z, delta.z, TS_WORLD); + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Scale", NK_TEXT_ALIGN_CENTERED); + vec3 abs_scale = {0.f, 0.f, 0.f}; + transform_get_absolute_scale(entity, &abs_scale); + if(editor_widget_v3(context, &abs_scale, "SX", "SY", "SZ", 0.1f, FLT_MAX, 1.f, 0.1f, row_height)) { - static const char* draw_modes[] = {"Triangles", "Lines", "Points"}; - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Debug Draw", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - nk_checkbox_label(context, "", &render_settings.debug_draw_enabled); - - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Debug Draw Mode", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - render_settings.debug_draw_mode = nk_combo(context, draw_modes, 3, render_settings.debug_draw_mode, 20, nk_vec2(180, 100)); - - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Debug Color", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - editor_widget_color_combov4(context, &render_settings.debug_draw_color, 200, 400); - nk_tree_pop(context); + entity->transform.scale = abs_scale; + transform_update_transmat(entity); } + } - if(nk_tree_push(context, NK_TREE_TAB, "Fog", NK_MAXIMIZED)) + /* Light */ + if(entity->type == ET_LIGHT) + { + if(nk_tree_push(context, NK_TREE_TAB, "Light", NK_MAXIMIZED)) { - static const char* fog_modes[] = {"None", "Linear", "Exponential", "Exponential Squared"}; - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Color", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - editor_widget_color_combov3(context, &render_settings.fog.color, 200, 400); - - nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Fog Mode", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - render_settings.fog.mode = nk_combo(context, - fog_modes, - 4, - render_settings.fog.mode, - 20, - nk_vec2(180, 100)); - + struct Light* light = (struct Light*)entity; + if(light->type > LT_POINT) + { + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "Invalid light type!", NK_TEXT_ALIGN_CENTERED); + } + else + { + static const char* light_types[] = {"Spot", "Directional", "Point"}; + float combo_width = nk_widget_width(context), combo_height = row_height * (LT_MAX); + nk_layout_row_dynamic(context, row_height, 2); - nk_label(context, "Density", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - struct nk_rect bounds = nk_widget_bounds(context); - nk_slider_float(context, 0.f, &render_settings.fog.density, 1.f, 0.005); - if(nk_input_is_mouse_hovering_rect(&context->input, bounds)) - { - if(nk_tooltip_begin(context, 100)) - { - nk_layout_row_dynamic(context, row_height, 1); - nk_labelf(context, NK_TEXT_ALIGN_CENTERED, "%.3f", render_settings.fog.density); - nk_tooltip_end(context); - } - } - + nk_label(context, "Light Type", NK_TEXT_ALIGN_LEFT); + nk_combobox(context, light_types, LT_MAX - 1, &light->type, row_height, nk_vec2(combo_width, combo_height)); + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Light Color", NK_TEXT_ALIGN_CENTERED); nk_layout_row_dynamic(context, row_height, 1); - nk_property_float(context, - "Start Distance", - 0.f, - &render_settings.fog.start_dist, - render_settings.fog.max_dist, - 5.f, 10.f); + editor_widget_color_combov3(context, &light->color, 200, 300); nk_layout_row_dynamic(context, row_height, 1); - nk_property_float(context, - "Max Distance", - render_settings.fog.start_dist, - &render_settings.fog.max_dist, - 10000.f, - 5.f, 10.f); - - nk_tree_pop(context); - } - renderer_settings_set(&render_settings); - } - else - { - editor_state.renderer_settings_window = 0; - } - nk_end(context); - } -} + nk_property_float(context, "Intensity", 0.f, &light->intensity, 100.f, 0.1f, 0.05f); -void editor_camera_update(float dt) -{ - struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; - float move_speed = editor_state.camera_move_speed, turn_speed = editor_state.camera_turn_speed; - vec3 offset = {0, 0, 0}; - float turn_up_down = 0.f; - float turn_left_right = 0.f; - float max_up_down = 60.f; - static float total_up_down_rot = 0.f; - vec3 rot_axis_up_down = {1, 0, 0}; - vec3 rot_axis_left_right = {0, 1, 0}; - - /* Look around */ - if(input_map_state_get("Turn_Up", KS_PRESSED)) turn_up_down += turn_speed; - if(input_map_state_get("Turn_Down", KS_PRESSED)) turn_up_down -= turn_speed; - if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed; - if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed; - - if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) - { - const float scale = 0.1f; - int cursor_lr, cursor_ud; - input_mouse_delta_get(&cursor_lr, &cursor_ud); - if(input_mouse_mode_get() != MM_RELATIVE) - { - input_mouse_mode_set(MM_RELATIVE); - cursor_lr = cursor_ud = 0; - } + if(light->type != LT_DIR) + { + nk_layout_row_dynamic(context, row_height, 1); + light->outer_angle = TO_RADIANS(nk_propertyf(context, "Outer Angle", TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 360, 1.f, 0.5f)); - turn_up_down = -cursor_ud * turn_speed * dt * scale; - turn_left_right = cursor_lr * turn_speed * dt * scale; - //log_message("ud : %d, lr : %d", cursor_ud, cursor_lr); - } - else - { - input_mouse_mode_set(MM_NORMAL); - turn_up_down *= dt; - turn_left_right *= dt; + nk_layout_row_dynamic(context, row_height, 1); + light->inner_angle = TO_RADIANS(nk_propertyf(context, "Inner Angle", 1.f, TO_DEGREES(light->inner_angle), TO_DEGREES(light->outer_angle), 1.f, 0.5f)); - //Picking - //If we're not looking around then allow picking - if(input_mousebutton_state_get(MSB_LEFT, KS_RELEASED)) - { - int mouse_x = 0, mouse_y = 0; - platform->mouse_position_get(&mouse_x, &mouse_y); - struct Ray ray = camera_screen_coord_to_ray(editor_camera, mouse_x, mouse_y); - //log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); + nk_layout_row_dynamic(context, row_height, 1); + nk_property_int(context, "Radius", 1, &light->radius, INT_MAX, 1, 1); - struct Scene* scene = game_state_get()->scene; - struct Raycast_Result ray_result; - scene_ray_intersect(scene, &ray, &ray_result); + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, "Falloff", 0.f, &light->falloff, 100.f, 0.1f, 0.05f); + } + } + nk_tree_pop(context); + } + } - if(ray_result.num_entities_intersected > 0) + /* Camera */ + if(entity->type == ET_CAMERA) + { + if(nk_tree_push(context, NK_TREE_TAB, "Camera", NK_MAXIMIZED)) { - //For now, just select the first entity that is intersected - struct Entity* intersected_entity = ray_result.entities_intersected[0]; + bool update = false; + struct Camera* camera = (struct Camera*)entity; + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Orthographic", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + bool ortho = nk_checkbox_label(context, "", &camera->ortho); + if(ortho != camera->ortho) + { + update = true; + } + - if(editor_state.selected_entity && editor_state.selected_entity != intersected_entity) + if(!camera->ortho) + { + nk_layout_row_dynamic(context, row_height, 1); + float new_fov = nk_propertyf(context, "Fov", 30.f, camera->fov, 90.f, 0.1f, 1.f); + if(new_fov != camera->fov) { - editor_state.selected_entity->editor_selected = false; - editor_state.selected_entity = NULL; + camera->fov = new_fov; + update = true; } - intersected_entity->editor_selected = true; - editor_state.selected_entity = intersected_entity; + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Aspect Ratio", NK_TEXT_ALIGN_LEFT); nk_labelf(context, NK_TEXT_ALIGN_RIGHT, "%.5f", camera->aspect_ratio); + } + + nk_layout_row_dynamic(context, row_height, 1); nk_label(context, "Clear Color", NK_TEXT_ALIGN_CENTERED); + nk_layout_row_dynamic(context, row_height, 1); + editor_widget_color_combov4(context, &camera->clear_color, 200, 300); + + nk_layout_row_dynamic(context, row_height, 1); + float new_zoom = nk_propertyf(context, "Zoom", 1.f, camera->zoom, FLT_MAX, 0.1f, 1.f); + if(new_zoom != camera->zoom) + { + camera->zoom = new_zoom; + update = true; + } + + nk_layout_row_dynamic(context, row_height, 1); + float new_near_z = nk_propertyf(context, "NearZ", -FLT_MAX, camera->nearz, camera->farz, 0.1f, 1.f); + if(new_near_z != camera->nearz) + { + camera->nearz = new_near_z; + update = true; + } + + nk_layout_row_dynamic(context, row_height, 1); + float new_far_z = nk_propertyf(context, "FarZ", camera->nearz, camera->farz, FLT_MAX, 0.1f, 2.f); + if(new_far_z != camera->farz) + { + camera->farz = new_far_z; + update = true; + } + + if(update) + { + camera_update_view(entity); + camera_update_proj(entity); + } + + nk_tree_pop(context); } + } + } + else + { + nk_label(context, "No Entity Selected", NK_TEXT_ALIGN_CENTERED); } + nk_tree_pop(context); + } + + nk_group_end(context); } - - total_up_down_rot += turn_up_down; - if(total_up_down_rot >= max_up_down) + } + nk_end(context); + context->style.window.padding = default_padding; + + /* Render Settings Window */ + if(editor_state.renderer_settings_window) + { + const int row_height = 25; + if(nk_begin_titled(context, "Renderer_Settings_Window", "Renderer Settings", nk_rect(half_width, half_height, 300, 350), window_flags)) { - total_up_down_rot = max_up_down; - turn_up_down = 0.f; + struct Render_Settings* render_settings = &game_state->renderer->settings; + if(nk_tree_push(context, NK_TREE_TAB, "Debug", NK_MAXIMIZED)) + { + static const char* draw_modes[] = {"Triangles", "Lines", "Points"}; + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Debug Draw", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + nk_checkbox_label(context, "", &render_settings->debug_draw_enabled); + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Debug Draw Mode", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + render_settings->debug_draw_mode = nk_combo(context, draw_modes, 3, render_settings->debug_draw_mode, 20, nk_vec2(180, 100)); + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Debug Color", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + editor_widget_color_combov4(context, &render_settings->debug_draw_color, 200, 400); + nk_tree_pop(context); + } + + if(nk_tree_push(context, NK_TREE_TAB, "Fog", NK_MAXIMIZED)) + { + static const char* fog_modes[] = {"None", "Linear", "Exponential", "Exponential Squared"}; + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Color", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + editor_widget_color_combov3(context, &render_settings->fog.color, 200, 400); + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Fog Mode", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + render_settings->fog.mode = nk_combo(context, + fog_modes, + 4, + render_settings->fog.mode, + 20, + nk_vec2(180, 100)); + + nk_layout_row_dynamic(context, row_height, 2); + nk_label(context, "Density", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + struct nk_rect bounds = nk_widget_bounds(context); + nk_slider_float(context, 0.f, &render_settings->fog.density, 1.f, 0.005); + if(nk_input_is_mouse_hovering_rect(&context->input, bounds)) + { + if(nk_tooltip_begin(context, 100)) + { + nk_layout_row_dynamic(context, row_height, 1); + nk_labelf(context, NK_TEXT_ALIGN_CENTERED, "%.3f", render_settings->fog.density); + nk_tooltip_end(context); + } + } + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, + "Start Distance", + 0.f, + &render_settings->fog.start_dist, + render_settings->fog.max_dist, + 5.f, 10.f); + + nk_layout_row_dynamic(context, row_height, 1); + nk_property_float(context, + "Max Distance", + render_settings->fog.start_dist, + &render_settings->fog.max_dist, + 10000.f, + 5.f, 10.f); + + nk_tree_pop(context); + } } - else if(total_up_down_rot <= -max_up_down) + else { - total_up_down_rot = -max_up_down; - turn_up_down = 0.f; + editor_state.renderer_settings_window = 0; } + nk_end(context); + } +} - if(turn_left_right != 0.f) +void editor_camera_update(float dt) +{ + struct Camera* editor_camera = &game_state_get()->scene->cameras[CAM_EDITOR]; + float move_speed = editor_state.camera_move_speed, turn_speed = editor_state.camera_turn_speed; + vec3 offset = {0, 0, 0}; + float turn_up_down = 0.f; + float turn_left_right = 0.f; + float max_up_down = 60.f; + static float total_up_down_rot = 0.f; + vec3 rot_axis_up_down = {1, 0, 0}; + vec3 rot_axis_left_right = {0, 1, 0}; + + /* Look around */ + if(input_map_state_get("Turn_Up", KS_PRESSED)) turn_up_down += turn_speed; + if(input_map_state_get("Turn_Down", KS_PRESSED)) turn_up_down -= turn_speed; + if(input_map_state_get("Turn_Right", KS_PRESSED)) turn_left_right += turn_speed; + if(input_map_state_get("Turn_Left", KS_PRESSED)) turn_left_right -= turn_speed; + + if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) + { + const float scale = 0.1f; + int cursor_lr, cursor_ud; + input_mouse_delta_get(&cursor_lr, &cursor_ud); + if(input_mouse_mode_get() != MM_RELATIVE) { - transform_rotate(editor_camera, &rot_axis_left_right, -turn_left_right, TS_WORLD); + input_mouse_mode_set(MM_RELATIVE); + cursor_lr = cursor_ud = 0; } - if(turn_up_down != 0.f) + turn_up_down = -cursor_ud * turn_speed * dt * scale; + turn_left_right = cursor_lr * turn_speed * dt * scale; + //log_message("ud : %d, lr : %d", cursor_ud, cursor_lr); + } + else + { + input_mouse_mode_set(MM_NORMAL); + turn_up_down *= dt; + turn_left_right *= dt; + + //Picking + //If we're not looking around then allow picking + if(input_mousebutton_state_get(MSB_LEFT, KS_RELEASED)) { - //transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL); - transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL); - } + log_message("editor picking"); + int mouse_x = 0, mouse_y = 0; + platform->mouse_position_get(&mouse_x, &mouse_y); + struct Ray ray = camera_screen_coord_to_ray(editor_camera, mouse_x, mouse_y); + //log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); + + struct Scene* scene = game_state_get()->scene; + struct Raycast_Result ray_result; + scene_ray_intersect(scene, &ray, &ray_result); + + if(ray_result.num_entities_intersected > 0) + { + //For now, just select the first entity that is intersected + struct Entity* intersected_entity = ray_result.entities_intersected[0]; + + if(editor_state.selected_entity && editor_state.selected_entity != intersected_entity) + { + editor_state.selected_entity->editor_selected = false; + editor_state.selected_entity = NULL; + } - /* Movement */ - if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= editor_state.camera_sprint_multiplier; - if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; - if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; - if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; - if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; - if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; - if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; - - vec3_scale(&offset, &offset, dt); - if(offset.x != 0 || offset.y != 0 || offset.z != 0) - { - transform_translate(editor_camera, &offset, TS_LOCAL); - //log_message("Position : %s", tostr_vec3(&transform->position)); + intersected_entity->editor_selected = true; + editor_state.selected_entity = intersected_entity; + } } + } + + total_up_down_rot += turn_up_down; + if(total_up_down_rot >= max_up_down) + { + total_up_down_rot = max_up_down; + turn_up_down = 0.f; + } + else if(total_up_down_rot <= -max_up_down) + { + total_up_down_rot = -max_up_down; + turn_up_down = 0.f; + } + + if(turn_left_right != 0.f) + { + transform_rotate(editor_camera, &rot_axis_left_right, -turn_left_right, TS_WORLD); + } + + if(turn_up_down != 0.f) + { + //transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL); + transform_rotate(editor_camera, &rot_axis_up_down, turn_up_down, TS_LOCAL); + } + + /* Movement */ + if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= editor_state.camera_sprint_multiplier; + if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; + if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; + if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; + if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; + if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; + if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; + + vec3_scale(&offset, &offset, dt); + if(offset.x != 0 || offset.y != 0 || offset.z != 0) + { + transform_translate(editor_camera, &offset, TS_LOCAL); + //log_message("Position : %s", tostr_vec3(&transform->position)); + } } void editor_widget_color_combov3(struct nk_context* context, vec3* color, int width, int height) { - struct nk_color temp_color = nk_rgba_f(color->x, color->y, color->z, 1.f); - if(nk_combo_begin_color(context, temp_color, nk_vec2(width, height))) + struct nk_color temp_color = nk_rgba_f(color->x, color->y, color->z, 1.f); + if(nk_combo_begin_color(context, temp_color, nk_vec2(width, height))) + { + enum color_mode {COL_RGB, COL_HSV}; + static int col_mode = COL_RGB; + nk_layout_row_dynamic(context, 25, 2); + col_mode = nk_option_label(context, "RGB", col_mode == COL_RGB) ? COL_RGB : col_mode; + col_mode = nk_option_label(context, "HSV", col_mode == COL_HSV) ? COL_HSV : col_mode; + nk_layout_row_dynamic(context, 120, 1); + temp_color = nk_color_picker(context, temp_color, NK_RGB); + nk_layout_row_dynamic(context, 25, 1); + if(col_mode == COL_RGB) { - enum color_mode {COL_RGB, COL_HSV}; - static int col_mode = COL_RGB; - nk_layout_row_dynamic(context, 25, 2); - col_mode = nk_option_label(context, "RGB", col_mode == COL_RGB) ? COL_RGB : col_mode; - col_mode = nk_option_label(context, "HSV", col_mode == COL_HSV) ? COL_HSV : col_mode; - nk_layout_row_dynamic(context, 120, 1); - temp_color = nk_color_picker(context, temp_color, NK_RGB); - nk_layout_row_dynamic(context, 25, 1); - if(col_mode == COL_RGB) - { - temp_color.r = (nk_byte)nk_propertyi(context, "#R:", 0, temp_color.r, 255, 1,1); - temp_color.g = (nk_byte)nk_propertyi(context, "#G:", 0, temp_color.g, 255, 1,1); - temp_color.b = (nk_byte)nk_propertyi(context, "#B:", 0, temp_color.b, 255, 1,1); - } - else - { - nk_byte tmp[4]; - nk_color_hsva_bv(tmp, temp_color); - tmp[0] = (nk_byte)nk_propertyi(context, "#H:", 0, tmp[0], 255, 1,1); - tmp[1] = (nk_byte)nk_propertyi(context, "#S:", 0, tmp[1], 255, 1,1); - tmp[2] = (nk_byte)nk_propertyi(context, "#V:", 0, tmp[2], 255, 1,1); - temp_color = nk_hsva_bv(tmp); - } - float empty = 1.f; - nk_color_f(&color->x, &color->y, &color->z, &empty, temp_color); - nk_combo_end(context); + temp_color.r = (nk_byte)nk_propertyi(context, "#R:", 0, temp_color.r, 255, 1,1); + temp_color.g = (nk_byte)nk_propertyi(context, "#G:", 0, temp_color.g, 255, 1,1); + temp_color.b = (nk_byte)nk_propertyi(context, "#B:", 0, temp_color.b, 255, 1,1); + } + else + { + nk_byte tmp[4]; + nk_color_hsva_bv(tmp, temp_color); + tmp[0] = (nk_byte)nk_propertyi(context, "#H:", 0, tmp[0], 255, 1,1); + tmp[1] = (nk_byte)nk_propertyi(context, "#S:", 0, tmp[1], 255, 1,1); + tmp[2] = (nk_byte)nk_propertyi(context, "#V:", 0, tmp[2], 255, 1,1); + temp_color = nk_hsva_bv(tmp); } + float empty = 1.f; + nk_color_f(&color->x, &color->y, &color->z, &empty, temp_color); + nk_combo_end(context); + } } void editor_widget_color_combov4(struct nk_context* context, vec4* color, int width, int height) { - struct nk_color temp_color = nk_rgba_f(color->x, color->y, color->z, color->w); - if(nk_combo_begin_color(context, temp_color, nk_vec2(width, height))) + struct nk_color temp_color = nk_rgba_f(color->x, color->y, color->z, color->w); + if(nk_combo_begin_color(context, temp_color, nk_vec2(width, height))) + { + enum color_mode {COL_RGB, COL_HSV}; + static int col_mode = COL_RGB; + nk_layout_row_dynamic(context, 25, 2); + col_mode = nk_option_label(context, "RGB", col_mode == COL_RGB) ? COL_RGB : col_mode; + col_mode = nk_option_label(context, "HSV", col_mode == COL_HSV) ? COL_HSV : col_mode; + nk_layout_row_dynamic(context, 120, 1); + temp_color = nk_color_picker(context, temp_color, NK_RGBA); + nk_layout_row_dynamic(context, 25, 1); + if(col_mode == COL_RGB) { - enum color_mode {COL_RGB, COL_HSV}; - static int col_mode = COL_RGB; - nk_layout_row_dynamic(context, 25, 2); - col_mode = nk_option_label(context, "RGB", col_mode == COL_RGB) ? COL_RGB : col_mode; - col_mode = nk_option_label(context, "HSV", col_mode == COL_HSV) ? COL_HSV : col_mode; - nk_layout_row_dynamic(context, 120, 1); - temp_color = nk_color_picker(context, temp_color, NK_RGBA); - nk_layout_row_dynamic(context, 25, 1); - if(col_mode == COL_RGB) - { - temp_color.r = (nk_byte)nk_propertyi(context, "#R:", 0, temp_color.r, 255, 1,1); - temp_color.g = (nk_byte)nk_propertyi(context, "#G:", 0, temp_color.g, 255, 1,1); - temp_color.b = (nk_byte)nk_propertyi(context, "#B:", 0, temp_color.b, 255, 1,1); - temp_color.a = (nk_byte)nk_propertyi(context, "#A:", 0, temp_color.a, 255, 1,1); - } - else - { - nk_byte tmp[4]; - nk_color_hsva_bv(tmp, temp_color); - tmp[0] = (nk_byte)nk_propertyi(context, "#H:", 0, tmp[0], 255, 1,1); - tmp[1] = (nk_byte)nk_propertyi(context, "#S:", 0, tmp[1], 255, 1,1); - tmp[2] = (nk_byte)nk_propertyi(context, "#V:", 0, tmp[2], 255, 1,1); - tmp[3] = (nk_byte)nk_propertyi(context, "#A:", 0, tmp[3], 255, 1,1); - temp_color = nk_hsva_bv(tmp); - } - nk_color_f(&color->x, &color->y, &color->z, &color->w, temp_color); - nk_combo_end(context); + temp_color.r = (nk_byte)nk_propertyi(context, "#R:", 0, temp_color.r, 255, 1,1); + temp_color.g = (nk_byte)nk_propertyi(context, "#G:", 0, temp_color.g, 255, 1,1); + temp_color.b = (nk_byte)nk_propertyi(context, "#B:", 0, temp_color.b, 255, 1,1); + temp_color.a = (nk_byte)nk_propertyi(context, "#A:", 0, temp_color.a, 255, 1,1); + } + else + { + nk_byte tmp[4]; + nk_color_hsva_bv(tmp, temp_color); + tmp[0] = (nk_byte)nk_propertyi(context, "#H:", 0, tmp[0], 255, 1,1); + tmp[1] = (nk_byte)nk_propertyi(context, "#S:", 0, tmp[1], 255, 1,1); + tmp[2] = (nk_byte)nk_propertyi(context, "#V:", 0, tmp[2], 255, 1,1); + tmp[3] = (nk_byte)nk_propertyi(context, "#A:", 0, tmp[3], 255, 1,1); + temp_color = nk_hsva_bv(tmp); } + nk_color_f(&color->x, &color->y, &color->z, &color->w, temp_color); + nk_combo_end(context); + } } void editor_cleanup(void) { - for(int i = 0; i < array_len(debug_vars_list); i++) - editor_debugvar_slot_remove(i); - array_free(debug_vars_list); - array_free(empty_indices); + for(int i = 0; i < array_len(debug_vars_list); i++) + editor_debugvar_slot_remove(i); + array_free(debug_vars_list); + array_free(empty_indices); } bool editor_widget_v3(struct nk_context* context, vec3* value, const char* name_x, const char* name_y, const char* name_z, float min, float max, float step, float inc_per_pixel, int row_height) { - bool changed = false; - vec3 val_copy = {0.f, 0.f, 0.f}; - vec3_assign(&val_copy, value); - nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_x, min, &value->x, max, step, inc_per_pixel); - nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_y, min, &value->y, max, step, inc_per_pixel); - nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_z, min, &value->z, max, step, inc_per_pixel); - if(!vec3_equals(&val_copy, value)) changed = true; - return changed; + bool changed = false; + vec3 val_copy = {0.f, 0.f, 0.f}; + vec3_assign(&val_copy, value); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_x, min, &value->x, max, step, inc_per_pixel); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_y, min, &value->y, max, step, inc_per_pixel); + nk_layout_row_dynamic(context, row_height, 1); nk_property_float(context, name_z, min, &value->z, max, step, inc_per_pixel); + if(!vec3_equals(&val_copy, value)) changed = true; + return changed; } void editor_show_entity_in_list(struct nk_context* context, struct Scene* scene, struct Entity* entity) { - if(!entity->active) return; + if(!entity->active) return; - nk_layout_row_dynamic(context, 20, 1); - if(nk_selectable_label(context, entity->name, NK_TEXT_ALIGN_LEFT, &entity->editor_selected)) + nk_layout_row_dynamic(context, 20, 1); + if(nk_selectable_label(context, entity->name, NK_TEXT_ALIGN_LEFT, &entity->editor_selected)) + { + if(editor_state.selected_entity && editor_state.selected_entity != entity) { - if(editor_state.selected_entity && editor_state.selected_entity != entity) - { - editor_state.selected_entity->editor_selected = false; - editor_state.selected_entity = NULL; - } - else if(editor_state.selected_entity && editor_state.selected_entity == entity && !entity->editor_selected) - { - editor_state.selected_entity = NULL; - } + editor_state.selected_entity->editor_selected = false; + editor_state.selected_entity = NULL; + } + else if(editor_state.selected_entity && editor_state.selected_entity == entity && !entity->editor_selected) + { + editor_state.selected_entity = NULL; + } - if(entity->editor_selected) - { - editor_state.selected_entity = entity; - } + if(entity->editor_selected) + { + editor_state.selected_entity = entity; } -} \ No newline at end of file + } +} diff --git a/src/libsymmetry/entity.h b/src/libsymmetry/entity.h index f023b18..88ab4fa 100644 --- a/src/libsymmetry/entity.h +++ b/src/libsymmetry/entity.h @@ -18,137 +18,137 @@ typedef void (*Collision_CB)(struct Entity* this_entity, struct Entity* other_en enum Entity_Type { - ET_NONE, - ET_DEFAULT, - ET_PLAYER, - ET_ROOT, - ET_CAMERA, - ET_LIGHT, - ET_STATIC_MESH, - ET_SOUND_SOURCE, - ET_MAX + ET_NONE, + ET_DEFAULT, + ET_PLAYER, + ET_ROOT, + ET_CAMERA, + ET_LIGHT, + ET_STATIC_MESH, + ET_SOUND_SOURCE, + ET_MAX }; enum LightType { - LT_SPOT = 0, - LT_DIR, - LT_POINT, - LT_INVALID, - LT_MAX + LT_SPOT = 0, + LT_DIR, + LT_POINT, + LT_INVALID, + LT_MAX }; enum Camera_Type { - CAM_EDITOR = 0, - CAM_GAME, - CAM_MAX + CAM_EDITOR = 0, + CAM_GAME, + CAM_MAX }; struct Transform { - vec3 position; - vec3 scale; - quat rotation; - mat4 trans_mat; - bool is_modified; - bool sync_physics; - struct Entity* parent; - struct Entity** children; + vec3 position; + vec3 scale; + quat rotation; + mat4 trans_mat; + bool is_modified; + bool sync_physics; + struct Entity* parent; + struct Entity** children; }; struct Entity { - int id; - int type; - char name[MAX_ENTITY_NAME_LEN]; - bool marked_for_deletion; - bool active; - bool editor_selected; - struct Transform transform; + int id; + int type; + char name[MAX_ENTITY_NAME_LEN]; + bool marked_for_deletion; + bool active; + bool editor_selected; + struct Transform transform; }; struct Model { - int geometry_index; - struct Material* material; - struct Variant material_params[MMP_MAX]; + int geometry_index; + struct Material* material; + struct Variant material_params[MMP_MAX]; }; struct Sound_Source { - struct Entity base; - int type; - bool playing; - bool loop; + struct Entity base; + int type; + bool playing; + bool loop; uint source_instance; - float min_distance; - float max_distance; - float rolloff_factor; - float volume; - int attenuation_type; - struct Sound_Source_Buffer* source_buffer; // Handle to the file from which the sound is loaded and played + float min_distance; + float max_distance; + float rolloff_factor; + float volume; + int attenuation_type; + struct Sound_Source_Buffer* source_buffer; // Handle to the file from which the sound is loaded and played }; struct Camera { - struct Entity base; - mat4 proj_mat; - mat4 view_mat; - mat4 view_proj_mat; - float fov; - float aspect_ratio; - float nearz; - float farz; - float zoom; - bool ortho; - int fbo; - int render_tex; - int depth_tex; - vec4 clear_color; - vec4 frustum[6]; - bool resizeable; + struct Entity base; + mat4 proj_mat; + mat4 view_mat; + mat4 view_proj_mat; + float fov; + float aspect_ratio; + float nearz; + float farz; + float zoom; + bool ortho; + int fbo; + int render_tex; + int depth_tex; + vec4 clear_color; + vec4 frustum[6]; + bool resizeable; }; struct Light { - struct Entity base; - float outer_angle; - float inner_angle; - float falloff; - float intensity; - vec3 color; - bool cast_shadow; - bool pcf_enabled; - bool valid; - int type; - int radius; - int shadow_map[4]; - float depth_bias; + struct Entity base; + float outer_angle; + float inner_angle; + float falloff; + float intensity; + vec3 color; + bool cast_shadow; + bool pcf_enabled; + bool valid; + int type; + int radius; + int shadow_map[4]; + float depth_bias; }; struct Collision { - Rigidbody rigidbody; - Collision_Shape collision_shape; - Collision_CB on_collision; + Rigidbody rigidbody; + Collision_Shape collision_shape; + Collision_CB on_collision; }; struct Static_Mesh { - struct Entity base; - struct Model model; - struct Collision collision; + struct Entity base; + struct Model model; + struct Collision collision; }; struct Player { - struct Entity base; - struct Static_Mesh* mesh; - struct Camera* camera_node; - float move_speed; - float move_speed_multiplier; - float turn_speed; + struct Entity base; + struct Static_Mesh* mesh; + struct Camera* camera_node; + float move_speed; + float move_speed_multiplier; + float turn_speed; }; void entity_init(struct Entity* entity, const char* name, struct Entity* parent); diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index 92b72ef..c5904f1 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -67,503 +67,503 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) platform = malloc(sizeof(*platform)); memcpy(platform, platform_api, sizeof(*platform_api)); - game_state = malloc(sizeof(*game_state)); - if(!game_state) + game_state = malloc(sizeof(*game_state)); + if(!game_state) + { + log_error("game:init", "Out of memory, failed to allocate game_state"); + return 0; + } + else + { + game_state->window = window; + game_state->is_initialized = false; + game_state->game_mode = GAME_MODE_GAME; + game_state->renderer = calloc(1, sizeof(*game_state->renderer)); + game_state->scene = calloc(1, sizeof(*game_state->scene)); + game_state->console = calloc(1, sizeof(*game_state->console)); + + log_file_handle_set(platform->log.file_handle_get()); + log_message_callback_set(game_on_log_message); + log_warning_callback_set(game_on_log_warning); + log_error_callback_set(game_on_log_error); + + if(!gl_load_extentions()) { - log_error("game:init", "Out of memory, failed to allocate game_state"); - return 0; + log_error("game:init", "Failed to load GL extentions"); + return false; } else { - game_state->window = window; - game_state->is_initialized = false; - game_state->game_mode = GAME_MODE_GAME; - game_state->renderer = calloc(1, sizeof(*game_state->renderer)); - game_state->scene = calloc(1, sizeof(*game_state->scene)); - game_state->console = calloc(1, sizeof(*game_state->console)); - - log_file_handle_set(platform->log.file_handle_get()); - log_message_callback_set(game_on_log_message); - log_warning_callback_set(game_on_log_warning); - log_error_callback_set(game_on_log_error); - - if(!gl_load_extentions()) - { - log_error("game:init", "Failed to load GL extentions"); - return false; - } - else - { - log_message("Loaded GL extentions"); - } - - - input_init(); - shader_init(); - texture_init(); - framebuffer_init(); - gui_init(); - console_init(game_state->console); - geom_init(); - platform->physics.init(); - platform->physics.gravity_set(0.f, -9.8f, 0.f); - platform->physics.body_set_moved_callback(entity_rigidbody_on_move); - platform->physics.body_set_collision_callback(entity_rigidbody_on_collision); - - editor_init(); - renderer_init(game_state->renderer); - scene_init(game_state->scene); + log_message("Loaded GL extentions"); } + + + input_init(); + shader_init(); + texture_init(); + framebuffer_init(); + gui_init(); + console_init(game_state->console); + geom_init(); + platform->physics.init(); + platform->physics.gravity_set(0.f, -9.8f, 0.f); + platform->physics.body_set_moved_callback(entity_rigidbody_on_move); + platform->physics.body_set_collision_callback(entity_rigidbody_on_collision); + + editor_init(); + renderer_init(game_state->renderer); + scene_init(game_state->scene); + } - /* Debug scene setup */ - game_scene_setup(); - game_state->is_initialized = true; - return game_run(); + /* Debug scene setup */ + game_scene_setup(); + game_state->is_initialized = true; + return game_run(); } void game_scene_setup(void) { - // struct Entity* player = scene_add_new("player", ET_CAMERA); - // game_state->player_node = player->id; - // vec3 viewer_pos = {10, 5, 100}; - // transform_set_position(player, &viewer_pos); - // int render_width, render_height; - //struct Hashmap* config = platform->config.get(); - //render_width = hashmap_int_get(config, "render_width"); - //render_height = hashmap_int_get(config, "render_height"); - // camera_create(player, render_width, render_height); - // camera_attach_fbo(player, render_width, render_height, 1, 1, 1); - // vec4_fill(&player->camera.clear_color, 0.3f, 0.6f, 0.9f, 1.0f); - - // vec4 color = {1.f, 1.f, 1.f, 1.f }; - // struct Entity* new_ent = scene_add_new("Model_Entity", ET_STATIC_MESH); - // vec3 position = {0, 0, -5}; - // transform_translate(new_ent, &position, TS_WORLD); - // new_ent->renderable = true; - // model_create(new_ent, "default.pamesh", "Blinn_Phong"); - // model_set_material_param(new_ent, "diffuse_color", &color); - // int tex = texture_create_from_file("white.tga", TU_DIFFUSE); - // model_set_material_param(new_ent, "diffuse_texture", &tex); - // vec3 scale = {1, 1, 1}; - // transform_scale(new_ent, &scale); - - // /* struct Entity* sound_ent = scene_add_as_child("Sound_ENT", ET_SOUND_SOURCE, new_ent->id); */ - // /* struct Sound_Source* sound_source = &sound_ent->sound_source; */ - // /* platform->sound.source_create(true, 1, &sound_source->source_handle, &sound_source->buffer_handles[0]); */ - // /* platform->sound.source_load_wav(sound_source->source_handle, */ - // /* sound_source->buffer_handles[0], */ - // /* "BigExplosion.wav"); */ - // /* //sound_source_relative_set(source, true); */ - // /* platform->sound.source_volume_set(sound_source->source_handle, 1.f); */ - // /* platform->sound.source_loop_set(sound_source->source_handle, true); */ - // /* platform->sound.source_play(sound_source->source_handle); */ - - // int parent_node = new_ent->id; - // int num_suz = 50; - // srand(time(NULL)); - // for(int i = 0; i < num_suz; i++) - // { - // int x = rand() % num_suz; - // int y = rand() % num_suz; - // int z = rand() % num_suz; - // x++; y++; z++; - // struct Entity* suz = scene_add_as_child("Suzanne", ET_STATIC_MESH, parent_node); - // //struct Entity* suz = scene_add_new("Suzanne", ET_STATIC_MESH); - // suz->renderable = true; - // model_create(suz, "default.pamesh", "Blinn_Phong"); - // model_set_material_param(suz, "diffuse_color", &color); - // float spec_str = 80.f; - // model_set_material_param(suz, "specular_strength", &spec_str); - // vec3 s_pos = {x, 0, z}; - // transform_translate(suz, &s_pos, TS_WORLD); - // } - - - // struct Entity* ground = scene_add_new("Ground", ET_STATIC_MESH); - // ground->renderable = true; - // model_create(ground, "default.pamesh", "Blinn_Phong"); - // model_set_material_param(ground, "diffuse_color", &color); - // int white_tex = texture_create_from_file("white.tga", TU_DIFFUSE); - // model_set_material_param(ground, "diffuse_texture", &white_tex); - // float spec_str = 80.f; - // model_set_material_param(ground, "specular_strength", &spec_str); - // vec3 pos = {0, -5, 0}; - // vec3 scale_ground = {400.f, 2.f, 400.f}; - // transform_set_position(ground, &pos); - // transform_scale(ground, &scale_ground); - - // /* struct Entity* screen = scene_add_new("Screen", NULL); */ - // /* struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); */ - // /* screen_model->geometry_index = geom_find("Quad"); */ - // /* struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); */ - // /* struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM); */ - // /* transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); */ - // /* struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); */ - // /* cam->nearz = 0.1f; */ - // /* cam->farz = 50.f; */ - // /* camera_update_proj(cam); */ - // /* camera_attach_fbo(cam, 128, 128, 1, 1, 0); */ - // /* model_set_material_param(screen_model, "diffuse_color", &color); */ - // /* model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); */ - - // const int MAX_LIGHTS = 10; - // for(int i = 0; i < MAX_LIGHTS; i++) - // { - // int x = rand() % MAX_LIGHTS; - // int z = rand() % MAX_LIGHTS; - // x++; z++; - // struct Entity* light_ent = scene_add_new("Light_Ent", ET_LIGHT); - // vec3 lt_pos = {x * 20, 0, z * 20}; - // transform_set_position(light_ent, <_pos); - // light_create(light_ent, LT_POINT); - // vec3_fill(&light_ent->light.color, 1.f / (float)x, 1.f / ((rand() % 10) + 1.f), 1.f / (float)z); - // light_ent->light.intensity = 1.f; - // } - - /////* log_message("Sizeof Entity : %d", sizeof(struct Entity)); */ - - /////* struct Entity* light_ent = entity_find("Ground"); */ - /////* entity_save(light_ent, "ground.ent", DT_INSTALL); */ - - // struct Entity* suz = entity_find("Suzanne"); - // struct Entity* sound_ent = scene_add_as_child("Sound_Ent", ET_SOUND_SOURCE, suz->id); - // struct Sound_Source* sound_source = &sound_ent->sound_source; - //sound_source->source_filename = str_new("sounds/teh_beatz.wav"); - // sound_source->type = ST_WAV; - // sound_source->attenuation_type = SA_INVERSE; - // sound_source->rolloff_factor = 0.95f; - // sound_source->loop = true; - // sound_source->volume = 0.5f; - // sound_source->min_distance = 1.f; - // sound_source->max_distance = 10.f; - // sound_source->playing = true; - - // sound_source->source_instance = 0; - // sound_source->source = NULL; - - // entity_apply_sound_params(sound_ent); - - // scene_save("test_scene.symtres", DIRT_INSTALL); - - // if(scene_load("test_scene.symtres", DIRT_INSTALL)) - // { - // log_message("Scene loaded!"); - // struct Entity* player = entity_find("player"); - // game_state->player_node = player->id; - - //struct Entity* suz = entity_find("Model_Entity"); - //suz_id = suz->id; - // /*struct Camera* camera = &player->camera; - // camera->ortho = true; - // camera->farz = 500.f; - // camera->nearz = -500.f; - // camera_update_proj(player);*/ - // } - - //platform->physics.cs_plane_create(0, 1, 0, 0); - ////Rigidbody box = platform->physics.body_box_create(2.5, 2.5, 2.5); - //Rigidbody box = platform->physics.body_sphere_create(3.5); - ///*platform->physics.body_position_set(box, 0.f, 50.f, 0.f); - //platform->physics.body_mass_set(box, 10.f);*/ - ///*platform->physics.body_data_set(box, (void*)suz_id);*/ - ////platform->physics.body_force_add(box, -100.f, 0.f, 0.f); - //struct Entity* suz = entity_find("Model_Entity"); - //entity_rigidbody_set(suz, box); - //suz->collision.on_collision = &on_collision_test; - - //Rigidbody sphere = platform->physics.body_sphere_create(3.5f); - //struct Entity* sphere_ent = entity_find("Sphere_Ent"); - //entity_rigidbody_set(sphere_ent, sphere); - - ////Collision_Shape plane = platform->physics.cs_plane_create(0, 1, 0, 0); - //Rigidbody ground_box = platform->physics.body_box_create(10, 5, 10); - //platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f); - ///*platform->physics.body_kinematic_set(ground_box);*/ - //struct Entity* ground = entity_find("Ground"); - ////entity_collision_shape_set(ground, plane); - //entity_rigidbody_set(ground, ground_box); - - struct Static_Mesh* ground = scene_static_mesh_create(game_state->scene, "Ground_Mesh", NULL, "default.pamesh", MAT_BLINN); - vec3 scale = {200.f, 1.f, 200.f}; - transform_scale(ground, &scale); - ground->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE); - ground->model.material_params[MMP_DIFFUSE].val_float = 0.5f; - ground->model.material_params[MMP_SPECULAR].val_float = 1.f; - ground->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; - vec3_fill(&ground->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 1.f, 1.f); + // struct Entity* player = scene_add_new("player", ET_CAMERA); + // game_state->player_node = player->id; + // vec3 viewer_pos = {10, 5, 100}; + // transform_set_position(player, &viewer_pos); + // int render_width, render_height; + //struct Hashmap* config = platform->config.get(); + //render_width = hashmap_int_get(config, "render_width"); + //render_height = hashmap_int_get(config, "render_height"); + // camera_create(player, render_width, render_height); + // camera_attach_fbo(player, render_width, render_height, 1, 1, 1); + // vec4_fill(&player->camera.clear_color, 0.3f, 0.6f, 0.9f, 1.0f); + + // vec4 color = {1.f, 1.f, 1.f, 1.f }; + // struct Entity* new_ent = scene_add_new("Model_Entity", ET_STATIC_MESH); + // vec3 position = {0, 0, -5}; + // transform_translate(new_ent, &position, TS_WORLD); + // new_ent->renderable = true; + // model_create(new_ent, "default.pamesh", "Blinn_Phong"); + // model_set_material_param(new_ent, "diffuse_color", &color); + // int tex = texture_create_from_file("white.tga", TU_DIFFUSE); + // model_set_material_param(new_ent, "diffuse_texture", &tex); + // vec3 scale = {1, 1, 1}; + // transform_scale(new_ent, &scale); + + // /* struct Entity* sound_ent = scene_add_as_child("Sound_ENT", ET_SOUND_SOURCE, new_ent->id); */ + // /* struct Sound_Source* sound_source = &sound_ent->sound_source; */ + // /* platform->sound.source_create(true, 1, &sound_source->source_handle, &sound_source->buffer_handles[0]); */ + // /* platform->sound.source_load_wav(sound_source->source_handle, */ + // /* sound_source->buffer_handles[0], */ + // /* "BigExplosion.wav"); */ + // /* //sound_source_relative_set(source, true); */ + // /* platform->sound.source_volume_set(sound_source->source_handle, 1.f); */ + // /* platform->sound.source_loop_set(sound_source->source_handle, true); */ + // /* platform->sound.source_play(sound_source->source_handle); */ + + // int parent_node = new_ent->id; + // int num_suz = 50; + // srand(time(NULL)); + // for(int i = 0; i < num_suz; i++) + // { + // int x = rand() % num_suz; + // int y = rand() % num_suz; + // int z = rand() % num_suz; + // x++; y++; z++; + // struct Entity* suz = scene_add_as_child("Suzanne", ET_STATIC_MESH, parent_node); + // //struct Entity* suz = scene_add_new("Suzanne", ET_STATIC_MESH); + // suz->renderable = true; + // model_create(suz, "default.pamesh", "Blinn_Phong"); + // model_set_material_param(suz, "diffuse_color", &color); + // float spec_str = 80.f; + // model_set_material_param(suz, "specular_strength", &spec_str); + // vec3 s_pos = {x, 0, z}; + // transform_translate(suz, &s_pos, TS_WORLD); + // } + + + // struct Entity* ground = scene_add_new("Ground", ET_STATIC_MESH); + // ground->renderable = true; + // model_create(ground, "default.pamesh", "Blinn_Phong"); + // model_set_material_param(ground, "diffuse_color", &color); + // int white_tex = texture_create_from_file("white.tga", TU_DIFFUSE); + // model_set_material_param(ground, "diffuse_texture", &white_tex); + // float spec_str = 80.f; + // model_set_material_param(ground, "specular_strength", &spec_str); + // vec3 pos = {0, -5, 0}; + // vec3 scale_ground = {400.f, 2.f, 400.f}; + // transform_set_position(ground, &pos); + // transform_scale(ground, &scale_ground); + + // /* struct Entity* screen = scene_add_new("Screen", NULL); */ + // /* struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); */ + // /* screen_model->geometry_index = geom_find("Quad"); */ + // /* struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); */ + // /* struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM); */ + // /* transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); */ + // /* struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); */ + // /* cam->nearz = 0.1f; */ + // /* cam->farz = 50.f; */ + // /* camera_update_proj(cam); */ + // /* camera_attach_fbo(cam, 128, 128, 1, 1, 0); */ + // /* model_set_material_param(screen_model, "diffuse_color", &color); */ + // /* model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); */ + + // const int MAX_LIGHTS = 10; + // for(int i = 0; i < MAX_LIGHTS; i++) + // { + // int x = rand() % MAX_LIGHTS; + // int z = rand() % MAX_LIGHTS; + // x++; z++; + // struct Entity* light_ent = scene_add_new("Light_Ent", ET_LIGHT); + // vec3 lt_pos = {x * 20, 0, z * 20}; + // transform_set_position(light_ent, <_pos); + // light_create(light_ent, LT_POINT); + // vec3_fill(&light_ent->light.color, 1.f / (float)x, 1.f / ((rand() % 10) + 1.f), 1.f / (float)z); + // light_ent->light.intensity = 1.f; + // } + + /////* log_message("Sizeof Entity : %d", sizeof(struct Entity)); */ + + /////* struct Entity* light_ent = entity_find("Ground"); */ + /////* entity_save(light_ent, "ground.ent", DT_INSTALL); */ + + // struct Entity* suz = entity_find("Suzanne"); + // struct Entity* sound_ent = scene_add_as_child("Sound_Ent", ET_SOUND_SOURCE, suz->id); + // struct Sound_Source* sound_source = &sound_ent->sound_source; + //sound_source->source_filename = str_new("sounds/teh_beatz.wav"); + // sound_source->type = ST_WAV; + // sound_source->attenuation_type = SA_INVERSE; + // sound_source->rolloff_factor = 0.95f; + // sound_source->loop = true; + // sound_source->volume = 0.5f; + // sound_source->min_distance = 1.f; + // sound_source->max_distance = 10.f; + // sound_source->playing = true; + + // sound_source->source_instance = 0; + // sound_source->source = NULL; + + // entity_apply_sound_params(sound_ent); + + // scene_save("test_scene.symtres", DIRT_INSTALL); + + // if(scene_load("test_scene.symtres", DIRT_INSTALL)) + // { + // log_message("Scene loaded!"); + // struct Entity* player = entity_find("player"); + // game_state->player_node = player->id; + + //struct Entity* suz = entity_find("Model_Entity"); + //suz_id = suz->id; + // /*struct Camera* camera = &player->camera; + // camera->ortho = true; + // camera->farz = 500.f; + // camera->nearz = -500.f; + // camera_update_proj(player);*/ + // } + + //platform->physics.cs_plane_create(0, 1, 0, 0); + ////Rigidbody box = platform->physics.body_box_create(2.5, 2.5, 2.5); + //Rigidbody box = platform->physics.body_sphere_create(3.5); + ///*platform->physics.body_position_set(box, 0.f, 50.f, 0.f); + //platform->physics.body_mass_set(box, 10.f);*/ + ///*platform->physics.body_data_set(box, (void*)suz_id);*/ + ////platform->physics.body_force_add(box, -100.f, 0.f, 0.f); + //struct Entity* suz = entity_find("Model_Entity"); + //entity_rigidbody_set(suz, box); + //suz->collision.on_collision = &on_collision_test; + + //Rigidbody sphere = platform->physics.body_sphere_create(3.5f); + //struct Entity* sphere_ent = entity_find("Sphere_Ent"); + //entity_rigidbody_set(sphere_ent, sphere); + + ////Collision_Shape plane = platform->physics.cs_plane_create(0, 1, 0, 0); + //Rigidbody ground_box = platform->physics.body_box_create(10, 5, 10); + //platform->physics.body_position_set(ground_box, 0.f, 0.f, 0.f); + ///*platform->physics.body_kinematic_set(ground_box);*/ + //struct Entity* ground = entity_find("Ground"); + ////entity_collision_shape_set(ground, plane); + //entity_rigidbody_set(ground, ground_box); + + struct Static_Mesh* ground = scene_static_mesh_create(game_state->scene, "Ground_Mesh", NULL, "default.pamesh", MAT_BLINN); + vec3 scale = {200.f, 1.f, 200.f}; + transform_scale(ground, &scale); + ground->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE); + ground->model.material_params[MMP_DIFFUSE].val_float = 0.5f; + ground->model.material_params[MMP_SPECULAR].val_float = 1.f; + ground->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; + vec3_fill(&ground->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 1.f, 1.f); - int num_suz = 50; - char suz_name[MAX_ENTITY_NAME_LEN]; - vec3 suz_pos = {0.f}; - for(int i = 0; i < num_suz; i++) - { - memset(&suz_name, '\0', MAX_ENTITY_NAME_LEN); - snprintf(&suz_name, MAX_ENTITY_NAME_LEN, "Suzanne_%d", i); - struct Static_Mesh* suzanne = scene_static_mesh_create(game_state->scene, suz_name, NULL, "sphere.symbres", MAT_BLINN); - suzanne->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE); - suzanne->model.material_params[MMP_DIFFUSE].val_float = 0.5f; - suzanne->model.material_params[MMP_SPECULAR].val_float = 1.f; - suzanne->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; - vec3_fill(&suzanne->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 0.f, 1.f); - suz_pos.x = i + 10.f; - suz_pos.y = 5.f; - suz_pos.z = i + 5.f; - transform_set_position(suzanne, &suz_pos); + int num_suz = 50; + char suz_name[MAX_ENTITY_NAME_LEN]; + vec3 suz_pos = {0.f}; + for(int i = 0; i < num_suz; i++) + { + memset(&suz_name, '\0', MAX_ENTITY_NAME_LEN); + snprintf(&suz_name[0], MAX_ENTITY_NAME_LEN, "Suzanne_%d", i); + struct Static_Mesh* suzanne = scene_static_mesh_create(game_state->scene, suz_name, NULL, "sphere.symbres", MAT_BLINN); + suzanne->model.material_params[MMP_DIFFUSE_TEX].val_int = texture_create_from_file("white.tga", TU_DIFFUSE); + suzanne->model.material_params[MMP_DIFFUSE].val_float = 0.5f; + suzanne->model.material_params[MMP_SPECULAR].val_float = 1.f; + suzanne->model.material_params[MMP_SPECULAR_STRENGTH].val_float = 1.f; + vec3_fill(&suzanne->model.material_params[MMP_DIFFUSE_COL].val_vec3, 1.f, 0.f, 1.f); + suz_pos.x = i + 10.f; + suz_pos.y = 5.f; + suz_pos.z = i + 5.f; + transform_set_position(suzanne, &suz_pos); - } + } - struct Light* light = scene_light_create(game_state->scene, "Test_Light", NULL, LT_POINT); - light->color.x = 1.f; - light->color.y = 1.f; - light->color.z = 1.f; - light->radius = 20.f; - vec3 light_pos = {0.f, 5.f, 0.f}; - transform_translate(light, &light_pos, TS_WORLD); + struct Light* light = scene_light_create(game_state->scene, "Test_Light", NULL, LT_POINT); + light->color.x = 1.f; + light->color.y = 1.f; + light->color.z = 1.f; + light->radius = 20; + vec3 light_pos = {0.f, 5.f, 0.f}; + transform_translate(light, &light_pos, TS_WORLD); } void game_debug(float dt) { - if(input_is_key_pressed(KEY_SPACE)) - { - struct Entity* model = scene_find(game_state->scene, "Light_Ent"); - vec3 x_axis = {0, 1, 0}; - transform_rotate(model, &x_axis, 25.f * dt, TS_WORLD); - } + if(input_is_key_pressed(KEY_SPACE)) + { + struct Entity* model = scene_find(game_state->scene, "Light_Ent"); + vec3 x_axis = {0, 1, 0}; + transform_rotate(model, &x_axis, 25.f * dt, TS_WORLD); + } - if(input_is_key_pressed(KEY_M)) - { - struct Entity* model = scene_find(game_state->scene, "Model_Entity"); - //vec3 y_axis = {0, 0, 1}; - //transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_LOCAL); - vec3 amount = {0, 0, -5 * dt}; - transform_translate(model, &amount, TS_LOCAL); - } + if(input_is_key_pressed(KEY_M)) + { + struct Entity* model = scene_find(game_state->scene, "Model_Entity"); + //vec3 y_axis = {0, 0, 1}; + //transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_LOCAL); + vec3 amount = {0, 0, -5 * dt}; + transform_translate(model, &amount, TS_LOCAL); + } - if(input_is_key_pressed(KEY_N)) - { - struct Entity* model = scene_find(game_state->scene, "Model_Entity"); - /* vec3 y_axis = {0, 0, 1}; */ - /* transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_WORLD); */ - vec3 amount = {0, 0, 5 * dt}; - transform_translate(model, &amount, TS_LOCAL); - } + if(input_is_key_pressed(KEY_N)) + { + struct Entity* model = scene_find(game_state->scene, "Model_Entity"); + /* vec3 y_axis = {0, 0, 1}; */ + /* transform_rotate(mod_tran, &y_axis, 25.f * dt, TS_WORLD); */ + vec3 amount = {0, 0, 5 * dt}; + transform_translate(model, &amount, TS_LOCAL); + } - /*struct Entity* model = scene_find("Model_Entity"); - vec3 x_axis = {0, 1, 0}; - transform_rotate(model, &x_axis, 50.f * dt, TS_WORLD); - vec3 amount = {0, 0, -5 * dt}; - transform_translate(model, &amount, TS_LOCAL);*/ + /*struct Entity* model = scene_find("Model_Entity"); + vec3 x_axis = {0, 1, 0}; + transform_rotate(model, &x_axis, 50.f * dt, TS_WORLD); + vec3 amount = {0, 0, -5 * dt}; + transform_translate(model, &amount, TS_LOCAL);*/ - struct Sprite_Batch* batch = game_state->renderer->sprite_batch; + struct Sprite_Batch* batch = game_state->renderer->sprite_batch; - sprite_batch_begin(batch); - static struct Sprite sprite; + sprite_batch_begin(batch); + static struct Sprite sprite; - sprite.vertices[0].position.x = 0.f; sprite.vertices[0].position.y = 0.f; - sprite.vertices[1].position.x = 50.f; sprite.vertices[1].position.y = 0.f; - sprite.vertices[2].position.x = 0.f; sprite.vertices[2].position.y = 50.f; - sprite.vertices[3].position.x = 0.f; sprite.vertices[3].position.y = 50.f; - sprite.vertices[4].position.x = 50.f; sprite.vertices[4].position.y = 50.f; - sprite.vertices[5].position.x = 50.f; sprite.vertices[5].position.y = 0.f; + sprite.vertices[0].position.x = 0.f; sprite.vertices[0].position.y = 0.f; + sprite.vertices[1].position.x = 50.f; sprite.vertices[1].position.y = 0.f; + sprite.vertices[2].position.x = 0.f; sprite.vertices[2].position.y = 50.f; + sprite.vertices[3].position.x = 0.f; sprite.vertices[3].position.y = 50.f; + sprite.vertices[4].position.x = 50.f; sprite.vertices[4].position.y = 50.f; + sprite.vertices[5].position.x = 50.f; sprite.vertices[5].position.y = 0.f; - sprite.vertices[0].uv.x = 0.f; sprite.vertices[0].uv.y = 0.f; - sprite.vertices[1].uv.x = 1.f; sprite.vertices[1].uv.y = 0.f; - sprite.vertices[2].uv.x = 0.f; sprite.vertices[2].uv.y = 1.f; - sprite.vertices[3].uv.x = 0.f; sprite.vertices[3].uv.y = 1.f; - sprite.vertices[4].uv.x = 1.f; sprite.vertices[4].uv.y = 1.f; - sprite.vertices[5].uv.x = 1.f; sprite.vertices[5].uv.y = 0.f; + sprite.vertices[0].uv.x = 0.f; sprite.vertices[0].uv.y = 0.f; + sprite.vertices[1].uv.x = 1.f; sprite.vertices[1].uv.y = 0.f; + sprite.vertices[2].uv.x = 0.f; sprite.vertices[2].uv.y = 1.f; + sprite.vertices[3].uv.x = 0.f; sprite.vertices[3].uv.y = 1.f; + sprite.vertices[4].uv.x = 1.f; sprite.vertices[4].uv.y = 1.f; + sprite.vertices[5].uv.x = 1.f; sprite.vertices[5].uv.y = 0.f; - sprite.vertices[0].color.x = 0.f; sprite.vertices[0].color.y = 0.f; sprite.vertices[0].color.z = 0.f; sprite.vertices[0].color.w = 1.f; - sprite.vertices[1].color.x = 1.f; sprite.vertices[1].color.y = 0.f; sprite.vertices[1].color.z = 0.f; sprite.vertices[1].color.w = 1.f; - sprite.vertices[2].color.x = 0.f; sprite.vertices[2].color.y = 1.f; sprite.vertices[2].color.z = 0.f; sprite.vertices[2].color.w = 1.f; - sprite.vertices[3].color.x = 1.f; sprite.vertices[3].color.y = 1.f; sprite.vertices[3].color.z = 0.f; sprite.vertices[3].color.w = 1.f; - sprite.vertices[4].color.x = 1.f; sprite.vertices[4].color.y = 1.f; sprite.vertices[4].color.z = 0.f; sprite.vertices[4].color.w = 1.f; - sprite.vertices[5].color.x = 1.f; sprite.vertices[5].color.y = 1.f; sprite.vertices[5].color.z = 0.f; sprite.vertices[5].color.w = 1.f; + sprite.vertices[0].color.x = 0.f; sprite.vertices[0].color.y = 0.f; sprite.vertices[0].color.z = 0.f; sprite.vertices[0].color.w = 1.f; + sprite.vertices[1].color.x = 1.f; sprite.vertices[1].color.y = 0.f; sprite.vertices[1].color.z = 0.f; sprite.vertices[1].color.w = 1.f; + sprite.vertices[2].color.x = 0.f; sprite.vertices[2].color.y = 1.f; sprite.vertices[2].color.z = 0.f; sprite.vertices[2].color.w = 1.f; + sprite.vertices[3].color.x = 1.f; sprite.vertices[3].color.y = 1.f; sprite.vertices[3].color.z = 0.f; sprite.vertices[3].color.w = 1.f; + sprite.vertices[4].color.x = 1.f; sprite.vertices[4].color.y = 1.f; sprite.vertices[4].color.z = 0.f; sprite.vertices[4].color.w = 1.f; + sprite.vertices[5].color.x = 1.f; sprite.vertices[5].color.y = 1.f; sprite.vertices[5].color.z = 0.f; sprite.vertices[5].color.w = 1.f; - sprite_batch_add_sprite(batch, &sprite); + sprite_batch_add_sprite(batch, &sprite); - sprite_batch_end(batch); + sprite_batch_end(batch); - //Raycast test - if(input_is_key_pressed(KEY_R)) - { - /*Collision_Shape ray = platform->physics.cs_ray_create(20.f, true, true); - vec3 position = {0.f, 0.f, 0.f}; - vec3 direction = {0.f, 0.f, 0.f}; - transform_get_absolute_forward(player_entity, &direction); - transform_get_absolute_position(player_entity, &position); - struct Raycast_Hit hit; - if(platform->physics.cs_ray_cast(ray, &hit, position.x, position.y, position.z, direction.x, direction.y, direction.z)) - { - struct Entity* entity_hit = entity_get(hit.entity_id); - log_message("Ray hit %s", entity_hit->name); - } - else - { - log_message("Ray didn't hit anything!"); - } - platform->physics.cs_remove(ray);*/ - } + //Raycast test + if(input_is_key_pressed(KEY_R)) + { + /*Collision_Shape ray = platform->physics.cs_ray_create(20.f, true, true); + vec3 position = {0.f, 0.f, 0.f}; + vec3 direction = {0.f, 0.f, 0.f}; + transform_get_absolute_forward(player_entity, &direction); + transform_get_absolute_position(player_entity, &position); + struct Raycast_Hit hit; + if(platform->physics.cs_ray_cast(ray, &hit, position.x, position.y, position.z, direction.x, direction.y, direction.z)) + { + struct Entity* entity_hit = entity_get(hit.entity_id); + log_message("Ray hit %s", entity_hit->name); + } + else + { + log_message("Ray didn't hit anything!"); + } + platform->physics.cs_remove(ray);*/ + } - // Immediate geometry test - vec3 im_position = { 0.f, 20.f, 0.f }; - vec3 im_scale = { 1.f, 1.f, 1.f }; - quat im_rot = { 0.f, 0.f, 0.f, 1.f }; - vec4 im_color = { 0.f, 1.f, 1.f, 1.f }; - quat_identity(&im_rot); - im_begin(im_position, im_rot, im_scale, im_color, GL_LINES); + // Immediate geometry test + vec3 im_position = { 0.f, 20.f, 0.f }; + vec3 im_scale = { 1.f, 1.f, 1.f }; + quat im_rot = { 0.f, 0.f, 0.f, 1.f }; + vec4 im_color = { 0.f, 1.f, 1.f, 1.f }; + quat_identity(&im_rot); + im_begin(im_position, im_rot, im_scale, im_color, GL_LINES); - im_pos(0.f, 0.f, 0.f); - im_pos(100.f, 100.f, 10.f); + im_pos(0.f, 0.f, 0.f); + im_pos(100.f, 100.f, 10.f); - im_end(); + im_end(); - im_position.x = -10; + im_position.x = -10; - im_color.x = 1.f; - im_color.y = 0.f; - im_begin(im_position, im_rot, im_scale, im_color, GL_TRIANGLES); + im_color.x = 1.f; + im_color.y = 0.f; + im_begin(im_position, im_rot, im_scale, im_color, GL_TRIANGLES); - float length = 200.f; + float length = 200.f; - //Front - im_pos(0.f, 0.f, 0.f); - im_pos(0.f, length, 0.f); - im_pos(length, length, 0.f); - im_pos(length, length, 0.f); - im_pos(length, 0.f, 0.f); - im_pos( 0.f, 0.f, 0.f); + //Front + im_pos(0.f, 0.f, 0.f); + im_pos(0.f, length, 0.f); + im_pos(length, length, 0.f); + im_pos(length, length, 0.f); + im_pos(length, 0.f, 0.f); + im_pos( 0.f, 0.f, 0.f); - //Back - im_pos(0.f, 0.f, length); - im_pos(0.f, length, length); - im_pos(length, length, length); - im_pos(length, length, length); - im_pos(length, 0.f, length); - im_pos( 0.f, 0.f, length); + //Back + im_pos(0.f, 0.f, length); + im_pos(0.f, length, length); + im_pos(length, length, length); + im_pos(length, length, length); + im_pos(length, 0.f, length); + im_pos( 0.f, 0.f, length); - //Left - im_pos(0.f, 0.f, 0.f); - im_pos(0.f, 0.f, length); - im_pos(0.f, length, length); - im_pos(0.f, length, length); - im_pos(0.f, length, 0.f); - im_pos(0.f, 0.f, length); + //Left + im_pos(0.f, 0.f, 0.f); + im_pos(0.f, 0.f, length); + im_pos(0.f, length, length); + im_pos(0.f, length, length); + im_pos(0.f, length, 0.f); + im_pos(0.f, 0.f, length); - //Right - im_pos(length, 0.f, 0.f); - im_pos(length, 0.f, length); - im_pos(length, length, length); - im_pos(length, length, length); - im_pos(length, length, 0.f); - im_pos(length, 0.f, length); + //Right + im_pos(length, 0.f, 0.f); + im_pos(length, 0.f, length); + im_pos(length, length, length); + im_pos(length, length, length); + im_pos(length, length, 0.f); + im_pos(length, 0.f, length); - im_end(); + im_end(); - im_position.x = -30.f; - im_begin(im_position, im_rot, im_scale, im_color, GL_LINES); + im_position.x = -30.f; + im_begin(im_position, im_rot, im_scale, im_color, GL_LINES); - im_pos(0.f, 0.f, 0.f); - im_pos(0.f, 0.f, 10.f); + im_pos(0.f, 0.f, 0.f); + im_pos(0.f, 0.f, 10.f); - im_pos(0.f, 0.f, 10.f); - im_pos(0.f, 10.f, 10.f); + im_pos(0.f, 0.f, 10.f); + im_pos(0.f, 10.f, 10.f); - im_pos(0.f, 10.f, 10.f); - im_pos(0.f, 10.f, 0.f); + im_pos(0.f, 10.f, 10.f); + im_pos(0.f, 10.f, 0.f); - im_pos(0.f, 10.f, 0.f); - im_pos(0.f, 0.f, 0.f); + im_pos(0.f, 10.f, 0.f); + im_pos(0.f, 0.f, 0.f); - im_end(); + im_end(); - vec4 prim_color = {1.f, 1.f, 0.f, 1.f}; - im_box(5.f, 2.f, 10.f, im_position, im_rot, prim_color, GDM_TRIANGLES); + vec4 prim_color = {1.f, 1.f, 0.f, 1.f}; + im_box(5.f, 2.f, 10.f, im_position, im_rot, prim_color, GDM_TRIANGLES); - for(int i = 0; i < 10; i++) - { - im_position.x += i * 2.f; - im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES); - } + for(int i = 0; i < 10; i++) + { + im_position.x += i * 2.f; + im_sphere(2.f, im_position, im_rot, prim_color, GDM_TRIANGLES); + } } bool game_run(void) { uint32 last_time = platform->ticks_get(); - bool should_window_close = 0; - while(!should_window_close) - { + bool should_window_close = 0; + while(!should_window_close) + { uint32 curr_time = platform->ticks_get(); - float delta_time = (float)(curr_time - last_time) / 1000.f; - last_time = curr_time; - if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */ + float delta_time = (float)(curr_time - last_time) / 1000.f; + last_time = curr_time; + if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */ - gui_input_begin(); + gui_input_begin(); platform->poll_events(&should_window_close); - gui_input_end(); + gui_input_end(); - game_update(delta_time, &should_window_close); - game_post_update(delta_time); - game_render(); - platform->window.swap_buffers(game_state->window); - } + game_update(delta_time, &should_window_close); + game_post_update(delta_time); + game_render(); + platform->window.swap_buffers(game_state->window); + } return true; } void game_update(float dt, bool* window_should_close) { - if(input_is_key_pressed(KEY_ESCAPE)) *window_should_close = true; + if(input_is_key_pressed(KEY_ESCAPE)) *window_should_close = true; if(input_map_state_get("Window_Fullscreen", KS_RELEASED)) platform->window.fullscreen_set(game_state->window, 1); if(input_map_state_get("Window_Maximize", KS_RELEASED)) platform->window.fullscreen_set(game_state->window, 0); - if(input_map_state_get("Console_Toggle", KS_RELEASED)) console_toggle(game_state->console); - if(input_map_state_get("Editor_Toggle", KS_RELEASED)) + if(input_map_state_get("Console_Toggle", KS_RELEASED)) console_toggle(game_state->console); + if(input_map_state_get("Editor_Toggle", KS_RELEASED)) + { + //editor_toggle(); + if(game_state->game_mode == GAME_MODE_EDITOR) { - //editor_toggle(); - if(game_state->game_mode == GAME_MODE_EDITOR) - { - game_state->game_mode = GAME_MODE_GAME; - game_state->scene->active_camera_index = CAM_GAME; - } - else if(game_state->game_mode == GAME_MODE_GAME) - { - game_state->game_mode = GAME_MODE_EDITOR; - game_state->scene->active_camera_index = CAM_EDITOR; - } + game_state->game_mode = GAME_MODE_GAME; + game_state->scene->active_camera_index = CAM_GAME; } - - if(input_map_state_get("Reload_Game_Lib", KS_RELEASED)) + else if(game_state->game_mode == GAME_MODE_GAME) { - *window_should_close = true; - platform->reload_game_lib(); - return; + game_state->game_mode = GAME_MODE_EDITOR; + game_state->scene->active_camera_index = CAM_EDITOR; } + } + + if(input_map_state_get("Reload_Game_Lib", KS_RELEASED)) + { + *window_should_close = true; + platform->reload_game_lib(); + return; + } - //game_debug(dt); - //debug_gui(dt); - console_update(game_state->console, gui_state_get(), dt); - scene_update(game_state->scene, dt); - if(game_state->game_mode == GAME_MODE_GAME) - { - platform->physics.step(dt); - } - else if(game_state->game_mode == GAME_MODE_EDITOR) - { - editor_update(dt); - } + //game_debug(dt); + //debug_gui(dt); + console_update(game_state->console, gui_state_get(), dt); + scene_update(game_state->scene, dt); + if(game_state->game_mode == GAME_MODE_GAME) + { + platform->physics.step(dt); + } + else if(game_state->game_mode == GAME_MODE_EDITOR) + { + editor_update(dt); + } } void game_post_update(float dt) { - input_post_update(); - scene_post_update(game_state->scene); - platform->sound.update_3d(); + input_post_update(); + scene_post_update(game_state->scene); + platform->sound.update_3d(); } void game_debug_gui(float dt) { - struct Gui_State* gui_state = gui_state_get(); - struct nk_context* ctx = &gui_state->context; + struct Gui_State* gui_state = gui_state_get(); + struct nk_context* ctx = &gui_state->context; /* window flags */ static int show_menu = nk_true; @@ -1001,27 +1001,27 @@ void game_debug_gui(float dt) /* good old week day formula (double because precision) */ {int year_n = (sel_date.tm_mon < 2) ? year-1: year; - int y = year_n % 100; - int c = year_n / 100; - int y4 = (int)((float)y / 4); - int c4 = (int)((float)c / 4); - int m = (int)(2.6 * (double)(((sel_date.tm_mon + 10) % 12) + 1) - 0.2); - int week_day = (((1 + m + y + y4 + c4 - 2 * c) % 7) + 7) % 7; - - /* weekdays */ - nk_layout_row_dynamic(ctx, 35, 7); - for (i = 0; i < (int)LEN(week_days); ++i) - nk_label(ctx, week_days[i], NK_TEXT_CENTERED); - - /* days */ - if (week_day > 0) nk_spacing(ctx, week_day); - for (i = 1; i <= days; ++i) { - sprintf(buffer, "%d", i); - if (nk_button_label(ctx, buffer)) { - sel_date.tm_mday = i; - nk_combo_close(ctx); - } - }} + int y = year_n % 100; + int c = year_n / 100; + int y4 = (int)((float)y / 4); + int c4 = (int)((float)c / 4); + int m = (int)(2.6 * (double)(((sel_date.tm_mon + 10) % 12) + 1) - 0.2); + int week_day = (((1 + m + y + y4 + c4 - 2 * c) % 7) + 7) % 7; + + /* weekdays */ + nk_layout_row_dynamic(ctx, 35, 7); + for (i = 0; i < (int)LEN(week_days); ++i) + nk_label(ctx, week_days[i], NK_TEXT_CENTERED); + + /* days */ + if (week_day > 0) nk_spacing(ctx, week_day); + for (i = 1; i <= days; ++i) { + sprintf(buffer, "%d", i); + if (nk_button_label(ctx, buffer)) { + sel_date.tm_mday = i; + nk_combo_close(ctx); + } + }} nk_combo_end(ctx); } } @@ -1628,7 +1628,7 @@ void game_debug_gui(float dt) bounds = nk_widget_bounds(ctx); nk_spacing(ctx, 1); if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && + nk_input_is_mouse_prev_hovering_rect(in, bounds)) && nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { a = row_layout[0] + in->mouse.delta.x; @@ -1651,7 +1651,7 @@ void game_debug_gui(float dt) bounds = nk_widget_bounds(ctx); nk_spacing(ctx, 1); if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && + nk_input_is_mouse_prev_hovering_rect(in, bounds)) && nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { b = (row_layout[2] + in->mouse.delta.x); @@ -1707,7 +1707,7 @@ void game_debug_gui(float dt) bounds = nk_widget_bounds(ctx); nk_spacing(ctx, 1); if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && + nk_input_is_mouse_prev_hovering_rect(in, bounds)) && nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { a = a + in->mouse.delta.y; @@ -1732,7 +1732,7 @@ void game_debug_gui(float dt) nk_layout_row_dynamic(ctx, 8, 1); bounds = nk_widget_bounds(ctx); if ((nk_input_is_mouse_hovering_rect(in, bounds) || - nk_input_is_mouse_prev_hovering_rect(in, bounds)) && + nk_input_is_mouse_prev_hovering_rect(in, bounds)) && nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { b = b + in->mouse.delta.y; @@ -1766,69 +1766,69 @@ void game_debug_gui(float dt) void game_render(void) { - renderer_draw(game_state->renderer, game_state->scene); + renderer_draw(game_state->renderer, game_state->scene); } void game_cleanup(void) { - if(game_state) + if(game_state) + { + if(game_state->is_initialized) { - if(game_state->is_initialized) - { - editor_cleanup(); - scene_destroy(game_state->scene); - input_cleanup(); - renderer_cleanup(game_state->renderer); - gui_cleanup(); - console_destroy(game_state->console); + editor_cleanup(); + scene_destroy(game_state->scene); + input_cleanup(); + renderer_cleanup(game_state->renderer); + gui_cleanup(); + console_destroy(game_state->console); geom_cleanup(); - framebuffer_cleanup(); - texture_cleanup(); - shader_cleanup(); - - free(game_state->console); - free(game_state->scene); - free(game_state->renderer); - } - free(game_state); - game_state = NULL; - } + framebuffer_cleanup(); + texture_cleanup(); + shader_cleanup(); - if(platform) - { - platform->physics.cleanup(); - free(platform); + free(game_state->console); + free(game_state->scene); + free(game_state->renderer); } + free(game_state); + game_state = NULL; + } + + if(platform) + { + platform->physics.cleanup(); + free(platform); + } } struct Game_State* game_state_get(void) { - return game_state; + return game_state; } void on_collision_test(struct Entity* this_ent, struct Entity* other_ent, Rigidbody body, Rigidbody body2) { - float y = this_ent->transform.position.y; - if(y < 10.f) - { - //vec3 translation = {0.f, 50.f, 0.f}; - //transform_translate(this_ent, &translation, TS_WORLD); - //platform->physics.body_force_add(body, 0.f, -100.f, 0.f); - } - //platform->physics.body_force_add(body, 0.f, 500.f, 0.f); + float y = this_ent->transform.position.y; + if(y < 10.f) + { + //vec3 translation = {0.f, 50.f, 0.f}; + //transform_translate(this_ent, &translation, TS_WORLD); + //platform->physics.body_force_add(body, 0.f, -100.f, 0.f); + } + //platform->physics.body_force_add(body, 0.f, 500.f, 0.f); } void game_on_log_message(const char* message, va_list args) { - console_on_log_message(game_state->console, message, args); + console_on_log_message(game_state->console, message, args); } void game_on_log_warning(const char* warning_message, va_list args) { - console_on_log_warning(game_state->console, warning_message, args); + console_on_log_warning(game_state->console, warning_message, args); } void game_on_log_error(const char* context, const char* error_message, va_list args) { - console_on_log_error(game_state->console, context, error_message, args); -} \ No newline at end of file + console_on_log_error(game_state->console, context, error_message, args); +} diff --git a/src/libsymmetry/material.h b/src/libsymmetry/material.h index 61655f0..d68f502 100644 --- a/src/libsymmetry/material.h +++ b/src/libsymmetry/material.h @@ -12,52 +12,52 @@ struct Static_Mesh; struct Uniform { - int location; - int type; + int location; + int type; }; enum Mat_Type { - MAT_BLINN = 0, - MAT_UNSHADED, - MAT_MAX + MAT_BLINN = 0, + MAT_UNSHADED, + MAT_MAX }; enum Mat_Model_Param { - MMP_DIFFUSE_TEX = 0, - MMP_DIFFUSE_COL, - MMP_DIFFUSE, - MMP_SPECULAR_STRENGTH, - MMP_SPECULAR, - MMP_MAX + MMP_DIFFUSE_TEX = 0, + MMP_DIFFUSE_COL, + MMP_DIFFUSE, + MMP_SPECULAR_STRENGTH, + MMP_SPECULAR, + MMP_MAX }; enum Mat_Pipeline_Param { - MPP_MODEL_MAT = 0, - MPP_INV_MODEL_MAT, - MPP_VIEW_MAT, - MPP_MVP, - MPP_FOG_MODE, - MPP_FOG_DENSITY, - MPP_FOG_START_DIST, - MPP_FOG_MAX_DIST, - MPP_FOG_COLOR, - MPP_CAM_POS, - MPP_TOTAL_LIGHTS, - MPP_AMBIENT_LIGHT, - MPP_MAX + MPP_MODEL_MAT = 0, + MPP_INV_MODEL_MAT, + MPP_VIEW_MAT, + MPP_MVP, + MPP_FOG_MODE, + MPP_FOG_DENSITY, + MPP_FOG_START_DIST, + MPP_FOG_MAX_DIST, + MPP_FOG_COLOR, + MPP_CAM_POS, + MPP_TOTAL_LIGHTS, + MPP_AMBIENT_LIGHT, + MPP_MAX }; struct Material { - int type; - int shader; - struct Static_Mesh* registered_static_meshes[MAX_MATERIAL_REGISTERED_STATIC_MESHES]; - bool lit; - struct Uniform model_params[MMP_MAX]; - struct Uniform pipeline_params[MPP_MAX]; + int type; + int shader; + struct Static_Mesh* registered_static_meshes[MAX_MATERIAL_REGISTERED_STATIC_MESHES]; + bool lit; + struct Uniform model_params[MMP_MAX]; + struct Uniform pipeline_params[MPP_MAX]; }; bool material_init(struct Material* material, int material_type); diff --git a/src/libsymmetry/player.c b/src/libsymmetry/player.c index 1eb2328..50aaf96 100644 --- a/src/libsymmetry/player.c +++ b/src/libsymmetry/player.c @@ -6,77 +6,79 @@ #include "../common/common.h" #include "camera.h" #include "bounding_volumes.h" +#include "../common/hashmap.h" +#include "../common/log.h" void player_init(struct Player* player, struct Scene* scene) { - entity_init(player, "Player", &scene->root_entity); - player->base.active = true; - player->base.id = 1; - player->base.type = ET_PLAYER; + entity_init(player, "Player", &scene->root_entity); + player->base.active = true; + player->base.id = 1; + player->base.type = ET_PLAYER; - struct Hashmap* config = platform->config.get(); - player->move_speed = hashmap_int_get(config, "player_move_speed"); - player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier"); - player->turn_speed = hashmap_int_get(config, "player_turn_speed"); + struct Hashmap* config = platform->config.get(); + player->move_speed = hashmap_int_get(config, "player_move_speed"); + player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier"); + player->turn_speed = hashmap_int_get(config, "player_turn_speed"); - player->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN); + player->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN); - struct Camera* player_camera = &scene->cameras[CAM_GAME]; - entity_rename(player_camera, "Player_Camera"); - player_camera->base.active = true; - player_camera->clear_color.x = 0.6f; - player_camera->clear_color.y = 0.6f; - player_camera->clear_color.z = 0.9f; - player_camera->clear_color.w = 1.f; - player->camera_node = player_camera; + struct Camera* player_camera = &scene->cameras[CAM_GAME]; + entity_rename(player_camera, "Player_Camera"); + player_camera->base.active = true; + player_camera->clear_color.x = 0.6f; + player_camera->clear_color.y = 0.6f; + player_camera->clear_color.z = 0.9f; + player_camera->clear_color.w = 1.f; + player->camera_node = player_camera; - int render_width = hashmap_int_get(config, "render_width"); - int render_height = hashmap_int_get(config, "render_height"); - camera_attach_fbo(player_camera, render_width, render_height, true, true, true); - transform_parent_set(player_camera, player, true); + int render_width = hashmap_int_get(config, "render_width"); + int render_height = hashmap_int_get(config, "render_height"); + camera_attach_fbo(player_camera, render_width, render_height, true, true, true); + transform_parent_set(player_camera, player, true); - vec3 cam_translation = {0.f, 20.f, 2.f}; - transform_translate(player_camera, &cam_translation, TS_LOCAL); + vec3 cam_translation = {0.f, 20.f, 2.f}; + transform_translate(player_camera, &cam_translation, TS_LOCAL); - vec3 cam_axis = {-1.f, 0.f, 0.f}; - transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL); + vec3 cam_axis = {-1.f, 0.f, 0.f}; + transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL); } void player_destroy(struct Player* player) { - entity_reset(player, player->base.id); - player->base.active = false; + entity_reset(player, player->base.id); + player->base.active = false; } void player_update(struct Player* player, struct Scene* scene, float dt) { - float move_speed = player->move_speed; - vec3 offset = {0.f, 0.f, 0.f}; + float move_speed = player->move_speed; + vec3 offset = {0.f, 0.f, 0.f}; - /* Movement */ - if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= player->move_speed_multiplier; - if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; - if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; - if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; - if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; - if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; - if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; + /* Movement */ + if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= player->move_speed_multiplier; + if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed; + if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed; + if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed; + if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed; + if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed; + if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed; - vec3_scale(&offset, &offset, dt); - if(offset.x != 0 || offset.y != 0 || offset.z != 0) - { - transform_translate(player, &offset, TS_LOCAL); - } + vec3_scale(&offset, &offset, dt); + if(offset.x != 0 || offset.y != 0 || offset.z != 0) + { + transform_translate(player, &offset, TS_LOCAL); + } - /* Aiming and Projectiles*/ - if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) - { - int mouse_x = 0, mouse_y = 0; - platform->mouse_position_get(&mouse_x, &mouse_y); - struct Ray ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y); - log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); + /* Aiming and Projectiles*/ + if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) + { + int mouse_x = 0, mouse_y = 0; + platform->mouse_position_get(&mouse_x, &mouse_y); + struct Ray ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y); + log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); - struct Raycast_Result ray_result; - scene_ray_intersect(scene, &ray, &ray_result); - } + struct Raycast_Result ray_result; + scene_ray_intersect(scene, &ray, &ray_result); + } } diff --git a/src/libsymmetry/renderer.c b/src/libsymmetry/renderer.c index 702977e..9cf1a26 100644 --- a/src/libsymmetry/renderer.c +++ b/src/libsymmetry/renderer.c @@ -33,475 +33,474 @@ void on_framebuffer_size_change(int width, int height); void renderer_init(struct Renderer* renderer) { - assert(renderer); + assert(renderer); - glClearColor(0.3f, 0.6f, 0.9f, 1.0f); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + glClearColor(0.3f, 0.6f, 0.9f, 1.0f); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); platform->windowresize_callback_set(on_framebuffer_size_change); - struct Hashmap* cvars = platform->config.get(); - renderer->settings.fog.mode = hashmap_int_get(cvars, "fog_mode"); - renderer->settings.fog.density = hashmap_float_get(cvars, "fog_density"); - renderer->settings.fog.start_dist = hashmap_float_get(cvars, "fog_start_dist"); - renderer->settings.fog.max_dist = hashmap_float_get(cvars, "fog_max_dist"); - renderer->settings.fog.color = hashmap_vec3_get(cvars, "fog_color"); - renderer->settings.debug_draw_enabled = hashmap_bool_get(cvars, "debug_draw_enabled"); - renderer->settings.debug_draw_physics = hashmap_bool_get(cvars, "debug_draw_physics"); - renderer->settings.debug_draw_mode = hashmap_int_get(cvars, "debug_draw_mode"); - renderer->settings.debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); - renderer->settings.ambient_light = hashmap_vec3_get(cvars, "ambient_light"); + struct Hashmap* cvars = platform->config.get(); + renderer->settings.fog.mode = hashmap_int_get(cvars, "fog_mode"); + renderer->settings.fog.density = hashmap_float_get(cvars, "fog_density"); + renderer->settings.fog.start_dist = hashmap_float_get(cvars, "fog_start_dist"); + renderer->settings.fog.max_dist = hashmap_float_get(cvars, "fog_max_dist"); + renderer->settings.fog.color = hashmap_vec3_get(cvars, "fog_color"); + renderer->settings.debug_draw_enabled = hashmap_bool_get(cvars, "debug_draw_enabled"); + renderer->settings.debug_draw_physics = hashmap_bool_get(cvars, "debug_draw_physics"); + renderer->settings.debug_draw_mode = hashmap_int_get(cvars, "debug_draw_mode"); + renderer->settings.debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); + renderer->settings.ambient_light = hashmap_vec3_get(cvars, "ambient_light"); - /* Quad geometry for final render */ - vec3* vertices = array_new(vec3); - vec2* uvs = array_new(vec2); - vec3* normals = array_new(vec3); - uint* indices = array_new(uint); - vec3 temp_v3; - vec2 temp_v2; - /* Vertices */ - temp_v3.x = -1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); - temp_v3.x = 1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); - temp_v3.x = 1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); - temp_v3.x = -1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); - /* Normals */ - temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3); - temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3); - /* Uvs */ - temp_v2.x = 0; temp_v2.y = 0; array_push(uvs, temp_v2, vec2); - temp_v2.x = 1; temp_v2.y = 0; array_push(uvs, temp_v2, vec2); - temp_v2.x = 1; temp_v2.y = 1; array_push(uvs, temp_v2, vec2); - temp_v2.x = 0; temp_v2.y = 1; array_push(uvs, temp_v2, vec2); - /* Indices */ - array_push(indices, 0, uint); array_push(indices, 1, uint); array_push(indices, 2, uint); - array_push(indices, 2, uint); array_push(indices, 3, uint); array_push(indices, 0, uint); + /* Quad geometry for final render */ + vec3* vertices = array_new(vec3); + vec2* uvs = array_new(vec2); + vec3* normals = array_new(vec3); + uint* indices = array_new(uint); + vec3 temp_v3; + vec2 temp_v2; + /* Vertices */ + temp_v3.x = -1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); + temp_v3.x = 1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); + temp_v3.x = 1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); + temp_v3.x = -1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3); + /* Normals */ + temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3); + temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3); + /* Uvs */ + temp_v2.x = 0; temp_v2.y = 0; array_push(uvs, temp_v2, vec2); + temp_v2.x = 1; temp_v2.y = 0; array_push(uvs, temp_v2, vec2); + temp_v2.x = 1; temp_v2.y = 1; array_push(uvs, temp_v2, vec2); + temp_v2.x = 0; temp_v2.y = 1; array_push(uvs, temp_v2, vec2); + /* Indices */ + array_push(indices, 0, uint); array_push(indices, 1, uint); array_push(indices, 2, uint); + array_push(indices, 2, uint); array_push(indices, 3, uint); array_push(indices, 0, uint); - renderer->quad_geo = geom_create("Quad", vertices, uvs, normals, indices, NULL); - array_free(vertices); - array_free(uvs); - array_free(normals); - array_free(indices); - - int width = -1, height = -1; - struct Game_State* game_state = game_state_get(); + renderer->quad_geo = geom_create("Quad", vertices, uvs, normals, indices, NULL); + array_free(vertices); + array_free(uvs); + array_free(normals); + array_free(indices); + + int width = -1, height = -1; + struct Game_State* game_state = game_state_get(); platform->window.get_size(game_state->window, &width, &height); - renderer->def_albedo_tex = texture_create("def_albedo_texture", - TU_DIFFUSE, - width, height, - GL_RGB, - GL_RGB16F, - GL_FLOAT, - NULL); - texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - renderer->def_depth_tex = texture_create("def_depth_texture", - TU_SHADOWMAP4, - width, height, - GL_DEPTH_COMPONENT, - GL_DEPTH_COMPONENT32F, - GL_FLOAT, - NULL); - texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - texture_set_param(renderer->def_depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - texture_set_param(renderer->def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - - renderer->def_fbo = framebuffer_create(width, height, true, false, true); - framebuffer_texture_set(renderer->def_fbo, renderer->def_albedo_tex, FA_COLOR_ATTACHMENT0); - framebuffer_texture_set(renderer->def_fbo, renderer->def_depth_tex, FA_DEPTH_ATTACHMENT); - renderer->composition_shader = shader_create("fbo.vert", "fbo.frag"); - renderer->debug_shader = shader_create("debug.vert", "debug.frag"); - - renderer->num_culled_slot = editor_debugvar_slot_create("Culled Geom", VT_INT); - renderer->num_rendered_slot = editor_debugvar_slot_create("Rendered Geom", VT_INT); - renderer->num_indices_slot = editor_debugvar_slot_create("Total Indices", VT_INT); - - renderer->sprite_batch = malloc(sizeof(*renderer->sprite_batch)); - if(!renderer->sprite_batch) - { - log_error("renderer:init", "Failed to allocated sprite batch"); - } - else - { - sprite_batch_create(renderer->sprite_batch, "sprite_map.tga", "sprite.vert", "sprite.frag", GL_TRIANGLES); - } - - im_init(); - - // Initialize materials - for(int i = 0; i < MAT_MAX; i++) - { - material_init(&renderer->materials[i], i); - } + renderer->def_albedo_tex = texture_create("def_albedo_texture", + TU_DIFFUSE, + width, height, + GL_RGB, + GL_RGB16F, + GL_FLOAT, + NULL); + texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + texture_set_param(renderer->def_albedo_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + renderer->def_depth_tex = texture_create("def_depth_texture", + TU_SHADOWMAP4, + width, height, + GL_DEPTH_COMPONENT, + GL_DEPTH_COMPONENT32F, + GL_FLOAT, + NULL); + texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + texture_set_param(renderer->def_depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + texture_set_param(renderer->def_depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + texture_set_param(renderer->def_depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + texture_set_param(renderer->def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + + renderer->def_fbo = framebuffer_create(width, height, true, false, true); + framebuffer_texture_set(renderer->def_fbo, renderer->def_albedo_tex, FA_COLOR_ATTACHMENT0); + framebuffer_texture_set(renderer->def_fbo, renderer->def_depth_tex, FA_DEPTH_ATTACHMENT); + renderer->composition_shader = shader_create("fbo.vert", "fbo.frag"); + renderer->debug_shader = shader_create("debug.vert", "debug.frag"); + + renderer->num_culled_slot = editor_debugvar_slot_create("Culled Geom", VT_INT); + renderer->num_rendered_slot = editor_debugvar_slot_create("Rendered Geom", VT_INT); + renderer->num_indices_slot = editor_debugvar_slot_create("Total Indices", VT_INT); + + renderer->sprite_batch = malloc(sizeof(*renderer->sprite_batch)); + if(!renderer->sprite_batch) + { + log_error("renderer:init", "Failed to allocated sprite batch"); + } + else + { + sprite_batch_create(renderer->sprite_batch, "sprite_map.tga", "sprite.vert", "sprite.frag", GL_TRIANGLES); + } + + im_init(); + + // Initialize materials + for(int i = 0; i < MAT_MAX; i++) + { + material_init(&renderer->materials[i], i); + } } void renderer_draw(struct Renderer* renderer, struct Scene* scene) { - /* Render each camera output into it's framebuffer or to the default framebuffer */ - for(int i = 0; i < MAX_CAMERAS; i++) + /* Render each camera output into it's framebuffer or to the default framebuffer */ + for(int i = 0; i < MAX_CAMERAS; i++) + { + struct Camera* camera = &scene->cameras[i]; + if(!camera->base.active) continue; + + int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo; + framebuffer_bind(fbo); { - struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) continue; - - int fbo = camera->fbo == -1 ? renderer->def_fbo : camera->fbo; - framebuffer_bind(fbo); + glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo)); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glClearColor(camera->clear_color.x, + camera->clear_color.y, + camera->clear_color.z, + camera->clear_color.w); + glEnable(GL_CULL_FACE ); + glCullFace(GL_BACK); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + static mat4 mvp; + for(int i = 0; i < MAT_MAX; i++) + { + /* for each material, get all the registered models and render them */ + struct Material* material = &renderer->materials[i]; + GL_CHECK(shader_bind(material->shader)); + + if(material->lit) /* Set light information */ { - glViewport(0, 0, framebuffer_width_get(fbo), framebuffer_height_get(fbo)); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glClearColor(camera->clear_color.x, - camera->clear_color.y, - camera->clear_color.z, - camera->clear_color.w); - glEnable(GL_CULL_FACE ); - glCullFace(GL_BACK); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - static mat4 mvp; - for(int i = 0; i < MAT_MAX; i++) + char uniform_name[MAX_UNIFORM_NAME_LEN]; + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + int light_count = -1; + for(int i = 0; i < MAX_LIGHTS; i++) + { + struct Light* light = &scene->lights[i]; /* TODO: Cull lights according to camera frustum */ + if(!light->base.active && light->valid) continue; + light_count++; + + vec3 light_pos = {0, 0, 0}; + transform_get_absolute_position(&light->base, &light_pos); + + if(light->type != LT_POINT) { - /* for each material, get all the registered models and render them */ - struct Material* material = &renderer->materials[i]; - GL_CHECK(shader_bind(material->shader)); - - if(material->lit) /* Set light information */ - { - char uniform_name[MAX_UNIFORM_NAME_LEN]; - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - int light_count = -1; - for(int i = 0; i < MAX_LIGHTS; i++) - { - struct Light* light = &scene->lights[i]; /* TODO: Cull lights according to camera frustum */ - if(!light->base.active && light->valid) continue; - light_count++; - - vec3 light_pos = {0, 0, 0}; - transform_get_absolute_position(&light->base, &light_pos); - - if(light->type != LT_POINT) - { - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count); - vec3 light_dir = {0.f, 0.f, 0.f}; - transform_get_absolute_lookat(&light->base, &light_dir); - vec3_norm(&light_dir, &light_dir); - shader_set_uniform_vec3(material->shader, uniform_name, &light_dir); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - } - - if(light->type != LT_DIR) - { - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count); - shader_set_uniform_vec3(material->shader, uniform_name, &light_pos); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count); - shader_set_uniform_float(material->shader, uniform_name, light->outer_angle); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].direction", light_count); + vec3 light_dir = {0.f, 0.f, 0.f}; + transform_get_absolute_lookat(&light->base, &light_dir); + vec3_norm(&light_dir, &light_dir); + shader_set_uniform_vec3(material->shader, uniform_name, &light_dir); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + } + + if(light->type != LT_DIR) + { + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].position", light_count); + shader_set_uniform_vec3(material->shader, uniform_name, &light_pos); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].outer_angle", light_count); + shader_set_uniform_float(material->shader, uniform_name, light->outer_angle); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count); - shader_set_uniform_float(material->shader, uniform_name, light->inner_angle); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].inner_angle", light_count); + shader_set_uniform_float(material->shader, uniform_name, light->inner_angle); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count); - shader_set_uniform_float(material->shader, uniform_name, light->falloff); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count); - shader_set_uniform_int(material->shader, uniform_name, light->radius); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - } + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].falloff", light_count); + shader_set_uniform_float(material->shader, uniform_name, light->falloff); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].radius", light_count); + shader_set_uniform_int(material->shader, uniform_name, light->radius); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + } - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count); - shader_set_uniform_vec3(material->shader, uniform_name, &light->color); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].color", light_count); + shader_set_uniform_vec3(material->shader, uniform_name, &light->color); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count); - shader_set_uniform_float(material->shader, uniform_name, light->intensity); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].intensity", light_count); + shader_set_uniform_float(material->shader, uniform_name, light->intensity); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count); - shader_set_uniform_int(material->shader, uniform_name, light->type); - memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); - } - - light_count++; // this variable is going to be used for looping an array so increase its length by one - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count)); - vec3 camera_pos = {0, 0, 0}; - transform_get_absolute_position(&camera->base, &camera_pos); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos)); - } - - /* Set material pipeline uniforms */ - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode)); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density)); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_START_DIST].type, material->pipeline_params[MPP_FOG_START_DIST].location, &renderer->settings.fog.start_dist)); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MAX_DIST].type, material->pipeline_params[MPP_FOG_MAX_DIST].location, &renderer->settings.fog.max_dist)); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color)); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_AMBIENT_LIGHT].type, material->pipeline_params[MPP_AMBIENT_LIGHT].location, &renderer->settings.ambient_light)); - if(material->lit) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat)); - - - for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++) - { - if(!material->registered_static_meshes[j]) continue; - - /* for each registered model, set up uniforms and render */ - struct Static_Mesh* mesh = material->registered_static_meshes[j]; - struct Geometry* geometry = geom_get(mesh->model.geometry_index); - - /* Check if model is in frustum */ - vec3 abs_pos, abs_scale; - transform_get_absolute_position(&mesh->base, &abs_pos); - transform_get_absolute_scale(&mesh->base, &abs_scale); - int intersection = bv_intersect_frustum_sphere(&camera->frustum, &geometry->bounding_sphere, &abs_pos, &abs_scale); - if(intersection == IT_OUTSIDE) - { - renderer->num_culled++; - continue; - } - else - { - renderer->num_indices += array_len(geometry->indices); - renderer->num_rendered++; - } - - /* set material params for the model */ - for(int k = 0; k < MMP_MAX; k++) - { - switch(mesh->model.material_params[k].type) - { - case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break; - case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break; - case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break; - case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break; - } - } - - /* Set pipeline uniforms that are derived per model */ - mat4_identity(&mvp); - mat4_mul(&mvp, &camera->view_proj_mat, &mesh->base.transform.trans_mat); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp)); - - if(material->lit) - { - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat)); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat)); - mat4 inv_mat; - mat4_identity(&inv_mat); - mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat); - GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat)); - } - - /* Render the geometry */ - //int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode); - //geom_render(model->geometry_index, draw_mode); - geom_render(mesh->model.geometry_index, GDM_TRIANGLES); - - for(int k = 0; k < MMP_MAX; k++) - { - /* unbind textures, if any */ - if(material->model_params[k].type == UT_TEX) - GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int)); - } - } - shader_unbind(); - } - editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered); - editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled); - editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices); - - renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0; + snprintf(uniform_name, MAX_UNIFORM_NAME_LEN, "lights[%d].type", light_count); + shader_set_uniform_int(material->shader, uniform_name, light->type); + memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); + } + + light_count++; // this variable is going to be used for looping an array so increase its length by one + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_TOTAL_LIGHTS].type, material->pipeline_params[MPP_TOTAL_LIGHTS].location, &light_count)); + vec3 camera_pos = {0, 0, 0}; + transform_get_absolute_position(&camera->base, &camera_pos); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_CAM_POS].type, material->pipeline_params[MPP_CAM_POS].location, &camera_pos)); } - framebuffer_unbind(); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - } - /* Final Render */ - struct Camera* active_camera = &scene->cameras[scene->active_camera_index]; - int width, height; - struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); - glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - shader_bind(renderer->composition_shader); - int final_render_tex = active_camera->render_tex == -1 ? renderer->def_albedo_tex : active_camera->render_tex; - texture_bind(final_render_tex); - geom_render(renderer->quad_geo, GDM_TRIANGLES); - texture_unbind(final_render_tex); - shader_unbind(); + /* Set material pipeline uniforms */ + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MODE].type, material->pipeline_params[MPP_FOG_MODE].location, &renderer->settings.fog.mode)); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_DENSITY].type, material->pipeline_params[MPP_FOG_DENSITY].location, &renderer->settings.fog.density)); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_START_DIST].type, material->pipeline_params[MPP_FOG_START_DIST].location, &renderer->settings.fog.start_dist)); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_MAX_DIST].type, material->pipeline_params[MPP_FOG_MAX_DIST].location, &renderer->settings.fog.max_dist)); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_FOG_COLOR].type, material->pipeline_params[MPP_FOG_COLOR].location, &renderer->settings.fog.color)); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_AMBIENT_LIGHT].type, material->pipeline_params[MPP_AMBIENT_LIGHT].location, &renderer->settings.ambient_light)); + if(material->lit) GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat)); - /* Debug Render */ - struct Hashmap* cvars = platform->config.get(); - if(hashmap_bool_get(cvars, "debug_draw_enabled")) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - vec4 debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); - shader_bind(renderer->debug_shader); + + for(int j = 0; j < MAX_MATERIAL_REGISTERED_STATIC_MESHES; j++) { - static mat4 mvp; - shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &debug_draw_color); - for(int i = 0; i < MAX_STATIC_MESHES; i++) + if(!material->registered_static_meshes[j]) continue; + + /* for each registered model, set up uniforms and render */ + struct Static_Mesh* mesh = material->registered_static_meshes[j]; + struct Geometry* geometry = geom_get(mesh->model.geometry_index); + + /* Check if model is in frustum */ + vec3 abs_pos, abs_scale; + transform_get_absolute_position(&mesh->base, &abs_pos); + transform_get_absolute_scale(&mesh->base, &abs_scale); + int intersection = bv_intersect_frustum_sphere(&camera->frustum[0], &geometry->bounding_sphere, &abs_pos, &abs_scale); + if(intersection == IT_OUTSIDE) + { + renderer->num_culled++; + continue; + } + else + { + renderer->num_indices += array_len(geometry->indices); + renderer->num_rendered++; + } + + /* set material params for the model */ + for(int k = 0; k < MMP_MAX; k++) + { + switch(mesh->model.material_params[k].type) { - struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active) continue; - struct Model* model = &mesh->model; - struct Transform* transform = &mesh->base.transform; - int geometry = model->geometry_index; - mat4_identity(&mvp); - mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); - shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); - geom_render(geometry, hashmap_int_get(cvars, "debug_draw_mode")); + case VT_INT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_int)); break; + case VT_FLOAT: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_float)); break; + case VT_VEC3: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec3)); break; + case VT_VEC4: GL_CHECK(shader_set_uniform(material->model_params[k].type, material->model_params[k].location, &mesh->model.material_params[k].val_vec4)); break; } + } + + /* Set pipeline uniforms that are derived per model */ + mat4_identity(&mvp); + mat4_mul(&mvp, &camera->view_proj_mat, &mesh->base.transform.trans_mat); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MVP].type, material->pipeline_params[MPP_MVP].location, &mvp)); + + if(material->lit) + { + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_VIEW_MAT].type, material->pipeline_params[MPP_VIEW_MAT].location, &camera->view_mat)); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_MODEL_MAT].type, material->pipeline_params[MPP_MODEL_MAT].location, &mesh->base.transform.trans_mat)); + mat4 inv_mat; + mat4_identity(&inv_mat); + mat4_inverse(&inv_mat, &mesh->base.transform.trans_mat); + GL_CHECK(shader_set_uniform(material->pipeline_params[MPP_INV_MODEL_MAT].type, material->pipeline_params[MPP_INV_MODEL_MAT].location, &inv_mat)); + } + + /* Render the geometry */ + //int indices = geom_render_in_frustum(model->geometry_index, &viewer->camera.frustum[0], entity, draw_mode); + //geom_render(model->geometry_index, draw_mode); + geom_render(mesh->model.geometry_index, GDM_TRIANGLES); + + for(int k = 0; k < MMP_MAX; k++) + { + /* unbind textures, if any */ + if(material->model_params[k].type == UT_TEX) + GL_CHECK(texture_unbind(mesh->model.material_params[k].val_int)); + } } shader_unbind(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + } + editor_debugvar_slot_set_int(renderer->num_rendered_slot, renderer->num_rendered); + editor_debugvar_slot_set_int(renderer->num_culled_slot, renderer->num_culled); + editor_debugvar_slot_set_int(renderer->num_indices_slot, renderer->num_indices); - // Debug Physics render - if(hashmap_bool_get(cvars, "debug_draw_physics")) + renderer->num_culled = renderer->num_rendered = renderer->num_indices = 0; + } + framebuffer_unbind(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + } + + /* Final Render */ + struct Camera* active_camera = &scene->cameras[scene->active_camera_index]; + int width, height; + struct Game_State* game_state = game_state_get(); + platform->window.get_size(game_state->window, &width, &height); + glViewport(0, 0, width, height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + shader_bind(renderer->composition_shader); + int final_render_tex = active_camera->render_tex == -1 ? renderer->def_albedo_tex : active_camera->render_tex; + texture_bind(final_render_tex); + geom_render(renderer->quad_geo, GDM_TRIANGLES); + texture_unbind(final_render_tex); + shader_unbind(); + + /* Debug Render */ + struct Hashmap* cvars = platform->config.get(); + if(hashmap_bool_get(cvars, "debug_draw_enabled")) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + vec4 debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); + shader_bind(renderer->debug_shader); { - static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f }; - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue; - - //Get collision mesh and it's props then render it - vec3 pos = {0.f}; - quat rot = {0.f, 0.f, 0.f, 1.f }; - if(mesh->collision.rigidbody) - { - platform->physics.body_position_get(mesh->collision.rigidbody, &pos.x, &pos.y, &pos.z); - platform->physics.body_rotation_get(mesh->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w); - } - else - { - platform->physics.cs_position_get(mesh->collision.collision_shape, &pos.x, &pos.y, &pos.z); - platform->physics.cs_rotation_get(mesh->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w); - } - - int collision_shape_type = platform->physics.cs_type_get(mesh->collision.collision_shape); - switch(collision_shape_type) - { - case CST_SPHERE: - { - float radius = platform->physics.cs_sphere_radius_get(mesh->collision.collision_shape); - im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES); - } - break; - case CST_BOX: - { - float x = 0.f, y = 0.f, z = 0.f; - platform->physics.cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z); - im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES); - }; - break; - default: break; - } - } + static mat4 mvp; + shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &debug_draw_color); + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* mesh = &scene->static_meshes[i]; + if(!mesh->base.active) continue; + struct Model* model = &mesh->model; + struct Transform* transform = &mesh->base.transform; + int geometry = model->geometry_index; + mat4_identity(&mvp); + mat4_mul(&mvp, &active_camera->view_proj_mat, &transform->trans_mat); + shader_set_uniform_mat4(renderer->debug_shader, "mvp", &mvp); + geom_render(geometry, hashmap_int_get(cvars, "debug_draw_mode")); + } + } + shader_unbind(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + + // Debug Physics render + if(hashmap_bool_get(cvars, "debug_draw_physics")) + { + static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f }; + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* mesh = &scene->static_meshes[i]; + if(!mesh->base.active || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue; + + //Get collision mesh and it's props then render it + vec3 pos = {0.f}; + quat rot = {0.f, 0.f, 0.f, 1.f }; + if(mesh->collision.rigidbody) + { + platform->physics.body_position_get(mesh->collision.rigidbody, &pos.x, &pos.y, &pos.z); + platform->physics.body_rotation_get(mesh->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w); + } + else + { + platform->physics.cs_position_get(mesh->collision.collision_shape, &pos.x, &pos.y, &pos.z); + platform->physics.cs_rotation_get(mesh->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w); + } + + int collision_shape_type = platform->physics.cs_type_get(mesh->collision.collision_shape); + switch(collision_shape_type) + { + case CST_SPHERE: + { + float radius = platform->physics.cs_sphere_radius_get(mesh->collision.collision_shape); + im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES); + } + break; + case CST_BOX: + { + float x = 0.f, y = 0.f, z = 0.f; + platform->physics.cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z); + im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES); + }; + break; + default: break; + } } + } - //Immediate mode geometry render - im_render(active_camera); + //Immediate mode geometry render + im_render(active_camera); - /* Render 2D stuff */ - shader_bind(renderer->sprite_batch->shader); - { - static mat4 ortho_mat; - mat4_identity(&ortho_mat); - int width, height; - struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); + /* Render 2D stuff */ + shader_bind(renderer->sprite_batch->shader); + { + static mat4 ortho_mat; + mat4_identity(&ortho_mat); + int width, height; + struct Game_State* game_state = game_state_get(); + platform->window.get_size(game_state->window, &width, &height); - mat4_ortho(&ortho_mat, 0.f, (float)width, (float)height, 0.f, -10.f, 10.f); - shader_set_uniform_mat4(renderer->sprite_batch->shader, "mvp", &ortho_mat); + mat4_ortho(&ortho_mat, 0.f, (float)width, (float)height, 0.f, -10.f, 10.f); + shader_set_uniform_mat4(renderer->sprite_batch->shader, "mvp", &ortho_mat); - sprite_batch_render(renderer->sprite_batch); - } - shader_unbind(); + sprite_batch_render(renderer->sprite_batch); + } + shader_unbind(); - /* Render UI */ - gui_render(NK_ANTI_ALIASING_ON); + /* Render UI */ + gui_render(NK_ANTI_ALIASING_ON); } void renderer_cleanup(struct Renderer* renderer) { - for(int i = 0; i < MAT_MAX; i++) - { - material_reset(&renderer->materials[i], i); - } - im_cleanup(); - sprite_batch_remove(renderer->sprite_batch); - free(renderer->sprite_batch); - geom_remove(renderer->quad_geo); - framebuffer_remove(renderer->def_fbo); - texture_remove(renderer->def_albedo_tex); - texture_remove(renderer->def_depth_tex); + for(int i = 0; i < MAT_MAX; i++) + { + material_reset(&renderer->materials[i]); + } + im_cleanup(); + sprite_batch_remove(renderer->sprite_batch); + free(renderer->sprite_batch); + geom_remove(renderer->quad_geo); + framebuffer_remove(renderer->def_fbo); + texture_remove(renderer->def_albedo_tex); + texture_remove(renderer->def_depth_tex); } void on_framebuffer_size_change(int width, int height) { - struct Scene* scene = game_state_get()->scene; - float aspect = (float)width / (float)height; - for(int i = 0; i < MAX_CAMERAS; i++) - { - struct Camera* viewer = &scene->cameras[i]; - viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f; - camera_update_proj(viewer); - } + struct Scene* scene = game_state_get()->scene; + float aspect = (float)width / (float)height; + for(int i = 0; i < MAX_CAMERAS; i++) + { + struct Camera* viewer = &scene->cameras[i]; + viewer->aspect_ratio = aspect > 0.f ? aspect : 4.f / 3.f; + camera_update_proj(viewer); + } - framebuffer_resize_all(width, height); + framebuffer_resize_all(width, height); } void renderer_clearcolor_set(float red, float green, float blue, float alpha) { - glClearColor(red, green, blue, alpha); + glClearColor(red, green, blue, alpha); } struct Material * renderer_material_get(int material_type) { - return NULL; + return NULL; } -void renderer_debug_draw_enabled(bool enabled) +void renderer_debug_draw_enabled(struct Renderer* renderer, bool enabled) { - struct Hashmap* cvars = platform->config.get(); - hashmap_bool_set(cvars, "debug_draw_enabled", enabled); -} - -void renderer_settings_get(struct Render_Settings* settings) -{ - struct Hashmap* cvars = platform->config.get(); - settings->fog.mode = hashmap_int_get(cvars, "fog_mode"); - settings->fog.density = hashmap_float_get(cvars, "fog_density"); - settings->fog.start_dist = hashmap_float_get(cvars, "fog_start_dist"); - settings->fog.max_dist = hashmap_float_get(cvars, "fog_max_dist"); - settings->fog.color = hashmap_vec3_get(cvars, "fog_color"); - settings->debug_draw_enabled = hashmap_bool_get(cvars, "debug_draw_enabled"); - settings->debug_draw_physics = hashmap_bool_get(cvars, "debug_draw_physics"); - settings->debug_draw_mode = hashmap_int_get(cvars, "debug_draw_mode"); - settings->debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); - settings->ambient_light = hashmap_vec3_get(cvars, "ambient_light"); + renderer->settings.debug_draw_mode = enabled; } -void renderer_settings_set(const struct Render_Settings* settings) -{ - struct Hashmap* cvars = platform->config.get(); - hashmap_int_set(cvars, "fog_mode", settings->fog.mode); - hashmap_float_set(cvars, "fog_density", settings->fog.density); - hashmap_float_set(cvars, "fog_start_dist", settings->fog.start_dist); - hashmap_float_set(cvars, "fog_max_dist", settings->fog.max_dist); - hashmap_vec3_set(cvars, "fog_color", &settings->fog.color); - hashmap_bool_set(cvars, "debug_draw_enabled", settings->debug_draw_enabled); - hashmap_bool_set(cvars, "debug_draw_physics", settings->debug_draw_physics); - hashmap_int_set(cvars, "debug_draw_mode", settings->debug_draw_mode); - hashmap_vec4_set(cvars, "debug_draw_color", &settings->debug_draw_color); - hashmap_vec3_set(cvars, "ambient_light", &settings->ambient_light); -} +/* void renderer_settings_get(struct Render_Settings* settings) */ +/* { */ +/* struct Hashmap* cvars = platform->config.get(); */ +/* settings->fog.mode = hashmap_int_get(cvars, "fog_mode"); */ +/* settings->fog.density = hashmap_float_get(cvars, "fog_density"); */ +/* settings->fog.start_dist = hashmap_float_get(cvars, "fog_start_dist"); */ +/* settings->fog.max_dist = hashmap_float_get(cvars, "fog_max_dist"); */ +/* settings->fog.color = hashmap_vec3_get(cvars, "fog_color"); */ +/* settings->debug_draw_enabled = hashmap_bool_get(cvars, "debug_draw_enabled"); */ +/* settings->debug_draw_physics = hashmap_bool_get(cvars, "debug_draw_physics"); */ +/* settings->debug_draw_mode = hashmap_int_get(cvars, "debug_draw_mode"); */ +/* settings->debug_draw_color = hashmap_vec4_get(cvars, "debug_draw_color"); */ +/* settings->ambient_light = hashmap_vec3_get(cvars, "ambient_light"); */ +/* } */ + +/* void renderer_settings_set(const struct Render_Settings* settings) */ +/* { */ +/* struct Hashmap* cvars = platform->config.get(); */ +/* hashmap_int_set(cvars, "fog_mode", settings->fog.mode); */ +/* hashmap_float_set(cvars, "fog_density", settings->fog.density); */ +/* hashmap_float_set(cvars, "fog_start_dist", settings->fog.start_dist); */ +/* hashmap_float_set(cvars, "fog_max_dist", settings->fog.max_dist); */ +/* hashmap_vec3_set(cvars, "fog_color", &settings->fog.color); */ +/* hashmap_bool_set(cvars, "debug_draw_enabled", settings->debug_draw_enabled); */ +/* hashmap_bool_set(cvars, "debug_draw_physics", settings->debug_draw_physics); */ +/* hashmap_int_set(cvars, "debug_draw_mode", settings->debug_draw_mode); */ +/* hashmap_vec4_set(cvars, "debug_draw_color", &settings->debug_draw_color); */ +/* hashmap_vec3_set(cvars, "ambient_light", &settings->ambient_light); */ +/* } */ diff --git a/src/libsymmetry/renderer.h b/src/libsymmetry/renderer.h index 0370854..e6f8232 100644 --- a/src/libsymmetry/renderer.h +++ b/src/libsymmetry/renderer.h @@ -9,45 +9,45 @@ struct Sprite_Batch; enum Fog_Mode { - FM_NONE = 0, - FM_LINEAR = 1, - FM_EXPONENTIAL = 2, - FM_EXPONENTIAL_SQRD = 3 + FM_NONE = 0, + FM_LINEAR = 1, + FM_EXPONENTIAL = 2, + FM_EXPONENTIAL_SQRD = 3 }; struct Fog { - int mode; - float density; - float start_dist; - float max_dist; - vec3 color; + int mode; + float density; + float start_dist; + float max_dist; + vec3 color; }; struct Render_Settings { - struct Fog fog; - vec3 ambient_light; - bool debug_draw_enabled; - vec4 debug_draw_color; - int debug_draw_mode; - bool debug_draw_physics; + struct Fog fog; + vec3 ambient_light; + bool debug_draw_enabled; + vec4 debug_draw_color; + int debug_draw_mode; + bool debug_draw_physics; }; struct Renderer { - int def_fbo; - int def_albedo_tex; - int def_depth_tex; - int quad_geo; - int composition_shader; - int debug_shader; - int num_culled , num_rendered , num_indices; - int num_culled_slot, num_rendered_slot, num_indices_slot; - struct Sprite_Batch* sprite_batch; - struct Render_Settings settings; - struct Material materials[MAT_MAX]; + int def_fbo; + int def_albedo_tex; + int def_depth_tex; + int quad_geo; + int composition_shader; + int debug_shader; + int num_culled , num_rendered , num_indices; + int num_culled_slot, num_rendered_slot, num_indices_slot; + struct Sprite_Batch* sprite_batch; + struct Render_Settings settings; + struct Material materials[MAT_MAX]; }; void renderer_init(struct Renderer* renderer); diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c index 7c9271e..1a52fe0 100644 --- a/src/libsymmetry/scene.c +++ b/src/libsymmetry/scene.c @@ -12,6 +12,7 @@ #include "game.h" #include "bounding_volumes.h" #include "geometry.h" +#include "editor.h" #include #include @@ -19,563 +20,570 @@ void scene_init(struct Scene* scene) { - assert(scene); - //Initialize the root entity - entity_init(&scene->root_entity, "ROOT_ENTITY", NULL); - scene->root_entity.active = true; - scene->root_entity.id = 0; - scene->root_entity.type = ET_ROOT; - - for(int i = 0; i < MAX_ENTITIES; i++) entity_reset(&scene->entities[i], i); - for(int i = 0; i < MAX_LIGHTS; i++) - { - entity_reset(&scene->lights[i], i); - scene->lights[i].type = ET_LIGHT; - } - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - entity_reset(&scene->static_meshes[i], i); - struct Static_Mesh* mesh = &scene->static_meshes[i]; - mesh->collision.collision_shape = NULL; - mesh->collision.rigidbody = NULL; - mesh->collision.on_collision = NULL; - mesh->model.geometry_index = -1; - mesh->model.material = NULL; - } - for(int i = 0; i < MAX_SOUND_SOURCES; i++) entity_reset(&scene->sound_sources[i], i); - for(int i = 0; i < MAX_CAMERAS; i++) - { - entity_init(&scene->cameras[i], NULL, &scene->root_entity); - camera_init(&scene->cameras[i], 1024, 768); - scene->cameras[i].base.id = i; - } - - player_init(&scene->player, scene); - editor_init_camera(); + assert(scene); + //Initialize the root entity + entity_init(&scene->root_entity, "ROOT_ENTITY", NULL); + scene->root_entity.active = true; + scene->root_entity.id = 0; + scene->root_entity.type = ET_ROOT; + + for(int i = 0; i < MAX_ENTITIES; i++) entity_reset(&scene->entities[i], i); + for(int i = 0; i < MAX_LIGHTS; i++) + { + entity_reset(&scene->lights[i], i); + scene->lights[i].type = ET_LIGHT; + } + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + entity_reset(&scene->static_meshes[i], i); + struct Static_Mesh* mesh = &scene->static_meshes[i]; + mesh->collision.collision_shape = NULL; + mesh->collision.rigidbody = NULL; + mesh->collision.on_collision = NULL; + mesh->model.geometry_index = -1; + mesh->model.material = NULL; + } + for(int i = 0; i < MAX_SOUND_SOURCES; i++) entity_reset(&scene->sound_sources[i], i); + for(int i = 0; i < MAX_CAMERAS; i++) + { + entity_init(&scene->cameras[i], NULL, &scene->root_entity); + camera_init(&scene->cameras[i], 1024, 768); + scene->cameras[i].base.id = i; + } + + player_init(&scene->player, scene); + editor_init_camera(); + + scene->active_camera_index = game_state_get()->game_mode == GAME_MODE_GAME ? CAM_GAME : CAM_EDITOR; +} - scene->active_camera_index = game_state_get()->game_mode == GAME_MODE_GAME ? CAM_GAME : CAM_EDITOR; +bool scene_load(struct Scene* scene, const char* filename, int dir_type) +{ + return false; } -bool scene_load(struct Scene* scene, const char* filename, int dir_type); -bool scene_save(struct Scene* scene, const char* filename, int dir_type); +bool scene_save(struct Scene* scene, const char* filename, int dir_type) +{ + return false; +} void scene_destroy(struct Scene* scene) { - assert(scene); - - for(int i = 0; i < MAX_ENTITIES; i++) scene_entity_remove(scene, &scene->entities[i]); - for(int i = 0; i < MAX_CAMERAS; i++) scene_camera_remove(scene, &scene->cameras[i]); - for(int i = 0; i < MAX_LIGHTS; i++) scene_light_remove(scene, &scene->lights[i]); - for(int i = 0; i < MAX_STATIC_MESHES; i++) scene_static_mesh_remove(scene, &scene->static_meshes[i]); - for(int i = 0; i < MAX_SOUND_SOURCES; i++) scene_sound_source_remove(scene, &scene->sound_sources[i]); - player_destroy(&scene->player); - entity_reset(&scene->root_entity, 0); - scene->root_entity.active = false; + assert(scene); + + for(int i = 0; i < MAX_ENTITIES; i++) scene_entity_remove(scene, &scene->entities[i]); + for(int i = 0; i < MAX_CAMERAS; i++) scene_camera_remove(scene, &scene->cameras[i]); + for(int i = 0; i < MAX_LIGHTS; i++) scene_light_remove(scene, &scene->lights[i]); + for(int i = 0; i < MAX_STATIC_MESHES; i++) scene_static_mesh_remove(scene, &scene->static_meshes[i]); + for(int i = 0; i < MAX_SOUND_SOURCES; i++) scene_sound_source_remove(scene, &scene->sound_sources[i]); + player_destroy(&scene->player); + entity_reset(&scene->root_entity, 0); + scene->root_entity.active = false; } void scene_update(struct Scene* scene, float dt) { - if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); + if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); } void scene_post_update(struct Scene* scene) { - assert(scene); + assert(scene); - for(int i = 0; i < MAX_ENTITIES; i++) + for(int i = 0; i < MAX_ENTITIES; i++) + { + struct Entity* entity = &scene->entities[i]; + if(!entity->active) continue; + + if(entity->marked_for_deletion) { - struct Entity* entity = &scene->entities[i]; - if(!entity->active) continue; + scene_entity_remove(scene, entity); + continue; + } - if(entity->marked_for_deletion) - { - scene_entity_remove(scene, entity); - continue; - } + if(entity->transform.is_modified) entity->transform.is_modified = false; + } - if(entity->transform.is_modified) entity->transform.is_modified = false; - } + for(int i = 0; i < MAX_CAMERAS; i++) + { + struct Camera* camera = &scene->cameras[i]; + if(!camera->base.active) continue; - for(int i = 0; i < MAX_CAMERAS; i++) + if(camera->base.marked_for_deletion) { - struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) continue; - - if(camera->base.marked_for_deletion) - { - scene_camera_remove(scene, camera); - continue; - } - - if(camera->base.transform.is_modified) - { - camera_update_view(camera); - camera->base.transform.is_modified = false; - } + scene_camera_remove(scene, camera); + continue; } - for(int i = 0; i < MAX_SOUND_SOURCES; i++) + if(camera->base.transform.is_modified) { - struct Sound_Source* sound_source = &scene->sound_sources[i]; - if(!sound_source->base.active) continue; - - if(sound_source->base.marked_for_deletion) - { - scene_sound_source_remove(scene, sound_source); - continue; - } - - if(sound_source->base.transform.is_modified) - { - vec3 abs_pos = {0.f, 0.f, 0.f}; - transform_get_absolute_position(&sound_source->base, &abs_pos); - platform->sound.source_instance_update_position(sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); - sound_source->base.transform.is_modified = false; - } + camera_update_view(camera); + camera->base.transform.is_modified = false; } + } - for(int i = 0; i < MAX_STATIC_MESHES; i++) + for(int i = 0; i < MAX_SOUND_SOURCES; i++) + { + struct Sound_Source* sound_source = &scene->sound_sources[i]; + if(!sound_source->base.active) continue; + + if(sound_source->base.marked_for_deletion) { - struct Static_Mesh* static_mesh = &scene->static_meshes[i]; - if(!static_mesh->base.active) continue; - - if(static_mesh->base.marked_for_deletion) - { - scene_static_mesh_remove(scene, static_mesh); - continue; - } - - if(static_mesh->base.transform.is_modified) - { - if(static_mesh->collision.rigidbody && static_mesh->base.transform.sync_physics) - { - quat abs_rot = { 0.f, 0.f, 0.f, 1.f }; - vec3 abs_pos = {0.f, 0.f, 0.f}; - transform_get_absolute_rot(&static_mesh->base, &abs_rot); - transform_get_absolute_position(&static_mesh->base, &abs_pos); - platform->physics.body_rotation_set(static_mesh->collision.rigidbody, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w); - platform->physics.body_position_set(static_mesh->collision.rigidbody, abs_pos.x, abs_pos.y, abs_pos.z); - } - static_mesh->base.transform.sync_physics = false; - static_mesh->base.transform.is_modified = false; - } + scene_sound_source_remove(scene, sound_source); + continue; } - for(int i = 0; i < MAX_LIGHTS; i++) + if(sound_source->base.transform.is_modified) { - struct Light* light = &scene->lights[i]; - if(!light->base.active) continue; - - if(light->base.marked_for_deletion) - { - scene_light_remove(scene, light); - continue; - } - - if(light->base.transform.is_modified) light->base.transform.is_modified = false; + vec3 abs_pos = {0.f, 0.f, 0.f}; + transform_get_absolute_position(&sound_source->base, &abs_pos); + platform->sound.source_instance_update_position(sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); + sound_source->base.transform.is_modified = false; } + } + + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* static_mesh = &scene->static_meshes[i]; + if(!static_mesh->base.active) continue; - for(int i = 0; i < MAX_ENTITIES; i++) + if(static_mesh->base.marked_for_deletion) { - struct Entity* entity = &scene->entities[i]; - if(!entity->active) continue; + scene_static_mesh_remove(scene, static_mesh); + continue; } - if(scene->player.base.transform.is_modified) + if(static_mesh->base.transform.is_modified) { + if(static_mesh->collision.rigidbody && static_mesh->base.transform.sync_physics) + { + quat abs_rot = { 0.f, 0.f, 0.f, 1.f }; vec3 abs_pos = {0.f, 0.f, 0.f}; - vec3 abs_fwd = {0.f, 0.f, -1.f}; - vec3 abs_up = {0.f, 1.f, 0.f}; - transform_get_absolute_position(&scene->player, &abs_pos); - transform_get_absolute_forward(&scene->player, &abs_fwd); - transform_get_absolute_up(&scene->player, &abs_up); - - platform->sound.listener_update(abs_pos.x, abs_pos.y, abs_pos.z, - abs_fwd.x, abs_fwd.y, abs_fwd.z, - abs_up.x, abs_up.y, abs_up.z); - scene->player.base.transform.is_modified = false; - } + transform_get_absolute_rot(&static_mesh->base, &abs_rot); + transform_get_absolute_position(&static_mesh->base, &abs_pos); + platform->physics.body_rotation_set(static_mesh->collision.rigidbody, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w); + platform->physics.body_position_set(static_mesh->collision.rigidbody, abs_pos.x, abs_pos.y, abs_pos.z); + } + static_mesh->base.transform.sync_physics = false; + static_mesh->base.transform.is_modified = false; + } + } + + for(int i = 0; i < MAX_LIGHTS; i++) + { + struct Light* light = &scene->lights[i]; + if(!light->base.active) continue; + + if(light->base.marked_for_deletion) + { + scene_light_remove(scene, light); + continue; + } + + if(light->base.transform.is_modified) light->base.transform.is_modified = false; + } + + for(int i = 0; i < MAX_ENTITIES; i++) + { + struct Entity* entity = &scene->entities[i]; + if(!entity->active) continue; + } + + if(scene->player.base.transform.is_modified) + { + vec3 abs_pos = {0.f, 0.f, 0.f}; + vec3 abs_fwd = {0.f, 0.f, -1.f}; + vec3 abs_up = {0.f, 1.f, 0.f}; + transform_get_absolute_position(&scene->player, &abs_pos); + transform_get_absolute_forward(&scene->player, &abs_fwd); + transform_get_absolute_up(&scene->player, &abs_up); + + platform->sound.listener_update(abs_pos.x, abs_pos.y, abs_pos.z, + abs_fwd.x, abs_fwd.y, abs_fwd.z, + abs_up.x, abs_up.y, abs_up.z); + scene->player.base.transform.is_modified = false; + } } struct Entity* scene_entity_create(struct Scene* scene, const char* name, struct Entity* parent) { - assert(scene); - - struct Entity* new_entity = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) - { - struct Entity* entity = &scene->entities[i]; - if(!entity->active) - { - new_entity = entity; - break; - } - } - - if(new_entity) - { - if(!parent) - parent = &scene->root_entity; - entity_init(new_entity, name, parent); - } - else - { - log_error("scene:entity_create", "Max entity limit reached!"); - } - - return new_entity; + assert(scene); + + struct Entity* new_entity = NULL; + for(int i = 0; i < MAX_ENTITIES; i++) + { + struct Entity* entity = &scene->entities[i]; + if(!entity->active) + { + new_entity = entity; + break; + } + } + + if(new_entity) + { + if(!parent) + parent = &scene->root_entity; + entity_init(new_entity, name, parent); + } + else + { + log_error("scene:entity_create", "Max entity limit reached!"); + } + + return new_entity; } struct Light* scene_light_create(struct Scene* scene, const char* name, struct Entity* parent, int light_type) { - assert(scene); - struct Light* new_light = NULL; - for(int i = 0; i < MAX_LIGHTS; i++) - { - struct Light* light = &scene->lights[i]; - if(!light->base.active) - { - new_light = light; - break; - } - } - - if(new_light) - { - entity_init(&new_light->base, name, parent ? parent : &scene->root_entity); - new_light->base.type = ET_LIGHT; - light_init(new_light, light_type); - } - else - { - log_error("scene:light_create", "Max light limit reached!"); - } - - return new_light; + assert(scene); + struct Light* new_light = NULL; + for(int i = 0; i < MAX_LIGHTS; i++) + { + struct Light* light = &scene->lights[i]; + if(!light->base.active) + { + new_light = light; + break; + } + } + + if(new_light) + { + entity_init(&new_light->base, name, parent ? parent : &scene->root_entity); + new_light->base.type = ET_LIGHT; + light_init(new_light, light_type); + } + else + { + log_error("scene:light_create", "Max light limit reached!"); + } + + return new_light; } struct Camera* scene_camera_create(struct Scene* scene, const char* name, struct Entity* parent, int width, int height) { - assert(scene); - struct Camera* new_camera = NULL; - for(int i = 0; i < MAX_CAMERAS; i++) - { - struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) - { - new_camera = camera; - break; - } - } - - if(new_camera) - { - entity_init(&new_camera->base, name, parent ? parent : &scene->root_entity); - new_camera->base.type = ET_CAMERA; - camera_init(new_camera, width, height); - } - else - { - log_error("scene:camera_create", "Max camera limit reached!"); - } - - return new_camera; + assert(scene); + struct Camera* new_camera = NULL; + for(int i = 0; i < MAX_CAMERAS; i++) + { + struct Camera* camera = &scene->cameras[i]; + if(!camera->base.active) + { + new_camera = camera; + break; + } + } + + if(new_camera) + { + entity_init(&new_camera->base, name, parent ? parent : &scene->root_entity); + new_camera->base.type = ET_CAMERA; + camera_init(new_camera, width, height); + } + else + { + log_error("scene:camera_create", "Max camera limit reached!"); + } + + return new_camera; } -struct Static_Model* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type) +struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type) { - assert(scene); - struct Static_Mesh* new_static_mesh = NULL; - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - struct Static_Mesh* static_mesh = &scene->static_meshes[i]; - if(!static_mesh->base.active) - { - new_static_mesh = static_mesh; - break; - } - } - - if(new_static_mesh) - { - entity_init(&new_static_mesh->base, name, parent ? parent : &scene->root_entity); - new_static_mesh->base.type = ET_STATIC_MESH; - model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type); - // TODO: handle creating collision mesh for the model at creation - } - else - { - log_error("scene:model_create", "Max model limit reached!"); - } - - return new_static_mesh; + assert(scene); + struct Static_Mesh* new_static_mesh = NULL; + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* static_mesh = &scene->static_meshes[i]; + if(!static_mesh->base.active) + { + new_static_mesh = static_mesh; + break; + } + } + + if(new_static_mesh) + { + entity_init(&new_static_mesh->base, name, parent ? parent : &scene->root_entity); + new_static_mesh->base.type = ET_STATIC_MESH; + model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type); + // TODO: handle creating collision mesh for the model at creation + } + else + { + log_error("scene:model_create", "Max model limit reached!"); + } + + return new_static_mesh; } struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char* name, struct Entity* parent, const char* filename, int type, bool loop, bool play) { - assert(scene && filename); - struct Sound_Source* new_sound_source = NULL; - for(int i = 0; i < MAX_SOUND_SOURCES; i++) - { - struct Sound_Source* sound_source = &scene->static_meshes[i]; - if(!sound_source->base.active) - { - new_sound_source = sound_source; - break; - } - } - - if(new_sound_source) - { - entity_init(&new_sound_source->base, name, parent ? parent : &scene->root_entity); - new_sound_source->base.type = ET_SOUND_SOURCE; - struct Entity* entity = &new_sound_source->base; - - new_sound_source->source_buffer = platform->sound.source_create(filename, type); - if(!new_sound_source->source_buffer) - { - log_error("entity:sync_sound_params", "Failed to load file '%s' to provide sound source for entity %s", filename, entity->name); - new_sound_source->source_instance = 0; - return new_sound_source; - } - - new_sound_source->source_instance = platform->sound.source_instance_create(new_sound_source->source_buffer, true); - vec3 abs_pos = {0.f, 0.f, 0.f}; - vec3 abs_fwd = {0.f, 0.f, -1.f}; - vec3 abs_up = {0.f, 1.f, 0.f}; - transform_get_absolute_position(entity, &abs_pos); - transform_get_absolute_forward(entity, &abs_fwd); - transform_get_absolute_up(entity, &abs_up); - platform->sound.source_instance_update_position(new_sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); - - new_sound_source->loop = loop; - new_sound_source->min_distance = 0.f; - new_sound_source->max_distance = 10.f; - new_sound_source->playing = play; - new_sound_source->attenuation_type = SA_INVERSE; - new_sound_source->rolloff_factor = 0.95f; - new_sound_source->volume = 1.f; - new_sound_source->type = type; - - platform->sound.source_instance_loop_set(new_sound_source->source_instance, new_sound_source->loop); - platform->sound.source_instance_min_max_distance_set(new_sound_source->source_instance, new_sound_source->min_distance, new_sound_source->max_distance); - platform->sound.source_instance_attenuation_set(new_sound_source->source_instance, new_sound_source->attenuation_type, new_sound_source->rolloff_factor); - platform->sound.source_instance_volume_set(new_sound_source->source_instance, new_sound_source->volume); - - platform->sound.update_3d(); - if(new_sound_source->playing) platform->sound.source_instance_play(new_sound_source->source_instance); - } - else - { - log_error("scene:sound_source_create", "Max sound source limit reached!"); - } - - return new_sound_source; + assert(scene && filename); + struct Sound_Source* new_sound_source = NULL; + for(int i = 0; i < MAX_SOUND_SOURCES; i++) + { + struct Sound_Source* sound_source = &scene->static_meshes[i]; + if(!sound_source->base.active) + { + new_sound_source = sound_source; + break; + } + } + + if(new_sound_source) + { + entity_init(&new_sound_source->base, name, parent ? parent : &scene->root_entity); + new_sound_source->base.type = ET_SOUND_SOURCE; + struct Entity* entity = &new_sound_source->base; + + new_sound_source->source_buffer = platform->sound.source_create(filename, type); + if(!new_sound_source->source_buffer) + { + log_error("entity:sync_sound_params", "Failed to load file '%s' to provide sound source for entity %s", filename, entity->name); + new_sound_source->source_instance = 0; + return new_sound_source; + } + + new_sound_source->source_instance = platform->sound.source_instance_create(new_sound_source->source_buffer, true); + vec3 abs_pos = {0.f, 0.f, 0.f}; + vec3 abs_fwd = {0.f, 0.f, -1.f}; + vec3 abs_up = {0.f, 1.f, 0.f}; + transform_get_absolute_position(entity, &abs_pos); + transform_get_absolute_forward(entity, &abs_fwd); + transform_get_absolute_up(entity, &abs_up); + platform->sound.source_instance_update_position(new_sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); + + new_sound_source->loop = loop; + new_sound_source->min_distance = 0.f; + new_sound_source->max_distance = 10.f; + new_sound_source->playing = play; + new_sound_source->attenuation_type = SA_INVERSE; + new_sound_source->rolloff_factor = 0.95f; + new_sound_source->volume = 1.f; + new_sound_source->type = type; + + platform->sound.source_instance_loop_set(new_sound_source->source_instance, new_sound_source->loop); + platform->sound.source_instance_min_max_distance_set(new_sound_source->source_instance, new_sound_source->min_distance, new_sound_source->max_distance); + platform->sound.source_instance_attenuation_set(new_sound_source->source_instance, new_sound_source->attenuation_type, new_sound_source->rolloff_factor); + platform->sound.source_instance_volume_set(new_sound_source->source_instance, new_sound_source->volume); + + platform->sound.update_3d(); + if(new_sound_source->playing) platform->sound.source_instance_play(new_sound_source->source_instance); + } + else + { + log_error("scene:sound_source_create", "Max sound source limit reached!"); + } + + return new_sound_source; } void scene_entity_remove(struct Scene* scene, struct Entity* entity) { - assert(scene && entity && entity->id >= 0); + assert(scene && entity && entity->id >= 0); - if(!entity->active) return; + if(!entity->active) return; - transform_destroy(entity); - entity->active = false; - entity->editor_selected = false; - entity->marked_for_deletion = false; - memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); + transform_destroy(entity); + entity->active = false; + entity->editor_selected = false; + entity->marked_for_deletion = false; + memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); } void scene_light_remove(struct Scene* scene, struct Light* light) { - assert(scene && light); - scene_entity_remove(scene, &light->base); + assert(scene && light); + scene_entity_remove(scene, &light->base); } void scene_camera_remove(struct Scene* scene, struct Camera* camera) { - assert(scene && camera); - scene_entity_remove(scene, &camera->base); + assert(scene && camera); + scene_entity_remove(scene, &camera->base); } void scene_static_mesh_remove(struct Scene* scene, struct Static_Mesh* mesh) { - assert(scene && mesh); + assert(scene && mesh); - mesh->collision.on_collision = NULL; - if(mesh->collision.collision_shape) platform->physics.cs_remove(mesh->collision.collision_shape); - if(mesh->collision.rigidbody) platform->physics.body_remove(mesh->collision.rigidbody); + mesh->collision.on_collision = NULL; + if(mesh->collision.collision_shape) platform->physics.cs_remove(mesh->collision.collision_shape); + if(mesh->collision.rigidbody) platform->physics.body_remove(mesh->collision.rigidbody); - model_reset(&mesh->model, mesh); - scene_entity_remove(scene, &mesh->base); + model_reset(&mesh->model, mesh); + scene_entity_remove(scene, &mesh->base); } void scene_sound_source_remove(struct Scene* scene, struct Sound_Source* source) { - assert(scene && source); + assert(scene && source); - platform->sound.source_instance_destroy(source->source_instance); - source->source_instance = 0; - scene_entity_remove(scene, &source->base); + platform->sound.source_instance_destroy(source->source_instance); + source->source_instance = 0; + scene_entity_remove(scene, &source->base); } struct Entity* scene_entity_find(struct Scene* scene, const char* name) { - assert(scene && name); - struct Entity* entity = NULL; + assert(scene && name); + struct Entity* entity = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->entities[i].name, MAX_ENTITY_NAME_LEN) == 0) { - if(strncmp(name, scene->entities[i].name, MAX_ENTITY_NAME_LEN) == 0) - { - entity = &scene->entities[i]; - break; - } + entity = &scene->entities[i]; + break; } + } - return entity; + return entity; } struct Light* scene_light_find(struct Scene* scene, const char* name) { - assert(scene && name); - struct Light* light = NULL; + assert(scene && name); + struct Light* light = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->lights[i].base.name, MAX_ENTITY_NAME_LEN) == 0) { - if(strncmp(name, scene->lights[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - light = &scene->lights[i]; - break; - } + light = &scene->lights[i]; + break; } + } - return light; + return light; } struct Camera* scene_camera_find(struct Scene* scene, const char* name) { - assert(scene && name); - struct Camera* camera = NULL; + assert(scene && name); + struct Camera* camera = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->cameras[i].base.name, MAX_ENTITY_NAME_LEN) == 0) { - if(strncmp(name, scene->cameras[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - camera = &scene->cameras[i]; - break; - } + camera = &scene->cameras[i]; + break; } + } - return camera; + return camera; } struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* name) { - assert(scene && name); - struct Static_Mesh* static_mesh = NULL; + assert(scene && name); + struct Static_Mesh* static_mesh = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->static_meshes[i].base.name, MAX_ENTITY_NAME_LEN) == 0) { - if(strncmp(name, scene->static_meshes[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - static_mesh = &scene->static_meshes[i]; - break; - } + static_mesh = &scene->static_meshes[i]; + break; } + } - return static_mesh; + return static_mesh; } struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name) { - assert(scene && name); - struct Sound_Source* sound_source = NULL; + assert(scene && name); + struct Sound_Source* sound_source = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->sound_sources[i].base.name, MAX_ENTITY_NAME_LEN) == 0) { - if(strncmp(name, scene->sound_sources[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - sound_source = &scene->sound_sources[i]; - break; - } + sound_source = &scene->sound_sources[i]; + break; } + } - return sound_source; + return sound_source; } struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) { - assert(scene && id != -1 && type < ET_MAX); - - struct Entity* entity = NULL; - - switch(type) - { - case ET_DEFAULT: entity = &scene->entities[id]; break; - case ET_CAMERA: entity = &scene->cameras[id]; break; - case ET_LIGHT: entity = &scene->lights[id]; break; - case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; - case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; - case ET_PLAYER: entity = &scene->player; break; - case ET_ROOT: entity = &scene->root_entity; break; - } - - return entity; + assert(scene && id != -1 && type < ET_MAX); + + struct Entity* entity = NULL; + + switch(type) + { + case ET_DEFAULT: entity = &scene->entities[id]; break; + case ET_CAMERA: entity = &scene->cameras[id]; break; + case ET_LIGHT: entity = &scene->lights[id]; break; + case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; + case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; + case ET_PLAYER: entity = &scene->player; break; + case ET_ROOT: entity = &scene->root_entity; break; + } + + return entity; } void* scene_find(struct Scene* scene, const char* name) { - void* entity = NULL; + void* entity = NULL; - entity = scene_entity_find(scene, name); - if(entity) return entity; + entity = scene_entity_find(scene, name); + if(entity) return entity; - entity = scene_light_find(scene, name); - if(entity) return entity; + entity = scene_light_find(scene, name); + if(entity) return entity; - entity = scene_camera_find(scene, name); - if(entity) return entity; + entity = scene_camera_find(scene, name); + if(entity) return entity; - entity = scene_static_mesh_find(scene, name); - if(entity) return entity; + entity = scene_static_mesh_find(scene, name); + if(entity) return entity; - return entity; + return entity; } void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity) { - assert(scene && entity); - transform_parent_set(entity, &scene->root_entity, true); + assert(scene && entity); + transform_parent_set(entity, &scene->root_entity, true); } void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent) { - assert(scene && entity && parent); - transform_parent_set(entity, parent, true); + assert(scene && entity && parent); + transform_parent_set(entity, parent, true); } void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results) { - assert(out_results); + assert(out_results); - memset(&out_results[0], '\0', sizeof(struct Entity*) * MAX_RAYCAST_ENTITIES_INTERSECT); - out_results->num_entities_intersected = 0; + memset(&out_results[0], '\0', sizeof(struct Entity*) * MAX_RAYCAST_ENTITIES_INTERSECT); + out_results->num_entities_intersected = 0; - for(int i = 0; i < MAX_STATIC_MESHES; i++) + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* mesh = &scene->static_meshes[i]; + if(!mesh->base.active) continue; + vec3 abs_pos = {0.f}; + transform_get_absolute_position(mesh, &abs_pos); + + struct Geometry* geometry = geom_get(mesh->model.geometry_index); + if(bv_intersect_sphere_ray(&geometry->bounding_sphere, &abs_pos, ray)) { - struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active) continue; - vec3 abs_pos = {0.f}; - transform_get_absolute_position(mesh, &abs_pos); - - struct Geometry* geometry = geom_get(mesh->model.geometry_index); - if(bv_intersect_sphere_ray(&geometry->bounding_sphere, &abs_pos, ray)) - { - out_results->entities_intersected[out_results->num_entities_intersected] = &mesh->base; - out_results->num_entities_intersected++; - } + out_results->entities_intersected[out_results->num_entities_intersected] = &mesh->base; + out_results->num_entities_intersected++; } + } } @@ -598,104 +606,104 @@ void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Re //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool scene_load(const char* filename, int directory_type) +bool scene_load_(const char* filename, int directory_type) { - // FILE* entity_file = platform->file.open(directory_type, filename, "r"); - //if(!entity_file) - //{ - // log_error("scene:load", "Failed to open scenefile %s for reading", filename); - // return false; - //} - - //int count = 0; - //int eof_char = -1; - //while(!feof(entity_file)) - //{ - // if(eof_char != -1) ungetc(eof_char, entity_file); - // struct Entity* new_entity = NULL; - // new_entity = entity_read(entity_file); - // if(!new_entity) - // { - // log_error("scene:load", "Error reading entity"); - // } - // else - // { - // log_message("Loaded %s", new_entity->name); - // count++; - // } - // eof_char = fgetc(entity_file); - // /* To check end of file, we get the next character and before beginning - // loop we check if eof occured, feof only returns true if the last read - // was an eof. If it wasn't eof then we return the character back to the - // stream and carry on. */ - //} - - //log_message("%d entites loaded from %s", count, filename); - //fclose(entity_file); - return entity_load(filename, directory_type); + // FILE* entity_file = platform->file.open(directory_type, filename, "r"); + //if(!entity_file) + //{ + // log_error("scene:load", "Failed to open scenefile %s for reading", filename); + // return false; + //} + + //int count = 0; + //int eof_char = -1; + //while(!feof(entity_file)) + //{ + // if(eof_char != -1) ungetc(eof_char, entity_file); + // struct Entity* new_entity = NULL; + // new_entity = entity_read(entity_file); + // if(!new_entity) + // { + // log_error("scene:load", "Error reading entity"); + // } + // else + // { + // log_message("Loaded %s", new_entity->name); + // count++; + // } + // eof_char = fgetc(entity_file); + // /* To check end of file, we get the next character and before beginning + // loop we check if eof occured, feof only returns true if the last read + // was an eof. If it wasn't eof then we return the character back to the + // stream and carry on. */ + //} + + //log_message("%d entites loaded from %s", count, filename); + //fclose(entity_file); + return entity_load(filename, directory_type); } -bool scene_save(const char* filename, int directory_type) +bool scene_save_(const char* filename, int directory_type) { - bool success = false; - /*FILE* scene_file = platform->file.open(directory_type, filename, "w"); - if(!scene_file) - { - log_error("scene:save", "Failed to create scenefile %s for writing", filename); - return false; - } + bool success = false; + /*FILE* scene_file = platform->file.open(directory_type, filename, "w"); + if(!scene_file) + { + log_error("scene:save", "Failed to create scenefile %s for writing", filename); + return false; + } - struct Parser* parser = parser_new(); - if(!parser) - { - log_error("scene:save", "Could not create Parser"); - fclose(scene_file); - return false; - } - - int* entities_to_write = array_new(int); - array_push(entities_to_write, root_node, int); - - bool done = false; - int count = 0; - while(!done) - { - struct Entity* entity = entity_get(entities_to_write[0]); - struct Parser_Object* object = parser_object_new(parser, PO_ENTITY); - if(!object) - { - log_error("scene:save", "Failed to create parser object for %s", entity->name); - continue; - } - - if(!entity_write(entity, object)) - { - log_error("scene:save", "Failed to write '%s' into parser object", entity->name); - continue; - } - - log_message("Entity '%s' written to file", entity->name); - count++; - for(int i = 0; i < array_len(entity->transform.children); i++) - array_push(entities_to_write, entity->transform.children[i], int); - - array_remove_at(entities_to_write, 0); - if(array_len(entities_to_write) == 0) done = true; - } - - if(parser_write_objects(parser, scene_file, filename)) - { - log_message("%d entities written to %s", count, filename); - } - else - { - log_error("scene:save", "Failed to write scene to %s", filename); - success = false; - } - - array_free(entities_to_write); - parser_free(parser); - fclose(scene_file);*/ + struct Parser* parser = parser_new(); + if(!parser) + { + log_error("scene:save", "Could not create Parser"); + fclose(scene_file); + return false; + } + + int* entities_to_write = array_new(int); + array_push(entities_to_write, root_node, int); + + bool done = false; + int count = 0; + while(!done) + { + struct Entity* entity = entity_get(entities_to_write[0]); + struct Parser_Object* object = parser_object_new(parser, PO_ENTITY); + if(!object) + { + log_error("scene:save", "Failed to create parser object for %s", entity->name); + continue; + } + + if(!entity_write(entity, object)) + { + log_error("scene:save", "Failed to write '%s' into parser object", entity->name); + continue; + } + + log_message("Entity '%s' written to file", entity->name); + count++; + for(int i = 0; i < array_len(entity->transform.children); i++) + array_push(entities_to_write, entity->transform.children[i], int); + + array_remove_at(entities_to_write, 0); + if(array_len(entities_to_write) == 0) done = true; + } + + if(parser_write_objects(parser, scene_file, filename)) + { + log_message("%d entities written to %s", count, filename); + } + else + { + log_error("scene:save", "Failed to write scene to %s", filename); + success = false; + } + + array_free(entities_to_write); + parser_free(parser); + fclose(scene_file);*/ - return success; + return success; } diff --git a/src/libsymmetry/scene.h b/src/libsymmetry/scene.h index 52aaef9..5589237 100644 --- a/src/libsymmetry/scene.h +++ b/src/libsymmetry/scene.h @@ -15,15 +15,15 @@ struct Ray; struct Scene { - struct Render_Settings renderer_profile; - struct Entity root_entity; - struct Player player; - struct Entity entities[MAX_ENTITIES]; - struct Static_Mesh static_meshes[MAX_STATIC_MESHES]; - struct Camera cameras[MAX_CAMERAS]; - struct Light lights[MAX_LIGHTS]; - struct Sound_Source sound_sources[MAX_SOUND_SOURCES]; - int active_camera_index; + struct Render_Settings renderer_profile; + struct Entity root_entity; + struct Player player; + struct Entity entities[MAX_ENTITIES]; + struct Static_Mesh static_meshes[MAX_STATIC_MESHES]; + struct Camera cameras[MAX_CAMERAS]; + struct Light lights[MAX_LIGHTS]; + struct Sound_Source sound_sources[MAX_SOUND_SOURCES]; + int active_camera_index; }; void scene_init(struct Scene* scene); @@ -36,7 +36,7 @@ void scene_post_update(struct Scene* scene); struct Entity* scene_entity_create(struct Scene* scene, const char* name, struct Entity* parent); struct Light* scene_light_create(struct Scene* scene, const char* name, struct Entity* parent, int light_type); struct Camera* scene_camera_create(struct Scene* scene, const char* name, struct Entity* parent, int width, int height); -struct Static_Model* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type); +struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type); struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char* name, struct Entity* parent, const char* filename, int type, bool loop, bool play); void scene_entity_remove(struct Scene* scene, struct Entity* entity);