forked from bartvdbraak/blender
16ea7fb353
safe to do, since verse is not enabled in release).
838 lines
28 KiB
C
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
|