void TrashCanEntity::Update()
{
	transformContext = 0;

	u8 derp = (u8)(updateCount % 30);
	float32 periodic = 0.5*sin(3.14159*(float32)derp/30.0);
	float32 derp2 = periodic + 1.0;

	oamRotateScale(&oamSub,
		0,
		degreesToAngle(periodic*10-30),
		floatToFixed(derp2, 8),
		floatToFixed(derp2, 8)	
	);

	if (shouldBeRemoved)
		return;

	if (IsTouchedByNearbyPlayer())
	{
		LivingEntity::Damage(gpPlayerEntity->mStats->attack);
		printf("Trashcan Ouch %d!\n", mStats->health);
	}

	Sprite::Update();
}
Example #2
0
vect3D Quaternion_toEuler(Quaternion q) {
	//http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm
	
	vect3D v;
	
	int32 test = mulf32(q.x, q.y) + mulf32(q.z, q.w);
	if(test > floatToFixed(0.499f, 12)) { // singularity at north pole
		v.x = 2 * atan2Lerp(q.x, q.w);
		v.y = floatToFixed(M_PI / 2.0f, 12);
		v.z = 0;
		return v;
	}
	if(test < floatToFixed(-0.499f, 12)) { // singularity at south pole
		v.x = -2 * atan2Lerp(q.x, q.w);
		v.y = floatToFixed(-M_PI / 2.0f, 12);
		v.z = 0;
		return v;
	}
	
    int32 sqx = mulf32(q.x, q.x);
    int32 sqy = mulf32(q.y, q.y);
    int32 sqz = mulf32(q.z, q.z);
	
    v.x = atan2Lerp(2 * mulf32(q.y, q.w) - 2 * mulf32(q.x, q.z), (1 << 12) - 2 * sqy - 2 * sqz);
	v.y = asinLerp(2 * test);
	v.z = atan2Lerp(2 * mulf32(q.x, q.w) - 2 * mulf32(q.y, q.z), (1 << 12) - 2 * sqx - 2 * sqz);
	
	return v;
}
void TerrainFile::setSize( U32 newSize, bool clear )
{
   // Make sure the resolution is a power of two.
   newSize = getNextPow2( newSize );

   // 
   if ( clear )
   {
      mLayerMap.setSize( newSize * newSize );
      mLayerMap.compact();
      dMemset( mLayerMap.address(), 0, mLayerMap.memSize() );

      // Initialize the elevation to something above
      // zero so that we have room to excavate by default.
      U16 elev = floatToFixed( 512.0f );

      mHeightMap.setSize( newSize * newSize );
      mHeightMap.compact();
      for ( U32 i = 0; i < mHeightMap.size(); i++ )
         mHeightMap[i] = elev;
   }
   else
   {
      // We're resizing here!



   }

   mSize = newSize;

   _buildGridMap();
}
void Tracker::buildUndistO2ITable(Camera* pCam) {
    int x, y;
    ARFloat cx, cy, ox, oy;
    unsigned int fixed;
    char* cachename = NULL;
    bool loaded = false;

    if (loadCachedUndist) {
        assert(pCam->getFileName() != "");
        cachename = new char[strlen(pCam->getFileName().c_str()) + 5];
        strcpy(cachename, pCam->getFileName().c_str());
        strcat(cachename, ".LUT");
    }

    // we have to take care here when using a memory manager that can not free memory
    // (usually this lookup table should only be built once - unless we change camera resolution)
    //
    if (undistO2ITable)
        delete[] undistO2ITable;

    undistO2ITable = new unsigned int[arImXsize * arImYsize];

    if (loadCachedUndist) {
        if (FILE* fp = fopen(cachename, "rb")) {
            size_t numBytes = fread(undistO2ITable, 1, arImXsize * arImYsize * sizeof(unsigned int), fp);
            fclose(fp);

            if (numBytes == arImXsize * arImYsize * sizeof(unsigned int))
                loaded = true;
        }
    }

    if (!loaded) {
        for (x = 0; x < arImXsize; x++) {
            for (y = 0; y < arImYsize; y++) {
                arCameraObserv2Ideal_std(pCam, (ARFloat) x, (ARFloat) y, &cx, &cy);
                floatToFixed(cx, cy, fixed);
                fixedToFloat(fixed, ox, oy);
                undistO2ITable[x + y * arImXsize] = fixed;
            }
        }

        if (loadCachedUndist)
            if (FILE* fp = fopen(cachename, "wb")) {
                fwrite(undistO2ITable, 1, arImXsize * arImYsize * sizeof(unsigned int), fp);
                fclose(fp);
            }
    }

    delete[] cachename;
}
Example #5
0
bool TerrainBlock::buildPolyList(AbstractPolyList* polyList, const Box3F &box, const SphereF&)
{
   if (box.maxExtents.z < -TerrainThickness || box.minExtents.z > fixedToFloat(gridMap[BlockShift]->maxHeight))
      return false;

   // Transform the bounding sphere into the object's coord space.  Note that this
   //  not really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F::One, "Error, handle the scale transform on the terrain");

   // Setup collision state data
   polyList->setTransform(&getTransform(), getScale());
   polyList->setObject(this);

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   if (!mTile && xStart<0)
      xStart = 0;
   S32 xExt = xEnd - xStart;
   if (xExt > MaxExtent)
      xExt = MaxExtent;
   xEnd = xStart + xExt;

   mHeightMax = floatToFixed(osBox.maxExtents.z);
   mHeightMin = (osBox.minExtents.z < 0.0f)? 0.0f: floatToFixed(osBox.minExtents.z);

   // Index of shared points
   U32 bp[(MaxExtent + 1) * 2],*vb[2];
   vb[0] = &bp[0];
   vb[1] = &bp[xExt + 1];
   clrbuf(vb[1],xExt + 1);

   bool emitted = false;
   for (S32 y = yStart; y < yEnd; y++) 
   {
      S32 yi = y & BlockMask;

      swap(vb[0],vb[1]);
      clrbuf(vb[1],xExt + 1);
      //
      for (S32 x = xStart; x < xEnd; x++) 
      {
         S32 xi = x & BlockMask;
         GridSquare *gs = findSquare(0, Point2I(xi, yi));

         // If we disable repeat, then skip non-primary
         if(!mTile && (x!=xi || y!=yi))
            continue;

         // holes only in the primary terrain block
         if (((gs->flags & GridSquare::Empty) && x == xi && y == yi) || gs->minHeight > mHeightMax || gs->maxHeight < mHeightMin)
            continue;
         emitted = true;

         // Add the missing points
         U32 vi[5];
         for (int i = 0; i < 4 ; i++) 
         {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            U32* vp = &vb[dy][x - xStart + dx];
            if (*vp == U32_MAX) 
            {
               Point3F pos;
               pos.x = (F32)((x + dx) * mSquareSize);
               pos.y = (F32)((y + dy) * mSquareSize);
               pos.z = fixedToFloat(getHeight(xi + dx, yi + dy));
               *vp = polyList->addPoint(pos);
            }
            vi[i] = *vp;
         }

         U32* vp = &vi[0];
         if (!(gs->flags & GridSquare::Split45))
            vi[4] = vi[0], vp++;

         BaseMatInstance* material = getMaterialInst( xi, yi );
         U32 surfaceKey = ((xi << 16) + yi) << 1;
         polyList->begin(material,surfaceKey);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[1]);
         polyList->vertex(vp[2]);
         polyList->plane(vp[0],vp[1],vp[2]);
         polyList->end();
         polyList->begin(material,surfaceKey + 1);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[2]);
         polyList->vertex(vp[3]);
         polyList->plane(vp[0],vp[2],vp[3]);
         polyList->end();
      }
   }
   return emitted;
}
Example #6
0
void TerrainBlock::buildConvex(const Box3F& box,Convex* convex)
{
   sTerrainConvexList.collectGarbage();

   //
   if (box.maxExtents.z < -TerrainThickness || box.minExtents.z > fixedToFloat(gridMap[BlockShift]->maxHeight))
      return;

   // Transform the bounding sphere into the object's coord space.  Note that this
   // not really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F(1, 1, 1), "Error, handle the scale transform on the terrain");

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   S32 xExt = xEnd - xStart;
   if (xExt > MaxExtent)
      xExt = MaxExtent;

   mHeightMax = floatToFixed(osBox.maxExtents.z);
   mHeightMin = (osBox.minExtents.z < 0)? 0: floatToFixed(osBox.minExtents.z);

   for (S32 y = yStart; y < yEnd; y++) {
      S32 yi = y & BlockMask;

      //
      for (S32 x = xStart; x < xEnd; x++) {
         S32 xi = x & BlockMask;
         GridSquare *gs = findSquare(0, Point2I(xi, yi));

         // If we disable repeat, then skip non-primary
         if(!mTile && (x!=xi || y!=yi))
            continue;

         // holes only in the primary terrain block
         if (((gs->flags & GridSquare::Empty) && x == xi && y == yi) ||
             gs->minHeight > mHeightMax || gs->maxHeight < mHeightMin)
            continue;

         U32 sid = (x << 16) + (y & ((1 << 16) - 1));
         Convex* cc = 0;

         // See if the square already exists as part of the working set.
         CollisionWorkingList& wl = convex->getWorkingList();
         for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
            if (itr->mConvex->getType() == TerrainConvexType &&
                static_cast<TerrainConvex*>(itr->mConvex)->squareId == sid) {
               cc = itr->mConvex;
               break;
            }
         if (cc)
            continue;

         // Create a new convex.
         TerrainConvex* cp = new TerrainConvex;
         sTerrainConvexList.registerObject(cp);
         convex->addToWorkingList(cp);
         cp->halfA = true;
         cp->square = 0;
         cp->mObject = this;
         cp->squareId = sid;
         cp->material = getMaterial(xi,yi)->index;//RDTODO
         cp->box.minExtents.set((F32)(x * mSquareSize), (F32)(y * mSquareSize), fixedToFloat(gs->minHeight));
         cp->box.maxExtents.x = cp->box.minExtents.x + mSquareSize;
         cp->box.maxExtents.y = cp->box.minExtents.y + mSquareSize;
         cp->box.maxExtents.z = fixedToFloat(gs->maxHeight);
         mObjToWorld.mul(cp->box);

         // Build points
         Point3F* pos = cp->point;
         for (int i = 0; i < 4 ; i++,pos++) {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            pos->x = (F32)((x + dx) * mSquareSize);
            pos->y = (F32)((y + dy) * mSquareSize);
            pos->z = fixedToFloat(getHeight(xi + dx, yi + dy));
         }

         // Build normals, then split into two Convex objects if the
         // square is concave
         if ((cp->split45 = gs->flags & GridSquare::Split45) == true) {
            VectorF *vp = cp->point;
            mCross(vp[0] - vp[1],vp[2] - vp[1],&cp->normal[0]);
            cp->normal[0].normalize();
            mCross(vp[2] - vp[3],vp[0] - vp[3],&cp->normal[1]);
            cp->normal[1].normalize();
            if (mDot(vp[3] - vp[1],cp->normal[0]) > 0) {
               TerrainConvex* nc = new TerrainConvex(*cp);
               sTerrainConvexList.registerObject(nc);
               convex->addToWorkingList(nc);
               nc->halfA = false;
               nc->square = cp;
               cp->square = nc;
            }
         }
         else {
            VectorF *vp = cp->point;
            mCross(vp[3] - vp[0],vp[1] - vp[0],&cp->normal[0]);
            cp->normal[0].normalize();
            mCross(vp[1] - vp[2],vp[3] - vp[2],&cp->normal[1]);
            cp->normal[1].normalize();
            if (mDot(vp[2] - vp[0],cp->normal[0]) > 0) {
               TerrainConvex* nc = new TerrainConvex(*cp);
               sTerrainConvexList.registerObject(nc);
               convex->addToWorkingList(nc);
               nc->halfA = false;
               nc->square = cp;
               cp->square = nc;
            }
         }
      }
   }
}
Example #7
0
bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, const Box3F &box, const SphereF&)
{
	PROFILE_SCOPE( TerrainBlock_buildPolyList );

   // First check to see if the query misses the 
   // terrain elevation range.
   const Point3F &terrainPos = getPosition();
   if (  box.maxExtents.z - terrainPos.z < -TerrainThickness || 
         box.minExtents.z - terrainPos.z > fixedToFloat( mFile->getMaxHeight() ) )
      return false;

   // Transform the bounding sphere into the object's coord 
   // space.  Note that this is really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F::One, "Error, handle the scale transform on the terrain");

   // Setup collision state data
   polyList->setTransform(&getTransform(), getScale());
   polyList->setObject(this);

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   if ( xStart < 0 )
      xStart = 0;
   S32 xExt = xEnd - xStart;
   if ( xExt > MaxExtent )
      xExt = MaxExtent;
   xEnd = xStart + xExt;

   U32 heightMax = floatToFixed(osBox.maxExtents.z);
   U32 heightMin = (osBox.minExtents.z < 0.0f)? 0.0f: floatToFixed(osBox.minExtents.z);

   // Index of shared points
   U32 bp[(MaxExtent + 1) * 2],*vb[2];
   vb[0] = &bp[0];
   vb[1] = &bp[xExt + 1];
   clrbuf(vb[1],xExt + 1);

   const U32 BlockMask = mFile->mSize - 1;

   bool emitted = false;
   for (S32 y = yStart; y < yEnd; y++) 
   {
      S32 yi = y & BlockMask;

      swap(vb[0],vb[1]);
      clrbuf(vb[1],xExt + 1);
      //
      for (S32 x = xStart; x < xEnd; x++) 
      {
         S32 xi = x & BlockMask;
         const TerrainSquare *sq = mFile->findSquare( 0, xi, yi );

         if ( x != xi || y != yi )
            continue;

         // holes only in the primary terrain block
         if (  ( ( sq->flags & TerrainSquare::Empty ) && x == xi && y == yi ) || 
               sq->minHeight > heightMax || 
               sq->maxHeight < heightMin )
            continue;

         emitted = true;

         // Add the missing points
         U32 vi[5];
         for (int i = 0; i < 4 ; i++) 
         {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            U32* vp = &vb[dy][x - xStart + dx];
            if (*vp == U32_MAX) 
            {
               Point3F pos;
               pos.x = (F32)((x + dx) * mSquareSize);
               pos.y = (F32)((y + dy) * mSquareSize);
               pos.z = fixedToFloat( mFile->getHeight(xi + dx, yi + dy) );
               *vp = polyList->addPoint(pos);
            }
            vi[i] = *vp;
         }

         U32* vp = &vi[0];
         if ( !( sq->flags & TerrainSquare::Split45 ) )
            vi[4] = vi[0], vp++;

         BaseMatInstance *material = NULL; //getMaterialInst( xi, yi );
         U32 surfaceKey = ((xi << 16) + yi) << 1;
         polyList->begin(material,surfaceKey);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[1]);
         polyList->vertex(vp[2]);
         polyList->plane(vp[0],vp[1],vp[2]);
         polyList->end();
         polyList->begin(material,surfaceKey + 1);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[2]);
         polyList->vertex(vp[3]);
         polyList->plane(vp[0],vp[2],vp[3]);
         polyList->end();
      }
   }

   return emitted;
}
void TerrainFile::import(  const GBitmap &heightMap, 
                           F32 heightScale,
                           const Vector<U8> &layerMap, 
                           const Vector<String> &materials,
                           bool flipYAxis )
{
   AssertFatal( heightMap.getWidth() == heightMap.getHeight(), "TerrainFile::import - Height map is not square!" );
   AssertFatal( isPow2( heightMap.getWidth() ), "TerrainFile::import - Height map is not power of two!" );

   const U32 newSize = heightMap.getWidth();
   if ( newSize != mSize )
   {
      mHeightMap.setSize( newSize * newSize );
      mHeightMap.compact();
      mSize = newSize;
   }

   // Convert the height map to heights.
   U16 *oBits = mHeightMap.address();
   if ( heightMap.getFormat() == GFXFormatR5G6B5 )
   {
      const F32 toFixedPoint = ( 1.0f / (F32)U16_MAX ) * floatToFixed( heightScale );
      const U16 *iBits = (const U16*)heightMap.getBits();
      if ( flipYAxis )
      {
         for ( U32 i = 0; i < mSize * mSize; i++ )
         {
            U16 height = convertBEndianToHost( *iBits );
            *oBits = (U16)mCeil( (F32)height * toFixedPoint );
            ++oBits;
            ++iBits;
         }
      }
      else
      {
         for(S32 y = mSize - 1; y >= 0; y--) {
            for(U32 x = 0; x < mSize; x++) {
               U16 height = convertBEndianToHost( *iBits );
               mHeightMap[x + y * mSize] = (U16)mCeil( (F32)height * toFixedPoint );
               ++iBits;
            }
         }
      }
   }
   else
   {
      const F32 toFixedPoint = ( 1.0f / (F32)U8_MAX ) * floatToFixed( heightScale );
      const U8 *iBits = heightMap.getBits();
      if ( flipYAxis )
      {
         for ( U32 i = 0; i < mSize * mSize; i++ )
         {
            *oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
            ++oBits;
            iBits += heightMap.getBytesPerPixel();
         }
      }
      else
      {
         for(S32 y = mSize - 1; y >= 0; y--) {
            for(U32 x = 0; x < mSize; x++) {
               mHeightMap[x + y * mSize] = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
               iBits += heightMap.getBytesPerPixel();
            }
         }
      }
   }

   // Copy over the layer map.
   AssertFatal( layerMap.size() == mHeightMap.size(), "TerrainFile::import - Layer map is the wrong size!" );
   mLayerMap = layerMap;
   mLayerMap.compact();

   // Resolve the materials.
   _resolveMaterials( materials );

   // Rebuild the collision grid map.
   _buildGridMap();
}