#include "scene.h"
#include "treestore.h"
#include "logger.h"
+#include "app.h"
#ifdef WIN32
#include <malloc.h>
static bool proc_node(MetaScene *mscn, struct ts_node *node);
static bool proc_scenefile(MetaScene *mscn, struct ts_node *node);
-static bool proc_mtledit(MetaScene *mscn, MaterialEdit *med, struct ts_node *node, TextureSet *texset);
+static bool proc_mtledit(MetaScene *mscn, MaterialEdit *med, struct ts_node *node);
static void apply_mtledit(Scene *scn, const MaterialEdit &med);
static void apply_mtledit(Material *mtl, const MaterialEdit &med);
static struct ts_attr *attr_inscope(struct ts_node *node, const char *name);
static void print_scene_graph(SceneNode *n, int level);
-MetaScene::MetaScene(SceneSet *sman, TextureSet *tman)
+MetaScene::MetaScene()
{
- sceneman = sman;
- texman = tman;
walk_mesh = 0;
}
struct SceneData {
- std::string walkmesh_regexp;
+ MetaScene *meta;
+ std::string walkmesh_regexp, spawn_regexp;
std::vector<MaterialEdit> mtledit;
};
const char *fname = ts_get_attr_str(node, "file");
if(fname) {
SceneData *sdat = new SceneData;
+ sdat->meta = mscn;
// datapath
struct ts_attr *adpath = attr_inscope(node, "datapath");
sdat->walkmesh_regexp = std::string(awmesh->val.str);
}
+ // spawn node
+ struct ts_attr *awspawn = attr_inscope(node, "spawn");
+ if(awspawn) {
+ switch(awspawn->val.type) {
+ case TS_VECTOR:
+ mscn->start_pos = Vec3(awspawn->val.vec[0], awspawn->val.vec[1],
+ awspawn->val.vec[2]);
+ break;
+
+ case TS_STRING:
+ default:
+ sdat->spawn_regexp = std::string(awspawn->val.str);
+ }
+ }
+ if((awspawn = attr_inscope(node, "spawn_rot")) && awspawn->val.type == TS_VECTOR) {
+ Quat rot;
+ rot.rotate(Vec3(1, 0, 0), deg_to_rad(awspawn->val.vec[0]));
+ rot.rotate(Vec3(0, 1, 0), deg_to_rad(awspawn->val.vec[1]));
+ rot.rotate(Vec3(0, 0, 1), deg_to_rad(awspawn->val.vec[2]));
+ mscn->start_rot = rot;
+ }
+
int namesz = mscn->datamap.lookup(fname, 0, 0);
char *namebuf = (char*)alloca(namesz + 1);
if(mscn->datamap.lookup(fname, namebuf, namesz + 1)) {
struct ts_node *child = node->child_list;
while(child) {
MaterialEdit medit;
- if(proc_mtledit(mscn, &medit, child, mscn->texman)) {
+ if(proc_mtledit(mscn, &medit, child)) {
sdat->mtledit.push_back(medit);
}
child = child->next;
}
- Scene *newscn = mscn->sceneman->get(fname);
+ Scene *newscn = sceneman.get(fname);
/* NOTE: setting all these after get() is not a race condition, because
* scene_loaded() which uses this, will only run in our main loop during
* SceneSet::update() on the main thread.
delete wscn;
}
+ // extract the spawn node
+ if(!sdat->spawn_regexp.empty() && (wscn = newscn->extract_nodes(sdat->spawn_regexp.c_str()))) {
+
+ int nmeshes = wscn->meshes.size();
+ int nnodes = wscn->nodes ? wscn->nodes->get_num_children() : 0;
+
+ if(nmeshes) {
+ Vec3 pos;
+ for(int i=0; i<nmeshes; i++) {
+ const Sphere &bsph = wscn->meshes[i]->get_bsphere();
+ pos += bsph.center;
+ }
+ pos /= (float)nmeshes;
+ sdat->meta->start_pos = pos;
+
+ } else if(nnodes) {
+ // just use the first one
+ SceneNode *first = wscn->nodes->get_child(0);
+ sdat->meta->start_pos = first->get_position();
+ sdat->meta->start_rot = first->get_rotation();
+ }
+ delete wscn;
+ }
+
int num_medits = sdat->mtledit.size();
for(int i=0; i<num_medits; i++) {
// perform material edits
return true;
}
-static bool proc_mtledit(MetaScene *mscn, MaterialEdit *med, struct ts_node *node, TextureSet *texset)
+static bool proc_mtledit(MetaScene *mscn, MaterialEdit *med, struct ts_node *node)
{
if(strcmp(node->name, "mtledit") != 0) {
return false;
// remove
med->tex = 0;
} else {
- med->tex = texset->get_texture(afile->val.str, TEX_2D, &mscn->datamap);
+ med->tex = texman.get_texture(afile->val.str, TEX_2D, &mscn->datamap);
}
}
// TODO add more edit modes