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. 794
      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
- 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
- Finish loading scene from file
- Update makefiles to be able to compile the code in it's current state
@ -325,3 +328,4 @@
* Fixed several bugs with entity loading
* Removed duplicate parsing logic
* 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);
}
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)
{
@ -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)
{
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}

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

@ -206,8 +206,8 @@ struct Parser* parser_load_objects(FILE* file, const char* filename)
char value_str[MAX_VALUE_LEN];
memset(format_str, '\0', 64);
snprintf(format_str, 64, " %%%d[^: ] : %%%d[^\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN);
char* line = strtok(obj_str, "\n");
snprintf(format_str, 64, " %%%d[^: ] : %%%d[^\r\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN);
char* line = strtok(obj_str, "\r\n");
do
{
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);
}
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);
}

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

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

@ -11,6 +11,8 @@
#include "framebuffer.h"
#include "../common/variant.h"
#include "../common/common.h"
#include "../common/parser.h"
#include "../common/hashmap.h"
#include <stdlib.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 */
fprintf(file, "name: %s\n", entity->name);
fprintf(file, "type: %d\n", entity->type);
fprintf(file, "is_listener: %s\n", entity->is_listener ? "true" : "false");
fprintf(file, "renderable: %s\n", entity->renderable ? "true" : "false");
fprintf(file, "Entity\n{\n");
fprintf(file, "\tname: %s\n", entity->name);
fprintf(file, "\ttype: %d\n", entity->type);
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);
fprintf(file, "parent: %s\n", parent ? parent->name : "NONE");
fprintf(file, "\tparent: %s\n", parent ? parent->name : "NONE");
/* Transform */
fprintf(file, "position: %.5f %.5f %.5f\n",
fprintf(file, "\tposition: %.5f %.5f %.5f\n",
entity->transform.position.x,
entity->transform.position.y,
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.y,
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.y,
entity->transform.rotation.z,
@ -233,27 +236,27 @@ bool entity_write(struct Entity* entity, FILE* file)
{
case ET_CAMERA:
{
fprintf(file, "ortho: %s\n", entity->camera.ortho ? "true" : "false");
fprintf(file, "resizeable: %s\n", entity->camera.resizeable ? "true" : "false");
fprintf(file, "fov: %.5f\n", entity->camera.fov);
fprintf(file, "nearz: %.5f\n", entity->camera.nearz);
fprintf(file, "farz: %.5f\n", entity->camera.farz);
fprintf(file, "clear_color: %.5f %.5f %.5f %.5f\n",
fprintf(file, "\tortho: %s\n", entity->camera.ortho ? "true" : "false");
fprintf(file, "\tresizeable: %s\n", entity->camera.resizeable ? "true" : "false");
fprintf(file, "\tfov: %.5f\n", entity->camera.fov);
fprintf(file, "\tnearz: %.5f\n", entity->camera.nearz);
fprintf(file, "\tfarz: %.5f\n", entity->camera.farz);
fprintf(file, "\tclear_color: %.5f %.5f %.5f %.5f\n",
entity->camera.clear_color.x,
entity->camera.clear_color.y,
entity->camera.clear_color.z,
entity->camera.clear_color.w);
if(entity->camera.fbo != -1)
{
fprintf(file, "has_fbo: true\n");
fprintf(file, "fbo_height: %d\n", framebuffer_height_get(entity->camera.fbo));
fprintf(file, "fbo_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, "fbo_has_depth_tex: %s\n", entity->camera.depth_tex == -1 ? "false" : "true");
fprintf(file, "\thas_fbo: true\n");
fprintf(file, "\tfbo_height: %d\n", framebuffer_height_get(entity->camera.fbo));
fprintf(file, "\tfbo_width: %d\n", framebuffer_width_get(entity->camera.fbo));
fprintf(file, "\tfbo_has_render_tex: %s\n", entity->camera.render_tex == -1 ? "false" : "true");
fprintf(file, "\tfbo_has_depth_tex: %s\n", entity->camera.depth_tex == -1 ? "false" : "true");
}
else
{
fprintf(file, "has_fbo: false\n");
fprintf(file, "\thas_fbo: false\n");
}
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 */
struct Material* material = material_get(entity->model.material);
struct Geometry* geom = geom_get(entity->model.geometry_index);
fprintf(file, "material: %s\n", material->name);
fprintf(file, "geometry: %s\n", geom->filename);
fprintf(file, "\tmaterial: %s\n", material->name);
fprintf(file, "\tgeometry: %s\n", geom->filename);
break;
}
case ET_LIGHT:
{
fprintf(file, "light_type: %d\n", entity->light.valid);
fprintf(file, "outer_angle: %.5f\n", entity->light.outer_angle);
fprintf(file, "inner_angle: %.5f\n", entity->light.inner_angle);
fprintf(file, "falloff: %.5f\n", entity->light.falloff);
fprintf(file, "radius: %d\n", entity->light.radius);
fprintf(file, "intensity: %.5f\n", entity->light.intensity);
fprintf(file, "depth_bias: %.5f\n", entity->light.depth_bias);
fprintf(file, "valid: %s\n", entity->light.valid ? "true" : "false");
fprintf(file, "cast_shadow: %s\n", entity->light.cast_shadow ? "true" : "false");
fprintf(file, "pcf_enabled: %s\n", entity->light.pcf_enabled ? "true" : "false");
fprintf(file, "color: %.5f %.5f %.5f\n",
fprintf(file, "\tlight_type: %d\n", entity->light.valid);
fprintf(file, "\touter_angle: %.5f\n", entity->light.outer_angle);
fprintf(file, "\tinner_angle: %.5f\n", entity->light.inner_angle);
fprintf(file, "\tfalloff: %.5f\n", entity->light.falloff);
fprintf(file, "\tradius: %d\n", entity->light.radius);
fprintf(file, "\tintensity: %.5f\n", entity->light.intensity);
fprintf(file, "\tdepth_bias: %.5f\n", entity->light.depth_bias);
fprintf(file, "\tvalid: %s\n", entity->light.valid ? "true" : "false");
fprintf(file, "\tcast_shadow: %s\n", entity->light.cast_shadow ? "true" : "false");
fprintf(file, "\tpcf_enabled: %s\n", entity->light.pcf_enabled ? "true" : "false");
fprintf(file, "\tcolor: %.5f %.5f %.5f\n",
entity->light.color.x,
entity->light.color.y,
entity->light.color.z);
@ -286,13 +289,13 @@ bool entity_write(struct Entity* entity, FILE* file)
}
case ET_SOUND_SOURCE:
{
fprintf(file, "active: %s\n", entity->sound_source.active ? "true" : "false");
fprintf(file, "relative: %s\n", entity->sound_source.relative ? "true" : "false");
fprintf(file, "\tactive: %s\n", entity->sound_source.active ? "true" : "false");
fprintf(file, "\trelative: %s\n", entity->sound_source.relative ? "true" : "false");
break;
}
};
fprintf(file, "\n");
fprintf(file, "}\n\n");
return true;
}
@ -314,334 +317,515 @@ bool entity_save(struct Entity* entity, const char* filename, int directory_type
return false;
}
struct Entity* entity_read(FILE* file)
struct Entity* entity_read(struct Parser_Object* object)
{
if(!file)
{
log_error("entity:read", "Invalid file handle");
return false;
}
assert(object);
struct Entity entity =
if(object->type != PO_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;
log_error("entity:read", "Invalid object type");
return NULL;
}
value_str++; /* Ignore the colon(:) and set the pointer after it */
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(sscanf(line_buffer, " %1024[^: ] : %*s", prop_str) != 1)
if(!name)
{
log_warning("Unable to read property name in line %d", current_line);
continue;
log_error("entity:read", "No entity name provided");
return NULL;
}
/* 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)
if(!parent_name)
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.renderable, &var_value);
log_error("entity:read", "No parent name provided");
return NULL;
}
/* 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)
if(type < 0 || type >= ET_MAX)
{
variant_from_str(&var_value, value_str, VT_QUAT);
variant_copy_out(&entity.transform.rotation, &var_value);
log_error("entity:read", "Invalid entity type");
return NULL;
}
/* Camera */
else if(strncmp("ortho", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
struct Entity* parent = entity_find(parent_name);
struct Entity* entity = entity_create(name, type, parent ? parent->id : -1);
if(!entity)
{
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);
log_error("entity:read", "Failed to create new entity");
return NULL;
}
/* 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)
// Common entity properties
if(hashmap_value_exists(object->data, "is_listener"))
entity->is_listener = hashmap_bool_get(object->data, "is_listener");
else
entity->is_listener = false;
if(hashmap_value_exists(object->data, "renderable"))
entity->renderable= hashmap_bool_get(object->data, "renderable");
else
entity->renderable= false;
// Transform properties
if(hashmap_value_exists(object->data, "position"))
{
variant_from_str(&var_value, value_str, VT_FLOAT);
variant_copy_out(&entity.light.depth_bias, &var_value);
vec3 position = hashmap_vec3_get(object->data, "position");
transform_translate(entity, &position, TS_PARENT);
}
else if(strncmp("valid", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
if(hashmap_value_exists(object->data, "rotation"))
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.light.valid, &var_value);
quat rotation = hashmap_quat_get(object->data, "rotation");
quat_assign(&entity->transform.rotation, &rotation);
}
else if(strncmp("cast_shadow", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
if(hashmap_value_exists(object->data, "scale"))
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.light.cast_shadow, &var_value);
vec3 scale = hashmap_vec3_get(object->data, "scale");
transform_scale(entity, &scale);
}
else if(strncmp("pcf_enabled", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
switch(entity->type)
{
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)
case ET_CAMERA:
{
variant_from_str(&var_value, value_str, VT_VEC3);
variant_copy_out(&entity.light.color, &var_value);
}
bool has_fbo = false;
bool fbo_has_depth_tex = false;
bool fbo_has_render_tex = false;
int fbo_width = -1;
int fbo_height = -1;
/* Model */
else if(strncmp("material", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
if(hashmap_value_exists(object->data, "fov")) entity->camera.fov = hashmap_float_get(object->data, "fov");
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");
if(hashmap_value_exists(object->data, "farz")) entity->camera.farz = hashmap_float_get(object->data, "farz");
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");
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");
if(hashmap_value_exists(object->data, "fbo_width")) fbo_width = hashmap_int_get(object->data, "fbo_width");
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"))
{
variant_from_str(&var_value, value_str, VT_STR);
material_name = str_new(var_value.val_str);
vec4 color = hashmap_vec4_get(object->data, "clear_color");
vec4_assign(&entity->camera.clear_color, &color);
}
else if(strncmp("geometry", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
float aspect_ratio = (float)fbo_width / (float)fbo_height;
entity->camera.aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio;
entity->camera.fbo = -1;
entity->camera.render_tex = -1;
entity->camera.depth_tex = -1;
if(has_fbo)
{
variant_from_str(&var_value, value_str, VT_STR);
geometry_name = str_new(var_value.val_str);
camera_attach_fbo(entity, fbo_width, fbo_height, fbo_has_depth_tex, fbo_has_render_tex, entity->camera.resizeable);
}
/* 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);
camera_update_proj(entity);
camera_update_view(entity);
}
else if(strncmp("relative", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
break;
case ET_LIGHT:
{
variant_from_str(&var_value, value_str, VT_BOOL);
variant_copy_out(&entity.sound_source.relative, &var_value);
if(hashmap_value_exists(object->data, "light_type")) entity->light.type = hashmap_int_get(object->data, "type");
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);
}
else if(strncmp("num_attached_buffers", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0)
break;
case ET_SOUND_SOURCE:
{
variant_from_str(&var_value, value_str, VT_INT);
variant_copy_out(&entity.sound_source.num_attached_buffers, &var_value);
if(hashmap_value_exists(object->data, "active")) entity->sound_source.active = hashmap_bool_get(object->data, "active");
if(hashmap_value_exists(object->data, "relative")) entity->sound_source.relative = hashmap_bool_get(object->data, "relative");
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);
}
else
break;
case ET_PLAYER:
{
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);
{
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;
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]);
default:
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");
if(!entity_file)
{
log_error("entity:load", "Failed to open entity file %s for writing", filename);
return NULL;
log_error("entity:load", "Failed to open entity file %s for reading", filename);
return false;
}
struct Entity* new_entity = NULL;
new_entity = entity_read(entity_file);
struct Parser* parsed_file = parser_load_objects(entity_file, filename);
struct Entity* new_entity = false;
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);
return new_entity;
return num_entites_loaded > 0 ? true : false;
}
const char* entity_type_name_get(struct Entity* entity)

@ -9,6 +9,7 @@
#define MAX_SOUND_SOURCE_BUFFERS 5
struct Material_Param;
struct Parser_Object;
enum Entity_Type
{
@ -128,9 +129,9 @@ struct Entity* entity_find(const char* name);
struct Entity* entity_get_all(void);
struct Entity* entity_get_parent(int node);
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);
struct Entity* entity_read(FILE* file);
struct Entity* entity_read(struct Parser_Object* object);
const char* entity_type_name_get(struct Entity* entity);

@ -201,22 +201,23 @@ void scene_setup(void)
// 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"); */
/* entity_save(light_ent, "ground.ent", DT_INSTALL); */
///* struct Entity* light_ent = entity_find("Ground"); */
///* 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);
if(scene_load("test.scene", DIRT_INSTALL))
if(scene_load("test.symtres", DIRT_INSTALL))
{
log_message("Scene loaded!");
struct Entity* player = entity_find("player");
game_state->player_node = player->id;
}
/*
FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "rb");
if(obj_file)
{
@ -240,7 +241,7 @@ void scene_setup(void)
else
{
log_warning("Failed to open obj_test.symtres");
}
}*/
}
void debug(float dt)

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

@ -15,8 +15,18 @@ void model_create(struct Entity* entity, const char* geo_name, const char* mater
{
struct Model* model = &entity->model;
/* 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);
int geo_index = geom_create_from_file(geo_name ? geo_name : "default.pamesh");
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;
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)
{
FILE* entity_file = platform->file.open(directory_type, filename, "rb");
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 true;
// 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)

Loading…
Cancel
Save