Completed loading and saving entities using the new Parser and Parser_Objects

dev
Shariq Shah 8 years ago
parent 114d44371e
commit 1a61236082
  1. 6
      README.md
  2. 272
      assets/test.symtres
  3. BIN
      build/genie.exe
  4. 32
      src/common/hashmap.c
  5. 1
      src/common/hashmap.h
  6. 6
      src/common/parser.c
  7. 1
      src/game/platform.c
  8. 11
      src/game/sound.c
  9. 834
      src/libsymmetry/entity.c
  10. 5
      src/libsymmetry/entity.h
  11. 13
      src/libsymmetry/game.c
  12. 2
      src/libsymmetry/material.c
  13. 14
      src/libsymmetry/model.c
  14. 66
      src/libsymmetry/scene.c

@ -155,7 +155,10 @@
- ## TODO - ## TODO
- Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that - Implment writing to file through the new Parser and Parser_Object
- Change Config to read/write using new Parser logic
- Store Materials in new format supported by parser
- Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards
- Implement sound/listener loading from scene file - Implement sound/listener loading from scene file
- Finish loading scene from file - Finish loading scene from file
- Update makefiles to be able to compile the code in it's current state - Update makefiles to be able to compile the code in it's current state
@ -325,3 +328,4 @@
* Fixed several bugs with entity loading * Fixed several bugs with entity loading
* Removed duplicate parsing logic * Removed duplicate parsing logic
* Fixed bugs in stripping key name for input map * Fixed bugs in stripping key name for input map
* Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that

@ -0,0 +1,272 @@
Entity
{
name: ROOT
type: 2
is_listener: false
renderable: false
parent: NONE
position: 0.00000 0.00000 0.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
}
Entity
{
name: player
type: 3
is_listener: false
renderable: false
parent: ROOT
position: 10.00000 5.00000 100.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
ortho: false
resizeable: true
fov: 60.00000
nearz: 0.10000
farz: 1000.00000
clear_color: 0.30000 0.60000 0.90000 1.00000
has_fbo: true
fbo_height: 768
fbo_width: 1024
fbo_has_render_tex: true
fbo_has_depth_tex: true
}
Entity
{
name: Model_Entity
type: 5
is_listener: false
renderable: true
parent: ROOT
position: 0.00000 0.00000 -5.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Ground
type: 5
is_listener: false
renderable: true
parent: ROOT
position: 0.00000 -5.00000 0.00000
scale: 400.00000 2.00000 400.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 20.00000 0.00000 60.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 1
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 20
intensity: 1.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 1.00000 0.12500 0.33333
}
Entity
{
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 60.00000 0.00000 40.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 1
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 20
intensity: 1.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 0.33333 0.20000 0.50000
}
Entity
{
name: Light_Ent
type: 4
is_listener: false
renderable: false
parent: ROOT
position: 20.00000 0.00000 20.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
light_type: 1
outer_angle: 0.52360
inner_angle: 0.34907
falloff: 1.50000
radius: 20
intensity: 1.00000
depth_bias: 0.00050
valid: true
cast_shadow: false
pcf_enabled: false
color: 1.00000 0.14286 1.00000
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 8.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 8.00000 0.00000 3.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 7.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 3.00000 0.00000 2.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 2.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 10.00000 0.00000 7.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 6.00000 0.00000 4.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}
Entity
{
name: Suzanne
type: 5
is_listener: false
renderable: true
parent: Model_Entity
position: 2.00000 0.00000 6.00000
scale: 1.00000 1.00000 1.00000
rotation: 0.00000 0.00000 0.00000 1.00000
material: Blinn_Phong
geometry: default.pamesh
}

Binary file not shown.

@ -126,6 +126,11 @@ void hashmap_value_remove(struct Hashmap* hashmap, const char* key)
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);
}
void hashmap_float_set(struct Hashmap* hashmap, const char* key, const float value) void hashmap_float_set(struct Hashmap* hashmap, const char* key, const float value)
{ {
@ -219,55 +224,64 @@ void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value)
float hashmap_float_get(const struct Hashmap* hashmap, const char* key) float hashmap_float_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_float;
} }
int hashmap_int_get(const struct Hashmap* hashmap, const char* key) int hashmap_int_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_int;
} }
double hashmap_double_get(const struct Hashmap* hashmap, const char* key) double hashmap_double_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_double;
} }
bool hashmap_bool_get(const struct Hashmap* hashmap, const char* key) bool hashmap_bool_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_bool;
} }
vec2 hashmap_vec2_get(const struct Hashmap* hashmap, const char* key) vec2 hashmap_vec2_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_vec2;
} }
vec3 hashmap_vec3_get(const struct Hashmap* hashmap, const char* key) vec3 hashmap_vec3_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_vec3;
} }
vec4 hashmap_vec4_get(const struct Hashmap* hashmap, const char* key) vec4 hashmap_vec4_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_vec4;
} }
quat hashmap_quat_get(const struct Hashmap* hashmap, const char* key) quat hashmap_quat_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_quat;
} }
const mat4* hashmap_mat4_get(const struct Hashmap* hashmap, const char* key) const mat4* hashmap_mat4_get(const struct Hashmap* hashmap, const char* key)
{ {
const struct Variant* variant = hashmap_value_get(hashmap, 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; return variant->val_mat4;
} }

@ -14,6 +14,7 @@ struct Variant;
struct Hashmap* hashmap_new(void); struct Hashmap* hashmap_new(void);
void hashmap_free(struct Hashmap* hashmap); void hashmap_free(struct Hashmap* hashmap);
void hashmap_value_remove(struct Hashmap* hashmap, const char* key); 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); 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); struct Variant* hashmap_value_get(const struct Hashmap* hashmap, const char* key);

