int main(int argc, char* argv[]) { puts("args: path/to/obj path/to/bmp"); FILE* const fobj = oload(argc == 3 ? argv[1] : "model/salesman.obj"); SDL_Surface* const fdif = sload(argc == 3 ? argv[2] : "model/salesman.bmp"); const Obj obj = oparse(fobj); const Triangles tv = tvgen(obj); // Triangle Vertices. const Triangles tt = ttgen(obj); // Triangle Textures. const Triangles tn = tngen(obj); // Triangle Normals. const Sdl sdl = ssetup(800, 600); float* const zbuff = (float*) malloc(sizeof(float) * sdl.xres * sdl.yres); for(Input input = iinit(); !input.done; input = ipump(input)) { uint32_t* const pixel = slock(sdl); reset(zbuff, pixel, sdl.xres * sdl.yres); const Vertex center = { 0.0f, 0.0f, 0.0f }; const Vertex upward = { 0.0f, 1.0f, 0.0f }; const Vertex eye = { sinf(input.xt), sinf(input.yt), cosf(input.xt) }; const Vertex z = vunit(vsub(eye, center)); const Vertex x = vunit(vcross(upward, z)); const Vertex y = vcross(z, x); for(int i = 0; i < tv.count; i++) { const Triangle nrm = tviewnrm(tn.triangle[i], x, y, z); const Triangle tex = tt.triangle[i]; const Triangle tri = tviewtri(tv.triangle[i], x, y, z, eye); const Triangle per = tperspective(tri); const Triangle vew = tviewport(per, sdl); const Target target = { vew, nrm, tex, fdif }; tdraw(sdl.yres, pixel, zbuff, target); } sunlock(sdl); schurn(sdl); spresent(sdl); } // Let the OS free hoisted memory for a quick exit. return 0; }
void resolve_collisions() { int i; //double friction = 0.9; vector normal = (vector) {1, M_PI/2}; point node_xy; for (i=0; i<NODES; i++) { node_xy = cast_point(&nodes[i].pos); double distance = node_xy.y; if (distance < nodes[i].radius) { double projection = vvmult(&nodes[i].vel, &normal); vector scaled = vsmult(&normal, 2*projection); vector reflection = vsub(&nodes[i].vel, &scaled); //reflection.m *= friction; nodes[i].vel = reflection; } } }
bool updateParticle(tParticle *particle,tEmitter *emitter, float dt) { if (particle == NULL)return false; if (particle->life > 0) { for(int i=0; i < substep; i++) { particle->prevPos = particle->pos; tVector dir = vsub(cursor->pos,particle->pos); tVector forces = vscale(dir,atractorScale); // tVector forces = vmake(0,0); forces=vadd(emitter->forces,forces); tVector incv = vscale(forces, 1.0f/particle->mass); particle->vel = vadd(particle->vel, vscale(incv,dt)); particle->pos = vadd(particle->pos, vscale(particle->vel,dt)); } //particle->prevColor = particle->color; //particle->color += particle->deltaColor; particle->radius = max(4.0f,((float)particle->life/(float)myEmmiter->life)*min_radius); particle->life--; } else//(particle->life == 0) { //... si la partícula ha muerto eliminarla y devolverla al grupo de partículas if (particle->prev != NULL) particle->prev->next = particle->next; else emitter->particle = particle->next; if (particle->next != NULL) particle->next->prev = particle->prev; //devuelve la particula al pool particle->next = particlePool.head->next; if( particlePool.head->next!=NULL)particlePool.head->next->prev = particle; particle->prev = particlePool.head; particlePool.head->next = particle; emitter->particleCount--; } return true; }
static void set_refract_ray_prim(t_env *e, t_env *refract) { t_vector n; refract->ray.loc = vadd(e->ray.loc, vmult(e->ray.dir, e->t)); n = get_normal(e, refract->ray.loc); if (refract->flags & RAY_INSIDE) { n = vunit(vsub((t_vector){0.0, 0.0, 0.0}, n)); if (refract_prim(e, refract, n)) refract->flags &= ~RAY_INSIDE; else set_reflect_ray(e, refract); } else { if (refract_prim(e, refract, n)) refract->flags |= RAY_INSIDE; else set_reflect_ray(e, refract); } }
void appendArrowHead(struct duDebugDraw* dd, const float* p, const float* q, const float s, unsigned int col) { const float eps = 0.001f; if (!dd) return; if (vdistSqr(p,q) < eps*eps) return; float ax[3], ay[3] = {0,1,0}, az[3]; vsub(az, q, p); vnormalize(az); vcross(ax, ay, az); vcross(ay, az, ax); vnormalize(ay); dd->vertex(p, col); // dd->vertex(p[0]+az[0]*s+ay[0]*s/2, p[1]+az[1]*s+ay[1]*s/2, p[2]+az[2]*s+ay[2]*s/2, col); dd->vertex(p[0]+az[0]*s+ax[0]*s/3, p[1]+az[1]*s+ax[1]*s/3, p[2]+az[2]*s+ax[2]*s/3, col); dd->vertex(p, col); // dd->vertex(p[0]+az[0]*s-ay[0]*s/2, p[1]+az[1]*s-ay[1]*s/2, p[2]+az[2]*s-ay[2]*s/2, col); dd->vertex(p[0]+az[0]*s-ax[0]*s/3, p[1]+az[1]*s-ax[1]*s/3, p[2]+az[2]*s-ax[2]*s/3, col); }
int intersect_disk(t_ray *r, t_prim *o, double *t) { t_vector point; double denominator; double numerator; double t0; if ((denominator = vdot(r->dir, o->normal)) == 0) return (0); numerator = vdot(o->loc, o->normal) - vdot(r->loc, o->normal); t0 = numerator / denominator; if (t0 > EPSILON) { point = vadd(r->loc, vmult(r->dir, t0)); if (vnormalize(vsub(point, o->loc)) <= o->radius) { *t = t0; return (1); } return (0); } return (0); }
/* Ok, simulate a track-ball. Project the points onto the virtual * trackball, then figure out the axis of rotation, which is the cross * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) * Note: This is a deformed trackball-- is a trackball in the center, * but is deformed into a hyperbolic sheet of rotation away from the * center. This particular function was chosen after trying out * several variations. * * It is assumed that the arguments to this routine are in the range * (-1.0 ... 1.0) */ void trackball(double q[4], double p1x, double p1y, double p2x, double p2y){ double axis[3]; /* Axis of rotation */ double phi; /* how much to rotate about axis */ double p1[3], p2[3], d[3]; double t; /* if zero rotation */ if(p1x == p2x && p1y == p2y){ vset(q, 0.0, 0.0, 0.0); q[3] = 1.0; return; } /* First, figure out z-coordinates for projection of P1 and P2 to */ /* the deformed sphere */ p1[0] = p1x; p1[1] = p1y; p1[2] = tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y); p2[0] = p2x; p2[1] = p2y; p2[2] = tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y); /* Now, we want the cross product of P1 and P2 */ vcross(axis, p2, p1); /* Figure out how much to rotate around that axis. */ vsub(d, p1, p2); t = vlength(d)/(2.0*TRACKBALLSIZE); /* Avoid problems with out-of-control values. */ if(t > 1.0){ t = 1.0; } if(t < -1.0){ t = -1.0; } phi = 2.0 * asin(t); axis_to_quat(axis, phi, q); }
double calcularIntensidadeEspecular(Object object, Ray rayOlho, Light luz) { double retorno = 0; //achando a normal Vec ponto = calcularPonto(object, rayOlho); Vec normal = calcularNormal(object, ponto); normal = normalize(normal); //achando o vetor oposto à luz Vec rIn = luz.dir; rIn = svmpy(-1, rIn); rIn = normalize(rIn); //R = 2N(N.L) - L ou R = N * 2*cos - L double cos = dot(normal, rIn); if(cos < 0) cos = 0; Vec r = vsub(svmpy(2 * cos, normal), rIn); r = normalize(r); //achando v (vetor do olho) Vec v = rayOlho.dir; v = svmpy(-1, v); v = normalize(v); //se não for raio de sombra Ray raySombra; raySombra.dir = rIn; raySombra.org = ponto; if(!isRaioSombra(raySombra)) { //intensidade = I * ks*cosª double cos2 = dot(r, v); if(cos2 < 0) cos2 = 0; retorno = luz.Int*(object.quad->m.Ks * (pow(cos2, object.quad->m.n))); } return retorno; }
vector<int> MakeNeighborhood(int width, int ndim, const int* dims) { int fwidth = 2*width + 1; int n = (int)(pow((double)fwidth, (double)ndim)); vector<int> vindex; vector<int> vsub(ndim); int i, j; for(i=0; i<n; ++i) { int m = i; bool bSelf = true; for(j=0; j<ndim; ++j) { vsub[j] = m % fwidth - width; m /= fwidth; if(vsub[j] != 0) { bSelf = false; } } if(bSelf) { //self is not its neighbor continue; } int index=Sub2IndCentered(vsub,ndim,dims); if(index != 0) { vindex.push_back(index); } } return vindex; }
void geRK4Integrate(ge_RK4State* state, double t, double dt){ ge_RK4Deriv a = geRK4Evaluate0(*state); ge_RK4Deriv b = geRK4Evaluate(*state, t, dt*1.0/3.0, a); ge_RK4Deriv ab; ab.force = vadd(2, a.force, b.force); ab.velocity = vadd(2, a.velocity, b.velocity); ge_RK4Deriv c = geRK4Evaluate(*state, t, dt*1.0/6.0, ab); ge_RK4Deriv ac; ac.force = vadd(2, a.force, vmulk(c.force, 3.0)); ac.velocity = vadd(2, a.velocity, vmulk(c.velocity, 3.0)); ge_RK4Deriv d = geRK4Evaluate(*state, t, dt*1.0/8.0, ac); ge_RK4Deriv acd; acd.force = vadd(2, a.force, vmulk(d.force, 4.0)); acd.velocity = vadd(2, vsub(2, a.velocity, vmulk(c.velocity, 3.0)), vmulk(d.velocity, 4.0)); ge_RK4Deriv e = geRK4Evaluate(*state, t, dt*1.0/2.0, acd); // state.position += 1.0f/6.0f * dt * (a.velocity + 4.0f*d.velocity + e.velocity); // state.momentum += 1.0f/6.0f * dt * (a.force + 4.0f*d.force + e.force); state->position = vadd(2, state->position, vmulk(vadd(3, a.velocity, vmulk(d.velocity, 4.0), e.velocity), 1.0f/6.0f * dt)); state->momentum = vadd(2, state->momentum, vmulk(vadd(3, a.force, vmulk(d.force, 4.0), e.force), 1.0f/6.0f * dt)); geRK4Recalculate(state); }
/* * Ok, simulate a track-ball. Project the points onto the virtual * trackball, then figure out the axis of rotation, which is the cross * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0) * Note: This is a deformed trackball-- is a trackball in the center, * but is deformed into a hyperbolic sheet of rotation away from the * center. This particular function was chosen after trying out * several variations. * * It is assumed that the arguments to this routine are in the range * (-1.0 ... 1.0) */ void trackball(float q[4], float p1x, float p1y, float p2x, float p2y, float tbSize) { float a[3]; // Axis of rotation float phi; // how much to rotate about axis float p1[3], p2[3], d[3]; float t; if( p1x == p2x && p1y == p2y ) { /* Zero rotation */ vzero(q); q[3] = 1.0; return; } // First, figure out z-coordinates for projection of P1 and P2 to deformed sphere vset( p1, p1x, p1y, tb_project_to_sphere(tbSize, p1x, p1y) ); vset( p2, p2x, p2y, tb_project_to_sphere(tbSize, p2x, p2y) ); // Now, we want the cross product of P1 and P2 vcross( p2, p1, a); // Figure out how much to rotate around that axis vsub( p1, p2, d); t = vlength(d) / ( 2.0f * tbSize ); // Avoid problems with out-of-control values if (t > 1.0) { t = 1.0; } if (t < -1.0) { t = -1.0; } phi = 2.0f * (float)asin(t); axis_to_quat( a, phi, q ); }
CAMLprim value ml_skin_set_anim (value anim_v) { int i; CAMLparam1 (anim_v); CAMLlocal1 (floats_v); State *s = &glob_state; struct bone *b = s->bones + 1; struct abone *ab = s->abones + 1; for (i = 0; i < s->num_bones; ++i, ++b) { floats_v = Field (anim_v, i); b->aq[0] = Double_field (floats_v, 0); b->aq[1] = Double_field (floats_v, 1); b->aq[2] = Double_field (floats_v, 2); b->aq[3] = Double_field (floats_v, 3); } b = s->bones + 1; for (i = 0; i < s->num_bones; ++i, ++b, ++ab) { float v[4], v1[4], q[4], q1[4]; struct bone *parent = &s->bones[b->parent]; qapply (v, parent->amq, b->v); qcompose (b->amq, b->aq, parent->amq); vadd (b->amv, v, parent->amv); qconjugate (q1, b->mq); qcompose (q, q1, b->amq); qapply (v, q, b->mv); vsub (v1, b->amv, v); q2matrixt (ab->cm, q, v1); } CAMLreturn (Val_unit); }
static int colorcheckmap(float ppos[3], float c[3]) { static float norm[3] = { 0.0f, 0.0f, 1.0f }; float ldir[3], vdir[3], h[3], dfact, kfact, r, g, b; int x, y; x = (int) ((ppos[0] + BASESIZE / 2) * (10.0f / BASESIZE)); if ((x < 0) || (x > 10)) return GL_FALSE; y = (int) ((ppos[1] + BASESIZE / 2) * (10.0f / BASESIZE)); if ((y < 0) || (y > 10)) return GL_FALSE; r = 255.0f; if (y & 1) { if (x & 1) g = 255.0f; else g = 0.0f; } else { if (x & 1) g = 0.0f; else g = 255.0f; } b = 0.0f; vsub(ldir, lightpos, ppos); vnormalize(ldir, ldir); if (seelight(ppos, ldir)) { c[0] = r * 0.05f; c[1] = g * 0.05f; c[2] = b * 0.05f; return GL_TRUE; } dfact = dprod(ldir, norm); if (dfact < 0.0f) dfact = 0.0f; vsub(vdir, obs, ppos); vnormalize(vdir, vdir); h[0] = 0.5f * (vdir[0] + ldir[0]); h[1] = 0.5f * (vdir[1] + ldir[1]); h[2] = 0.5f * (vdir[2] + ldir[2]); kfact = dprod(h, norm); kfact = pow(kfact, 6.0) * 7.0 * 255.0; r = r * dfact + kfact; g = g * dfact + kfact; b = b * dfact + kfact; c[0] = clamp255(r); c[1] = clamp255(g); c[2] = clamp255(b); return GL_TRUE; }
static void updatereflectmap(int slot) { float rf, r, g, b, t, dfact, kfact, rdir[3]; float rcol[3], ppos[3], norm[3], ldir[3], h[3], vdir[3], planepos[3]; int x, y; glBindTexture(GL_TEXTURE_2D, reflectid); for (y = slot * TEX_REFLECT_SLOT_SIZE; y < (slot + 1) * TEX_REFLECT_SLOT_SIZE; y++) for (x = 0; x < TEX_REFLECT_WIDTH; x++) { ppos[0] = sphere_pos[y][x][0] + objpos[0]; ppos[1] = sphere_pos[y][x][1] + objpos[1]; ppos[2] = sphere_pos[y][x][2] + objpos[2]; vsub(norm, ppos, objpos); vnormalize(norm, norm); vsub(ldir, lightpos, ppos); vnormalize(ldir, ldir); vsub(vdir, obs, ppos); vnormalize(vdir, vdir); rf = 2.0f * dprod(norm, vdir); if (rf > EPSILON) { rdir[0] = rf * norm[0] - vdir[0]; rdir[1] = rf * norm[1] - vdir[1]; rdir[2] = rf * norm[2] - vdir[2]; t = -objpos[2] / rdir[2]; if (t > EPSILON) { planepos[0] = objpos[0] + t * rdir[0]; planepos[1] = objpos[1] + t * rdir[1]; planepos[2] = 0.0f; if (!colorcheckmap(planepos, rcol)) rcol[0] = rcol[1] = rcol[2] = 0.0f; } else rcol[0] = rcol[1] = rcol[2] = 0.0f; } else rcol[0] = rcol[1] = rcol[2] = 0.0f; dfact = 0.1f * dprod(ldir, norm); if (dfact < 0.0f) { dfact = 0.0f; kfact = 0.0f; } else { h[0] = 0.5f * (vdir[0] + ldir[0]); h[1] = 0.5f * (vdir[1] + ldir[1]); h[2] = 0.5f * (vdir[2] + ldir[2]); kfact = dprod(h, norm); kfact = pow(kfact, 4.0); if (kfact < 1.0e-10) kfact = 0.0; } r = dfact + kfact; g = dfact + kfact; b = dfact + kfact; r *= 255.0f; g *= 255.0f; b *= 255.0f; r += rcol[0]; g += rcol[1]; b += rcol[2]; r = clamp255(r); g = clamp255(g); b = clamp255(b); reflectmap[y][x][0] = (GLubyte) r; reflectmap[y][x][1] = (GLubyte) g; reflectmap[y][x][2] = (GLubyte) b; } glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_REFLECT_SLOT_SIZE, TEX_REFLECT_WIDTH, TEX_REFLECT_SLOT_SIZE, GL_RGB, GL_UNSIGNED_BYTE, &reflectmap[slot * TEX_REFLECT_SLOT_SIZE][0][0]); }
void DistanceTransformEuclid(vector<double>& D, const vector<unsigned char>& L, int ndim, const int* dims) { int i,n; for(i=0; i<D.size(); ++i) { if(L[i]) D[i]=0; else D[i]=INFINITY_FELZENSWALB; } int nvoxels=numberOfElements(ndim,dims); int stride=1; vector<int> vsub(ndim); //subscript buffer for(n=0; n<ndim; ++n) { vector<double> buffer(dims[n]); int offset=0; for(int m=0; m<nvoxels/dims[n]; m++) { //compute the offset int m2=m; int k; for(k=0; k<ndim; ++k) { if(k!=n) { vsub[k]=m2 % dims[k]; m2/=dims[k]; } else vsub[k]=0; } int offset=0; int stride2=1; for(k=0; k<ndim; ++k) { offset+=vsub[k]*stride2; stride2*=dims[k]; } //copy relevant line of data for(k=0; k<dims[n]; ++k) buffer[k]=GetData(D,offset+k*stride,(double)0); //do the computation vector<double> dst = dt_Felzenszwalb(buffer,dims[n]); //update the distance for(k=0; k<dims[n]; ++k) SetData(D,offset+k*stride,dst[k]); } stride*=dims[n]; } //take the square root of the distance square for(n=0; n<D.size(); ++n) D[n]=sqrt(D[n]); //no array limit checking... }
//----------------------------------------------------------------------------- void RunGame() { // Control main ship if (g_gs == GS_VICTORY || g_gs == GS_STARTING) { if (MAIN_SHIP.vel.y < SHIP_CRUISE_SPEED) { MAIN_SHIP.vel.y = SAFEADD(MAIN_SHIP.vel.y, SHIP_INC_SPEED, SHIP_CRUISE_SPEED); } MAIN_SHIP.fuel = SAFESUB(MAIN_SHIP.fuel, FRAME_FUEL_COST); } // Heal main ship if (g_gs != GS_DYING) { if (MAIN_SHIP.energy < MAX_ENERGY && MAIN_SHIP.fuel > MIN_FUEL_FOR_HEAL) { MAIN_SHIP.energy = SAFEADD(MAIN_SHIP.energy, ENERGY_HEAL_PER_FRAME, MAX_ENERGY); MAIN_SHIP.fuel = SAFESUB(MAIN_SHIP.fuel, FUEL_HEAL_PER_FRAME); LOG(("- energy: %f, fuel: %f\n", MAIN_SHIP.energy, MAIN_SHIP.fuel)); } } // Move entities for (int i = MAX_ENTITIES - 1; i >= 0; i--) { if (g_entities[i].type != E_NULL) { g_entities[i].pos = vadd(g_entities[i].pos, g_entities[i].vel); // Remove entities that fell off screen if (g_entities[i].pos.y < g_camera_offset - G_HEIGHT) g_entities[i].type = E_NULL; } } // Advance "stars" for (int i = 0; i < MAX_ENTITIES; i++) { if (g_entities[i].type == E_STAR) g_entities[i].gfxscale *= 1.008f; } // Dont let steering off the screen if (MAIN_SHIP.pos.x < MAINSHIP_RADIUS) MAIN_SHIP.pos.x = MAINSHIP_RADIUS; if (MAIN_SHIP.pos.x > G_WIDTH - MAINSHIP_RADIUS) MAIN_SHIP.pos.x = G_WIDTH - MAINSHIP_RADIUS; // Check collisions if (g_gs == GS_PLAYING) { // Check everything against ship for (int i = 1; i < MAX_ENTITIES; i++) { // Should check against ship? if (g_entities[i].type == E_ROCK || g_entities[i].type == E_JUICE || g_entities[i].type == E_MINE || g_entities[i].type == E_DRONE) { float distance = vlen2(vsub(g_entities[i].pos, MAIN_SHIP.pos)); // Distance from object to ship float crash_distance = CORE_FSquare(g_entities[i].radius + MAIN_SHIP.radius); // Minimum allowed distance before crash if (distance < crash_distance) { switch (g_entities[i].type) { case E_ROCK: if (g_entities[i].energy > 0) { MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, ROCK_CRASH_ENERGY_LOSS); MAIN_SHIP.vel.y = SHIP_START_SPEED; // Set rock velocity vec2 vel_direction = vsub(g_entities[i].pos, MAIN_SHIP.pos); // direction of rock velocity, away from ship vec2 normalized_vel_direction = vunit(vel_direction); // normalize vec2 vel = vscale(normalized_vel_direction, CRASH_VEL); // Scale, ie give the rock correct speed. g_entities[i].vel = vel; g_entities[i].energy = 0; } break; case E_JUICE: MAIN_SHIP.fuel = SAFEADD(MAIN_SHIP.fuel, JUICE_FUEL, MAX_FUEL); g_entities[i].type = E_NULL; break; case E_MINE: MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, MINE_CRASH_ENERGY_LOSS); MAIN_SHIP.vel.y = SHIP_START_SPEED; g_entities[i].type = E_NULL; break; case E_DRONE: MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, MINE_CRASH_ENERGY_LOSS); MAIN_SHIP.vel.y = SHIP_START_SPEED; g_entities[i].type = E_NULL; break; default: break; } } } else if (g_entities[i].type == E_ROCKET) { // Check all hit-able objects against this rocket for (int j = 1; i < MAX_ENTITIES; j++) { // Should check against rocket? if (g_entities[j].type == E_ROCK || g_entities[j].type == E_MINE || g_entities[j].type == E_DRONE) { float distance = vlen2(vsub(g_entities[i].pos, g_entities[j].pos)); float crash_distance = CORE_FSquare(g_entities[i].radius + g_entities[j].radius); if (distance < crash_distance) { // Impact! g_entities[i].type = E_NULL; g_entities[j].type = E_NULL; break; } } } } } } // Generate new level elements as we advance GenNextElements(); // Possibly insert new juice if (g_gs == GS_PLAYING) { float trench = MAIN_SHIP.pos.y - g_current_race_pos; // How much advanced from previous frame if (CORE_RandChance(trench * JUICE_CHANCE_PER_PIXEL)) { vec2 pos = vmake(CORE_FRand(0.f, G_WIDTH), g_camera_offset + G_HEIGHT + GEN_IN_ADVANCE); // Random x, insert 400y above window vec2 vel = vmake(CORE_FRand(-1.f, +1.f), CORE_FRand(-1.f, +1.f)); // Random small velocity to make rocks "float" InsertEntity(E_JUICE, pos, vel, JUICE_RADIUS, g_juice, false, true); } } // Set camera to follow the main ship g_camera_offset = MAIN_SHIP.pos.y - G_HEIGHT / 8.f; g_current_race_pos = MAIN_SHIP.pos.y; if (g_gs == GS_PLAYING) { if (g_current_race_pos >= RACE_END) // Check if victory { g_gs = GS_VICTORY; g_gs_timer = 0.f; MAIN_SHIP.gfxadditive = true; } } // Advance game mode g_gs_timer += FRAMETIME; switch (g_gs) { case GS_STARTING: if (g_gs_timer >= STARTING_TIME) // Start delay before starting to play { g_gs = GS_PLAYING; g_gs_timer = 0.f; } break; case GS_DYING: if (g_gs_timer >= DYING_TIME) { ResetNewGame(); } break; case GS_PLAYING: if (MAIN_SHIP.energy <= 0.f || MAIN_SHIP.fuel <= 0.f) // No energy or fuel --> die { g_gs = GS_DYING; g_gs_timer = 0.f; MAIN_SHIP.gfx = g_ship_RR; } break; case GS_VICTORY: if (CORE_RandChance(1.f / 10.f)) { InsertEntity(E_STAR, MAIN_SHIP.pos, vadd(MAIN_SHIP.vel, vmake(CORE_FRand(-5.f, 5.f), CORE_FRand(-5.f, 5.f))), 0, g_star, false, true); } if (g_gs_timer >= 8.f) // Should use VICTORY_TIME, but stupid VS dont want me to... { ResetNewGame(); } break; } g_time_from_last_rocket += FRAMETIME; }
void closestPtPointTriangle(float* closest, const float* p, const float* a, const float* b, const float* c) { // Check if P in vertex region outside A float ab[3], ac[3], ap[3]; vsub(ab, b, a); vsub(ac, c, a); vsub(ap, p, a); float d1 = vdot(ab, ap); float d2 = vdot(ac, ap); if (d1 <= 0.0f && d2 <= 0.0f) { // barycentric coordinates (1,0,0) vcopy(closest, a); return; } // Check if P in vertex region outside B float bp[3]; vsub(bp, p, b); float d3 = vdot(ab, bp); float d4 = vdot(ac, bp); if (d3 >= 0.0f && d4 <= d3) { // barycentric coordinates (0,1,0) vcopy(closest, b); return; } // Check if P in edge region of AB, if so return projection of P onto AB float vc = d1*d4 - d3*d2; if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { // barycentric coordinates (1-v,v,0) float v = d1 / (d1 - d3); closest[0] = a[0] + v * ab[0]; closest[1] = a[1] + v * ab[1]; closest[2] = a[2] + v * ab[2]; return; } // Check if P in vertex region outside C float cp[3]; vsub(cp, p, c); float d5 = vdot(ab, cp); float d6 = vdot(ac, cp); if (d6 >= 0.0f && d5 <= d6) { // barycentric coordinates (0,0,1) vcopy(closest, c); return; } // Check if P in edge region of AC, if so return projection of P onto AC float vb = d5*d2 - d1*d6; if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { // barycentric coordinates (1-w,0,w) float w = d2 / (d2 - d6); closest[0] = a[0] + w * ac[0]; closest[1] = a[1] + w * ac[1]; closest[2] = a[2] + w * ac[2]; return; } // Check if P in edge region of BC, if so return projection of P onto BC float va = d3*d6 - d5*d4; if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { // barycentric coordinates (0,1-w,w) float w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); closest[0] = b[0] + w * (c[0] - b[0]); closest[1] = b[1] + w * (c[1] - b[1]); closest[2] = b[2] + w * (c[2] - b[2]); return; } // P inside face region. Compute Q through its barycentric coordinates (u,v,w) float denom = 1.0f / (va + vb + vc); float v = vb * denom; float w = vc * denom; closest[0] = a[0] + ab[0] * v + ac[0] * w; closest[1] = a[1] + ab[1] * v + ac[1] * w; closest[2] = a[2] + ab[2] * v + ac[2] * w; }
static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, KX_Obstacles& obstacles, float levelHeight, const float vmax, const float* spos, const float cs, const int nspos, float* res, float maxToi, float velWeight, float curVelWeight, float sideWeight, float toiWeight) { vset(res, 0,0); const float ivmax = 1.0f / vmax; float adir[2], adist; vcpy(adir, activeObst->pvel); if (vlen(adir) > 0.01f) vnorm(adir); else vset(adir,0,0); float activeObstPos[2]; vset(activeObstPos, activeObst->m_pos.x(), activeObst->m_pos.y()); adist = vdot(adir, activeObstPos); float minPenalty = FLT_MAX; for (int n = 0; n < nspos; ++n) { float vcand[2]; vcpy(vcand, &spos[n*2]); // Find min time of impact and exit amongst all obstacles. float tmin = maxToi; float side = 0; int nside = 0; for (int i = 0; i < obstacles.size(); ++i) { KX_Obstacle* ob = obstacles[i]; bool res = filterObstacle(activeObst, activeNavMeshObj, ob, levelHeight); if (!res) continue; float htmin, htmax; if (ob->m_shape==KX_OBSTACLE_CIRCLE) { float vab[2]; // Moving, use RVO vscale(vab, vcand, 2); vsub(vab, vab, activeObst->vel); vsub(vab, vab, ob->vel); // Side // NOTE: dp, and dv are constant over the whole calculation, // they can be precomputed per object. const float* pa = activeObstPos; float pb[2]; vset(pb, ob->m_pos.x(), ob->m_pos.y()); const float orig[2] = {0,0}; float dp[2],dv[2],np[2]; vsub(dp,pb,pa); vnorm(dp); vsub(dv,ob->dvel, activeObst->dvel); const float a = triarea(orig, dp,dv); if (a < 0.01f) { np[0] = -dp[1]; np[1] = dp[0]; } else { np[0] = dp[1]; np[1] = -dp[0]; } side += clamp(min(vdot(dp,vab)*2,vdot(np,vab)*2), 0.0f, 1.0f); nside++; if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, vab, ob->m_pos, ob->m_rad, htmin, htmax)) continue; // Handle overlapping obstacles. if (htmin < 0.0f && htmax > 0.0f) { // Avoid more when overlapped. htmin = -htmin * 0.5f; } } else if (ob->m_shape == KX_OBSTACLE_SEGMENT) { MT_Point3 p1 = ob->m_pos; MT_Point3 p2 = ob->m_pos2; //apply world transform if (ob->m_type == KX_OBSTACLE_NAV_MESH) { KX_NavMeshObject* navmeshobj = static_cast<KX_NavMeshObject*>(ob->m_gameObj); p1 = navmeshobj->TransformToWorldCoords(p1); p2 = navmeshobj->TransformToWorldCoords(p2); } float p[2], q[2]; vset(p, p1.x(), p1.y()); vset(q, p2.x(), p2.y()); // NOTE: the segments are assumed to come from a navmesh which is shrunken by // the agent radius, hence the use of really small radius. // This can be handle more efficiently by using seg-seg test instead. // If the whole segment is to be treated as obstacle, use agent->rad instead of 0.01f! const float r = 0.01f; // agent->rad if (distPtSegSqr(activeObstPos, p, q) < sqr(r+ob->m_rad)) { float sdir[2], snorm[2]; vsub(sdir, q, p); snorm[0] = sdir[1]; snorm[1] = -sdir[0]; // If the velocity is pointing towards the segment, no collision. if (vdot(snorm, vcand) < 0.0f) continue; // Else immediate collision. htmin = 0.0f; htmax = 10.0f; } else { if (!sweepCircleSegment(activeObstPos, r, vcand, p, q, ob->m_rad, htmin, htmax)) continue; } // Avoid less when facing walls. htmin *= 2.0f; } if (htmin >= 0.0f) { // The closest obstacle is somewhere ahead of us, keep track of nearest obstacle. if (htmin < tmin) tmin = htmin; } } // Normalize side bias, to prevent it dominating too much. if (nside) side /= nside; const float vpen = velWeight * (vdist(vcand, activeObst->dvel) * ivmax); const float vcpen = curVelWeight * (vdist(vcand, activeObst->vel) * ivmax); const float spen = sideWeight * side; const float tpen = toiWeight * (1.0f/(0.1f+tmin/maxToi)); const float penalty = vpen + vcpen + spen + tpen; if (penalty < minPenalty) { minPenalty = penalty; vcpy(res, vcand); } } }
void CChildView::PrefilterEnvMap(float* res, float Roughness, float* R){ //int maxY = imgOriginal.GetHeight(), maxX = imgOriginal.GetWidth(); int maxY = cube[0].GetHeight(), maxX = cube[0].GetWidth(); float angle1, angle2, angle3, a, b; int plane; COLORREF pixel; float* N = R; float* V = R; res[0] = res[1] = res[2] = 0; int NumSamples = 512; float TotalWeight = 0.0; float* Xi = new float[2]; float* H = new float[3]; float* L = new float[3]; float* center = new float[3]; float* tmp = new float[3]; float* z = new float[3]; float* x = new float[3]; x[0] = 1.0f; x[1] = 0.0f; x[2] = 0.0f; z[0] = 0.0f; z[1] = 0.0f; z[2] = 1.0f; center[0] = 0.5; center[1] = 0.5; center[2] = -0.5; for (int i = 0; i < NumSamples; i++) { Hammersley(Xi, i, NumSamples); ImportanceSampleGGX(H, Xi, Roughness, N); vmul(L, 2.0f * dot(V, H), H); vsub(L, V); float NoL = saturate(dot(N, L)); if (NoL > 0){ //First we calculate the angle of plane x-z,z-y to axis z, x-y to axis x //x-z z tmp[0] = L[0]; tmp[1] = 0.0f; tmp[2] = L[2]; normalize(tmp); angle1 = tmp[2]; //x-y y tmp[0] = L[0]; tmp[1] = L[1]; tmp[2] = 0.0f; normalize(tmp); angle2 = tmp[0]; //y-z z tmp[0] = 0.0f; tmp[1] = L[1]; tmp[2] = L[2]; normalize(tmp); angle3 = tmp[2]; //judge in which plane if (angle1 >= 0.71f && angle3 >= 0.71f){ plane = 2; vmul(L, 0.5f / L[2], L); a = L[1] + 0.5f; b = (L[0] + 0.5f); } else if (angle1 <= -0.71f && angle3 <= -0.71f){ plane = 3; vmul(L, 0.5f / L[2], L); a = 1.0f - (L[1] + 0.5f); b = L[0] + 0.5f; } else if (angle2 >= 0.71f){ plane = 4; vmul(L, 0.5f / L[0], L); a = 1.0f - (L[1] + 0.5f); b = 1.0f - (L[2] + 0.5f); } else if (angle2 <= -0.71f){ plane = 5; vmul(L, 0.5f / L[0], L); a = 1.0f - (L[1] + 0.5f); b = 1.0f - (L[2] + 0.5f); } else if (L[1] >= 0){ plane = 1; vmul(L, 0.5f / L[1], L); a = (L[0] + 0.5f); b = (L[2] + 0.5f); } else if (L[1] < 0){ plane = 0; vmul(L, 0.5f / L[1], L); a = L[0] + 0.5f; b = 1.0f - (L[2] + 0.5f); } else{ plane = 0; a = 0; b = 0; ::AfxMessageBox(_T("ERROR")); } //Eliminate boundary if (a > 1.0f || a<0.0f || b>1.0f || b < 0.0f){ CString tstr; tstr.Format(_T("plane: %d a: %lf b: %lf"), plane, a, b); //::AfxMessageBox(tstr); } a = (a < 0.0f) ? 0.0f : a; b = (b < 0.0f) ? 0.0f : b; a = (a > 1.0f) ? 1.0f : a; b = (b > 1.0f) ? 1.0f : b; a = a * (maxX-1); b = (1.0f-b) * (maxY-1); pixel = cube[plane].GetPixel((int)a,(int)b); L[0] = GetRValue(pixel); L[1] = GetGValue(pixel); L[2] = GetBValue(pixel); vmul(L, NoL, L); vadd(res, L); //res += textureCube(cubemap, L).rgb * NoL; TotalWeight += NoL; } } vmul(res, 1/TotalWeight, res); delete[] Xi; delete[] H; delete[] L; delete[] center; delete[] tmp; delete[] x; delete[] z; }
static void simulate(void) { int sh, i, j, pl, pl2, actp; double l; Vec2d v; for(i = 0; i < conf.segmentSteps; ++i) { for(pl = 0; pl < conf.maxPlayers; ++pl) { SimPlayer* p = &(player[pl]); if(p->watch) continue; if(!p->active) continue; for(sh = 0; sh < conf.numShots; ++sh) { SimShot* s = &(p->shot[sh]); SimMissile* m = &(s->missile); if(!m->live) continue; for(j = 0; j < conf.numPlanets; ++j) { v = vsub(planet[j].position, m->position); l = length(v); if (l <= planet[j].radius) { planetHit(s); } v = vdiv(v, l); v = vmul(v, planet[j].mass / (l * l)); v = vdiv(v, conf.segmentSteps); m->speed = vadd(m->speed, v); } v = vdiv(m->speed, conf.segmentSteps); m->position = vadd(m->position, v); for(pl2 = 0; pl2 < conf.maxPlayers; ++pl2) { if(!player[pl2].active) continue; l = distance(player[pl2].position, m->position); if ( (l <= conf.playerDiameter) && (m->leftSource == 1) ) { if(conf.debug & 1) printf("l = %.5f playerDiameter = %.5f missile.x = %.5f missile.y = %.5f player.x = %5f player.y = %5f\n",l,conf.playerDiameter,m->position.x,m->position.y,player[pl2].position.x,player[pl2].position.y); playerHit(s, pl, pl2); } if ( (l > (conf.playerDiameter + 1)) && (pl2 == pl) ) { m->leftSource = 1; } } if ( (m->position.x < -conf.marginleft) || (m->position.x > conf.battlefieldW + conf.marginright) || (m->position.y < -conf.margintop) || (m->position.y > conf.battlefieldH + conf.marginbottom) ) { wallHit(s); } } } } for(pl = 0, actp = 0; pl < conf.maxPlayers; ++pl) actp += player[pl].active; for(pl = 0; pl < conf.maxPlayers; ++pl) { SimPlayer* p = &(player[pl]); if(!p->active) continue; if(p->watch) continue; if(p->timeout) p->timeout--; if(p->valid || actp == 1) p->timeout = conf.timeout; for(sh = 0; sh < conf.numShots; ++sh) { SimShot* s = &(p->shot[sh]); if(!s->missile.live) continue; p->timeout = conf.timeout; player[currentPlayer].timeoutcnt = 0; s->dot[s->length++] = d2f(s->missile.position); if(s->length == conf.maxSegments) { s->missile.live = 0; allSendShotFinished(s); } } } }
static void cpArbiterApplyImpulse_NEON(cpArbiter *arb) { cpBody *a = arb->body_a; cpBody *b = arb->body_b; cpFloatx2_t surface_vr = vld((cpFloat_t *)&arb->surface_vr); cpFloatx2_t n = vld((cpFloat_t *)&arb->n); cpFloat_t friction = arb->u; int numContacts = arb->count; struct cpContact *contacts = arb->contacts; for(int i=0; i<numContacts; i++) { struct cpContact *con = contacts + i; cpFloatx2_t r1 = vld((cpFloat_t *)&con->r1); cpFloatx2_t r2 = vld((cpFloat_t *)&con->r2); cpFloatx2_t perp = vmake(-1.0, 1.0); cpFloatx2_t r1p = vmul(vrev(r1), perp); cpFloatx2_t r2p = vmul(vrev(r2), perp); cpFloatx2_t vBias_a = vld((cpFloat_t *)&a->v_bias); cpFloatx2_t vBias_b = vld((cpFloat_t *)&b->v_bias); cpFloatx2_t wBias = vmake(a->w_bias, b->w_bias); cpFloatx2_t vb1 = vadd(vBias_a, vmul_n(r1p, vget_lane(wBias, 0))); cpFloatx2_t vb2 = vadd(vBias_b, vmul_n(r2p, vget_lane(wBias, 1))); cpFloatx2_t vbr = vsub(vb2, vb1); cpFloatx2_t v_a = vld((cpFloat_t *)&a->v); cpFloatx2_t v_b = vld((cpFloat_t *)&b->v); cpFloatx2_t w = vmake(a->w, b->w); cpFloatx2_t v1 = vadd(v_a, vmul_n(r1p, vget_lane(w, 0))); cpFloatx2_t v2 = vadd(v_b, vmul_n(r2p, vget_lane(w, 1))); cpFloatx2_t vr = vsub(v2, v1); cpFloatx2_t vbn_vrn = vpadd(vmul(vbr, n), vmul(vr, n)); cpFloatx2_t v_offset = vmake(con->bias, -con->bounce); cpFloatx2_t jOld = vmake(con->jBias, con->jnAcc); cpFloatx2_t jbn_jn = vmul_n(vsub(v_offset, vbn_vrn), con->nMass); jbn_jn = vmax(vadd(jOld, jbn_jn), vdup_n(0.0)); cpFloatx2_t jApply = vsub(jbn_jn, jOld); cpFloatx2_t t = vmul(vrev(n), perp); cpFloatx2_t vrt_tmp = vmul(vadd(vr, surface_vr), t); cpFloatx2_t vrt = vpadd(vrt_tmp, vrt_tmp); cpFloatx2_t jtOld = {}; jtOld = vset_lane(con->jtAcc, jtOld, 0); cpFloatx2_t jtMax = vrev(vmul_n(jbn_jn, friction)); cpFloatx2_t jt = vmul_n(vrt, -con->tMass); jt = vmax(vneg(jtMax), vmin(vadd(jtOld, jt), jtMax)); cpFloatx2_t jtApply = vsub(jt, jtOld); cpFloatx2_t i_inv = vmake(-a->i_inv, b->i_inv); cpFloatx2_t nperp = vmake(1.0, -1.0); cpFloatx2_t jBias = vmul_n(n, vget_lane(jApply, 0)); cpFloatx2_t jBiasCross = vmul(vrev(jBias), nperp); cpFloatx2_t biasCrosses = vpadd(vmul(r1, jBiasCross), vmul(r2, jBiasCross)); wBias = vadd(wBias, vmul(i_inv, biasCrosses)); vBias_a = vsub(vBias_a, vmul_n(jBias, a->m_inv)); vBias_b = vadd(vBias_b, vmul_n(jBias, b->m_inv)); cpFloatx2_t j = vadd(vmul_n(n, vget_lane(jApply, 1)), vmul_n(t, vget_lane(jtApply, 0))); cpFloatx2_t jCross = vmul(vrev(j), nperp); cpFloatx2_t crosses = vpadd(vmul(r1, jCross), vmul(r2, jCross)); w = vadd(w, vmul(i_inv, crosses)); v_a = vsub(v_a, vmul_n(j, a->m_inv)); v_b = vadd(v_b, vmul_n(j, b->m_inv)); // TODO would moving these earlier help pipeline them better? vst((cpFloat_t *)&a->v_bias, vBias_a); vst((cpFloat_t *)&b->v_bias, vBias_b); vst_lane((cpFloat_t *)&a->w_bias, wBias, 0); vst_lane((cpFloat_t *)&b->w_bias, wBias, 1); vst((cpFloat_t *)&a->v, v_a); vst((cpFloat_t *)&b->v, v_b); vst_lane((cpFloat_t *)&a->w, w, 0); vst_lane((cpFloat_t *)&b->w, w, 1); vst_lane((cpFloat_t *)&con->jBias, jbn_jn, 0); vst_lane((cpFloat_t *)&con->jnAcc, jbn_jn, 1); vst_lane((cpFloat_t *)&con->jtAcc, jt, 0); } }
/* * Rasterize triangle in 3D into 2D raster plane. */ void ri_rasterize_triangle( ri_raster_plane_t *plane, ri_triangle_t *triangle) { int s, t; /* * Use ray casting for robust rasterization. */ int i; int hit; uint32_t tid; ri_float_t tparam, uparam, vparam; ri_vector_t dir; /* * p = S P M F E v * * S = | 1/2 w 0 0 0 | * | 0 1/2 h 0 0 | * | 0 0 0 0 | * | 0 0 0 0 | * * P = Projection * * | 1 | * M = | ---------- 0 0 -offt[0] | * | tan(fov/2) | * | | * | 1 | * | 0 ---------- 0 -offt[1] | * | tan(fov/2) | * | | * | 0 0 0 0 | * | | * | 0 0 0 0 | * * F = | du_x du_y du_z 0 | * | dv_x dv_y dv_z 0 | * | -dw_x -dw_y -dw_z 0 | * | 0 0 0 0 | * * E = | 1 0 0 -org_x | * | 0 1 0 -org_y | * | 0 0 1 -org_z | * | 0 0 0 1 | * * v = | x | * | y | * | z | * | w | */ ri_vector_t vo; ri_vector_t w; ri_vector_t p[3]; int width = plane->width; int height = plane->height; ri_float_t fov = plane->fov; /* in degree */ ri_float_t fov_rad = fov * M_PI / 180.0; for (i = 0; i < 3; i++) { /* vo = E v */ vsub( vo, triangle->v[i], plane->org ); /* w = F E v */ w[0] = plane->frame[0][0] * vo[0] + plane->frame[0][1] * vo[1] + plane->frame[0][2] * vo[2]; w[1] = plane->frame[1][0] * vo[0] + plane->frame[1][1] * vo[1] + plane->frame[1][2] * vo[2]; w[2] = -plane->frame[2][0] * vo[0] - plane->frame[2][1] * vo[1] - plane->frame[2][2] * vo[2]; /* p = M F E v */ p[i][0] = (1.0 / tan(0.5 * fov_rad)) * w[0]; p[i][1] = (1.0 / tan(0.5 * fov_rad)) * w[1]; p[i][2] = w[2]; printf("[raster] proj p = %f, %f, %f\n", p[i][0], p[i][1], p[i][2]); p[i][0] /= -w[2]; /* w = -z */ p[i][1] /= -w[2]; printf("[raster] proj p/w = %f, %f\n", p[i][0], p[i][1]); p[i][0] -= plane->offset[0]; p[i][1] -= plane->offset[1]; printf("[raster] offsetted = %f, %f\n", p[i][0], p[i][1]); p[i][0] *= 0.5 * width; p[i][1] *= 0.5 * height; printf("[raster] scaled = %f, %f\n", p[i][0], p[i][1]); } /* * Compute 2D bbox. */ ri_float_t bmin[2], bmax[2]; bmin[0] = bmax[0] = p[0][0]; bmin[1] = bmax[1] = p[0][1]; bmin[0] = (p[1][0] < bmin[0]) ? p[1][0] : bmin[0]; bmax[0] = (p[1][0] > bmax[0]) ? p[1][0] : bmax[0]; bmin[1] = (p[2][1] < bmin[1]) ? p[2][1] : bmin[1]; bmax[1] = (p[2][1] > bmax[1]) ? p[2][1] : bmax[1]; printf("[raster] bbox = (%d, %d) - (%d, %d)\n", (int)bmin[0], (int)bmin[1], (int)bmax[0], (int)bmax[1] ); for (t = (int)bmin[1]; t < (int)bmax[1]; t++) { for (s = (int)bmin[0]; s < (int)bmax[0]; s++) { /* corner + s * frame[0] + t * frame[1] */ dir[0] = plane->corner[0] + s * plane->frame[0][0] + t * plane->frame[1][0]; dir[1] = plane->corner[1] + s * plane->frame[0][1] + t * plane->frame[1][1]; dir[2] = plane->corner[2] + s * plane->frame[0][2] + t * plane->frame[1][2]; tparam = RI_INFINITY; printf("dir = %f, %f, %f\n", dir[0], dir[1], dir[2]); hit = ri_triangle_isect( &tid, &tparam, &uparam, &vparam, triangle, plane->org, dir, 0 ); if (hit) { printf("hit [%d, %d] t = %f\n", s, t, tparam); #ifdef RI_BVH_TRACE_BEAM_STATISTICS g_beamstattrav.nrasterpixels++; if ( image[ t * width + s ] < tparam ) { g_beamstattrav.noverdraws++; } #endif plane->t[ t * width + s ] = tparam; } else { printf("nohit[%d][%d]\n", s, t); } } } }
void Render() { glClear(GL_COLOR_BUFFER_BIT); // Render background, only tiles within camera view int first_tile = (int)floorf(g_camera_offset / G_HEIGHT); for (int i = first_tile; i < first_tile + 2; i++) { vec2 pos = vsub(vadd(vmake(G_WIDTH / 2.0f, G_HEIGHT / 2.0f), vmake(0.f, (float)i * G_HEIGHT)), vmake(0.f, g_camera_offset)); // split up, what does it? vec2 size = vmake(G_WIDTH, G_HEIGHT); CORE_RenderCenteredSprite(pos, size, g_bkg); } // Draw entities for (int i = MAX_ENTITIES - 1; i >= 0; i--) { if (g_entities[i].type != E_NULL) { ivec2 size = CORE_GetBmpSize(g_entities[i].gfx); vec2 pos = g_entities[i].pos; pos.x = (float)((int)pos.x); pos.y = (float)((int)pos.y); if (g_entities[i].has_shadow) // renders shadows first { vec2 s_pos = vadd(vsub(pos, vmake(0.f, g_camera_offset)), vmake(0.f, -SHADOW_OFFSET)); vec2 s_size = vmake(size.x * SPRITE_SCALE * g_entities[i].gfxscale * SHADOW_SCALE, size.y * SPRITE_SCALE * g_entities[i].gfxscale * SHADOW_SCALE); int s_texture = g_entities[i].gfx; rgba s_color = vmake(0.f, 0.f, 0.f, 0.4f); bool s_additive = g_entities[i].gfxadditive; CORE_RenderCenteredSprite(s_pos, s_size, s_texture, s_color, s_additive); } // Render not shadows vec2 offset_pos = vsub(pos, vmake(0.f, g_camera_offset)); // Adjust to where camera is at vec2 scaled_size = vmake(size.x * SPRITE_SCALE * g_entities[i].gfxscale, size.y * SPRITE_SCALE * g_entities[i].gfxscale); int texture = g_entities[i].gfx; rgba color = g_entities[i].color; bool additive = g_entities[i].gfxadditive; CORE_RenderCenteredSprite(offset_pos, scaled_size, texture, color, additive); } } if (g_gs != GS_VICTORY) // if not yet won { // Draw UI // The energy bar float energy_ratio = MAIN_SHIP.energy / MAX_ENERGY; vec2 e_bar_pos = vmake(ENERGY_BAR_W / 2.f, energy_ratio * ENERGY_BAR_H / 2.f); vec2 e_bar_size = vmake(ENERGY_BAR_W, ENERGY_BAR_H * energy_ratio); CORE_RenderCenteredSprite(e_bar_pos, e_bar_size, g_energy, COLOR_WHITE, true); // The fuel bar float fuel_ratio = MAIN_SHIP.fuel / MAX_FUEL; vec2 f_bar_pos = vmake(G_WIDTH - FUEL_BAR_W / 2.f, fuel_ratio * FUEL_BAR_H / 2.f); vec2 f_bar_size = vmake(FUEL_BAR_W, FUEL_BAR_H * fuel_ratio); CORE_RenderCenteredSprite(f_bar_pos, f_bar_size, g_fuel, COLOR_WHITE, true); // Draw how long you have lasted int num_chunks = (int)((g_current_race_pos / RACE_END) * MAX_CHUNKS); for (int i = 0; i < num_chunks; i++) { vec2 c_pos = vmake(G_WIDTH - 100.f, 50.f + i * 50.f); vec2 c_size = vmake(CHUNK_W, CHUNK_H); CORE_RenderCenteredSprite(c_pos, c_size, g_pearl); } } }
void CChildView::OnSrtpCubemap(){ // TODO: 在此添加命令处理程序代码 CWaitCursor wait; //int maxY = imgOriginal.GetHeight(), maxX = imgOriginal.GetWidth(); cube[0].Load(_T("left.png")); cube[1].Load(_T("right.png")); cube[2].Load(_T("up.png")); cube[3].Load(_T("buttom.png")); cube[4].Load(_T("front.png")); cube[5].Load(_T("back.png")); float* center = new float[3]; float* reflect = new float[3]; float* res = new float[3]; CImage tmpimg; for (int j = 0; j < 6; j++){ center[0] = 0.5; center[1] = 0.5; center[2] = 0.5; for (int i = 1; i < 8; i++){ int newY, newX; newY = newX = (int)pow(2.0,(8-i)); tmpimg.Create(newX, newY, 24, 0); float Roughness = (i > 4) ? 0.5f * (i - 4) : i*0.1f; for (int x = 0; x < newX; x++){ //列循环 for (int y = 0; y < newY; y++){ //行循环 switch (j){ case 0: reflect[0] = 1.0f - (float)x * 1.0f / (float)newX; reflect[1] = 0.0f; reflect[2] = 1.0f - (float)y * 1.0f / (float)newY; break; case 1: reflect[0] = (float)x * 1.0f / (float)newX; reflect[1] = 1.0f; reflect[2] = 1.0f - (float)y * 1.0f / (float)newY; break; case 2: reflect[0] = 1.0f - (float)y * 1.0f / (float)newY; reflect[1] = (float)x * 1.0f / (float)newX; reflect[2] = 1.0f; break; case 3: reflect[0] = (float)y * 1.0f / (float)newY; reflect[1] = (float)x * 1.0f / (float)newX; reflect[2] = 0.0f; break; case 4: reflect[0] = 1.0f; reflect[1] = 1.0f - (float)x * 1.0f / (float)newX; reflect[2] = 1.0f - (float)y * 1.0f / (float)newY; break; case 5: reflect[0] = 0.0; reflect[1] = (float)x * 1.0f / (float)newX; reflect[2] = 1.0f - (float)y * 1.0f / (float)newY; break; } vsub(reflect, center); normalize(reflect); PrefilterEnvMap(res, Roughness, reflect); tmpimg.SetPixelRGB(x, y, (byte)res[0], (byte)res[1], (byte)res[2]); } } CString str,pre; pre.Format(_T("%d"), j); pre = pre + _T("-"); str.Format(_T("%d"), i); str = pre + str + _T(".bmp"); HRESULT hResult = tmpimg.Save(str); if (FAILED(hResult)) { CString fmt; fmt.Format(_T("Save image failed:\n%x - %s"), hResult, _com_error(hResult).ErrorMessage()); ::AfxMessageBox(fmt); return; } tmpimg.Destroy(); } } delete[] center; delete[] reflect; delete[] res; Invalidate(); UpdateWindow(); }
f32 vdistance( const triple* x, const triple* y ){ triple v = *y; vsub( &v, x ); return vlength( &v ); }
msym_error_t partitionEquivalenceSets(int length, msym_element_t *elements[length], msym_element_t *pelements[length], msym_geometry_t g, int *esl, msym_equivalence_set_t **es, msym_thresholds_t *thresholds) { int ns = 0, gd = geometryDegenerate(g); double *e = calloc(length,sizeof(double)); double *s = calloc(length,sizeof(double)); int *sp = calloc(length,sizeof(int)); //set partition int *ss = calloc(length,sizeof(int)); //set size double (*ev)[3] = calloc(length,sizeof(double[3])); double (*ep)[3] = calloc(length,sizeof(double[3])); double (*vec)[3] = calloc(length, sizeof(double[3])); double *m = calloc(length, sizeof(double)); for(int i = 0;i < length;i++){ vcopy(elements[i]->v, vec[i]); m[i] = elements[i]->m; } for(int i=0; i < length; i++){ for(int j = i+1; j < length;j++){ double w = m[i]*m[j]/(m[i]+m[j]); double dist; double v[3]; double proji[3], projj[3]; vnorm2(vec[i],v); vproj_plane(vec[j], v, proji); vscale(w, proji, proji); vadd(proji,ep[i],ep[i]); vnorm2(vec[j],v); vproj_plane(vec[i], v, projj); vscale(w, projj, projj); vadd(projj,ep[j],ep[j]); vsub(vec[j],vec[i],v); dist = vabs(v); vscale(w/dist,v,v); vadd(v,ev[i],ev[i]); vsub(ev[j],v,ev[j]); double dij = w*dist; //This is sqrt(I) for a diatomic molecule along an axis perpendicular to the bond with O at center of mass. e[i] += dij; e[j] += dij; s[i] += SQR(dij); s[j] += SQR(dij); } vsub(vec[i],ev[i],ev[i]); } for(int i = 0; i < length; i++){ double v[3]; double w = m[i]/2.0; double dist = vabs(elements[i]->v); double dii = w*dist; vscale(w,elements[i]->v,v); vsub(ev[i],v,ev[i]); // Plane projection can't really differentiate certain types of structures when we add the initial vector, // but not doing so will result in huge cancellation errors on degenerate point groups, // also large masses will mess up the eq check when this is 0. if(gd) vadd(ep[i],v,ep[i]); e[i] += dii; s[i] += SQR(dii); } for(int i = 0; i < length; i++){ if(e[i] >= 0.0){ sp[i] = i; for(int j = i+1; j < length;j++){ if(e[j] >= 0.0){ double vabsevi = vabs(ev[i]), vabsevj = vabs(ev[j]), vabsepi = vabs(ep[i]), vabsepj = vabs(ep[j]); double eep = 0.0, eev = fabs((vabsevi)-(vabsevj))/((vabsevi)+(vabsevj)), ee = fabs((e[i])-(e[j]))/((e[i])+(e[j])), es = fabs((s[i])-(s[j]))/((s[i])+(s[j])); if(!(vabsepi < thresholds->zero && vabsepj < thresholds->zero)){ eep = fabs((vabsepi)-(vabsepj))/((vabsepi)+(vabsepj)); } double max = fmax(eev,fmax(eep,fmax(ee, es))); if(max < thresholds->equivalence && elements[i]->n == elements[j]->n){ e[j] = max > 0.0 ? -max : -1.0; sp[j] = i; } } } e[i] = -1.0; } } for(int i = 0; i < length;i++){ int j = sp[i]; ns += (ss[j] == 0); ss[j]++; } msym_equivalence_set_t *eqs = calloc(ns,sizeof(msym_equivalence_set_t)); msym_element_t **lelements = elements; msym_element_t **pe = pelements; if(elements == pelements){ lelements = malloc(sizeof(msym_element_t *[length])); memcpy(lelements, elements, sizeof(msym_element_t *[length])); } for(int i = 0, ni = 0; i < length;i++){ if(ss[i] > 0){ int ei = 0; eqs[ni].elements = pe; eqs[ni].length = ss[i]; for(int j = 0; j < length;j++){ if(sp[j] == i){ double err = (e[j] > -1.0) ? fabs(e[j]) : 0.0; eqs[ni].err = fmax(eqs[ni].err,err); eqs[ni].elements[ei++] = lelements[j]; } } pe += ss[i]; ni++; } } if(elements == pelements){ free(lelements); } free(m); free(vec); free(s); free(e); free(sp); free(ss); free(ev); free(ep); *es = eqs; *esl = ns; return MSYM_SUCCESS; }
t_vector get_sphere_normale(t_vector p, t_sphere *f) { return (vnormalize(vsub(p, f->center))); }
static int path_decimate(gstack_t** path, double* Dmin) { size_t n = gstack_size(*path); double xmin = pow(*Dmin, 2); corner_t cns[n]; /* empty the stack into a corners array - we do this in reverse order so the gstack_push below gives us a gstack_t in the same order (needed due to an assumed orientation of the boundaries) */ for (int i = 0 ; i < n ; i++) { if (gstack_pop(*path, (void*)(cns+(n-1-i))) != 0) return -1; } /* cache metric tensor and ellipse centres */ vector_t e[n]; m2_t mt[n]; for (int i = 0 ; i < n ; i++) { ellipse_t E; arrow_ellipse(&(cns[i].A), &E); mt[i] = ellipse_mt(E); e[i] = E.centre; } /* create ellipse intersection graph */ graph_t G; if (graph_init(n,&G) != 0) return -1; size_t err = 0; for (int i = 0 ; i < n-1 ; i++) { for (int j = i+1 ; j < n ; j++) { double x = contact_mt(vsub(e[j], e[i]), mt[i], mt[j]); /* failed contact() results in edge not being included in the graph so possible intesection survives - save the number for a warning (below) */ if (x<0) { err++; continue; } /* weight of each node is the maximum of the contact-distances of the incoming edges */ if (x < xmin) { double w1 = graph_get_weight(G, i), w2 = graph_get_weight(G, j); graph_set_weight(G, i, MAX(w1, x)); graph_set_weight(G, j, MAX(w2, x)); if (graph_add_edge(G, i, j) != 0) return -1; } } } if (err) fprintf(stderr,"failed contact distance for %i pairs\n", (int)err); /* greedy node deletion to obtain non-intersecting subset */ size_t maxi; while (graph_maxedge(G, &maxi) > 0) if (graph_del_node(G, maxi) != 0) return -1; /* dump back into gstack */ for (int i = 0 ; i < n ; i++) if ( !graph_node_flag(G, i, NODE_STALE) ) gstack_push(*path, (void*)(cns+i)); graph_clean(&G); return 1; }