blender/extern/verse/dist/vs_node_object.c
Nathan Letwory 16ea7fb353 * sync with verse cvs (for silencing some warnings +
safe to do, since verse is not
 enabled in release).
2007-01-25 07:07:32 +00:00

838 lines
28 KiB
C

/*
**
*/
#include <stdio.h>
#include <stdlib.h>
#include "v_cmd_gen.h"
#if !defined V_GENERATE_FUNC_MODE
#include "verse.h"
#include "v_util.h"
#include "vs_server.h"
extern void verse_send_o_link_set(VNodeID node_id, uint16 link_id, VNodeID link, const char *name, uint32 target_id);
extern void verse_send_o_link_destroy(VNodeID node_id, uint16 link_id);
typedef struct {
VNodeID link;
char name[16];
uint32 target_id;
/* Animation parameters. */
uint32 time_s;
uint32 time_f;
uint32 dimensions;
real64 pos[4];
real64 speed[4];
real64 accel[4];
real64 scale[4];
real64 scale_speed[4];
} VSLink;
typedef struct {
char name[16];
uint8 param_count;
VNOParamType *param_types;
char *param_names;
} VSMethod;
typedef struct {
char name[VN_O_METHOD_GROUP_NAME_SIZE];
VSMethod *methods;
unsigned int method_count;
VSSubscriptionList *subscribers;
} VSMethodGroup;
typedef struct {
real64 position[3];
VNQuat64 rotation;
real64 scale[3];
/* VSSubscriptionList *subscribers;*/
} VSTransform;
typedef struct {
VSNodeHead head;
VSTransform transform;
VSSubscriptionList *trans_sub64;
VSSubscriptionList *trans_sub32;
real64 light[3];
VSMethodGroup *groups;
uint16 group_count;
VSLink *links;
uint16 link_count;
boolean hidden;
} VSNodeObject;
VSNodeObject * vs_o_create_node(unsigned int owner)
{
VSNodeObject *node;
unsigned int i, j;
char name[48];
node = malloc(sizeof *node);
vs_add_new_node(&node->head, V_NT_OBJECT);
sprintf(name, "Object_Node_%u", node->head.id);
create_node_head(&node->head, name, owner);
node->trans_sub64 = vs_create_subscription_list();
node->trans_sub32 = vs_create_subscription_list();
node->transform.position[0] = node->transform.position[1] = node->transform.position[2] = 0;
node->transform.rotation.x = node->transform.rotation.y = node->transform.rotation.z = 0.0;
node->transform.rotation.w = 1.0;
node->transform.scale[0] = node->transform.scale[1] = node->transform.scale[2] = 1.0;
node->light[0] = node->light[1] = node->light[2] = V_REAL64_MAX;
node->groups = malloc((sizeof *node->groups) * 16);
node->group_count = 16;
for(i = 0; i < 16; i++)
{
node->groups[i].name[0] = 0;
node->groups[i].methods = NULL;
node->groups[i].method_count = 0;
node->groups[i].subscribers = NULL;
}
node->link_count = 16;
node->links = malloc((sizeof *node->links) * node->link_count);
for(i = 0; i < node->link_count; i++)
{
node->links[i].link = -1;
node->links[i].name[0] = 0;
node->links[i].target_id = -1;
node->links[i].dimensions = 0;
for(j = 0; j < 4; j++)
{
node->links[i].pos[j] = 0.0;
node->links[i].speed[j] = 0.0;
node->links[i].accel[j] = 0.0;
node->links[i].scale[j] = 0.0;
node->links[i].scale_speed[j] = 0.0;
}
}
node->hidden = FALSE;
return node;
}
void vs_o_destroy_node(VSNodeObject *node)
{
unsigned int i, j;
destroy_node_head(&node->head);
for(i = 0; i < node->group_count; i++)
{
if(node->groups[i].name[0] != 0)
{
for(j = 0; j < node->groups[i].method_count; j++)
{
if(node->groups[i].methods[j].name[0] != 0 && node->groups[i].methods[j].param_count != 0)
{
free(node->groups[i].methods[j].param_types);
free(node->groups[i].methods[j].param_names);
}
}
if(node->groups[i].methods != NULL)
free(node->groups[i].methods);
}
}
free(node->groups);
free(node);
}
void vs_o_subscribe(VSNodeObject *node)
{
unsigned int i;
for(i = 0; i < node->link_count; i++)
{
const VSLink *lnk = node->links + i;
if(lnk->name[0] != 0)
{
verse_send_o_link_set(node->head.id, i, lnk->link, lnk->name, lnk->target_id);
if(lnk->dimensions != 0)
{
verse_send_o_anim_run(node->head.id, i, lnk->time_s, lnk->time_f, lnk->dimensions,
lnk->pos, lnk->speed, lnk->accel,
lnk->scale, lnk->scale_speed);
}
}
}
if(node->light[0] != V_REAL64_MAX || node->light[1] != V_REAL64_MAX || node->light[2] != V_REAL64_MAX)
verse_send_o_light_set(node->head.id, node->light[0], node->light[1], node->light[2]);
for(i = 0; i < node->group_count; i++)
{
if(node->groups[i].name[0] != 0)
verse_send_o_method_group_create(node->head.id, i, node->groups[i].name);
}
if(node->hidden)
verse_send_o_hide(node->head.id, TRUE);
}
void vs_o_unsubscribe(VSNodeObject *node)
{
unsigned int i;
for(i = 0; i < node->group_count; i++)
if(node->groups[i].name[0] != 0)
vs_remove_subscriptor(node->groups[i].subscribers);
vs_remove_subscriptor(node->trans_sub64);
vs_remove_subscriptor(node->trans_sub32);
}
static void callback_send_o_transform_pos_real32(void *user, VNodeID node_id, uint32 time_s, uint32 time_f, real32 *pos, real32 *speed, real32 *accelerate, real32 *drag_normal, real32 drag)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->transform.position[0] = pos[0];
node->transform.position[1] = pos[1];
node->transform.position[2] = pos[2];
if((count = vs_get_subscript_count(node->trans_sub64)) > 0) /* Anyone listening at 64 bits? */
{
real64 spd[3], acc[3], drn[3], *pspd = NULL, *pacc = NULL, *pdrn = NULL;
pspd = (speed != NULL) ? spd : NULL;
pacc = (accelerate != NULL) ? acc : NULL;
pdrn = (drag_normal != NULL) ? drn : NULL;
/* Convert non-position values to 64-bit. */
for(i = 0; i < 3; i++)
{
if(speed != NULL)
spd[i] = speed[i];
if(accelerate != NULL)
acc[i] = accelerate[i];
if(drag_normal != NULL)
drn[i] = drag_normal[i];
}
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub64, i);
verse_send_o_transform_pos_real64(node_id, time_s, time_f, node->transform.position, pspd, pacc, pdrn, drag);
}
}
count = vs_get_subscript_count(node->trans_sub32);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub32, i);
verse_send_o_transform_pos_real32(node_id, time_s, time_f, pos, speed, accelerate, drag_normal, drag);
}
vs_reset_subscript_session();
}
static void callback_send_o_transform_rot_real32(void *user, VNodeID node_id, uint32 time_s, uint32 time_f, const VNQuat32 *rot,
const VNQuat32 *speed, const VNQuat32 *accelerate, const VNQuat32 *drag_normal, real32 drag)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->transform.rotation.x = rot->x;
node->transform.rotation.y = rot->y;
node->transform.rotation.z = rot->z;
node->transform.rotation.w = rot->w;
if((count = vs_get_subscript_count(node->trans_sub64)) > 0)
{
VNQuat64 spd, acc, drn, *p[3];
/* Convert 32-bit quaternions to 64-bit. Converter handles NULLs, has nice return semantics. */
p[0] = v_quat64_from_quat32(&spd, speed);
p[1] = v_quat64_from_quat32(&acc, accelerate);
p[2] = v_quat64_from_quat32(&drn, drag_normal);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub64, i);
verse_send_o_transform_rot_real64(node_id, time_s, time_f, &node->transform.rotation, p[0], p[1], p[2], drag);
}
}
count = vs_get_subscript_count(node->trans_sub32);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub32, i);
verse_send_o_transform_rot_real32(node_id, time_s, time_f, rot, speed, accelerate, drag_normal, drag);
}
vs_reset_subscript_session();
}
static void callback_send_o_transform_scale_real32(void *user, VNodeID node_id, real32 scale_x, real32 scale_y, real32 scale_z)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->transform.scale[0] = scale_x;
node->transform.scale[1] = scale_y;
node->transform.scale[2] = scale_z;
count = vs_get_subscript_count(node->trans_sub64);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub64, i);
verse_send_o_transform_scale_real64(node_id, scale_x, scale_y, scale_z);
}
count = vs_get_subscript_count(node->trans_sub32);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub32, i);
verse_send_o_transform_scale_real32(node_id, scale_x, scale_y, scale_z);
}
vs_reset_subscript_session();
}
static void callback_send_o_transform_pos_real64(void *user, VNodeID node_id, uint32 time_s, uint32 time_f, const real64 *pos,
const real64 *speed, const real64 *accelerate, const real64 *drag_normal, real64 drag)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->transform.position[0] = pos[0];
node->transform.position[1] = pos[1];
node->transform.position[2] = pos[2];
count = vs_get_subscript_count(node->trans_sub64);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub64, i);
verse_send_o_transform_pos_real64(node_id, time_s, time_f, node->transform.position, speed, accelerate, drag_normal, drag);
}
if((count = vs_get_subscript_count(node->trans_sub32)) > 0) /* Anyone listening at 32 bits? */
{
real32 ps[3], spd[3], acc[3], drn[3], *p[] = { NULL, NULL, NULL };
ps[0] = pos[0];
ps[1] = pos[1];
ps[2] = pos[2];
if(speed != NULL)
{
p[0] = spd;
spd[0] = speed[0];
spd[1] = speed[1];
spd[2] = speed[2];
}
else
p[0] = NULL;
if(accelerate != NULL)
{
p[1] = acc;
acc[0] = accelerate[0];
acc[1] = accelerate[1];
acc[2] = accelerate[2];
}
else
p[1] = NULL;
if(drag_normal != NULL)
{
p[1] = drn;
drn[0] = drag_normal[0];
drn[1] = drag_normal[1];
drn[2] = drag_normal[2];
}
else
p[2] = NULL;
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub32, i);
verse_send_o_transform_pos_real32(node_id, time_s, time_f, ps, p[0], p[1], p[2], (real32) drag);
}
}
vs_reset_subscript_session();
}
static void callback_send_o_transform_rot_real64(void *user, VNodeID node_id, uint32 time_s, uint32 time_f, const VNQuat64 *rot,
const VNQuat64 *speed, const VNQuat64 *accelerate, const VNQuat64 *drag_normal, real64 drag)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->transform.rotation = *rot;
count = vs_get_subscript_count(node->trans_sub64);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub64, i);
verse_send_o_transform_rot_real64(node_id, time_s, time_f, &node->transform.rotation, speed, accelerate, drag_normal, drag);
}
if((count = vs_get_subscript_count(node->trans_sub32)) > 0) /* Anyone listening at 32 bits? */
{
VNQuat32 rt, spd, acc, drn, *p[3];
v_quat32_from_quat64(&rt, rot);
p[0] = v_quat32_from_quat64(&spd, speed);
p[1] = v_quat32_from_quat64(&acc, accelerate);
p[2] = v_quat32_from_quat64(&drn, drag_normal);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub32, i);
verse_send_o_transform_rot_real32(node_id, time_s, time_f, &rt, p[0], p[1], p[2], (real32) drag);
}
}
vs_reset_subscript_session();
}
static void callback_send_o_transform_scale_real64(void *user, VNodeID node_id, real64 scale_x, real64 scale_y, real64 scale_z)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->transform.scale[0] = scale_x;
node->transform.scale[1] = scale_y;
node->transform.scale[2] = scale_z;
count = vs_get_subscript_count(node->trans_sub64);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub64, i);
verse_send_o_transform_scale_real64(node_id, scale_x, scale_y, scale_z);
}
count = vs_get_subscript_count(node->trans_sub32);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->trans_sub32, i);
verse_send_o_transform_scale_real32(node_id, (real32) scale_x, (real32) scale_y, (real32) scale_z);
}
vs_reset_subscript_session();
}
static void callback_send_o_transform_subscribe(void *user, VNodeID node_id, VNRealFormat type)
{
VSNodeObject *node;
uint32 time_s, time_f;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
verse_session_get_time(&time_s, &time_f);
if(type == VN_FORMAT_REAL32)
{
real32 tpos[3];
VNQuat32 rot;
vs_add_new_subscriptor(node->trans_sub32);
tpos[0] = node->transform.position[0];
tpos[1] = node->transform.position[1];
tpos[2] = node->transform.position[2];
verse_send_o_transform_pos_real32(node_id, time_s, time_f, tpos, NULL, NULL, NULL, 0.0f);
v_quat32_from_quat64(&rot, &node->transform.rotation);
verse_send_o_transform_rot_real32(node_id, time_s, time_f, &rot, NULL, NULL, NULL, 0.0f);
verse_send_o_transform_scale_real32(node_id, (real32) node->transform.scale[0], (real32) node->transform.scale[1], (real32) node->transform.scale[2]);
}
else
{
vs_add_new_subscriptor(node->trans_sub64);
verse_send_o_transform_pos_real64(node_id, time_s, time_f, node->transform.position, NULL, NULL, NULL, 0);
verse_send_o_transform_rot_real64(node_id, time_s, time_f, &node->transform.rotation, NULL, NULL, NULL, 0);
verse_send_o_transform_scale_real64(node_id, node->transform.scale[0], node->transform.scale[1], node->transform.scale[2]);
}
}
static void callback_send_o_transform_unsubscribe(void *user, VNodeID node_id, VNRealFormat type)
{
VSNodeObject *node;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
if(type == VN_FORMAT_REAL32)
vs_remove_subscriptor(node->trans_sub32);
else
vs_remove_subscriptor(node->trans_sub64);
}
static void callback_send_o_light_set(void *user, VNodeID node_id, real64 light_r, real64 light_g, real64 light_b)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
node->light[0] = light_r;
node->light[1] = light_g;
node->light[2] = light_b;
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_light_set(node_id, light_r, light_g, light_b);
}
vs_reset_subscript_session();
}
static void callback_send_o_link_set(void *user, VNodeID node_id, uint16 link_id, VNodeID link, const char *name, uint32 target_id)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
if(name[0] == 0)
return;
if(vs_get_node_head(link) == 0)
link = 0;
if(link_id >= node->link_count || node->links[link_id].name[0] == 0)
{
for(link_id = 0; link_id < node->link_count && node->links[link_id].name[0] != 0; link_id++);
if(link_id == node->link_count)
{
i = node->link_count;
node->link_count += 16;
node->links = realloc(node->links, (sizeof *node->links) * node->link_count);
for(; i < node->link_count; i++)
{
node->links[i].name[0] = 0;
node->links[i].dimensions = 0;
}
}
}
node->links[link_id].link = link;
for(i = 0; i < 15 && name[i] != 0; i++)
node->links[link_id].name[i] = name[i];
node->links[link_id].name[i] = 0;
node->links[link_id].target_id = target_id;
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_link_set(node_id, link_id, link, name, target_id);
}
vs_reset_subscript_session();
}
static void callback_send_o_link_destroy(void *user, VNodeID node_id, uint16 link_id)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
if(link_id >= node->link_count || node->links[link_id].name[0] == 0)
return;
node->links[link_id].name[0] = 0;
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_link_destroy(node_id, link_id);
}
vs_reset_subscript_session();
}
static void callback_send_o_method_group_create(void *user, VNodeID node_id, uint16 group_id, char *name)
{
VSNodeObject *node;
unsigned int i, j, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
for(i = 0; i < node->group_count; i++)
{
for(j = 0; node->groups[i].name[j] == name[j] && node->groups[i].name[j] != 0; j++);
if(node->groups[i].name[j] == name[j])
return;
}
if(group_id >= node->group_count || node->groups[group_id].name[0] == 0)
{
for(group_id = 0; group_id < node->group_count && node->groups[group_id].name[0] != 0; group_id++)
if(group_id == node->group_count)
{
node->groups = realloc(node->groups, sizeof(*node->groups) * (node->group_count + 16));
for(i = node->group_count; i < node->group_count + 16u; i++)
{
node->groups[i].name[0] = 0;
node->groups[i].methods = NULL;
node->groups[i].method_count = 0;
}
node->group_count += 16;
}
node->groups[group_id].subscribers = vs_create_subscription_list();
}
for(i = 0; i < 15 && name[i] != 0; i++)
node->groups[group_id].name[i] = name[i];
node->groups[group_id].name[i] = 0;
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_method_group_create(node_id, group_id, name);
}
vs_reset_subscript_session();
}
static void callback_send_o_method_group_destroy(void *user, VNodeID node_id, uint16 group_id)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
if(group_id >= node->group_count || node->groups[group_id].name[0] == 0)
return;
node->groups[group_id].name[0] = 0;
for(i = 0; i < node->groups[group_id].method_count; i++)
{
if(node->groups[group_id].methods[i].name[0] != 0 && node->groups[group_id].methods[i].param_count > 0)
{
free(node->groups[group_id].methods[i].param_names);
free(node->groups[group_id].methods[i].param_types);
}
}
free(node->groups[group_id].methods);
node->groups[group_id].methods = NULL;
node->groups[group_id].method_count = 0;
vs_destroy_subscription_list(node->groups[group_id].subscribers);
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_method_group_destroy(node_id, group_id);
}
vs_reset_subscript_session();
}
static void callback_send_o_method_group_subscribe(void *user, VNodeID node_id, uint16 group_id)
{
VSNodeObject *node;
unsigned int i, j;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
if(group_id < node->group_count && node->groups[group_id].name[0] != 0)
vs_add_new_subscriptor(node->groups[group_id].subscribers);
for(i = 0; i < node->groups[group_id].method_count; i++)
{
if(node->groups[group_id].methods[i].name[0] != 0)
{
char *names[255];
for(j = 0; j < node->groups[group_id].methods[i].param_count; j++)
names[j] = &node->groups[group_id].methods[i].param_names[j * 16];
verse_send_o_method_create(node_id, group_id, i, node->groups[group_id].methods[i].name, node->groups[group_id].methods[i].param_count, node->groups[group_id].methods[i].param_types, (const char **) names);
}
}
}
static void callback_send_o_method_group_unsubscribe(void *user, VNodeID node_id, uint16 group_id)
{
VSNodeObject *node;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
if(group_id < node->group_count && node->groups[group_id].name[0] != 0)
vs_remove_subscriptor(node->groups[group_id].subscribers);
}
static void callback_send_o_method_create(void *user, VNodeID node_id, uint16 group_id, uint16 method_id, char *name, uint8 param_count, VNOParamType *param_types, char * *param_names)
{
VSNodeObject *node;
unsigned int i, j, count;
VSMethodGroup *group;
node = (VSNodeObject *) vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
if(group_id >= node->group_count || node->groups[group_id].name[0] == 0)
return;
group = &node->groups[group_id];
for(i = 0; i < group->method_count; i++)
{
if(i != method_id)
{
for(j = 0; group->methods[i].name[j] == name[j] && group->methods[i].name[j] != 0; j++);
if(group->methods[i].name[j] == name[j])
return;
}
}
if(method_id < group->method_count && group->methods[method_id].name[0] != 0)
{
for(i = 0; i < 16; i++)
group->methods[method_id].name[i] = name[i];
if(group->methods[method_id].param_count != 0)
{
free(group->methods[method_id].param_names);
free(group->methods[method_id].param_types);
}
}else
{
for(method_id = 0; method_id < group->method_count && group->methods[method_id].name[0] != 0; method_id++);
if(method_id == group->method_count)
{
group->methods = realloc(group->methods, sizeof(*group->methods) * (group->method_count + 16));
for(i = group->method_count; i < group->method_count + 16; i++)
group->methods[i].name[0] = 0;
group->method_count += 16;
}
}
for(i = 0; i < VN_O_METHOD_NAME_SIZE && name[i] != 0; i++)
group->methods[method_id].name[i] = name[i];
group->methods[method_id].name[i] = '\0';
group->methods[method_id].param_count = param_count;
if(param_count > 0)
{
group->methods[method_id].param_types = malloc((sizeof *group->methods[method_id].param_types) * param_count);
group->methods[method_id].param_names = malloc((sizeof *group->methods[method_id].param_names) * param_count * 16);
}
for(i = 0; i < param_count; i++)
{
group->methods[method_id].param_types[i] = param_types[i];
for(j = 0; j < 15 && param_names[i][j] != 0; j++)
group->methods[method_id].param_names[i * 16 + j] = param_names[i][j];
group->methods[method_id].param_names[i * 16 + j] = 0;
}
count = vs_get_subscript_count(node->groups[group_id].subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->groups[group_id].subscribers, i);
verse_send_o_method_create(node_id, group_id, method_id, name, param_count, param_types, (const char **) param_names);
}
vs_reset_subscript_session();
}
static void callback_send_o_method_destroy(void *user, VNodeID node_id, uint16 group_id, uint16 method_id)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
if(group_id >= node->group_count || node->groups[group_id].name[0] == 0 || method_id >= node->groups[group_id].method_count || node->groups[group_id].methods[method_id].name[0] == 0)
return;
node->groups[group_id].methods[method_id].name[0] = 0;
if(node->groups[group_id].methods[method_id].param_count != 0)
{
free(node->groups[group_id].methods[method_id].param_names);
free(node->groups[group_id].methods[method_id].param_types);
}
count = vs_get_subscript_count(node->groups[group_id].subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->groups[group_id].subscribers, i);
verse_send_o_method_destroy(node_id, group_id, method_id);
}
vs_reset_subscript_session();
}
static void callback_send_o_method_call(void *user, VNodeID node_id, uint16 group_id, uint16 method_id, VNodeID sender, void *params)
{
VNOParam unpacked_params[255];
void *data;
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || vs_get_node(node_id, V_NT_OBJECT) == NULL)
return;
if(group_id >= node->group_count || node->groups[group_id].name[0] == 0 || method_id >= node->groups[group_id].method_count || node->groups[group_id].methods[method_id].name[0] == 0)
return;
if(!verse_method_call_unpack(params, node->groups[group_id].methods[method_id].param_count, node->groups[group_id].methods[method_id].param_types, unpacked_params))
return;
sender = vs_get_avatar();
count = vs_get_subscript_count(node->groups[group_id].subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->groups[group_id].subscribers, i);
data = verse_method_call_pack(node->groups[group_id].methods[method_id].param_count, node->groups[group_id].methods[method_id].param_types, unpacked_params);
if(data != NULL)
verse_send_o_method_call(node_id, group_id, method_id, sender, data);
}
vs_reset_subscript_session();
}
static void callback_send_o_anim_run(void *user, VNodeID node_id, uint16 link_id, uint32 time_s, uint32 time_f, uint8 dimensions, real64 *pos,
real64 *speed, real64 *accel, real64 *scale, real64 *scale_speed)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL)
return;
if(link_id >= node->link_count || node->links[link_id].name[0] == 0)
return;
if(NULL == vs_get_node(node->links[link_id].link, V_NT_CURVE))
return;
node->links[link_id].time_s = time_s;
node->links[link_id].time_f = time_f;
node->links[link_id].dimensions = dimensions;
for(i = 0; i < dimensions && i < 4; i++)
{
node->links[link_id].pos[i] = pos[i];
node->links[link_id].speed[i] = speed[i];
node->links[link_id].accel[i] = accel[i];
node->links[link_id].scale[i] = scale[i];
node->links[link_id].scale_speed[i] = scale_speed[i];
}
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_anim_run(node_id, link_id, time_s, time_f, dimensions, pos, speed, accel, scale, scale_speed);
}
vs_reset_subscript_session();
}
static void callback_send_o_hide(void *user, VNodeID node_id, uint8 hidden)
{
VSNodeObject *node;
unsigned int i, count;
node = (VSNodeObject *)vs_get_node(node_id, V_NT_OBJECT);
if(node == NULL || hidden == node->hidden)
return;
node->hidden = hidden;
count = vs_get_subscript_count(node->head.subscribers);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(node->head.subscribers, i);
verse_send_o_hide(node_id, hidden);
}
vs_reset_subscript_session();
}
void vs_o_callback_init(void)
{
verse_callback_set(verse_send_o_transform_pos_real32, callback_send_o_transform_pos_real32, NULL);
verse_callback_set(verse_send_o_transform_rot_real32, callback_send_o_transform_rot_real32, NULL);
verse_callback_set(verse_send_o_transform_scale_real32, callback_send_o_transform_scale_real32, NULL);
verse_callback_set(verse_send_o_transform_pos_real64, callback_send_o_transform_pos_real64, NULL);
verse_callback_set(verse_send_o_transform_rot_real64, callback_send_o_transform_rot_real64, NULL);
verse_callback_set(verse_send_o_transform_scale_real64, callback_send_o_transform_scale_real64, NULL);
verse_callback_set(verse_send_o_transform_subscribe, callback_send_o_transform_subscribe, NULL);
verse_callback_set(verse_send_o_transform_unsubscribe, callback_send_o_transform_unsubscribe, NULL);
verse_callback_set(verse_send_o_link_set, callback_send_o_link_set, NULL);
verse_callback_set(verse_send_o_light_set, callback_send_o_light_set, NULL);
verse_callback_set(verse_send_o_link_set, callback_send_o_link_set, NULL);
verse_callback_set(verse_send_o_link_destroy, callback_send_o_link_destroy, NULL);
verse_callback_set(verse_send_o_method_group_create, callback_send_o_method_group_create, NULL);
verse_callback_set(verse_send_o_method_group_destroy, callback_send_o_method_group_destroy, NULL);
verse_callback_set(verse_send_o_method_group_subscribe, callback_send_o_method_group_subscribe, NULL);
verse_callback_set(verse_send_o_method_group_unsubscribe, callback_send_o_method_group_unsubscribe, NULL);
verse_callback_set(verse_send_o_method_create, callback_send_o_method_create, NULL);
verse_callback_set(verse_send_o_method_destroy, callback_send_o_method_destroy, NULL);
verse_callback_set(verse_send_o_method_call, callback_send_o_method_call, NULL);
verse_callback_set(verse_send_o_anim_run, callback_send_o_anim_run, NULL);
verse_callback_set(verse_send_o_hide, callback_send_o_hide, NULL);
}
#endif