view TaskManager/Test/test_render/SceneGraphRoot.cpp @ 215:7ca6a2ef5be9

fix SceneGraph Constructor, Destructor
author gongo@gendarme.local
date Sun, 01 Feb 2009 22:14:44 +0900
parents 159519cdca1f
children 0f1ff7b06157
line wrap: on
line source

#include <SDL.h>
#include <SDL_image.h>
#include <libxml/parser.h>
#include "SceneGraphRoot.h"
#include "xml.h"
#include "sys.h"
#include "TextureHash.h"
#include "texture.h"
#include "SGList.h"

SceneGraphRoot::SceneGraphRoot(void)
{
    sg_src = new SceneGraphPtr[SGLIST_LENGTH];
    camera = new Camera;
    iterator = new SceneGraphIterator;

    sg_exec_list = NULL;
    sg_draw_list = NULL;
    sg_available_list = NULL;

    // TODO
    //   今はとりあえず camera を Root にしています
    sg_exec_list = camera;

    addNext(camera);
}

SceneGraphRoot::~SceneGraphRoot(void)
{
    SceneGraphPtr p = sg_available_list;

    while (p) {
	SceneGraphPtr tmp = p->next;
	delete p;
	p = tmp;
    }

    delete [] sg_src;
    delete camera;
    delete iterator;
}

void
SceneGraphRoot::registSceneGraph(SceneGraphPtr sg)
{
    for (int i = 0; i < SGLIST_LENGTH; i++) {
	if (strcmp(sg->name, sglist_table[i]) == 0) {
	    sg->sgid = i;
	    sg_src[i] = sg;
	    return;
	}
    }

    fprintf(stderr, "error: (%s:%3d) Can't find Scene \"%s\"\n",
	    __FUNCTION__, __LINE__, sg->name);
}

void
SceneGraphRoot::addNext(SceneGraphPtr sg)
{
    SceneGraphPtr last = sg_available_list;

    if (!last) {
	sg_available_list = sg;
    } else {
	while (last->next) {
	    last = last->next;
	}
	last->next = sg;
	sg->prev = last;
    }
}

/* XMLファイルからポリゴンを作成  */
void
SceneGraphRoot::createFromXMLfile(const char *xmlfile)
{
    xmlDocPtr doc;
    xmlNodePtr cur;
    SceneGraphPtr tmp;
    
    /* パース DOM生成 */
    doc = xmlParseFile(xmlfile);
    cur = xmlDocGetRootElement(doc);

    /* ??  */
    xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");

    /* XMLのノードを一つずつ解析  */
    for (cur=cur->children; cur; cur=cur->next) {
	/* 扱うのはsurfaceオンリー  */
	if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) {
	    continue;
	}

	/* ポリゴン(SceneGraph)生成  */
	tmp = new SceneGraph(cur);

	registSceneGraph(tmp);
    }

    xmlFreeDoc(doc);
}

SceneGraphPtr
SceneGraphRoot::createSceneGraph(int id)
{
    SceneGraphPtr src;
    SceneGraphPtr p;

    if (id < 0 || id > SGLIST_LENGTH) {
	return NULL;
    }

    /* オリジナルの SceneGraph */
    src = sg_src[id];

    /* ユーザーにはオリジナルの clone を返す */
    p = src->clone();

    addNext(p);

    return p;
}

/**
 * 何も表示しない、move,collision もしない SceneGraph を生成
 * いずれ、Transform3D 的なものに回す予定
 */
SceneGraphPtr
SceneGraphRoot::createSceneGraph(void)
{
    SceneGraphPtr p = new SceneGraph;

    addNext(p);
    p->flag_drawable = 0;

    return p;
}

void
SceneGraphRoot::allExecute(int screen_w, int screen_h)
{
    SceneGraphPtr top = sg_exec_list;
    SceneGraphPtr t = top; /* top = Camera (090128 現在) */
    CameraPtr camera = (CameraPtr)t;
    
    camera->move_execute(screen_w, screen_h);
    camera->update(screen_w, screen_h);
    
    t = camera->children;

    while (t) {
	t->move_execute(screen_w, screen_h);
	t->collision_check(screen_w, screen_h, top);

	t->frame++;

	//if (t->parent != NULL) {
	get_matrix(t->matrix, t->angle, t->xyz, t->parent->matrix);
	//} else {
	//get_matrix(t->matrix, t->angle, t->xyz, NULL);
	//}

	if (t->children != NULL) {
	    t = t->children;
	} else if (t->brother != NULL) {
	    t = t->brother;
	} else {
	    while (t) {
		if (t->brother != NULL) {
		    t = t->brother;
		    break;
		} else {
		    if (t->parent == NULL) {
			t = NULL;
			break;
		    } else {
			t = t->parent;
		    }
		}
	    }
	}
    }
}

void
SceneGraphRoot::checkRemove(void)
{
    SceneGraphPtr p = sg_available_list;
    SceneGraphPtr p1;

    while (p) {
	p1 = p->next;
	if (p->isRemoved()) {
	    sg_exec_list = p->realRemoveFromTree(sg_exec_list);
	    sg_available_list = p->realRemoveFromList(sg_available_list);
	}
	p = p1;
    }

    // 現在、exec と draw は別で処理できてないので、一緒にする
    sg_draw_list = sg_exec_list;
}

SceneGraphPtr
SceneGraphRoot::getExecuteSceneGraph(void)
{
    return sg_exec_list;
}

SceneGraphPtr
SceneGraphRoot::getDrawSceneGraph(void)
{
    return sg_draw_list;
}

void
SceneGraphRoot::updateControllerState(void)
{
    controller->check();
}

void
SceneGraphRoot::setSceneData(SceneGraphPtr sg)
{
    //sg_draw_list = sg_exec_list = sg;
    sg_exec_list->addChild(sg);
    sg_draw_list = sg_exec_list;
}

Pad*
SceneGraphRoot::getController(void)
{
    return controller;
}

SceneGraphIteratorPtr
SceneGraphRoot::getIterator(void)
{
    iterator->set(sg_available_list);
    return iterator;
}

SceneGraphIteratorPtr
SceneGraphRoot::getIterator(SceneGraphPtr list)
{
    iterator->set(list);
    return iterator;
}