void computeBV<AABB>(const Convex& s, AABB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  AABB bv_;
  for(int i = 0; i < s.num_points; ++i)
  {
    Vec3f new_p = matMulVec(R, s.points[i]) + T;
    bv_ += new_p;
  }

  bv = bv_;
}
void computeBV<AABB>(const Sphere& s, AABB& bv)
{
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  bv.max_ = T + Vec3f(s.radius, s.radius, s.radius);
  bv.min_ = T + Vec3f(-s.radius, -s.radius, -s.radius);
}
void computeBV<AABB>(const Plane& s, AABB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);

  Vec3f n = matMulVec(R, n);

  AABB bv_;
  if(n[1] == (BVH_REAL)0.0 && n[2] == (BVH_REAL)0.0)
  {
    // normal aligned with x axis
    if(n[0] < 0) bv_.min_[0] = -s.d;
    else if(n[0] > 0) bv_.max_[0] = s.d;
  }
  else if(n[0] == (BVH_REAL)0.0 && n[2] == (BVH_REAL)0.0)
  {
    // normal aligned with y axis
    if(n[1] < 0) bv_.min_[1] = -s.d;
    else if(n[1] > 0) bv_.max_[1] = s.d;
  }
  else if(n[0] == (BVH_REAL)0.0 && n[1] == (BVH_REAL)0.0)
  {
    // normal aligned with z axis
    if(n[2] < 0) bv_.min_[2] = -s.d;
    else if(n[2] > 0) bv_.max_[2] = s.d;
  }

  bv = bv_;
}
void computeBV<OBB>(const Sphere& s, OBB& bv)
{
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  bv.To = T;
  bv.axis[0] = Vec3f(1, 0, 0);
  bv.axis[1] = Vec3f(0, 1, 0);
  bv.axis[2] = Vec3f(0, 0, 1);
  bv.extent = Vec3f(s.radius, s.radius, s.radius);
}
void computeBV<OBB>(const Convex& s, OBB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  fit(s.points, s.num_points, bv);

  Vec3f axis[3];
  axis[0] = matMulVec(R, bv.axis[0]);
  axis[1] = matMulVec(R, bv.axis[1]);
  axis[2] = matMulVec(R, bv.axis[2]);

  bv.axis[0] = axis[0];
  bv.axis[1] = axis[1];
  bv.axis[2] = axis[2];

  bv.To = matMulVec(R, bv.To) + T;

}
void computeBV<OBB>(const Cylinder& s, OBB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  bv.To = T;
  bv.axis[0] = Vec3f(R[0][0], R[1][0], R[2][0]);
  bv.axis[1] = Vec3f(R[0][1], R[1][1], R[2][1]);
  bv.axis[2] = Vec3f(R[0][2], R[1][2], R[2][2]);
  bv.extent = Vec3f(s.radius, s.radius, s.lz / 2);
}
void computeBV<OBB>(const Box& s, OBB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  bv.To = T;
  bv.axis[0] = Vec3f(R[0][0], R[1][0], R[2][0]);
  bv.axis[1] = Vec3f(R[0][1], R[1][1], R[2][1]);
  bv.axis[2] = Vec3f(R[0][2], R[1][2], R[2][2]);
  bv.extent = s.side * (BVH_REAL)0.5;
}
Example #8
0
void fpscont(Camera* cam) {

    // Rip out position
    //
    float vec_pos[4];
    float* mat_world = cam->mat_world;
    memcpy(vec_pos, &mat_world[12], sizeof(vec_pos));
    memset(&mat_world[12], 0, sizeof(float) * 3);


    // Mouse-look
    //
    short center_x = display.getWidth()/2;
    short center_y = display.getHeight()/2;

    short delta_x = mouse.pos[0] - center_x;
    short delta_y = mouse.pos[1] - center_y;
    mouse.setPos(center_x, center_y);

    float mat_rotx[16];
    matRot(mat_rotx, delta_y * -0.001f, 0);
    matMul(mat_world, mat_rotx, mat_world);

    float mat_roty[16];
    matRot(mat_roty, delta_x * -0.001f, 1);
    matMul(mat_roty, mat_world, mat_world);


    // Movement
    //
    char up_down = keyboard.keyDown('w') - keyboard.keyDown('s');
    char right_left = keyboard.keyDown('d') - keyboard.keyDown('a');

    float speed = 0.5;
    float vec_vel[4];
    vec_vel[0] = right_left * speed;
    vec_vel[1] = 0;
    vec_vel[2] = -up_down * speed;
    vec_vel[3] = 1;

    matMulVec(mat_world, vec_vel, vec_vel);

    vecAdd(vec_pos, vec_vel, vec_pos);
    vec_pos[3] = 1;

    memcpy(cam->mat_view, cam->mat_world, sizeof(float) * 16);
    memcpy(&cam->mat_world[12], vec_pos, sizeof(vec_pos));

    cameraWorldToView(cam);



}
void computeBV<OBB>(const Plane& s, OBB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  // generate other two axes orthonormal to plane normal
  const Vec3f& w = s.n;
  Vec3f u, v;
  float inv_length;
  if(fabs(w[0]) >= fabs(w[1]))
  {
    inv_length = 1.0 / sqrt(w[0] * w[0] + w[2] * w[2]);
    u[0] = -w[2] * inv_length;
    u[1] = 0;
    u[2] = w[0] * inv_length;
    v[0] = w[1] * u[2];
    v[1] = w[2] * u[0] - w[0] * u[2];
    v[2] = -w[1] * u[0];
  }
  else
  {
    inv_length = 1.0 / sqrt(w[1] * w[1] + w[2] * w[2]);
    u[0] = 0;
    u[1] = w[2] * inv_length;
    u[2] = -w[1] * inv_length;
    v[0] = w[1] * u[2] - w[2] * u[1];
    v[1] = -w[0] * u[2];
    v[2] = w[0] * u[1];
  }

  bv.axis[0] = w;
  bv.axis[1] = u;
  bv.axis[2] = v;

  bv.extent = Vec3f(0, std::numeric_limits<BVH_REAL>::max(), std::numeric_limits<BVH_REAL>::max());

  Vec3f p = s.n * s.d;
  bv.To = matMulVec(R, p) + T;
}
void computeBV<AABB>(const Cylinder& s, AABB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  BVH_REAL x_range = fabs(R[0][0] * s.radius) + fabs(R[0][1] * s.radius) + 0.5 * fabs(R[0][2] * s.lz);
  BVH_REAL y_range = fabs(R[1][0] * s.radius) + fabs(R[1][1] * s.radius) + 0.5 * fabs(R[1][2] * s.lz);
  BVH_REAL z_range = fabs(R[2][0] * s.radius) + fabs(R[2][1] * s.radius) + 0.5 * fabs(R[2][2] * s.lz);

  bv.max_ = T + Vec3f(x_range, y_range, z_range);
  bv.min_ = T + Vec3f(-x_range, -y_range, -z_range);
}
void computeBV<AABB>(const Box& s, AABB& bv)
{
  Vec3f R[3];
  matMulMat(s.getRotation(), s.getLocalRotation(), R);
  Vec3f T = matMulVec(s.getRotation(), s.getLocalTranslation()) + s.getTranslation();

  BVH_REAL x_range = 0.5 * (fabs(R[0][0] * s.side[0]) + fabs(R[0][1] * s.side[1]) + fabs(R[0][2] * s.side[2]));
  BVH_REAL y_range = 0.5 * (fabs(R[1][0] * s.side[0]) + fabs(R[1][1] * s.side[1]) + fabs(R[1][2] * s.side[2]));
  BVH_REAL z_range = 0.5 * (fabs(R[2][0] * s.side[0]) + fabs(R[2][1] * s.side[1]) + fabs(R[2][2] * s.side[2]));

  bv.max_ = T + Vec3f(x_range, y_range, z_range);
  bv.min_ = T + Vec3f(-x_range, -y_range, -z_range);
}
void triangleVertexShading(JmJob *data)
{
	VertexJob v;
	dmaBlockGet(&v, (uintptr_t)data->p1, sizeof(VertexJob), DmaTag);

	Vec halfSizeAdd = vec(0.5f * sw,  0.5f * sh, 0, 1);
	Vec halfSizeMul = vec(0.5f * sw, -0.5f * sh, 1, 0);
	Vec zero = vec(0);

	Mat transform;
	matMul(&transform, v.projection, v.world);

	while(true)
	{
		unsigned int k = interlockedExchangeAdd(v.counter, VerticesAtATime);
		if(k >= v.end) break;

		unsigned int end = std::min(k + VerticesAtATime, v.end);
		unsigned int num = end - k;
		unsigned int numtris = num / 3;
#ifndef PLATFORM_PS3_SPU
		Triangle3D vertexShadingTris[TriangleAtATime];
#endif
		dmaBlockGet(vertexShadingTris, (uintptr_t)&v.input[k], numtris * sizeof(Triangle3D), DmaTag);

		for(unsigned int u = 0; u < numtris; u++)
		{
			const Triangle3D &tri = vertexShadingTris[u];

			Triangle3D triOut[5];
			Vec vtx[8];
			int numTrisOut = 1;

			if(g_EnableBackfaceCulling)
			{
				// We can't do the backface culling using a determinant of a 2x2 matrix
				// in screen space because then we would have 'holes' in the output data
				// therefor it happens here, in wordspace.

				Vec e1 = vecSub(tri.p3, tri.p1);
				Vec e2 = vecSub(tri.p2, tri.p1);
				Vec n = vecCross(e1, e2);
				Vec a = vecDot(v.camerapos, n);

				if(vecGetElem(a, VecComponent::X) > 0) continue;
			}

			// perspective project
			matMulVec(&triOut[0].p1, transform, tri.p1);
			matMulVec(&triOut[0].p2, transform, tri.p2);
			matMulVec(&triOut[0].p3, transform, tri.p3);

			// cull against znear
			Vec m1 = vecCmpLE(vecSplat<VecComponent::Z>(triOut[0].p1), zero);
			Vec m2 = vecCmpLE(vecSplat<VecComponent::Z>(triOut[0].p2), zero);
			Vec m3 = vecCmpLE(vecSplat<VecComponent::Z>(triOut[0].p3), zero);

			Vec c2 = vecAnd(vecAnd(m1, m2), m3);
#ifdef PLATFORM_PS3
			vec_uint4 ones = (vec_uint4){0xffffffff,0xffffffff,0xffffffff,0xffffffff};
			if(vec_all_eq((vec_uint4)c2, ones)) continue;
#else
			int result = vecMaskToInt(c2);
			if(result == 15) continue; // discard, all behind nearz
#endif

#if 1
			// clip triangles that intersect znear
			static const int NumVerticesInATriangle = 3;
			int numVertsOut = triangleClipToPlane(
				(Vec*)&triOut[0], 
				vtx, 
				NumVerticesInATriangle, 
				vec(0, 0, 1, 0)
				);

			// Very simple triangulation routine
			numTrisOut = 0;
			for(int i = 2; i < numVertsOut; i++)
			{
				triOut[numTrisOut].p1 = vtx[0];
				triOut[numTrisOut].p2 = vtx[i];
				triOut[numTrisOut].p3 = vtx[i - 1];
				numTrisOut++;
			}
#endif

			for(int i = 0; i < numTrisOut; i++)
			{
				// perspective divide
				triOut[i].p1 = vecMul(triOut[i].p1, vecRcp(vecSplat<VecComponent::W>(triOut[i].p1)));
				triOut[i].p2 = vecMul(triOut[i].p2, vecRcp(vecSplat<VecComponent::W>(triOut[i].p2)));
				triOut[i].p3 = vecMul(triOut[i].p3, vecRcp(vecSplat<VecComponent::W>(triOut[i].p3)));

				// transform to screen space
				Vec r1 = vecMadd(triOut[i].p1, halfSizeMul, halfSizeAdd);
				Vec r2 = vecMadd(triOut[i].p2, halfSizeMul, halfSizeAdd);
				Vec r3 = vecMadd(triOut[i].p3, halfSizeMul, halfSizeAdd);

#ifdef PLATFORM_PS3_SPU
				Triangle3DSetup &r = setup[s][sidx];
#else
				Triangle3DSetup r;
#endif
				memcpy(&r.x1, &r1, sizeof(float) * 3);
				memcpy(&r.x2, &r2, sizeof(float) * 3);
				memcpy(&r.x3, &r3, sizeof(float) * 3);

				// deltas
				r.dx1 = r.x1 - r.x2;
				r.dx2 = r.x2 - r.x3;
				r.dx3 = r.x3 - r.x1;

				r.dy1 = r.y1 - r.y2;
				r.dy2 = r.y2 - r.y3;
				r.dy3 = r.y3 - r.y1;

#ifdef PLATFORM_PS3_SPU
				sidx++;
				if(sidx >= MaxSetupBuffered)
				{
					dmaWaitAll(1 << DmaListTag);

					unsigned int l = interlockedExchangeAdd(v.outputCnt, sidx);

					for(unsigned int u = 0; u < sidx; u++)
					{
						setuplist[u].notify = 0;
						setuplist[u].reserved = 0;
						setuplist[u].size = sizeof(Triangle3DSetup);
						setuplist[u].eal = (uintptr_t)&v.output[u + l];
					}

					cellDmaListPut(setup[s], 0, setuplist, sizeof(setuplist), DmaListTag, 0, 0);
					sidx = 0;
					s ^= 1;
				}
#else
				unsigned int l = interlockedExchangeAdd(v.outputCnt, 1);
				if(l >= MaxTrianglesDrawn) { interlockedExchangeSub(v.outputCnt, 1); break; }
				else dmaBlockPut(&r, (uintptr_t)&v.output[l], sizeof(Triangle3DSetup), DmaTag);
#endif
			}
		}
	}

#ifdef PLATFORM_PS3_SPU
	if(sidx > 0)
	{
		dmaWaitAll(1 << DmaListTag);
		unsigned int l = interlockedExchangeAdd(v.outputCnt, sidx);

		for(unsigned int u = 0; u < sidx; u++)
		{
			setuplist[u].notify = 0;
			setuplist[u].reserved = 0;
			setuplist[u].size = sizeof(Triangle3DSetup);
			setuplist[u].eal = (uintptr_t)&v.output[u + l];
		}
		
		cellDmaListPut(setup[s], 0, setuplist, sidx * sizeof(CellDmaListElement), DmaListTag + 1, 0, 0);
		dmaWaitAll(1 << (DmaListTag + 1));
	}
#endif
}
Example #13
0
bool PhysicsWorld::Intersects(const StaticPhysicsEntity &s, const DynamicPhysicsEntity &d, Vec &outNormal, Vec &outDir)
{
	float dmin = 0, radiusSquared;

	Vec min, max, center, scale;

	min = vec(-1, -1, -1, 0);
	max = vec(1, 1, 1, 0);
	scale = vec(1, 1, 1, 0);

	Mat m, sc;

	center = entGetTransform(d.ent)->GetPosition();
	entGetTransform(s.ent)->GetMatrix(&m);
	entGetTransform(d.ent)->GetMatrix(&sc);

	// scale the unit vector and take the largest component
	// as the radius for the sphere; as long as we don't do
	// silly rotations we should be ok
	matMulVec(&scale, sc, scale);
	radiusSquared = vecMax(scale);
	radiusSquared *= radiusSquared;

	// we don't have an inv matrix of anything so instead
	// we transform everything to worldspace and do the 
	// calculations there

	// rot + scale
	matMulVec(&min, m, min);
	matMulVec(&max, m, max);

	// pos
	Vec p = entGetTransform(s.ent)->GetPosition();
	min = vecAdd(min, p);
	max = vecAdd(max, p);

	// the actual intersection test (don't test w)
	for(int i = 0; i < 3; i++)
	{
		float C = vecGetElem(center, i);

		float Bmin = vecGetElem(min, i);
		float Bmax = vecGetElem(max, i);

		if(C < Bmin)		dmin += square(C - Bmin);
		else if(C > Bmax)	dmin += square(C - Bmax);
	}

	if(dmin <= radiusSquared)
	{
		Ray r;
		r.o = center;
		r.d = vecSub(p, center);
		r.d = vecNormalize(r.d);

		float dist;
		bool hit = RayBoxIntersection(r, min, max, dist, outNormal);
		outDir = vecMul(r.d, vec(dist));

		return hit;
	}

	return false;
}