mirror of
https://github.com/quelsolaar/MergeSource
synced 2025-02-01 09:58:42 -05:00
260 lines
8.0 KiB
C
260 lines
8.0 KiB
C
#define PERSUADE_INTERNAL
|
|
#include "persuade2.h"
|
|
#include "p2_sds_geo.h"
|
|
#include "p2_sds_obj.h"
|
|
//extern ESObjectNode *e_ns_get_node(uint connection, uint node_id);
|
|
|
|
/*typedef void EObjLink;*/
|
|
|
|
double p_anim_evaluate_anim(ENode *o_node, double *output, uint seconds, uint fractions, char *name, double default_value)
|
|
{
|
|
double write[4], tmp[4], scale[4], pos[4];
|
|
ENode *c_node;
|
|
EObjLink *link;
|
|
ECurve *curve;
|
|
boolean found = FALSE;
|
|
|
|
if(output == NULL)
|
|
output = tmp;
|
|
output[0] = default_value;
|
|
output[1] = 0;
|
|
output[2] = 0;
|
|
output[3] = 0;
|
|
for(link = e_nso_get_next_link(o_node, 0); link != NULL; link = e_nso_get_next_link(o_node, e_nso_get_link_id(link) + 1))
|
|
{
|
|
c_node = e_ns_get_node(0, e_nso_get_link_node(link));
|
|
if(c_node != NULL && e_ns_get_node_type(c_node) == V_NT_CURVE)
|
|
{
|
|
if(e_nso_get_anim_active(link))
|
|
{
|
|
e_nso_get_anim_evaluate_pos(link, pos, seconds, fractions);
|
|
e_nso_get_anim_evaluate_scale(link, scale, seconds, fractions);
|
|
if((curve = e_nsc_get_curve_by_name(c_node, name)) != NULL)
|
|
{
|
|
if(!found)
|
|
output[0] = 0;
|
|
found = TRUE;
|
|
e_nsc_evaluate_curve(curve, write, pos[0]);
|
|
output[0] += write[0] * scale[0];
|
|
output[1] += write[1] * scale[0];
|
|
output[2] += write[2] * scale[0];
|
|
output[3] += write[3] * scale[0];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return output[0];
|
|
}
|
|
|
|
boolean p_lod_anim_bones_update_test(PMesh *mesh, ENode *o_node, ENode *g_node)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
boolean p_lod_anim_scale_update_test(PMesh *mesh, ENode *o_node)
|
|
{
|
|
double scale[3];
|
|
e_nso_get_scale(o_node, scale);
|
|
if(mesh->anim.scale[0] != (pgreal)scale[0] || mesh->anim.scale[1] != (pgreal)scale[1] || mesh->anim.scale[2] != (pgreal)scale[2])
|
|
{
|
|
mesh->anim.scale[0] = (pgreal)scale[0];
|
|
mesh->anim.scale[1] = (pgreal)scale[1];
|
|
mesh->anim.scale[2] = (pgreal)scale[2];
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
boolean p_lod_anim_layer_update_test(PMesh *mesh, ENode *o_node, ENode *g_node)
|
|
{
|
|
double weight;
|
|
boolean update = FALSE;
|
|
EGeoLayer *layer;
|
|
uint i = 0;
|
|
|
|
if(mesh->anim.layers.layers == NULL)
|
|
{
|
|
if(mesh->anim.layers.layers != NULL)
|
|
free(mesh->anim.layers.layers);
|
|
mesh->anim.layers.layer_count = 0;
|
|
for(layer = e_nsg_get_layer_next(g_node, 0); layer != NULL; layer = e_nsg_get_layer_next(g_node, e_nsg_get_layer_id(layer) + 1))
|
|
if(VN_G_LAYER_VERTEX_XYZ == e_nsg_get_layer_type(layer))
|
|
mesh->anim.layers.layer_count++;
|
|
mesh->anim.layers.layers = malloc((sizeof *mesh->anim.layers.layers) * mesh->anim.layers.layer_count);
|
|
for(i = 0; i < mesh->anim.layers.layer_count; i++)
|
|
{
|
|
mesh->anim.layers.layers[i].version = 0;
|
|
mesh->anim.layers.layers[i].data = NULL;
|
|
mesh->anim.layers.layers[i].weight[0] = 0;
|
|
}
|
|
}
|
|
|
|
if(mesh->anim.layers.data_version != e_ns_get_node_version_data(g_node) || mesh->anim.play.layers)
|
|
{
|
|
mesh->anim.play.layers = FALSE;
|
|
i = 0;
|
|
for(layer = e_nsg_get_layer_next(g_node, 0); layer != NULL; layer = e_nsg_get_layer_next(g_node, e_nsg_get_layer_id(layer) + 1))
|
|
{
|
|
if(VN_G_LAYER_VERTEX_XYZ == e_nsg_get_layer_type(layer))
|
|
{
|
|
if(i == 0)
|
|
weight = p_anim_evaluate_anim(o_node, NULL, mesh->anim.seconds, mesh->anim.fractions, e_nsg_get_layer_name(layer), 1);
|
|
else
|
|
weight = p_anim_evaluate_anim(o_node, NULL, mesh->anim.seconds, mesh->anim.fractions, e_nsg_get_layer_name(layer), 0);
|
|
if((mesh->anim.layers.layers[i].weight[0] / mesh->anim.scale[0] + 0.0001 > weight &&
|
|
mesh->anim.layers.layers[i].weight[0] / mesh->anim.scale[0] - 0.0001 < weight) ||
|
|
mesh->anim.layers.layers[i].version != e_nsg_get_layer_version(layer))
|
|
update = TRUE;
|
|
mesh->anim.layers.layers[i].weight[0] = weight * mesh->anim.scale[0];
|
|
mesh->anim.layers.layers[i].weight[1] = weight * mesh->anim.scale[1];
|
|
mesh->anim.layers.layers[i].weight[2] = weight * mesh->anim.scale[2];
|
|
mesh->anim.layers.layers[i++].version = e_nsg_get_layer_version(layer);
|
|
}
|
|
}
|
|
mesh->anim.layers.data_version = e_ns_get_node_version_data(g_node);
|
|
}
|
|
return update || mesh->anim.play.layers;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
if(mesh->anim.geometry_data_version != e_ns_get_node_version_data(g_node))
|
|
update_bones = TRUE;
|
|
|
|
|
|
if(update_bones != TRUE)
|
|
{
|
|
i = 0;
|
|
for(layer = e_nsg_get_layer_next(g_node, 0); layer != NULL; layer = e_nsg_get_layer_next(g_node, 0))
|
|
if(mesh->anim.layer_versions[i++] != e_nsg_get_layer_version(layer))
|
|
break;
|
|
if(layer != NULL)
|
|
{
|
|
uint16 bone;
|
|
for(bone = e_nsg_get_bone_next(g_node, 0); update_bones != TRUE && bone != (uint16)-1; bone = e_nsg_get_bone_next(g_node, bone + 1))
|
|
{
|
|
bone_layer = e_nsg_get_layer_by_name(g_node, e_nsg_get_bone_weight(g_node, bone));
|
|
if(bone_layer != NULL)
|
|
{
|
|
i = 0;
|
|
for(layer = e_nsg_get_layer_next(g_node, 0); layer != NULL && layer != bone_layer; layer = e_nsg_get_layer_next(g_node, 0))
|
|
i++;
|
|
if(layer == bone_layer && mesh->anim.layer_versions[i] != e_nsg_get_layer_version(layer))
|
|
update_bones = TRUE;
|
|
}
|
|
bone_layer = e_nsg_get_layer_by_name(g_node, e_nsg_get_bone_reference(g_node, bone));
|
|
|
|
if(bone_layer != NULL)
|
|
{
|
|
i = 0;
|
|
for(layer = e_nsg_get_layer_next(g_node, 0); layer != NULL && layer != bone_layer; layer = e_nsg_get_layer_next(g_node, 0))
|
|
i++;
|
|
if(layer == bone_layer && mesh->anim.layer_versions[i] != e_nsg_get_layer_version(layer))
|
|
update_bones = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(mesh->anim.global_curve_mode != e_ns_get_global_version(0, V_NT_CURVE))
|
|
{
|
|
update = TRUE;
|
|
}
|
|
|
|
e_nso_get_scale(o_node, scale);
|
|
if(mesh->anim.scale[0] != scale[0] || mesh->anim.scale[1] != scale[1] || mesh->anim.scale[2] != scale[2])
|
|
{
|
|
mesh->anim.scale[0] = scale[0];
|
|
mesh->anim.scale[1] = scale[1];
|
|
mesh->anim.scale[2] = scale[2];
|
|
update = TRUE;
|
|
}
|
|
|
|
mesh->anim.object_version = e_ns_get_node_version_struct(o_node);
|
|
mesh->anim.geometry_data_version = e_ns_get_node_version_data(g_node);
|
|
mesh->anim.global_curve_mode = e_ns_get_global_version(0, V_NT_CURVE);
|
|
return update;
|
|
}
|
|
*/
|
|
|
|
/*
|
|
extern void e_nsg_get_bone_pos32(ENode *g_node, uint16 bone_id, float *pos);
|
|
extern void e_nsg_get_bone_pos64(ENode *g_node, uint16 bone_id, double *pos);
|
|
extern void e_nsg_get_bone_rot32(ENode *g_node, uint16 bone_id, float *rot);
|
|
extern void e_nsg_get_bone_rot64(ENode *g_node, uint16 bone_id, double *rot);
|
|
*/
|
|
void p_lod_anim_vertex_array(pgreal *vertex, uint cv_count, PMesh *mesh, ENode *g_node)
|
|
{
|
|
pgreal *v, *data, x, y, z;
|
|
uint i = 1, j;
|
|
EGeoLayer *layer;
|
|
|
|
layer = e_nsg_get_layer_by_id(g_node, 0);
|
|
x = mesh->anim.layers.layers[0].weight[0];
|
|
y = mesh->anim.layers.layers[0].weight[1];
|
|
z = mesh->anim.layers.layers[0].weight[2];
|
|
v = vertex;
|
|
data = e_nsg_get_layer_data(g_node, layer);
|
|
for(j = 0; j < cv_count; j++)
|
|
{
|
|
*v++ = *data++ * x;
|
|
*v++ = *data++ * y;
|
|
*v++ = *data++ * z;
|
|
}
|
|
|
|
for(layer = e_nsg_get_layer_next(g_node, 0); layer != NULL; layer = e_nsg_get_layer_next(g_node, e_nsg_get_layer_id(layer) + 1))
|
|
{
|
|
if(VN_G_LAYER_VERTEX_XYZ == e_nsg_get_layer_type(layer) && i < mesh->anim.layers.layer_count)
|
|
{
|
|
if(mesh->anim.layers.layers[i].weight[0] > 0.00001 || mesh->anim.layers.layers[i].weight[0] < -0.00001 ||
|
|
mesh->anim.layers.layers[i].weight[1] > 0.00001 || mesh->anim.layers.layers[i].weight[1] < -0.00001 ||
|
|
mesh->anim.layers.layers[i].weight[2] > 0.00001 || mesh->anim.layers.layers[i].weight[2] < -0.00001)
|
|
{
|
|
x = mesh->anim.layers.layers[i].weight[0];
|
|
y = mesh->anim.layers.layers[i].weight[1];
|
|
z = mesh->anim.layers.layers[i].weight[2];
|
|
v = vertex;
|
|
data = e_nsg_get_layer_data(g_node, layer);
|
|
for(j = 0; j < cv_count; j++)
|
|
{
|
|
*v++ += *data++ * x;
|
|
*v++ += *data++ * y;
|
|
*v++ += *data++ * z;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
if(mesh->anim.bonereference)
|
|
{
|
|
k = 0;
|
|
for(i = 0; i < cv_count; i++)
|
|
{
|
|
x = *v;
|
|
*v = 0;
|
|
y = v[1];
|
|
v[1] = 0;
|
|
z = v[2];
|
|
v[2] = 0;
|
|
for(j = 0; j < mesh->anim.ref_count[i]; j++)
|
|
{
|
|
m = &matrix[mesh->anim.bonereference[k] * 16];
|
|
f = mesh->anim.boneweight[k++];
|
|
v[0] += (m[0] * x + m[1] * y + m[2] * z + m[3]) * f;
|
|
v[1] += (m[4] * x + m[5] * y + m[6] * z + m[7]) * f;
|
|
v[2] += (m[8] * x + m[9] * y + m[10] * z + m[11]) * f;
|
|
}
|
|
v += 3;
|
|
}
|
|
}
|
|
}*/
|