inline void pointdynamics(point_t *curpt) // Calculate point movement { GLdouble r = vnorm(&curpt->pos); vector_t grav; vector_t rotf; vector_t coriolis; if(r > c_Re) { // Points outside Earth grav = vscale(-c_Ge * curpt->m / pow(r,3), &curpt->pos); vaddto(&curpt->f, &grav); } else { // Take care of points that vector_t scaled; // are inside Earth curpt->pos = vscale(c_Re / vnorm(&curpt->pos), &curpt->pos); scaled = vscale(-vdot(&curpt->pos, &curpt->v) / c_Re / c_Re, &curpt->pos); vaddto(&curpt->v, &scaled); curpt->v = vscale(0, &curpt->v); } rotf = vscale(c_Vang * c_Vang * curpt->m, &curpt->pos); rotf.z = 0; vset(&coriolis, 2 * curpt->v.y * curpt->m * c_Vang, -2 * curpt->v.x * curpt->m * c_Vang, 0); vaddto(&curpt->f, &rotf); vaddto(&curpt->f, &coriolis); vaddscaled(&curpt->v, TIMESTEP / curpt->m, &curpt->f); vaddscaled(&curpt->pos, TIMESTEP, &curpt->v); if(curtime <= 0) { curpt->v = vscale(.99, &curpt->v); } }
void simul() { for(int i = 0; i < numpoints; i++) { vset(&points[i].f, 0, 0, 0); } for(int i = 0; i < numpoints - 1; i++) { vector_t vdiff; GLdouble axialv, frict, elast; vector_t diff = vsub(&points[i+1].pos, &points[i].pos); GLdouble l = vnorm(&diff); vector_t f; elast = points[i].k * (1 - points[i].initlen / l); if(elast < 0) { elast = 0; } points[i].tension = elast * l; vdiff = vsub(&points[i+1].v, &points[i].v); axialv = vdot(&vdiff, &diff) / l; frict = axialv / l * points[i].frict; f = vscale(elast + frict, &diff); vaddto(&points[i].f, &f); vsubfrom(&points[i+1].f, &f); } for(int i = 0; i < numpoints; i++) { double loading = points[i].tension / points[i].crosssect / c_Slim; if(loading > 1 && curtime > 0) { points[i].k = 0; points[i].frict = 0; } } for(int i = 0; i < numpoints; i++) { pointdynamics(&points[i]); } { points[0].pos.x = c_Re * cos(0 / 180.0 * M_PI); points[0].pos.y = 0; points[0].pos.z = c_Re * sin(0 / 180.0 * M_PI); vset(&points[0].v, 0, 0, 0); if(curtime > 1) { points[BREAKPOINT].k = 0; points[BREAKPOINT].frict = 0; } } curtime += TIMESTEP; }
static void translate (State *s, float *vdst, float *ndst) { int i, j; struct abone *b; float *vsrc = s->ptrs[0]; float *nsrc = (float *) ((char *) vsrc + AL32 (s->num_vertices * 3 * sizeof (GLfloat))); struct skin *skin = s->skin; #ifdef TIMING double S = now (), E; #endif #ifdef USE_ALTIVEC vector unsigned char p0 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19 }; vector unsigned char p1 = { 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23 }; vector unsigned char p2 = { 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }; for (i = 0, j = 0; i < s->num_vertices >> 2; ++i, j += 48) { vector float v0, v1, v2, n0, n1, n2; vector float vx, vy, vz, nx, ny, nz; vector float vr0, vr1, vr2, vr3; vector float nr0, nr1, nr2, nr3; #ifdef G4 if (!(i & 3)) { DCB (dcbz, vdst, j); DCB (dcbz, ndst, j); } DCB (dcbz, vdst, j + 32); DCB (dcbz, ndst, j + 32); #endif DCB (dcbt, skin, 0); DCB (dcbt, skin + 1, 0); DCB (dcbt, skin + 2, 0); DCB (dcbt, skin + 3, 0); DCB (dcbt, vsrc, j + 64); DCB (dcbt, nsrc, j + 64); DCB (dcbt, vsrc, j + 96); DCB (dcbt, nsrc, j + 96); /* Load */ v0 = vec_ld (j, vsrc); v1 = vec_ld (j + 16, vsrc); v2 = vec_ld (j + 32, vsrc); n0 = vec_ld (j, nsrc); n1 = vec_ld (j + 16, nsrc); n2 = vec_ld (j + 32, nsrc); /* First vertex/normal */ vx = vec_splat (v0, 0); vy = vec_splat (v0, 1); vz = vec_splat (v0, 2); nx = vec_splat (n0, 0); ny = vec_splat (n0, 1); nz = vec_splat (n0, 2); vr0 = appbones (s, skin, vx, vy, vz, nx, ny, nz, &nr0); skin++; /* Second vertex/normal */ vx = vec_splat (v0, 3); vy = vec_splat (v1, 0); vz = vec_splat (v1, 1); nx = vec_splat (n0, 3); ny = vec_splat (n1, 0); nz = vec_splat (n1, 1); vr1 = appbones (s, skin, vx, vy, vz, nx, ny, nz, &nr1); skin++; /* Third vertex/normal */ vx = vec_splat (v1, 2); vy = vec_splat (v1, 3); vz = vec_splat (v2, 0); nx = vec_splat (n1, 2); ny = vec_splat (n1, 3); nz = vec_splat (n2, 0); vr2 = appbones (s, skin, vx, vy, vz, nx, ny, nz, &nr2); skin++; /* Fourth vertex/normal */ vx = vec_splat (v2, 1); vy = vec_splat (v2, 2); vz = vec_splat (v2, 3); nx = vec_splat (n2, 1); ny = vec_splat (n2, 2); nz = vec_splat (n2, 3); vr3 = appbones (s, skin, vx, vy, vz, nx, ny, nz, &nr3); skin++; /* Assemble */ v0 = vec_perm (vr0, vr1, p0); v1 = vec_perm (vr1, vr2, p1); v2 = vec_perm (vr2, vr3, p2); n0 = vec_perm (nr0, nr1, p0); n1 = vec_perm (nr1, nr2, p1); n2 = vec_perm (nr2, nr3, p2); /* Store */ vec_st (v0, j, vdst); vec_st (v1, j + 16, vdst); vec_st (v2, j + 32, vdst); vec_st (n0, j, ndst); vec_st (n1, j + 16, ndst); vec_st (n2, j + 32, ndst); } i <<= 2; vsrc += i*3; nsrc += i*3; vdst += i*3; ndst += i*3; #else i = 0; #endif for (; i < s->num_vertices; ++i, vsrc += 3, nsrc += 3, vdst += 3, ndst += 3, ++skin) { int num_bones, bone_index; float v[3] = {0,0,0}, n[3] = {0,0,0}, v0[4], v1[4], w; num_bones = skin->boneinfo & 3; bone_index = skin->boneinfo >> 2; for (j = 0; j < num_bones; ++j) { w = skin->weights[j]; b = &s->abones[bone_index & 0x3ff]; bone_index >>= 10; mapply_to_point (v1, b->cm, vsrc); v1[0] *= w; v1[1] *= w; v1[2] *= w; mapply_to_vector (v0, b->cm, nsrc); v0[0] *= w; v0[1] *= w; v0[2] *= w; vaddto (v, v1); vaddto (n, v0); } vcopy (vdst, v); vcopy (ndst, n); } #ifdef TIMING E = now (); printf ("took %f sec\n", E - S); #endif }