|
Re: vec_for_vertex gap issue
[Re: Superku]
#472309
04/19/18 11:55
04/19/18 11:55
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Hi, I feel that tentacles thingy appealing and gived a try to an approach with animated polylines and quadratic bezier curves. Probably worse than bones but it has been fun I use the tentacles skills to store an array of vectors that serve as polyline.
void tentacleInit(ENTITY *entTentacle) {
c_setminmax(entTentacle);
entTentacle->skill99 = floatv(entTentacle->max_x / 8.5); // section length
int _i = 0;
for (; _i<9; _i+=1) {
entTentacle->skill[_i*3] = 50 - _i * 4;
entTentacle->skill[1+_i*3] = 0;
entTentacle->skill[2+_i*3] = 0;
vec_set(&entTentacle->skill[30 + _i * 3], &entTentacle->skill[_i * 3]);
}
entTentacle->material = mtl_create();
effect_load(entTentacle->material, "tentacle.fx");
entTentacle->material->flags |= ENABLE_TREE;
entTentacle->material->event = evnTentacle;
}
Those vectors are processed and passes to the material each frame.
void evnTentacle () {
float fSpline[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
fSpline[0] = -0.5 * my->skill[0];
fSpline[1] = -0.5 * my->skill[2]; // swapped X & Z axes
fSpline[2] = -0.5 * my->skill[1];
int _i = 1;
for(; _i<10; _i+=1) {
fSpline[_i*3] = fSpline[-3+_i*3];
fSpline[1+_i*3] = fSpline[-2+_i*3];
fSpline[2+_i*3] = fSpline[-1+_i*3];
fSpline[_i*3] += (float)my->skill[-3+_i*3];
fSpline[1+_i*3] += (float)my->skill[-1+_i*3]; // swapped X & Z axes
fSpline[2+_i*3] += (float)my->skill[-2+_i*3];
}
LPD3DXEFFECT fx1 = my->material->d3deffect;
if (fx1) {
fx1->SetValue("fSpline", fSpline, 30 * sizeof(float));
fx1->SetValue("fStep", &my->skill99, sizeof(var));
}
}
I presented a tentacle along the X axe so I assign the mesh into the polyline according to its position in length.
float3 fSpline[10];
float fStep;
float3 doSpline(in float depth, out float3 vTangent) {
depth = max(depth - fStep * 0.5f, 0);
float index = floor(depth / fStep);
float factor = fmod(depth, fStep) / fStep;
float3 v1 = lerp(fSpline[index], fSpline[index+1], 0.5);
float3 v1b = lerp(v1, fSpline[index+1], factor);
float3 v2 = lerp(fSpline[index+1], fSpline[index+2], 0.5);
float3 v2b = lerp(fSpline[index+1], v2, factor);
vTangent = normalize(v2b - v1b);
return lerp(v1b, v2b, factor);
}
I use the returned tangent in order to rotate (not really) transverse sections.
void VS (
in float4 inPos: POSITION,
out float4 outPos: POSITION,
out float3 outNormal: TEXCOORD0) {
float3 vTangent = 0;
float3 vPos = doSpline(inPos.x, vTangent);
outPos.x = vPos.x - vTangent.y * inPos.y - vTangent.z * inPos.z;
outPos.y = vPos.y + inPos.y;
outPos.z = vPos.z + inPos.z;
outPos.w = 1.0f;
outNormal = normalize(mul(outPos.xyz - vPos, (float3x3)matWorld));
outPos = mul(outPos, matWorldViewProj);
}
This simplification needs the tangent to be smaller than 45 degrees from the X axe, so the tentacles has to point, more or less, to the front. Otherway it looks wrong. Logaritmic distribution of angular speeds and segment lengths beside a single step of forward inverse kinematic make the random animation look pretty soft and natural.
void tentacleAnimate (ENTITY *entTentacle) {
int _i = 0;
for(; _i<9; _i+=1) {
VECTOR vOff;
vec_diff(&vOff, &entTentacle->skill[30+_i*3], &entTentacle->skill[_i*3]);
var _length = 2 * time_step / (9 - _i);
if (vec_length(&vOff) < _length) {
entTentacle->skill[30+_i*3] = 10;
entTentacle->skill[31+_i*3] = random(10+_i*10) - (_i+1)*5;
entTentacle->skill[32+_i*3] = random(10+_i*10) - (_i+1)*5;
vec_normalize(&entTentacle->skill[30+_i*3], 50 - _i * 4);
} else {
vec_normalize(&vOff, _length);
}
vec_add(&entTentacle->skill[_i*3], &vOff);
vec_sub(&entTentacle->skill[(_i+1)*3], &vOff); // forward inverse kinematic
}
}
Salud!
|
|
|
|