"Fossies" - the Fresh Open Source Software archive 
Member "graph/src/anitroll/atom.c" of archive pixcon-5.02.tar.gz:
#include <stdlib.h>
#include <string.h>
#include "quark.h"
#include "pstring.h"
/* *************************************************************
************************************************************* */
void eventtype::evaluate(int frameno, atom *source, dbl_llist_manager *hiearchy_manager) {
vfile *infile; // input file
string_type token;
string_type parent, object; // temp string
int number; // # of changes during an event
int j; // loop vars
float temp; // temp array
quark *qtr; // quark pointer
infile = (vfile *)global_resource_manager->find_resource_object(RESOURCE_SFILE, NULL, NULL);
if (!infile->scan_data(efilename.string, EVENT_PATH.string)) {
global_resource_manager->register_resource_object(RESOURCE_SFILE, infile);
sprintf(perror_buffer, "Warning: can't access %s...\n", efilename.string);
pprintf(perror_buffer);
return;
}
infile->scan_token(&token);
for (number=asc2int(token.string); number>0; number--) {
infile->scan_token(&token);
object.stringcpy(&token); // backup in case of quark name
lower_case(token.string);
if (!token.stringcmp("composite")) { // the following event affects atom
infile->scan_token(&token);
lower_case(token.string);
source->flags |= QUARK_FLAG_RECALC;
if (!token.stringcmp("spline")) // xyz dof change
source->motion.read_spline(infile, timefactor, &token);
else // quaternion dof
source->motion.read_quaternion(infile, timefactor, &token);
}
else if (!token.stringcmp("move")) { // change parent of a child
infile->scan_token(&token);
object.stringcpy(&token);
infile->scan_token(&token);
source->move_quark(object.string, token.string);
}
else if (!token.stringcmp("drop")) { // make a child indep. object
infile->scan_token(&token);
source->drop_quark(frameno, token.string, hiearchy_manager, infile);
}
// absorb another object
else if (!token.stringcmp("absorb")) {
infile->scan_token(&token);
object.stringcpy(&token);
infile->scan_token(&token);
if (!source->name.stringcmp(object.string))
source->join_atom(object.string, token.string, hiearchy_manager);
}
else if (!token.stringcmp("take")) {// take child from object
infile->scan_token(&token);
object.stringcpy(&token);
infile->scan_token(&token);
parent.stringcpy(&token);
infile->scan_token(&token);
source->take_quark(object.string, parent.string, token.string, hiearchy_manager);
}
else if (!token.stringcmp("scale")) { // global scale of object
infile->scan_token(&token);
temp = (float)atof(token.string);
infile->scan_token(&token);
source->scale_quark(temp, token.string);
}
else { // child event
qtr = source->find((quark *)NULL, object.string);
if (qtr)
qtr->new_action(infile, timefactor, NULL);
else { // cant find item, so junk event
sprintf(perror_buffer, "Warning::ATOM... Can't find %s\n", object.string);
pprintf(perror_buffer);
infile->scan_token(&token);
lower_case(token.string);
if (!token.stringcmp("spline") || !token.stringcmp("quaternion")) {
infile->scan_token(&token);
j = asc2int(token.string);
infile->scan_token(&token);
infile->scan_token(&token);
infile->scan_token(&token);
for (; j>-1; j--) {
infile->scan_token(&token);
infile->scan_token(&token);
infile->scan_token(&token);
}
}
}
}
}
global_resource_manager->register_resource_object(RESOURCE_SFILE, infile);
}
/* *************************************************************
************************************************************* */
void atom::render_object(engine *proc, quark *parent, frustum_type *frustum, unsigned int frustum_flag) {
linktype *ptr;
// cull node w/ view frustum
if ((old_state.state_flags & STATE_MASK_TREE) == STATE_FLAG_TNONE)
frustum_flag = 0;
if (frustum_flag && (old_state.state_flags & STATE_MASK_TREE) == STATE_FLAG_TSPHERE &&
query_frustum_clip(old_state.tree_radius, old_state.tree_center, frustum, &frustum_flag, frustum_fail_data)) {
flags &= ~QUARK_FLAG_VISIBLE;
return;
}
flags |= QUARK_FLAG_VISIBLE;
for (ptr=(linktype *)edge.head; ptr; ptr=(linktype *)ptr->next)
ptr->link->render_object(proc, this, frustum, frustum_flag);
}
/* *************************************************************
************************************************************* */
void atom::new_action(vfile *infile, float timefactor, char *buffer) {
}
/* *************************************************************
************************************************************* */
int atom::query_whatwasi(int type) {
return (atom::query_whatami() == type) ? 1 : quark::query_whatwasi(type);
}
/* *************************************************************
This is the destructor for this class
************************************************************* */
int atom::parse(vfile *infile, string_type *token) {
if (!quark::parse(infile, token))
read_event(infile, token, 0);
return 1;
}
/* *************************************************************
Read in an object's data
************************************************************* */
int atom::read_data(char *filename) {
vfile *infile;
string_type token;
infile = (vfile *)global_resource_manager->find_resource_object(RESOURCE_SFILE, NULL, NULL);
if (!infile->scan_data(filename, ATOM_PATH.string)) {
global_resource_manager->register_resource_object(RESOURCE_SFILE, infile);
return 0;
}
name.stringcpy(filename);
while (read_quark(infile, &token, 0));
global_resource_manager->register_resource_object(RESOURCE_SFILE, infile);
return 1;
}
/* *************************************************************
************************************************************* */
basic_event *atom::read_event(vfile *infile, string_type *token, int frame_offset) {
eventtype *ptr;
basic_event *qtr;
ptr = new eventtype;
infile->scan_token(token);
ptr->event = asc2int(token->string) + frame_offset;
// "event_mult"
infile->scan_token(token);
infile->scan_token(token);
ptr->timefactor = (float)atof(token->string);
// "event"
infile->scan_token(token);
infile->scan_token(&ptr->efilename);
for (qtr = (basic_event *)event_manager.head; qtr && qtr->event < ptr->event; qtr = (basic_event *)qtr->next);
if (qtr)
event_manager.insert(ptr, qtr);
else
event_manager.append(ptr, NULL);
return ptr;
}
/* *************************************************************
This function implements new events
************************************************************* */
void atom::new_action(int frameno, dbl_llist_manager *hiearchy_manager) {
basic_event *ptr; // event pointer
for (ptr=(basic_event *)event_manager.head; ptr && frameno >= ptr->event; ptr = (basic_event *)event_manager.head) {
ptr->evaluate(frameno, this, hiearchy_manager);
event_manager.remove(ptr);
delete ptr;
}
}
/* ********************************************************
******************************************************** */
int atom::scale_quark(float s, char *part) {
quark *target, *parent;
target = find(NULL, part, &parent);
if (target) {
target->apply_scale(s);
return 1;
}
sprintf(perror_buffer, "Could not scale %s\n", part);
pprintf(perror_buffer);
return 0;
}
/* ********************************************************
This function changes the parent of a child - moves it w/in its own atom tree
******************************************************** */
int atom::move_quark(char *child, char *parent) {
quark *ptr; // temp pointers
quark *old_parent = NULL; // temp pointer
quark *new_parent;
// find "child" and make sure not to assign a child to a node in the child's tree
ptr = find(NULL, child, &old_parent);
if (!ptr || ptr->find(NULL, parent)) {
sprintf(perror_buffer, "Could not move %s to %s\n", child, parent);
pprintf(perror_buffer);
return 0;
}
// find new parent
new_parent = !strcmp(parent, TOKEN_NULL_STR) ? this : find(NULL, parent);
if (!new_parent) {
sprintf(perror_buffer, "Could not move %s to %s\n", child, parent);
pprintf(perror_buffer);
return 0;
}
if (old_parent) {
old_parent->remove_link(ptr);
ptr->remove_link(old_parent);
}
else
remove_link(ptr);
ptr->create_link(new_parent);
new_parent->create_link(ptr);
return 1;
}
/* ********************************************************
This function makes a child an independent object
******************************************************** */
int atom::drop_quark(int frameno, char *child, dbl_llist_manager *hiearchy_manager, vfile *infile) {
atom_list_type *tree;
atom *atr; // new object
quark *old_child; // child to drop
quark *old_parent = (quark *)NULL; // parent of child
string_type token; // temp string
linktype *ptr;
old_child = find(NULL, child, &old_parent);
if (!old_child) { // cant find child....
infile->scan_token(&token);
infile->scan_token(&token);
infile->scan_token(&token);
do {
if (!infile->scan_token(&token) || token.string[0] == '}')
break;
} while (1);
return 0;
}
if (!old_parent) { // since root node is to be dropped, reuse old atom
event_manager.dest();
atr = this;
}
else {
old_parent->remove_link(old_child);
old_child->remove_link(old_parent);
// make new object
hiearchy_manager->append(tree = new atom_list_type, NULL);
tree->htree = atr = new atom;
atr->edge.insert(ptr = new linktype, NULL);
ptr->link = old_child;
}
// read object events
infile->scan_token(&token);
atr->name.stringcpy(&token);
infile->scan_token(&token); // "{"
do {
if (!infile->scan_token(&token) || token.string[0] == '}')
break;
atr->read_event(infile, &token, frameno);
} while (1);
// update object
atr->new_action(frameno, hiearchy_manager);
return 1;
}
/* ********************************************************
This function takes another object, and makes it
a part of it.
NOTE: events from one does not transfer over to the new object
******************************************************** */
int atom::join_atom(char *part, char *parent, dbl_llist_manager *hiearchy_manager) {
atom *btr; // atom pointers
quark *ptr; // quark pointers
string_type token;
quark *qtr;
linktype *rtr;
atom_list_type *tree;
token.stringcpy(parent);
lower_case(token.string);
// move to a child
if (token.stringcmp("link")) {
ptr = find((quark *)NULL, parent);
if (!ptr)
return 0;
}
// coexists w/ current children
else
ptr = this;
for (tree = (atom_list_type *)hiearchy_manager->head; tree && tree->htree->name.stringcmp(part); tree = (atom_list_type *)tree->next);
if (!tree)
return 0;
// remove atom from the master list
hiearchy_manager->remove(tree);
btr = tree->htree;
tree->htree = NULL;
delete tree;
for (rtr = (linktype *)btr->edge.head; rtr; rtr = (linktype *)rtr->next) {
qtr = rtr->link;
rtr->link = NULL;
ptr->create_link(qtr);
qtr->create_link(ptr);
}
// delete old atom
delete btr;
return 1;
}
/* ********************************************************
This function takes part of another object, and makes it
a part of itself
******************************************************** */
int atom::take_quark(char *dest, char *parent, char *part, dbl_llist_manager *hiearchy_manager) {
atom_list_type *atr; // target pointer
quark *child, *new_parent; // quark pointers
quark *old_parent = NULL; // quark pointer
for (atr = (atom_list_type *)hiearchy_manager->head; atr && atr->htree->name.stringcmp(parent); atr=(atom_list_type *)atr->next);
if (!atr || !(child = atr->htree->find(NULL, part, &old_parent))) {
sprintf(perror_buffer, "Could not take %s from %s to %s\n", part, parent, dest);
pprintf(perror_buffer);
return 0;
}
new_parent = !strcmp(dest, TOKEN_NULL_STR) ? this : find(NULL, dest);
if (!new_parent) {
sprintf(perror_buffer, "Could not take %s from %s to %s\n", part, parent, dest);
pprintf(perror_buffer);
return 0;
}
if (old_parent) {
old_parent->remove_link(child);
child->remove_link(old_parent);
}
else {
atr->htree->remove_link(child);
// wipe out empty node
if (!atr->htree->edge.head) {
hiearchy_manager->remove(atr);
delete atr;
}
}
new_parent->create_link(child);
child->create_link(new_parent);
return 1;
}