@ -206,8 +206,8 @@ struct Parser* parser_load_objects(FILE* file, const char* filename)
char value_str[MAX_VALUE_LEN]; char value_str[MAX_VALUE_LEN];
memset(format_str, '\0', 64); 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[^\r\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN);
char* line = strtok(obj_str, "\n"); char* line = strtok(obj_str, "\r\n");
do do
{ {
memset(key_str, '\0', HASH_MAX_KEY_LEN); memset(key_str, '\0', HASH_MAX_KEY_LEN);
@ -228,7 +228,7 @@ struct Parser* parser_load_objects(FILE* file, const char* filename)
} }
hashmap_str_set(object->data, key_str, value_str); hashmap_str_set(object->data, key_str, value_str);
} }
while((line = strtok(NULL, "\n")) != NULL); while((line = strtok(NULL, "\r\n")) != NULL);
//log_to_stdout("Object found\nType: %s\n%s\n\n", type_str, obj_str); //log_to_stdout("Object found\nType: %s\n%s\n\n", type_str, obj_str);
} }

@ -9,6 +9,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <ctype.h>
struct Window struct Window
{ {

@ -10,11 +10,12 @@
#include <AL/alc.h> #include <AL/alc.h>
#include <AL/alext.h> #include <AL/alext.h>
#if defined(_MSC_VER) //#if defined(_MSC_VER)
#include <SDL.h> // #include <SDL.h>
#else //#else
#include <SDL2/SDL.h> // #include <SDL2/SDL.h>
#endif //#endif
#include <SDL.h>
struct Sound_State struct Sound_State
{ {

@ -11,6 +11,8 @@
#include "framebuffer.h" #include "framebuffer.h"
#include "../common/variant.h" #include "../common/variant.h"
#include "../common/common.h" #include "../common/common.h"
#include "../common/parser.h"
#include "../common/hashmap.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -206,24 +208,25 @@ bool entity_write(struct Entity* entity, FILE* file)
} }
/* First write all properties common to all entity types */ /* First write all properties common to all entity types */
fprintf(file, "name: %s\n", entity->name); fprintf(file, "Entity\n{\n");
fprintf(file, "type: %d\n", entity->type); fprintf(file, "\tname: %s\n", entity->name);
fprintf(file, "is_listener: %s\n", entity->is_listener ? "true" : "false"); fprintf(file, "\ttype: %d\n", entity->type);
fprintf(file, "renderable: %s\n", entity->renderable ? "true" : "false"); fprintf(file, "\tis_listener: %s\n", entity->is_listener ? "true" : "false");
fprintf(file, "\trenderable: %s\n", entity->renderable ? "true" : "false");
struct Entity* parent = entity_get_parent(entity->id); struct Entity* parent = entity_get_parent(entity->id);
fprintf(file, "parent: %s\n", parent ? parent->name : "NONE"); fprintf(file, "\tparent: %s\n", parent ? parent->name : "NONE");
/* Transform */ /* Transform */
fprintf(file, "position: %.5f %.5f %.5f\n", fprintf(file, "\tposition: %.5f %.5f %.5f\n",
entity->transform.position.x, entity->transform.position.x,
entity->transform.position.y, entity->transform.position.y,
entity->transform.position.z); entity->transform.position.z);
fprintf(file, "scale: %.5f %.5f %.5f\n", fprintf(file, "\tscale: %.5f %.5f %.5f\n",
entity->transform.scale.x, entity->transform.scale.x,
entity->transform.scale.y, entity->transform.scale.y,
entity->transform.scale.z); entity->transform.scale.z);
fprintf(file, "rotation: %.5f %.5f %.5f %.5f\n", fprintf(file, "\trotation: %.5f %.5f %.5f %.5f\n",
entity->transform.rotation.x, entity->transform.rotation.x,
entity->transform.rotation.y, entity->transform.rotation.y,
entity->transform.rotation.z, entity->transform.rotation.z,
@ -233,27 +236,27 @@ bool entity_write(struct Entity* entity, FILE* file)
{ {
case ET_CAMERA: case ET_CAMERA:
{ {
fprintf(file, "ortho: %s\n", entity->camera.ortho ? "true" : "false"); fprintf(file, "\tortho: %s\n", entity->camera.ortho ? "true" : "false");
fprintf(file, "resizeable: %s\n", entity->camera.resizeable ? "true" : "false"); fprintf(file, "\tresizeable: %s\n", entity->camera.resizeable ? "true" : "false");
fprintf(file, "fov: %.5f\n", entity->camera.fov); fprintf(file, "\tfov: %.5f\n", entity->camera.fov);
fprintf(file, "nearz: %.5f\n", entity->camera.nearz); fprintf(file, "\tnearz: %.5f\n", entity->camera.nearz);
fprintf(file, "farz: %.5f\n", entity->camera.farz); fprintf(file, "\tfarz: %.5f\n", entity->camera.farz);
fprintf(file, "clear_color: %.5f %.5f %.5f %.5f\n", fprintf(file, "\tclear_color: %.5f %.5f %.5f %.5f\n",
entity->camera.clear_color.x, entity->camera.clear_color.x,
entity->camera.clear_color.y, entity->camera.clear_color.y,
entity->camera.clear_color.z, entity->camera.clear_color.z,
entity->camera.clear_color.w); entity->camera.clear_color.w);
if(entity->camera.fbo != -1) if(entity->camera.fbo != -1)
{ {
fprintf(file, "has_fbo: true\n"); fprintf(file, "\thas_fbo: true\n");
fprintf(file, "fbo_height: %d\n", framebuffer_height_get(entity->camera.fbo)); fprintf(file, "\tfbo_height: %d\n", framebuffer_height_get(entity->camera.fbo));
fprintf(file, "fbo_width: %d\n", framebuffer_width_get(entity->camera.fbo)); fprintf(file, "\tfbo_width: %d\n", framebuffer_width_get(entity->camera.fbo));
fprintf(file, "fbo_has_render_tex: %s\n", entity->camera.render_tex == -1 ? "false" : "true"); fprintf(file, "\tfbo_has_render_tex: %s\n", entity->camera.render_tex == -1 ? "false" : "true");
fprintf(file, "fbo_has_depth_tex: %s\n", entity->camera.depth_tex == -1 ? "false" : "true"); fprintf(file, "\tfbo_has_depth_tex: %s\n", entity->camera.depth_tex == -1 ? "false" : "true");
} }
else else
{ {
fprintf(file, "has_fbo: false\n"); fprintf(file, "\thas_fbo: false\n");
} }
break; break;
} }
@ -262,23 +265,23 @@ bool entity_write(struct Entity* entity, FILE* file)
/* TODO: Change this after adding proper support for exported models from blender */ /* TODO: Change this after adding proper support for exported models from blender */
struct Material* material = material_get(entity->model.material); struct Material* material = material_get(entity->model.material);
struct Geometry* geom = geom_get(entity->model.geometry_index); struct Geometry* geom = geom_get(entity->model.geometry_index);
fprintf(file, "material: %s\n", material->name); fprintf(file, "\tmaterial: %s\n", material->name);
fprintf(file, "geometry: %s\n", geom->filename); fprintf(file, "\tgeometry: %s\n", geom->filename);
break; break;
} }
case ET_LIGHT: case ET_LIGHT:
{ {
fprintf(file, "light_type: %d\n", entity->light.valid); fprintf(file, "\tlight_type: %d\n", entity->light.valid);
fprintf(file, "outer_angle: %.5f\n", entity->light.outer_angle); fprintf(file, "\touter_angle: %.5f\n", entity->light.outer_angle);
fprintf(file, "inner_angle: %.5f\n", entity->light.inner_angle); fprintf(file, "\tinner_angle: %.5f\n", entity->light.inner_angle);
fprintf(file, "falloff: %.5f\n", entity->light.falloff); fprintf(file, "\tfalloff: %.5f\n", entity->light.falloff);
fprintf(file, "radius: %d\n", entity->light.radius); fprintf(file, "\tradius: %d\n", entity->light.radius);
fprintf(file, "intensity: %.5f\n", entity->light.intensity); fprintf(file, "\tintensity: %.5f\n", entity->light.intensity);
fprintf(file, "depth_bias: %.5f\n", entity->light.depth_bias); fprintf(file, "\tdepth_bias: %.5f\n", entity->light.depth_bias);
fprintf(file, "valid: %s\n", entity->light.valid ? "true" : "false"); fprintf(file, "\tvalid: %s\n", entity->light.valid ? "true" : "false");
fprintf(file, "cast_shadow: %s\n", entity->light.cast_shadow ? "true" : "false"); fprintf(file, "\tcast_shadow: %s\n", entity->light.cast_shadow ? "true" : "false");
fprintf(file, "pcf_enabled: %s\n", entity->light.pcf_enabled ? "true" : "false"); fprintf(file, "\tpcf_enabled: %s\n", entity->light.pcf_enabled ? "true" : "false");
fprintf(file, "color: %.5f %.5f %.5f\n", fprintf(file, "\tcolor: %.5f %.5f %.5f\n",
entity->light.color.x, entity->light.color.x,
entity->light.color.y, entity->light.color.y,
entity->light.color.z); entity->light.color.z);
@ -286,13 +289,13 @@ bool entity_write(struct Entity* entity, FILE* file)
} }
case ET_SOUND_SOURCE: case ET_SOUND_SOURCE:
{ {
fprintf(file, "active: %s\n", entity->sound_source.active ? "true" : "false"); fprintf(file, "\tactive: %s\n", entity->sound_source.active ? "true" : "false");
fprintf(file, "relative: %s\n", entity->sound_source.relative ? "true" : "false"); fprintf(file, "\trelative: %s\n", entity->sound_source.relative ? "true" : "false");
break; break;
} }
}; };
fprintf(file, "\n"); fprintf(file, "}\n\n");
return true; return true;
} }
@ -314,334 +317,515 @@ bool entity_save(struct Entity* entity, const char* filename, int directory_type
return false; return false;
} }
struct Entity* entity_read(FILE* file) struct Entity* entity_read(struct Parser_Object* object)
{ {
if(!file) assert(object);
if(object->type != PO_ENTITY)
{ {
log_error("entity:read", "Invalid file handle"); log_error("entity:read", "Invalid object type");
return false; return NULL;
} }
struct Entity entity = const char* name = hashmap_str_get(object->data, "name");
const char* parent_name = hashmap_str_get(object->data, "parent");
int type = hashmap_int_get(object->data, "type");
if(!name)
{ {
.id = -1, log_error("entity:read", "No entity name provided");
.type = ET_NONE, return NULL;
.is_listener = false, }
.renderable = false,
.marked_for_deletion = false,
.name = "DEFAULT_ENTITY_NAME",
.editor_selected = 0
};
int current_line = 0; if(!parent_name)
char* material_name = NULL; {
char* entity_name = NULL; log_error("entity:read", "No parent name provided");
char* geometry_name = NULL; return NULL;
char* parent_name = NULL; }
int camera_fbo_width = -1;
int camera_fbo_height = -1;
char line_buffer[MAX_LINE_LEN];
char prop_str[MAX_ENTITY_PROP_NAME_LEN];
static struct Variant var_value = { .type = VT_NONE};
variant_free(&var_value); if(type < 0 || type >= ET_MAX)
memset(prop_str, '\0', MAX_ENTITY_PROP_NAME_LEN); {
memset(line_buffer, '\0', MAX_LINE_LEN); log_error("entity:read", "Invalid entity type");
return NULL;
}
while(fgets(line_buffer, MAX_LINE_LEN -1, file)) struct Entity* parent = entity_find(parent_name);
struct Entity* entity = entity_create(name, type, parent ? parent->id : -1);
if(!entity)
{ {
current_line++; log_error("entity:read", "Failed to create new entity");
memset(prop_str, '\0', MAX_ENTITY_PROP_NAME_LEN); return NULL;
}
if(line_buffer[0] == '#') continue; // Common entity properties
if(strlen(line_buffer) == 0 || isspace(line_buffer[0])) break; if(hashmap_value_exists(object->data, "is_listener"))
entity->is_listener = hashmap_bool_get(object->data, "is_listener");
else
entity->is_listener = false;
char* value_str = strstr(line_buffer, ":"); if(hashmap_value_exists(object->data, "renderable"))
if(!value_str) entity->renderable= hashmap_bool_get(object->data, "renderable");
{ else
log_warning("Malformed value in line %d", current_line); entity->renderable= false;
continue;
}
value_str++; /* Ignore the colon(:) and set the pointer after it */ // Transform properties
if(hashmap_value_exists(object->data, "position"))
{
vec3 position = hashmap_vec3_get(object->data, "position");
transform_translate(entity, &position, TS_PARENT);
}
if(sscanf(line_buffer, " %1024[^: ] : %*s", prop_str) != 1) if(hashmap_value_exists(object->data, "rotation"))
{ {
log_warning("Unable to read property name in line %d", current_line); quat rotation = hashmap_quat_get(object->data, "rotation");
continue; quat_assign(&entity->transform.rotation, &rotation);
} }
/* Common entity properties */ if(hashmap_value_exists(object->data, "scale"))
if(strncmp("name", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) {
{ vec3 scale = hashmap_vec3_get(object->data, "scale");
variant_from_str(&var_value, value_str, VT_STR); transform_scale(entity, &scale);
entity_name = str_new(var_value.val_str); }
//variant_copy_out(&entity.name, &var_value);
}
else if(strncmp("parent", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_STR);
parent_name = str_new(var_value.val_str);
//variant_copy_out(&entity.name, &var_value);
}
else if(strncmp("type", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_INT);
variant_copy_out(&entity.type, &var_value);
}
else if(strncmp("is_listener", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.is_listener, &var_value);
}
else if(strncmp("renderable", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.renderable, &var_value);
}
/* Transform */ switch(entity->type)
else if(strncmp("position", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) {
{ case ET_CAMERA:
variant_from_str(&var_value, value_str, VT_VEC3); {
variant_copy_out(&entity.transform.position, &var_value); bool has_fbo = false;
} bool fbo_has_depth_tex = false;
else if(strncmp("scale", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) bool fbo_has_render_tex = false;
{ int fbo_width = -1;
variant_from_str(&var_value, value_str, VT_VEC3); int fbo_height = -1;
variant_copy_out(&entity.transform.scale, &var_value);
}
else if(strncmp("rotation", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_QUAT);
variant_copy_out(&entity.transform.rotation, &var_value);
}
/* Camera */ if(hashmap_value_exists(object->data, "fov")) entity->camera.fov = hashmap_float_get(object->data, "fov");
else if(strncmp("ortho", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) if(hashmap_value_exists(object->data, "resizeable")) entity->camera.resizeable = hashmap_bool_get(object->data, "resizeable");
{ if(hashmap_value_exists(object->data, "nearz")) entity->camera.nearz = hashmap_float_get(object->data, "nearz");
variant_from_str(&var_value, value_str, VT_BOOL); if(hashmap_value_exists(object->data, "farz")) entity->camera.farz = hashmap_float_get(object->data, "farz");
variant_copy_out(&entity.camera.ortho, &var_value); if(hashmap_value_exists(object->data, "ortho")) entity->camera.ortho = hashmap_bool_get(object->data, "ortho");
} if(hashmap_value_exists(object->data, "has_fbo")) has_fbo = hashmap_bool_get(object->data, "has_fbo");
else if(strncmp("resizeable", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) if(hashmap_value_exists(object->data, "fbo_has_depth_tex")) fbo_has_depth_tex = hashmap_bool_get(object->data, "fbo_has_depth_tex");
{ if(hashmap_value_exists(object->data, "fbo_has_render_tex")) fbo_has_render_tex = hashmap_bool_get(object->data, "fbo_has_render_tex");
variant_from_str(&var_value, value_str, VT_BOOL); if(hashmap_value_exists(object->data, "fbo_width")) fbo_width = hashmap_int_get(object->data, "fbo_width");
variant_copy_out(&entity.camera.resizeable, &var_value); if(hashmap_value_exists(object->data, "fbo_height")) fbo_height = hashmap_int_get(object->data, "fbo_height");
} if(hashmap_value_exists(object->data, "clear_color"))
else if(strncmp("fov", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.camera.fov, &var_value);
}
else if(strncmp("nearz", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.camera.nearz, &var_value);
}
else if(strncmp("farz", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.camera.farz, &var_value);
}
else if(strncmp("has_fbo", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
entity.camera.fbo = var_value.val_bool ? 0 : -1;
}
else if(strncmp("fbo_height", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{ {
variant_from_str(&var_value, value_str, VT_INT); vec4 color = hashmap_vec4_get(object->data, "clear_color");
variant_copy_out(&camera_fbo_height, &var_value); vec4_assign(&entity->camera.clear_color, &color);
}
else if(strncmp("fbo_width", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_INT);
variant_copy_out(&camera_fbo_width, &var_value);
}
else if(strncmp("fbo_has_depth_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
entity.camera.depth_tex = var_value.val_bool ? 0 : -1;
}
else if(strncmp("fbo_has_render_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
entity.camera.render_tex = var_value.val_bool ? 0 : -1;
}
else if(strncmp("clear_color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_VEC4);
variant_copy_out(&entity.camera.clear_color, &var_value);
} }
/* Light */ float aspect_ratio = (float)fbo_width / (float)fbo_height;
else if(strncmp("light_type", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) entity->camera.aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio;
{
variant_from_str(&var_value, value_str, VT_INT);
variant_copy_out(&entity.light.type, &var_value);
}
else if(strncmp("outer_angle", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.light.outer_angle, &var_value);
}
else if(strncmp("inner_angle", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.light.inner_angle, &var_value);
}
else if(strncmp("falloff", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.light.falloff, &var_value);
}
else if(strncmp("radius", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_INT);
variant_copy_out(&entity.light.radius, &var_value);
}
else if(strncmp("intensity", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.light.intensity, &var_value);
}
else if(strncmp("depth_bias", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.light.depth_bias, &var_value);
}
else if(strncmp("valid", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.light.valid, &var_value);
}
else if(strncmp("cast_shadow", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.light.cast_shadow, &var_value);
}
else if(strncmp("pcf_enabled", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.light.pcf_enabled, &var_value);
}
else if(strncmp("color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_VEC3);
variant_copy_out(&entity.light.color, &var_value);
}
/* Model */ entity->camera.fbo = -1;
else if(strncmp("material", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) entity->camera.render_tex = -1;
{ entity->camera.depth_tex = -1;
variant_from_str(&var_value, value_str, VT_STR);
material_name = str_new(var_value.val_str);
}
else if(strncmp("geometry", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_STR);
geometry_name = str_new(var_value.val_str);
}
/* Sound Source */ if(has_fbo)
else if(strncmp("active", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.sound_source.active, &var_value);
}
else if(strncmp("relative", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.sound_source.relative, &var_value);
}
else if(strncmp("num_attached_buffers", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
{
variant_from_str(&var_value, value_str, VT_INT);
variant_copy_out(&entity.sound_source.num_attached_buffers, &var_value);
}
else
{ {
log_warning("Unknown entity property '%s' in line %d", prop_str, current_line); camera_attach_fbo(entity, fbo_width, fbo_height, fbo_has_depth_tex, fbo_has_render_tex, entity->camera.resizeable);
} }
variant_free(&var_value); camera_update_proj(entity);
} camera_update_view(entity);
/* Do the things after assignment */
struct Entity* parent_entity = NULL;
if(strcmp(parent_name, "NONE") != 0)
parent_entity = entity_find(parent_name);
struct Entity* new_entity = entity_create(entity_name, entity.type, parent_entity ? parent_entity->id : -1);
free(entity_name);
transform_translate(new_entity, &entity.transform.position, TS_PARENT);
quat_assign(&new_entity->transform.rotation, &entity.transform.rotation);
transform_scale(new_entity, &entity.transform.scale);
if(entity.renderable) new_entity->renderable = true;
switch(new_entity->type) }
{ break;
case ET_CAMERA:
new_entity->camera.fbo = -1;
new_entity->camera.depth_tex = -1;
new_entity->camera.render_tex = -1;
new_entity->camera.resizeable = false;
new_entity->camera.nearz = entity.camera.nearz;
new_entity->camera.farz = entity.camera.farz;
new_entity->camera.ortho = entity.camera.ortho;
new_entity->camera.fov = entity.camera.fov;
float aspect_ratio = (float)camera_fbo_width / (float)camera_fbo_height;
new_entity->camera.aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio;
camera_update_view(new_entity);
camera_update_proj(new_entity);
if(entity.camera.fbo != -1)
{
camera_attach_fbo(new_entity, camera_fbo_width, camera_fbo_height,
entity.camera.depth_tex == -1 ? false : true,
entity.camera.render_tex == -1 ? false : true,
entity.camera.resizeable);
}
vec4_assign(&new_entity->camera.clear_color, &entity.camera.clear_color);
break;
case ET_STATIC_MESH:
model_create(new_entity, geometry_name, material_name);
free(geometry_name);
free(material_name);
break;
case ET_LIGHT: case ET_LIGHT:
memcpy(&new_entity->light, &entity.light, sizeof(struct Light)); {
light_add(new_entity); if(hashmap_value_exists(object->data, "light_type")) entity->light.type = hashmap_int_get(object->data, "type");
break; if(hashmap_value_exists(object->data, "outer_angle")) entity->light.outer_angle = hashmap_float_get(object->data, "outer_angle");
if(hashmap_value_exists(object->data, "inner_angle")) entity->light.inner_angle = hashmap_float_get(object->data, "inner_angle");
if(hashmap_value_exists(object->data, "falloff")) entity->light.falloff = hashmap_float_get(object->data, "falloff");
if(hashmap_value_exists(object->data, "intensity")) entity->light.intensity = hashmap_float_get(object->data, "intensity");
if(hashmap_value_exists(object->data, "depth_bias")) entity->light.depth_bias = hashmap_float_get(object->data, "depth_bias");
if(hashmap_value_exists(object->data, "color")) entity->light.color = hashmap_vec3_get(object->data, "color");
if(hashmap_value_exists(object->data, "cast_shadow")) entity->light.cast_shadow = hashmap_bool_get(object->data, "cast_shadow");
if(hashmap_value_exists(object->data, "pcf_enabled")) entity->light.pcf_enabled = hashmap_bool_get(object->data, "pcf_enabled");
if(hashmap_value_exists(object->data, "radius")) entity->light.radius = hashmap_int_get(object->data, "radius");
light_add(entity);
}
break;
case ET_SOUND_SOURCE: case ET_SOUND_SOURCE:
platform->sound.source_create(entity.sound_source.relative, {
entity.sound_source.num_attached_buffers, if(hashmap_value_exists(object->data, "active")) entity->sound_source.active = hashmap_bool_get(object->data, "active");
&new_entity->sound_source.source_handle, if(hashmap_value_exists(object->data, "relative")) entity->sound_source.relative = hashmap_bool_get(object->data, "relative");
&new_entity->sound_source.buffer_handles[0]); if(hashmap_value_exists(object->data, "num_attached_buffers")) entity->sound_source.num_attached_buffers = (uint)hashmap_int_get(object->data, "num_attached_buffers");
platform->sound.source_create(entity->sound_source.relative,
entity->sound_source.num_attached_buffers,
&entity->sound_source.source_handle,
&entity->sound_source.buffer_handles);
}
break;
case ET_PLAYER:
{
}
break;
case ET_STATIC_MESH:
{
char* geometry_name = NULL;
char* material_name = NULL;
if(hashmap_value_exists(object->data, "geometry")) geometry_name = hashmap_str_get(object->data, "geometry");
if(hashmap_value_exists(object->data, "material")) material_name = hashmap_str_get(object->data, "material");
model_create(entity, geometry_name, material_name);
}
break;
default:
break; break;
}; }
return new_entity; return entity;
//struct Entity entity =
//{
// .id = -1,
// .type = ET_NONE,
// .is_listener = false,
// .renderable = false,
// .marked_for_deletion = false,
// .name = "DEFAULT_ENTITY_NAME",
// .editor_selected = 0
//};
//
// int current_line = 0;
//char* material_name = NULL;
//char* entity_name = NULL;
//char* geometry_name = NULL;
//char* parent_name = NULL;
//int camera_fbo_width = -1;
//int camera_fbo_height = -1;
// char line_buffer[MAX_LINE_LEN];
// char prop_str[MAX_ENTITY_PROP_NAME_LEN];
//static struct Variant var_value = { .type = VT_NONE};
// variant_free(&var_value);
//memset(prop_str, '\0', MAX_ENTITY_PROP_NAME_LEN);
//memset(line_buffer, '\0', MAX_LINE_LEN);
//while(fgets(line_buffer, MAX_LINE_LEN -1, file))
//{
// current_line++;
// memset(prop_str, '\0', MAX_ENTITY_PROP_NAME_LEN);
// if(line_buffer[0] == '#') continue;
// if(strlen(line_buffer) == 0 || isspace(line_buffer[0])) break;
// char* value_str = strstr(line_buffer, ":");
// if(!value_str)
// {
// log_warning("Malformed value in line %d", current_line);
// continue;
// }
// value_str++; /* Ignore the colon(:) and set the pointer after it */
//
// if(sscanf(line_buffer, " %1024[^: ] : %*s", prop_str) != 1)
// {
// log_warning("Unable to read property name in line %d", current_line);
// continue;
// }
// /* Common entity properties */
// if(strncmp("name", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_STR);
// entity_name = str_new(var_value.val_str);
// //variant_copy_out(&entity.name, &var_value);
// }
// else if(strncmp("parent", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_STR);
// parent_name = str_new(var_value.val_str);
// //variant_copy_out(&entity.name, &var_value);
// }
// else if(strncmp("type", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_INT);
// variant_copy_out(&entity.type, &var_value);
// }
// else if(strncmp("is_listener", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.is_listener, &var_value);
// }
// else if(strncmp("renderable", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.renderable, &var_value);
// }
//
// /* Transform */
// else if(strncmp("position", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_VEC3);
// variant_copy_out(&entity.transform.position, &var_value);
// }
// else if(strncmp("scale", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_VEC3);
// variant_copy_out(&entity.transform.scale, &var_value);
// }
// else if(strncmp("rotation", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_QUAT);
// variant_copy_out(&entity.transform.rotation, &var_value);
// }
// /* Camera */
// else if(strncmp("ortho", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.camera.ortho, &var_value);
// }
// else if(strncmp("resizeable", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.camera.resizeable, &var_value);
// }
// else if(strncmp("fov", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.camera.fov, &var_value);
// }
// else if(strncmp("nearz", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.camera.nearz, &var_value);
// }
// else if(strncmp("farz", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.camera.farz, &var_value);
// }
// else if(strncmp("has_fbo", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// entity.camera.fbo = var_value.val_bool ? 0 : -1;
// }
// else if(strncmp("fbo_height", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_INT);
// variant_copy_out(&camera_fbo_height, &var_value);
// }
// else if(strncmp("fbo_width", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_INT);
// variant_copy_out(&camera_fbo_width, &var_value);
// }
// else if(strncmp("fbo_has_depth_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// entity.camera.depth_tex = var_value.val_bool ? 0 : -1;
// }
// else if(strncmp("fbo_has_render_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// entity.camera.render_tex = var_value.val_bool ? 0 : -1;
// }
// else if(strncmp("clear_color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_VEC4);
// variant_copy_out(&entity.camera.clear_color, &var_value);
// }
// /* Light */
// else if(strncmp("light_type", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_INT);
// variant_copy_out(&entity.light.type, &var_value);
// }
// else if(strncmp("outer_angle", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.light.outer_angle, &var_value);
// }
// else if(strncmp("inner_angle", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.light.inner_angle, &var_value);
// }
// else if(strncmp("falloff", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.light.falloff, &var_value);
// }
// else if(strncmp("radius", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_INT);
// variant_copy_out(&entity.light.radius, &var_value);
// }
// else if(strncmp("intensity", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.light.intensity, &var_value);
// }
// else if(strncmp("depth_bias", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_FLOAT);
// variant_copy_out(&entity.light.depth_bias, &var_value);
// }
// else if(strncmp("valid", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.light.valid, &var_value);
// }
// else if(strncmp("cast_shadow", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.light.cast_shadow, &var_value);
// }
// else if(strncmp("pcf_enabled", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.light.pcf_enabled, &var_value);
// }
// else if(strncmp("color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_VEC3);
// variant_copy_out(&entity.light.color, &var_value);
// }
// /* Model */
// else if(strncmp("material", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_STR);
// material_name = str_new(var_value.val_str);
// }
// else if(strncmp("geometry", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_STR);
// geometry_name = str_new(var_value.val_str);
// }
// /* Sound Source */
// else if(strncmp("active", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.sound_source.active, &var_value);
// }
// else if(strncmp("relative", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_BOOL);
// variant_copy_out(&entity.sound_source.relative, &var_value);
// }
// else if(strncmp("num_attached_buffers", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
// {
// variant_from_str(&var_value, value_str, VT_INT);
// variant_copy_out(&entity.sound_source.num_attached_buffers, &var_value);
// }
// else
// {
// log_warning("Unknown entity property '%s' in line %d", prop_str, current_line);
// }
// variant_free(&var_value);
//}
///* Do the things after assignment */
//struct Entity* parent_entity = NULL;
//if(strcmp(parent_name, "NONE") != 0)
// parent_entity = entity_find(parent_name);
//
//struct Entity* new_entity = entity_create(entity_name, entity.type, parent_entity ? parent_entity->id : -1);
//free(entity_name);
//transform_translate(new_entity, &entity.transform.position, TS_PARENT);
//quat_assign(&new_entity->transform.rotation, &entity.transform.rotation);
//transform_scale(new_entity, &entity.transform.scale);
//
//if(entity.renderable) new_entity->renderable = true;
//
//switch(new_entity->type)
//{
//case ET_CAMERA:
// new_entity->camera.fbo = -1;
// new_entity->camera.depth_tex = -1;
// new_entity->camera.render_tex = -1;
// new_entity->camera.resizeable = false;
// new_entity->camera.nearz = entity.camera.nearz;
// new_entity->camera.farz = entity.camera.farz;
// new_entity->camera.ortho = entity.camera.ortho;
// new_entity->camera.fov = entity.camera.fov;
// float aspect_ratio = (float)camera_fbo_width / (float)camera_fbo_height;
// new_entity->camera.aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio;
// camera_update_view(new_entity);
// camera_update_proj(new_entity);
// if(entity.camera.fbo != -1)
// {
// camera_attach_fbo(new_entity, camera_fbo_width, camera_fbo_height,
// entity.camera.depth_tex == -1 ? false : true,
// entity.camera.render_tex == -1 ? false : true,
// entity.camera.resizeable);
// }
// vec4_assign(&new_entity->camera.clear_color, &entity.camera.clear_color);
// break;
//case ET_STATIC_MESH:
// model_create(new_entity, geometry_name, material_name);
// free(geometry_name);
// free(material_name);
// break;
//case ET_LIGHT:
// memcpy(&new_entity->light, &entity.light, sizeof(struct Light));
// light_add(new_entity);
// break;
//case ET_SOUND_SOURCE:
// platform->sound.source_create(entity.sound_source.relative,
// entity.sound_source.num_attached_buffers,
// &new_entity->sound_source.source_handle,
// &new_entity->sound_source.buffer_handles[0]);
// break;
//};
//return new_entity;
} }
struct Entity* entity_load(const char* filename, int directory_type) bool entity_load(const char* filename, int directory_type)
{ {
FILE* entity_file = platform->file.open(directory_type, filename, "rb"); FILE* entity_file = platform->file.open(directory_type, filename, "rb");
if(!entity_file) if(!entity_file)
{ {
log_error("entity:load", "Failed to open entity file %s for writing", filename); log_error("entity:load", "Failed to open entity file %s for reading", filename);
return NULL; return false;
} }
struct Entity* new_entity = NULL; struct Parser* parsed_file = parser_load_objects(entity_file, filename);
new_entity = entity_read(entity_file); struct Entity* new_entity = false;
if(new_entity)
log_message("Entity %s loaded from %s", new_entity->name, filename);
else
log_error("entity:load", "Failed to load entity from %s", filename);
if(!parsed_file)
{
log_error("entity:load", "Failed to parse file '%s' for entity definition", filename);
fclose(entity_file);
return false;
}
if(array_len(parsed_file->objects) == 0)
{
log_error("entity:load", "No objects found in file %s", filename);
parser_free(parsed_file);
fclose(entity_file);
return false;
}
int num_entites_loaded = 0;
for(int i = 0; i < array_len(parsed_file->objects); i++)
{
struct Parser_Object* object = &parsed_file->objects[i];
if(object->type != PO_ENTITY) continue;
new_entity = entity_read(object);
if(new_entity)
{
num_entites_loaded++;
log_message("Entity %s loaded from %s", new_entity->name, filename);
}
else
{
log_error("entity:load", "Failed to load entity from %s", filename);
}
}
parser_free(parsed_file);
fclose(entity_file); fclose(entity_file);
return new_entity; return num_entites_loaded > 0 ? true : false;
} }
const char* entity_type_name_get(struct Entity* entity) const char* entity_type_name_get(struct Entity* entity)

@ -9,6 +9,7 @@
#define MAX_SOUND_SOURCE_BUFFERS 5 #define MAX_SOUND_SOURCE_BUFFERS 5
struct Material_Param; struct Material_Param;
struct Parser_Object;
enum Entity_Type enum Entity_Type
{ {
@ -128,9 +129,9 @@ struct Entity* entity_find(const char* name);
struct Entity* entity_get_all(void); struct Entity* entity_get_all(void);
struct Entity* entity_get_parent(int node); struct Entity* entity_get_parent(int node);
bool entity_save(struct Entity* entity, const char* filename, int directory_type); bool entity_save(struct Entity* entity, const char* filename, int directory_type);
struct Entity* entity_load(const char* filename, int directory_type); bool entity_load(const char* filename, int directory_type);
bool entity_write(struct Entity* entity, FILE* file); bool entity_write(struct Entity* entity, FILE* file);
struct Entity* entity_read(FILE* file); struct Entity* entity_read(struct Parser_Object* object);
const char* entity_type_name_get(struct Entity* entity); const char* entity_type_name_get(struct Entity* entity);

@ -201,22 +201,23 @@ void scene_setup(void)
// light_ent->light.intensity = 1.f; // light_ent->light.intensity = 1.f;
//} //}
/* log_message("Sizeof Entity : %d", sizeof(struct Entity)); */ ///* log_message("Sizeof Entity : %d", sizeof(struct Entity)); */
/* struct Entity* light_ent = entity_find("Ground"); */ ///* struct Entity* light_ent = entity_find("Ground"); */
/* entity_save(light_ent, "ground.ent", DT_INSTALL); */ ///* entity_save(light_ent, "ground.ent", DT_INSTALL); */
//scene_save("test.scene", DIRT_INSTALL); //scene_save("test.symtres", DIRT_INSTALL);
//struct Entity* light = entity_load("light.ent", DT_INSTALL); //struct Entity* light = entity_load("light.ent", DT_INSTALL);
if(scene_load("test.scene", DIRT_INSTALL)) if(scene_load("test.symtres", DIRT_INSTALL))
{ {
log_message("Scene loaded!"); log_message("Scene loaded!");
struct Entity* player = entity_find("player"); struct Entity* player = entity_find("player");
game_state->player_node = player->id; game_state->player_node = player->id;
} }
/*
FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "rb"); FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "rb");
if(obj_file) if(obj_file)
{ {
@ -240,7 +241,7 @@ void scene_setup(void)
else else
{ {
log_warning("Failed to open obj_test.symtres"); log_warning("Failed to open obj_test.symtres");
} }*/
} }
void debug(float dt) void debug(float dt)

@ -191,7 +191,7 @@ bool material_register_model(struct Entity* entity, const char* material_name)
assert(material_name && entity); assert(material_name && entity);
bool success = false; bool success = false;
int index = material_get_index(material_name); int index = material_get_index(material_name);
if(index < -1) if(index <= -1)
{ {
log_error("material:register_model", "Material '%s' not found", material_name); log_error("material:register_model", "Material '%s' not found", material_name);
return success; return success;

@ -15,8 +15,18 @@ void model_create(struct Entity* entity, const char* geo_name, const char* mater
{ {
struct Model* model = &entity->model; struct Model* model = &entity->model;
/* if no name is given for geometry, use default */ /* if no name is given for geometry, use default */
if(!geo_name) geo_name = "default.pamesh"; int geo_index = geom_create_from_file(geo_name ? geo_name : "default.pamesh");
int geo_index = geom_create_from_file(geo_name);
if(geo_index == -1)
{
log_error("model:create", "Failed to load model %s", geo_name);
geo_index = geom_create_from_file("default.pamesh");
if(geo_index == -1)
{
log_error("model:create", "Could not load default model 'default.pamesh' ");
return;
}
}
model->geometry_index = geo_index; model->geometry_index = geo_index;
if(!material_register_model(entity, material_name ? material_name : "Unshaded")) if(!material_register_model(entity, material_name ? material_name : "Unshaded"))

@ -130,39 +130,39 @@ struct Entity* scene_get_parent(struct Entity* entity)
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, "rb"); // FILE* entity_file = platform->file.open(directory_type, filename, "r");
if(!entity_file) //if(!entity_file)
{ //{
log_error("scene:load", "Failed to open scenefile %s for reading", filename); // log_error("scene:load", "Failed to open scenefile %s for reading", filename);
return false; // return false;
} //}
int count = 0; //int count = 0;
int eof_char = -1; //int eof_char = -1;
while(!feof(entity_file)) //while(!feof(entity_file))
{ //{
if(eof_char != -1) ungetc(eof_char, entity_file); // if(eof_char != -1) ungetc(eof_char, entity_file);
struct Entity* new_entity = NULL; // struct Entity* new_entity = NULL;
new_entity = entity_read(entity_file); // new_entity = entity_read(entity_file);
if(!new_entity) // if(!new_entity)
{ // {
log_error("scene:load", "Error reading entity"); // log_error("scene:load", "Error reading entity");
} // }
else // else
{ // {
log_message("Loaded %s", new_entity->name); // log_message("Loaded %s", new_entity->name);
count++; // count++;
} // }
eof_char = fgetc(entity_file); // eof_char = fgetc(entity_file);
/* To check end of file, we get the next character and before beginning // /* 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 // 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 // was an eof. If it wasn't eof then we return the character back to the
stream and carry on. */ // stream and carry on. */
} //}
log_message("%d entites loaded from %s", count, filename); //log_message("%d entites loaded from %s", count, filename);
fclose(entity_file); //fclose(entity_file);
return true; return entity_load(filename, directory_type);
} }
bool scene_save(const char* filename, int directory_type) bool scene_save(const char* filename, int directory_type)

Loading…
Cancel
Save