예제 #1
0
bool Grid::canNudge(bool left)
{

	bool ret = true;
	if(!current)
	{
		return false;
	}
	int direction = 1;
	if(left)
	{
		direction = -1;
	}
	Vec4<Vec2i> blocks = current->getBricks();
	if(blocks.X().Y() < H && (blocks.X().X()+direction > 0) && (blocks.X().X() + direction < (W-1)) && GD[((blocks.X().Y())*W)+blocks.X().X()+direction])
	{
		ret = false;
	}
	if(blocks.Y().Y() < H && (blocks.Y().X()+direction > 0) && (blocks.Y().X() + direction < (W-1)) && GD[((blocks.Y().Y())*W)+blocks.Y().X()+direction])
	{
		ret = false;
	}
	if(blocks.Z().Y() < H && (blocks.Z().X()+direction > 0) && (blocks.Z().X() + direction < (W-1)) && GD[((blocks.Z().Y())*W)+blocks.Z().X()+direction])
	{
		ret = false;
	}
	if(blocks.W().Y() < H && (blocks.W().X()+direction > 0) && (blocks.W().X() + direction < (W-1)) && GD[((blocks.W().Y())*W)+blocks.W().X()+direction])
	{
		ret = false;
	}

	return ret;


}
예제 #2
0
bool Grid::collision()
{
	bool ret = false;
	if(!current)
	{
		return false;
	}
	Vec4<Vec2i> blocks = current->getBricks();
	if(blocks.X().Y() < H && (blocks.X().Y() == 0 || GD[((blocks.X().Y()-1)*W)+blocks.X().X()]))
	{
		ret = true;
	}
	if(blocks.Y().Y() < H && (blocks.Y().Y() == 0 || GD[((blocks.Y().Y()-1)*W)+blocks.Y().X()]))
	{
		ret = true;
	}
	if(blocks.Z().Y() < H && (blocks.Z().Y() == 0 || GD[((blocks.Z().Y()-1)*W)+blocks.Z().X()]))
	{
		ret = true;
	}
	if(blocks.W().Y() < H && (blocks.W().Y() == 0 || GD[((blocks.W().Y()-1)*W)+blocks.W().X()]))
	{
		ret = true;
	}



	return ret;
}
예제 #3
0
파일: vec4.cpp 프로젝트: alexiskhb/C.G.
Vec4 Vec4::cross3(Vec4 a, Vec4 b) {
	Vec4 result = Vec4(
			a.Y()*b.Z() - a.Z()*b.Y(),
			a.Z()*b.X() - a.X()*b.Z(),
			a.X()*b.Y() - a.Y()*b.X());
	if (!a.isValid() || !b.isValid())
		result.valid = VTERR;
	return result;
}
예제 #4
0
파일: Sphere.cpp 프로젝트: 0x0002/Renderer
bool Sphere::Intersect( Ray const &ray, float *tHit, float *epsilon, DifferentialGeometry *geom ) const {
    Transform tf = Tform();
    Ray r = ray * Inverse( tf );

    float t;
    if( !Intersect( ray, &t ) )
        return false;

    // compute differential geometry
    Vec4 p = ray.Point( t );

    float x = p.X();
    float y = p.Y();
    float z = p.Z();

    if( x == 0.0f && z == 0.0f ) {
        // can't have both atan2 arguments be zero
        z = kEpsilon * m_radius;
    }
    float theta = atan2( p.X(), p.Z() );

    if( theta < 0.0f ) {
        // remap theta to [0, 2pi] to match sphere's definition
        theta += k2Pi;
    }

    float phi = Acos( Clamp( z / m_radius, -1.0f, 1.0f ) );

    // parameterize sphere hit
    float u = theta * kInv2Pi;
    float v = phi * kInvPi;

    float sTheta, cTheta;
    float sPhi, cPhi;
    SinCos( theta, &sTheta, &cTheta );
    SinCos( phi, &sPhi, &cPhi );

    Vec4 dpdu( k2Pi * z, 0.0f, -k2Pi * x, 0.0f );
    Vec4 dpdv( kPi * y * sTheta, -kPi * m_radius * sPhi, kPi * y * cTheta, 0.0f );
    Vec4 d2pdu2( -k2Pi * k2Pi * x, 0.0f, -k2Pi * k2Pi * z, 0.0f );
    Vec4 d2pduv( k2Pi * kPi * y * cTheta, 0.0f, -k2Pi * kPi * y * sTheta, 0.0f );
    Vec4 d2pdv2( -kPi * kPi * x, -kPi * kPi * y, -kPi * kPi * z, 0.0f );

    // change in normal is computed using Weingarten equations
    Scalar E = Dot( dpdu, dpdu );
    Scalar F = Dot( dpdu, dpdv );
    Scalar G = Dot( dpdv, dpdv );
    Vec4 N = Normalize( Cross(  dpdu, dpdv ) );
    Scalar e = Dot( N, d2pdu2 );
    Scalar f = Dot( N, d2pduv );
    Scalar g = Dot( N, d2pdv2 );

    Scalar h = 1.0f / ( E * G - F * F );
    Vec4 dndu = ( f * F - e * G ) * h * dpdu + ( e * F - f * E ) * h * dpdv;
    Vec4 dndv = ( g * F - f * G ) * h * dpdu + ( f * F - g * E ) * h * dpdv;

    *tHit = t;
    *epsilon = 5e-4f * t;

    // return world space differential geometry
    *geom = DifferentialGeometry( Handle(), p * tf, dpdu * tf, dpdv * tf, Normal( dndu ) * tf, Normal( dndv ) * tf, u, v );

    return true;
}
예제 #5
0
void Grid::Update()
{
	if(GameOver())
	{
		return;
	}

	if(current)
	{
		current->Update();
		//check for boundaries
		Vec4<Vec2i> blocks = current->getBricks();
		int minX = blocks.X().X();
		int maxX = blocks.X().X();
		if (blocks.Y().X() < minX)
		{
			minX = blocks.Y().X();
		}
		if (blocks.Y().X() > maxX)
		{
			maxX = blocks.Y().X();
		}
		if (blocks.Z().X() < minX)
		{
			minX = blocks.Z().X();
		}
		if (blocks.Z().X() > maxX)
		{
			maxX = blocks.Z().X();
		}
		if (blocks.W().X() < minX)
		{
			minX = blocks.W().X();
		}
		if (blocks.W().X() > maxX)
		{
			maxX = blocks.W().X();
		}
		if (minX < 0)
		{
			current->nudge(-minX,0);
		}
		if (maxX >= W)
		{
			current->nudge((W-maxX)-1,0);
		}

		if(collision())
		{
			
			Brick* b = new Brick(Vec3f(blocks.X().X()*2,blocks.X().Y()*2,0));
			Game::instance()->addObject(b);
			int a = blocks.X().Y()*W+blocks.X().X();
			if(a < GD.size())
			{
				GD[a] = b;
			}
			b = new Brick(Vec3f(blocks.Y().X()*2,blocks.Y().Y()*2,0));
			Game::instance()->addObject(b);
			a = blocks.Y().Y()*W+blocks.Y().X();
			if(a < GD.size())
			{
				GD[a] = b;
			}
			b =  new Brick(Vec3f(blocks.Z().X()*2,blocks.Z().Y()*2,0));
			Game::instance()->addObject(b);
			a = blocks.Z().Y()*W+blocks.Z().X();
			if(a < GD.size())
			{
				GD[a] = b;
			}
			b =  new Brick(Vec3f(blocks.W().X()*2,blocks.W().Y()*2,0));
			Game::instance()->addObject(b);
			a = blocks.W().Y()*W+blocks.W().X();
			if(a < GD.size())
			{
				GD[a] = b;
			}
			delete current;
			current = 0;
			lines();
			if(GameOver())
			{

				SoundManager::instance()->playSound(failfx);
			}
			else
			{
				SoundManager::instance()->playSound(dropfx);
			}
		}

	}
	else
	{
		current = new Tetrad();
		current->setPivot(Vec2i(5,17));
		int lf =  -linecount/7;
		current->setVel(Vec3f(0,-1+lf,0));
		current->setPos(Vec3f(2*5,2*17,0));
	}





}
예제 #6
0
파일: vec4.cpp 프로젝트: alexiskhb/C.G.
floatv Vec4::dot3(Vec4 a, Vec4 b) {
	floatv result = 0.0;
	if ()
	result = a.X()*b.X() + a.Y()*b.Y() + a.Z()*b.Z();
	return result;
}
예제 #7
0
void BitoneClusterFit::ClusterFit4Constant(void* block)
{
  // declare variables
  int const count = m_bitones->GetCount();
  Vec4 const two = VEC4_CONST(2.0f);
  Vec4 const one = VEC4_CONST(1.0f);

  Vec4 const onethird_onethird2  (1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 9.0f);
  Vec4 const twothirds_twothirds2(2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, 4.0f / 9.0f);
  Vec4 const twonineths                                     = VEC4_CONST(2.0f / 9.0f);

  assume((count > 0) && (count <= 16));

  // check all possible clusters and iterate on the total order
  Vec4 beststart = VEC4_CONST(0.0f);
  Vec4 bestend = VEC4_CONST(0.0f);
  Scr4 besterror = m_besterror;
  u8 bestindices[16];
  int bestiteration = 0;
  int besti = 0, bestj = 0, bestk = 0;

  // prepare an ordering using the principle axis
  ConstructOrdering(m_principle, 0);

  // loop over iterations (we avoid the case that all points in first or last cluster)
  for (int iterationIndex = 0;;) {
    // cache some values
    Vec4 const xsum_wsum = m_xsum_wsum;

    // constants if weights == 1
    Vec4 alphabeta_dltas  = *((Vec4 *)part2delta[0]);
    Vec4 *alphabeta_inits = (Vec4 *)part2inits[0];
    float *alphabeta_factors = (float *)part2factors;

#if 0
  Vec4 lasta = Vec4(0.0f);
  Vec4 lastb = xsum_wsum;
  Vec4 lastc = Vec4(0.0f);
#endif

    // first cluster [0,i) is at the start
    Vec4 part0 = VEC4_CONST(0.0f);
    for (int i = 0; i < count; ++i) {

    // second cluster [i,j) is one third along
    Vec4 part1 = VEC4_CONST(0.0f);
    for (int j = i;;) {

    // third cluster [j,k) is two thirds along
    Vec4 part2 = (j == 0) ? m_points_weights[0] : VEC4_CONST(0.0f);
    Vec4 alphabeta_val = *alphabeta_inits++;
    int kmin = (j == 0) ? 1 : j;
    for (int k = kmin;;) {
	  // TODO: the inner alphabeta_sum seems always to be the same sequence
	  Vec4 alphabeta_factor = alphabeta_val * Vec4(*alphabeta_factors++);

	  // compute least squares terms directly
	  Vec4 const alphax_sum =   MultiplyAdd(part2, onethird_onethird2, MultiplyAdd(part1, twothirds_twothirds2, part0));
	  Vec4 const  betax_sum = /*MultiplyAdd(part1, onethird_onethird2, MultiplyAdd(part2, twothirds_twothirds2, part3))*/ xsum_wsum - alphax_sum;

	  Vec4 const    alpha2_sum = alphabeta_val.SplatX();
	  Vec4 const     beta2_sum = alphabeta_val.SplatY();
	  Vec4 const alphabeta_sum = alphabeta_val.SplatZ();

	  Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_factor.SplatZ(), alphax_sum * alphabeta_factor.SplatY());
	  Vec4 b = NegativeMultiplySubtract(alphax_sum, alphabeta_factor.SplatZ(),  betax_sum * alphabeta_factor.SplatX());

#if 0
	  // last cluster [k,count) is at the end
	  Vec4 part3 = xsum_wsum - part2 - part1 - part0;

	  // compute least squares terms directly
	  Vec4 const _alphax_sum = MultiplyAdd(part2, onethird_onethird2, MultiplyAdd(part1, twothirds_twothirds2, part0));
	  Vec4 const  _betax_sum = MultiplyAdd(part1, onethird_onethird2, MultiplyAdd(part2, twothirds_twothirds2, part3));
//	  Vec4 const  _betac_sum = xsum_wsum - _alphax_sum;

	  Vec4 const _alpha2_sum = _alphax_sum.SplatW();
	  Vec4 const  _beta2_sum =  _betax_sum.SplatW();

	  Vec4 const _alphabeta_sum = twonineths * (part1 + part2).SplatW();

	  // compute the least-squares optimal points
	  Vec4 _factor = Reciprocal(NegativeMultiplySubtract(_alphabeta_sum, _alphabeta_sum, _alpha2_sum * _beta2_sum));
	  Vec4 _a = NegativeMultiplySubtract( _betax_sum, _alphabeta_sum, _alphax_sum *  _beta2_sum) * _factor;
	  Vec4 _b = NegativeMultiplySubtract(_alphax_sum, _alphabeta_sum,  _betax_sum * _alpha2_sum) * _factor;

#undef	limit
#define	limit 2e-5
	  assert(fabs(_alpha2_sum.W() - alpha2_sum.X()) < limit);
	  assert(fabs(_beta2_sum.W() - beta2_sum.X()) < limit);
	  assert(fabs(_alphabeta_sum.W() - alphabeta_sum.X()) < limit);

	  if (alphabeta_factors[-1] != FLT_MAX) {
	    assert(fabs(_factor.W() - alphabeta_factors[-1]) < limit);

	    assert(fabs(_alpha2_sum.W()    * _factor.W() - alphabeta_factor.X()) < limit);
	    assert(fabs(_beta2_sum.W()     * _factor.W() - alphabeta_factor.Y()) < limit);
	    assert(fabs(_alphabeta_sum.W() * _factor.W() - alphabeta_factor.Z()) < limit);

	    assert(fabs(a.X() - _a.X()) < limit);
	    assert(fabs(a.Y() - _a.Y()) < limit);
	    assert(fabs(a.Z() - _a.Z()) < limit);

	    assert(fabs(b.X() - _b.X()) < limit);
	    assert(fabs(b.Y() - _b.Y()) < limit);
	    assert(fabs(b.Z() - _b.Z()) < limit);
	  }

#if 0
	  fprintf(stderr, "{%.9ff},", _factor.W());
	  if (k == kmin)
	    fprintf(stderr, "{%.9f, %.9f, %.9f},\n", alpha2_sum.W(), beta2_sum.W(), alphabeta_sum.W());
	  fprintf(stderr, "{%.9f/*%.9f*/,%.9f/*%.9f*/,%.9f,%.9f},\n",
	    alpha2_sum.W(), lasta.W() - alpha2_sum.W(),
	    beta2_sum.W(), lastb.W() - beta2_sum.W(),
	    alphabeta_sum.W(), lastc.W() - alphabeta_sum.W(),
	    factor.W());

	  lasta = alpha2_sum;
	  lastb = beta2_sum;
	  lastc = alphabeta_sum;
#endif
#endif

	  // snap floating-point-values to the integer-lattice
	  a = Truncate(a * 255.0f) * (1.0f / 255.0f);
	  b = Truncate(b * 255.0f) * (1.0f / 255.0f);

	  // compute the error (we skip the constant xxsum)
	  Vec4 e1 = MultiplyAdd(a * a, alpha2_sum, b * b * beta2_sum);
	  Vec4 e2 = NegativeMultiplySubtract(a, alphax_sum, a * b * alphabeta_sum);
	  Vec4 e3 = NegativeMultiplySubtract(b, betax_sum, e2);
	  Vec4 e4 = MultiplyAdd(two, e3, e1);

	  // apply the metric to the error term
	  Scr4 eS = e4;

	  // keep the solution if it wins
	  if (besterror > eS) {
	    besterror = eS;

	    beststart = a;
	    bestend = b;
	    bestiteration = iterationIndex;

	    besti = i;
	    bestj = j;
	    bestk = k;
	  }

      alphabeta_val += alphabeta_dltas;

      // advance
      if (k == count) break;
      part2 += m_points_weights[k]; ++k; }

      // advance
      if (j == count) break;
      part1 += m_points_weights[j]; ++j; }

      // advance
      part0 += m_points_weights[i];
    }

    // stop if we didn't improve in this iteration
    if (bestiteration != iterationIndex)
      break;

    // advance if possible
    ++iterationIndex;
    if (iterationIndex == m_iterationCount)
      break;

    // stop if a new iteration is an ordering that has already been tried
    Vec3 axis = (bestend - beststart).GetVec3();
    if (!ConstructOrdering(axis, iterationIndex))
      break;
  }

  // save the block if necessary
  if (besterror < m_besterror) {
    // save the error
    m_besterror = besterror;

    // remap the indices
    u8 const* order = (u8*)m_order + 16 * bestiteration;

    u8 unordered[16];
    for (int m =     0; m < besti; ++m)
      unordered[order[m]] = 0;
    for (int m = besti; m < bestj; ++m)
      unordered[order[m]] = 2;
    for (int m = bestj; m < bestk; ++m)
      unordered[order[m]] = 3;
    for (int m = bestk; m < count; ++m)
      unordered[order[m]] = 1;

    m_bitones->RemapIndices(unordered, bestindices);

    // save the block
    WriteBitoneBlock4(beststart.GetVec3(), bestend.GetVec3(), bestindices, block);
  }
}