Beispiel #1
0
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;
}
Beispiel #2
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;
		}
	}
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
	}
}
Beispiel #5
0
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);

}
Beispiel #6
0
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);
}
Beispiel #7
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);
   }
Beispiel #8
0
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;
}
Beispiel #10
0
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);
}
Beispiel #11
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(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 );
}
Beispiel #12
0
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);
}
Beispiel #13
0
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;
}
Beispiel #14
0
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...
}
Beispiel #16
0
//-----------------------------------------------------------------------------
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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);
		}
	}
}
Beispiel #19
0
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;
}
Beispiel #20
0
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);
         }
      }
   }
}
Beispiel #21
0
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);
    }
}
Beispiel #22
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);
            }
        }
    }
}
Beispiel #23
0
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);
		}
	}
}
Beispiel #24
0
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();
}
Beispiel #25
0
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;
}
Beispiel #27
0
t_vector		get_sphere_normale(t_vector p, t_sphere *f)
{
	return (vnormalize(vsub(p, f->center)));
}
Beispiel #28
0
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;
}