void CMatCanvas::Create(CWnd* parent,CRect pos,UINT in_winId)
{
 	const char* cName = AfxRegisterWndClass(CS_OWNDC | 
 			CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT,
 			::LoadCursor(NULL,IDC_ARROW));
	Base::Create(cName, "Canvas" ,WS_VISIBLE, pos, parent, in_winId,NULL);

	// DMMSOLID added point
	Point2I temp(0,0);
	GFXCDSSurface::create(m_pSurface, TRUE,
		pos.Width(), pos.Height(), GetSafeHwnd(), &temp);

	RectI screenView(Point2I(0,0),Point2I(pos.Width()-1, pos.Height()-1));

//    double max_dim = (pos.Width() > pos.Height()) ? (double)pos.Width() : (double)pos.Height();
//	RectF worldView(Point2F(-pos.Width()/max_dim, pos.Height()/max_dim),
//			            Point2F(pos.Width()/max_dim, -pos.Height()/max_dim));
	RectF worldView(Point2F(0, 0),
			            Point2F(pos.Width(), pos.Height()));

    m_pTSCamera = new TSPerspectiveCamera(screenView, worldView, 1.F, 1.0E4f);

    m_renderContext->setSurface(m_pSurface);
    m_renderContext->setPointArray(&DefaultPointArray);
    m_renderContext->setCamera(m_pTSCamera);
    m_renderContext->setLights(m_GSceneLights);

    m_renderContext->getSurface()->setHazeSource(GFX_HAZE_NONE);
//    m_renderContext->getSurface()->setShadeSource(GFX_SHADE_NONE);
    m_renderContext->getSurface()->setAlphaSource(GFX_ALPHA_NONE);
    m_renderContext->getSurface()->setTransparency(FALSE);

}
bool ShapeView::onAdd()
{
   RectF rect;
   float width, height;

   if (Parent::onAdd())
   {
      active = true;
      camera = new TSPerspectiveCamera(
         RectI(Point2I(0, 0),       Point2I(0, 0)),
         RectF(Point2F(0.0f, 0.0f), Point2F(0.0f, 0.0f)),
         256.0f, 1.0E8f);

      scene = new TSSceneLighting;
      scene->setAmbientIntensity(ColorF(0.7f, 0.7f, 0.7f));

      light = new TSLight;
      light->setType(TS::Light::LightDirectional);
      light->setIntensity(1.0f, 1.0f, 1.0f);
      scene->installLight(light);

      return (true);
   }

   return (false);
}
Beispiel #3
0
void Sphere::generate() {
	S32 segments2 = segments / 2;
	S32 slices2 = slices / 2;

	Vertex *points = new Vertex[segments * slices * 2];
	U32 point = 0;

	for (S32 y = -slices2; y < slices2; y ++) {
		float cosy = cos(y * step);
		float cosy1 = cos((y + 1) * step);
		float siny = sin(y * step);
		float siny1 = sin((y + 1) * step);

		for (S32 i = -segments2; i < segments2; i ++) {
			float cosi = cos(i * step);
			float sini = sin(i * step);

			//Math not invented by me
			Point3F point0 = Point3F(radius * cosi * cosy, radius * siny, radius * sini * cosy);
			Point3F point1 = Point3F(radius * cosi * cosy1, radius * siny1, radius * sini * cosy1);
			Point4F color0 = Point4F(fabs(point0.x), fabs(point0.y), fabs(point0.z), radius).normalize();
			Point4F color1 = Point4F(fabs(point1.x), fabs(point1.y), fabs(point1.z), radius).normalize();

			color0 /= color0.z;
			color1 /= color1.z;

			Point2F uv0 = Point2F((F32)i / (F32)segments2, (F32)y / (F32)slices2);
			Point2F uv1 = Point2F((F32)i / (F32)segments2, (F32)(y + 1) / (F32)slices2);

			Point3F tangent0 = point0.cross(Point3F(0, 0, 1)).normalize();
			Point3F tangent1 = point1.cross(Point3F(0, 0, 1)).normalize();
			Point3F bitangent0 = point0.cross(tangent0).normalize();
			Point3F bitangent1 = point0.cross(tangent0).normalize();

			points[point].point = point0;
			points[point].uv = uv0;
			points[point].normal = point0;
			points[point].tangent = tangent0;
			points[point].bitangent = bitangent0;
			point ++;
			points[point].point = point1;
			points[point].uv = uv1;
			points[point].normal = point1;
			points[point].tangent = tangent1;
			points[point].bitangent = bitangent1;
			point ++;
		}
	}

	//Generate a buffer
	glGenBuffers(1, &renderBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, renderBuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * point, points, GL_STATIC_DRAW);

	delete [] points;
}
Point2F BiQuadToSqr::transform( const Point2F &p ) const
{
    Point2F kA = m_kP00 - p;

    F32 fAB = mDotPerp( kA, m_kB );
    F32 fAC = mDotPerp( kA, m_kC);

    // 0 = ac*bc+(bc^2+ac*bd-ab*cd)*s+bc*bd*s^2 = k0 + k1*s + k2*s^2
    F32 fK0 = fAC*m_fBC;
    F32 fK1 = m_fBC*m_fBC + fAC*m_fBD - fAB*m_fCD;
    F32 fK2 = m_fBC*m_fBD;

    if (mFabs(fK2) > POINT_EPSILON)
    {
        // s-equation is quadratic
        F32 fInv = 0.5f/fK2;
        F32 fDiscr = fK1*fK1 - 4.0f*fK0*fK2;
        F32 fRoot = mSqrt( mFabs(fDiscr) );

        Point2F kResult0( 0, 0 );
        kResult0.x = (-fK1 - fRoot)*fInv;
        kResult0.y = fAB/(m_fBC + m_fBD*kResult0.x);
        F32 fDeviation0 = deviation(kResult0);
        if ( fDeviation0 == 0.0f )
            return kResult0;

        Point2F kResult1( 0, 0 );
        kResult1.x = (-fK1 + fRoot)*fInv;
        kResult1.y = fAB/(m_fBC + m_fBD*kResult1.x);
        F32 fDeviation1 = deviation(kResult1);
        if ( fDeviation1 == 0.0f )
            return kResult1;

        if (fDeviation0 <= fDeviation1)
        {
            if ( fDeviation0 < POINT_EPSILON )
                return kResult0;
        }
        else
        {
            if ( fDeviation1 < POINT_EPSILON )
                return kResult1;
        }
    }
    else
    {
        // s-equation is linear
        Point2F kResult( 0, 0 );

        kResult.x = -fK0/fK1;
        kResult.y = fAB/(m_fBC + m_fBD*kResult.x);
        F32 fDeviation = deviation(kResult);
        if ( fDeviation < POINT_EPSILON )
            return kResult;
    }

    // point is outside the quadrilateral, return invalid
    return Point2F(F32_MAX,F32_MAX);
}
Beispiel #5
0
void Scene::loop() {
	//Basic movement
	glm::mat4x4 delta = glm::mat4x4(1);

	if (movement[4]) pitch -= keyCameraSpeed;
	if (movement[5]) pitch += keyCameraSpeed;
	if (movement[6]) yaw -= keyCameraSpeed;
	if (movement[7]) yaw += keyCameraSpeed;

	delta = glm::rotate(delta, -yaw, glm::vec3(0, 0, 1));

	float speed = movementSpeed;
	if (mouseButtons[1])
		speed *= 2.f;

	Point2F move = Point2F();
	if (movement[0]) move.x -= speed;
	if (movement[1]) move.x += speed;
	if (movement[2]) move.y -= speed;
	if (movement[3]) move.y += speed;

#ifdef BUILD_PHYSICS
	glm::vec3 torque = glm::vec3(glm::translate(delta, glm::vec3(move.x, move.y, 0))[3]);
	delta = glm::rotate(delta, -pitch, glm::vec3(1, 0, 0));

	sphere->applyTorque(Point3F(torque.x, torque.y, torque.z) * 20);

	if (sphere->getColliding()) {
		Point3F normal = sphere->getCollisionNormal();
		if (movement[8] && normal.dot(Point3F(0, 0, 1)) > 0.1)
			sphere->applyImpulse((normal + Point3F(0, 0, 1)) / 2.f, Point3F(0, 0, -1));
	} else {
		sphere->applyImpulse(Point3F(torque.y, -torque.x, torque.z) / 4.f, Point3F(0, 0, 0));
	}

	Point3F pos = sphere->getPosition();
	cameraPosition = glm::vec3(pos.x, pos.y, pos.z);
	cameraPosition += glm::vec3(glm::translate(delta, glm::vec3(0, -2.5, 0))[3]);

	if (sphere->getPosition().z < difs[0]->interior[0]->boundingBox.getMin().x) {
		sphere->setPosition(Point3F(0, 30, 60));
	}
#else /* BUILD_PHYSICS */
	move *= 3;
	if (movement[8])
		move *= 2;

	delta = glm::rotate(delta, -pitch, glm::vec3(1, 0, 0));
	delta = glm::translate(delta, glm::vec3(move.y, -move.x, 0));

	cameraPosition += glm::vec3(delta[3]);
#endif /* BUILD_PHYSICS */
}
Point2F ITR3DMImport::power2Size(const Point2F& ts)
{
   // Find smallest 2^n size that bounds givin size.
   static int table[] =  { 1, 2, 4, 8, 16, 32, 64, 128, 256 };
   int x = 0, y = 0;
   for (; x < sizeof(table) * sizeof(*table); x++)
      if (ts.x <= table[x])
         break;
   for (; y < sizeof(table) * sizeof(*table); y++)
      if (ts.y <= table[y])
         break;
   return Point2F(table[x],table[y]);
};
Beispiel #7
0
bool BaseFeatureLayer::Initialize()
{
	RETURN_FALSE_IF_FALSE(ILayer::Initialize());

	TextureButton* returnButton = NodeFactory::Instance().CreateTextureButton("Close.png", "CloseSelected.png");
	returnButton->OnTap += Bind(&BaseFeatureLayer::OnReturn,this);
	returnButton->SetDock(DockPoint::LeftTop);
	returnButton->SetAnchor(0.f, 1.f);
	AddChild(returnButton);

	TextureButton* refreshButton = NodeFactory::Instance().CreateTextureButton("Refresh.png", "RefreshSelected.png");
	refreshButton->OnTap += Bind(&BaseFeatureLayer::OnRefresh, this);
	refreshButton->SetDock(DockPoint::MiddleBottom);
	refreshButton->SetAnchor(0.5f, 0.f);
	AddChild(refreshButton);


	float xPadding = refreshButton->Size().Width*0.5f + 100.f;

	TextureButton* leftButton = NodeFactory::Instance().CreateTextureButton("Left.png", "LeftSelected.png");
	leftButton->OnTap += Bind(&BaseFeatureLayer::OnLeft, this);
	leftButton->SetDock(DockPoint::MiddleBottom);
	leftButton->SetAnchor(0.5f, 0.f);
	leftButton->SetRelativePosition(Point2F(-xPadding, 0.f));
	AddChild(leftButton);


	TextureButton* rightButton = NodeFactory::Instance().CreateTextureButton("Left.png", "LeftSelected.png");
	rightButton->OnTap += Bind(&BaseFeatureLayer::OnRight, this);
	rightButton->SetDock(DockPoint::MiddleBottom);
	rightButton->SetAnchor(0.5f, 0.f);
	rightButton->SetRelativePosition(Point2F(xPadding, 0.f));
	rightButton->SetFlipX(true);
	AddChild(rightButton);


	return true;
}
Beispiel #8
0
// Used to build potential target list
static void _scanCallback( SceneObject* object, void* data )
{
   AITurretShape* turret = (AITurretShape*)data;

   ShapeBase* shape = dynamic_cast<ShapeBase*>(object);
   if (shape && shape->getDamageState() == ShapeBase::Enabled)
   {
      Point3F targetPos = shape->getBoxCenter();

      // Put target position into the scan node's space
      turret->mScanWorkspaceScanWorldMat.mulP(targetPos);

      // Is the target within scanning distance
      if (targetPos.lenSquared() > turret->getMaxScanDistanceSquared())
         return;

      // Make sure the target is in front and within the maximum
      // heading range
      Point2F targetXY(targetPos.x, targetPos.y);
      targetXY.normalizeSafe();
      F32 headingDot = mDot(Point2F(0, 1), targetXY);
      F32 heading = mAcos(headingDot);
      if (headingDot < 0 || heading > turret->getMaxScanHeading())
         return;

      // Make sure the target is in front and within the maximum
      // pitch range
      Point2F targetZY(targetPos.z, targetPos.y);
      targetZY.normalizeSafe();
      F32 pitchDot = mDot(Point2F(0, 1), targetZY);
      F32 pitch = mAcos(pitchDot);
      if (pitchDot < 0 || pitch > turret->getMaxScanPitch())
         return;

      turret->addPotentialTarget(shape);
   }
}
void SmoothSlopeAction::process(Selection * sel, const Gui3DMouseEvent &, bool selChanged, Type)  
{  
   if(!sel->size())  
      return;  
  
   if(selChanged)  
   {  
      // Perform simple 2d linear regression on x&z and y&z:  
      // b = (Avg(xz) - Avg(x)Avg(z))/(Avg(x^2) - Avg(x)^2)  
      Point2F prod(0.f, 0.f);   // mean of product for covar  
      Point2F avgSqr(0.f, 0.f); // mean sqr of x, y for var  
      Point2F avgPos(0.f, 0.f);  
      F32 avgHeight = 0.f;  
      F32 z;  
      Point2F pos;  
      for(U32 k = 0; k < sel->size(); k++)  
      {  
         mTerrainEditor->getUndoSel()->add((*sel)[k]);  
         pos = Point2F((*sel)[k].mGridPoint.gridPos.x, (*sel)[k].mGridPoint.gridPos.y);  
         z = (*sel)[k].mHeight;  
  
         prod += pos * z;  
         avgSqr += pos * pos;  
         avgPos += pos;  
         avgHeight += z;  
      }  
  
      prod /= sel->size();  
      avgSqr /= sel->size();  
      avgPos /= sel->size();  
      avgHeight /= sel->size();  
  
      Point2F avgSlope = (prod - avgPos*avgHeight)/(avgSqr - avgPos*avgPos);  
  
      F32 goalHeight;  
      for(U32 i = 0; i < sel->size(); i++)  
      {  
         goalHeight = avgHeight + ((*sel)[i].mGridPoint.gridPos.x - avgPos.x)*avgSlope.x +  
            ((*sel)[i].mGridPoint.gridPos.y - avgPos.y)*avgSlope.y;  
         (*sel)[i].mHeight += (goalHeight - (*sel)[i].mHeight) * (*sel)[i].mWeight;  
         mTerrainEditor->setGridInfo((*sel)[i]);  
      }  
      mTerrainEditor->scheduleGridUpdate();  
   }  
}  
void waterFind( SceneObject *obj, void *key )
{     
   PROFILE_SCOPE( waterFind );

   // This is called for each WaterObject the ShapeBase object is overlapping.

   ContainerQueryInfo *info = static_cast<ContainerQueryInfo*>(key);
   WaterObject *water = dynamic_cast<WaterObject*>(obj);      
   AssertFatal( water != NULL, "containerQuery - waterFind(), passed object was not of class WaterObject!");      

   // Get point at the bottom/center of the box.
   Point3F testPnt = info->box.getCenter();
   testPnt.z = info->box.minExtents.z;

   F32 coverage = water->getWaterCoverage(info->box);

   // Since a WaterObject can have global bounds we may get this call
   // even though we have zero coverage.  If so we want to early out and
   // not save the water properties.
   if ( coverage == 0.0f )
      return;

   // Add in flow force.  Would be appropriate to try scaling it by coverage
   // thought. Or perhaps have getFlow do that internally and take
   // the box parameter.
   info->appliedForce += water->getFlow( testPnt );

   // Only save the following properties for the WaterObject with the
   // greatest water coverage for this ShapeBase object.
   if ( coverage < info->waterCoverage )
      return;
   
   info->waterCoverage = coverage;
   info->liquidType = water->getLiquidType();
   info->waterViscosity = water->getViscosity();
   info->waterDensity = water->getDensity();
   info->waterHeight = water->getSurfaceHeight( Point2F(testPnt.x,testPnt.y) );   
   info->waterObject = water;
}
void SoftSelectAction::process(Selection * sel, const Gui3DMouseEvent &, bool selChanged, Type type)
{
   TerrainBlock *terrBlock = mTerrainEditor->getActiveTerrain();
   if ( !terrBlock )
      return;
      
   // allow process of current selection
   Selection tmpSel;
   if(sel == mTerrainEditor->getCurrentSel())
   {
      tmpSel = *sel;
      sel = &tmpSel;
   }

   if(type == Begin || type == Process)
      mFilter.set(1, &mTerrainEditor->mSoftSelectFilter);

   //
   if(selChanged)
   {
      F32 radius = mTerrainEditor->mSoftSelectRadius;
      if(radius == 0.f)
         return;

      S32 squareSize = terrBlock->getSquareSize();
      U32 offset = U32(radius / F32(squareSize)) + 1;

      for(U32 i = 0; i < sel->size(); i++)
      {
         GridInfo & info = (*sel)[i];

         info.mPrimarySelect = true;
         info.mWeight = mFilter.getValue(0);

         if(!mTerrainEditor->getCurrentSel()->add(info))
            mTerrainEditor->getCurrentSel()->setInfo(info);

         Point2F infoPos((F32)info.mGridPoint.gridPos.x, (F32)info.mGridPoint.gridPos.y);

         //
         for(S32 x = info.mGridPoint.gridPos.x - offset; x < info.mGridPoint.gridPos.x + (offset << 1); x++)
            for(S32 y = info.mGridPoint.gridPos.y - offset; y < info.mGridPoint.gridPos.y + (offset << 1); y++)
            {
               //
               Point2F pos((F32)x, (F32)y);

               F32 dist = Point2F(pos - infoPos).len() * F32(squareSize);

               if(dist > radius)
                  continue;

               F32 weight = mFilter.getValue(dist / radius);

               //
               GridInfo gInfo;
               GridPoint gridPoint = info.mGridPoint;
               gridPoint.gridPos.set(x, y);

               if(mTerrainEditor->getCurrentSel()->getInfo(Point2I(x, y), gInfo))
               {
                  if(gInfo.mPrimarySelect)
                     continue;

                  if(gInfo.mWeight < weight)
                  {
                     gInfo.mWeight = weight;
                     mTerrainEditor->getCurrentSel()->setInfo(gInfo);
                  }
               }
               else
               {
                  Vector<GridInfo> gInfos;
                  mTerrainEditor->getGridInfos(gridPoint, gInfos);

                  for (U32 z = 0; z < gInfos.size(); z++)
                  {
                     gInfos[z].mWeight = weight;
                     gInfos[z].mPrimarySelect = false;
                     mTerrainEditor->getCurrentSel()->add(gInfos[z]);
                  }
               }
            }
      }
   }
}
Beispiel #12
0
void TerrainBlock::_updateBaseTexture(bool writeToCache)
{
   if ( !mBaseShader && !_initBaseShader() )
      return;

   // This can sometimes occur outside a begin/end scene.
   const bool sceneBegun = GFX->canCurrentlyRender();
   if ( !sceneBegun )
      GFX->beginScene();

   GFXDEBUGEVENT_SCOPE( TerrainBlock_UpdateBaseTexture, ColorI::GREEN );

   PROFILE_SCOPE( TerrainBlock_UpdateBaseTexture );

   GFXTransformSaver saver;

   const U32 maxTextureSize = GFX->getCardProfiler()->queryProfile( "maxTextureSize", 1024 );

   U32 baseTexSize = getNextPow2( mBaseTexSize );
   baseTexSize = getMin( maxTextureSize, baseTexSize );
   Point2I destSize( baseTexSize, baseTexSize );

   // Setup geometry
   GFXVertexBufferHandle<GFXVertexPT> vb;
   {
      F32 copyOffsetX = 2.0f * GFX->getFillConventionOffset() / (F32)destSize.x;
      F32 copyOffsetY = 2.0f * GFX->getFillConventionOffset() / (F32)destSize.y;

      GFXVertexPT points[4];
      points[0].point = Point3F(1.0 - copyOffsetX, -1.0 + copyOffsetY, 0.0);
      points[0].texCoord = Point2F(1.0, 1.0f);
      points[1].point = Point3F(1.0 - copyOffsetX, 1.0 + copyOffsetY, 0.0);
      points[1].texCoord = Point2F(1.0, 0.0f);
      points[2].point = Point3F(-1.0 - copyOffsetX, -1.0 + copyOffsetY, 0.0);
      points[2].texCoord = Point2F(0.0, 1.0f);
      points[3].point = Point3F(-1.0 - copyOffsetX, 1.0 + copyOffsetY, 0.0);
      points[3].texCoord = Point2F(0.0, 0.0f);

      vb.set( GFX, 4, GFXBufferTypeVolatile );
      GFXVertexPT *ptr = vb.lock();
      if(ptr)
      {
         dMemcpy( ptr, points, sizeof(GFXVertexPT) * 4 );
         vb.unlock();
      }
   }

   GFXTexHandle blendTex;

   // If the base texture is already a valid render target then 
   // use it to render to else we create one.
   if (  mBaseTex.isValid() && 
         mBaseTex->isRenderTarget() &&
         mBaseTex->getFormat() == GFXFormatR8G8B8A8 &&
         mBaseTex->getWidth() == destSize.x &&
         mBaseTex->getHeight() == destSize.y )
      blendTex = mBaseTex;
   else
      blendTex.set( destSize.x, destSize.y, GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, "" );

   GFX->pushActiveRenderTarget();   

   // Set our shader stuff
   GFX->setShader( mBaseShader );
   GFX->setShaderConstBuffer( mBaseShaderConsts );
   GFX->setStateBlock( mBaseShaderSB );
   GFX->setVertexBuffer( vb );

   mBaseTarget->attachTexture( GFXTextureTarget::Color0, blendTex );
   GFX->setActiveRenderTarget( mBaseTarget );

   GFX->clear( GFXClearTarget, ColorI(0,0,0,255), 1.0f, 0 );

   GFX->setTexture( 0, mLayerTex );
   mBaseShaderConsts->setSafe( mBaseLayerSizeConst, (F32)mLayerTex->getWidth() );      

   for ( U32 i=0; i < mBaseTextures.size(); i++ )
   {
      GFXTextureObject *tex = mBaseTextures[i];
      if ( !tex )
         continue;

      GFX->setTexture( 1, tex );

      F32 baseSize = mFile->mMaterials[i]->getDiffuseSize();
      F32 scale = 1.0f;
      if ( !mIsZero( baseSize ) )
         scale = getWorldBlockSize() / baseSize;
      
      // A mistake early in development means that texture
      // coords are not flipped correctly.  To compensate
      // we flip the y scale here.
      mBaseShaderConsts->setSafe( mBaseTexScaleConst, Point2F( scale, -scale ) );
      mBaseShaderConsts->setSafe( mBaseTexIdConst, (F32)i );

      GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
   }

   mBaseTarget->resolve();
   
   GFX->setShader( NULL );
   //GFX->setStateBlock( NULL ); // WHY NOT?
   GFX->setShaderConstBuffer( NULL );
   GFX->setVertexBuffer( NULL );

   GFX->popActiveRenderTarget();

   // End it if we begun it... Yeehaw!
   if ( !sceneBegun )
      GFX->endScene();

   /// Do we cache this sucker?
   if (mBaseTexFormat == NONE || !writeToCache)
   {
      // We didn't cache the result, so set the base texture
      // to the render target we updated.  This should be good
      // for realtime painting cases.
      mBaseTex = blendTex;
   }
   else if (mBaseTexFormat == DDS)
   {
      String cachePath = _getBaseTexCacheFileName();

      FileStream fs;
      if ( fs.open( _getBaseTexCacheFileName(), Torque::FS::File::Write ) )
      {
         // Read back the render target, dxt compress it, and write it to disk.
         GBitmap blendBmp( destSize.x, destSize.y, false, GFXFormatR8G8B8A8 );
         blendTex.copyToBmp( &blendBmp );

         /*
         // Test code for dumping uncompressed bitmap to disk.
         {
         FileStream fs;
         if ( fs.open( "./basetex.png", Torque::FS::File::Write ) )
         {
         blendBmp.writeBitmap( "png", fs );
         fs.close();
         }         
         }
         */

         blendBmp.extrudeMipLevels();

         DDSFile *blendDDS = DDSFile::createDDSFileFromGBitmap( &blendBmp );
         DDSUtil::squishDDS( blendDDS, GFXFormatDXT1 );

         // Write result to file stream
         blendDDS->write( fs );
         
         delete blendDDS;
      }
      fs.close();
   }
   else
   {
      FileStream stream;
      if (!stream.open(_getBaseTexCacheFileName(), Torque::FS::File::Write))
      {
         mBaseTex = blendTex;
         return;
      }

      GBitmap bitmap(blendTex->getWidth(), blendTex->getHeight(), false, GFXFormatR8G8B8);
      blendTex->copyToBmp(&bitmap);
      bitmap.writeBitmap(formatToExtension(mBaseTexFormat), stream);
   }
}
Beispiel #13
0
bool SceneCullingState::isOccludedByTerrain( SceneObject* object ) const
{
   PROFILE_SCOPE( SceneCullingState_isOccludedByTerrain );

   // Don't try to occlude globally bounded objects.
   if( object->isGlobalBounds() )
      return false;

   const Vector< SceneObject* >& terrains = getSceneManager()->getContainer()->getTerrains();
   const U32 numTerrains = terrains.size();

   for( U32 terrainIdx = 0; terrainIdx < numTerrains; ++ terrainIdx )
   {
      TerrainBlock* terrain = dynamic_cast< TerrainBlock* >( terrains[ terrainIdx ] );
      if( !terrain )
         continue;

      MatrixF terrWorldTransform = terrain->getWorldTransform();

      Point3F localCamPos = getCameraState().getViewPosition();
      terrWorldTransform.mulP(localCamPos);
      F32 height;
      terrain->getHeight( Point2F( localCamPos.x, localCamPos.y ), &height );
      bool aboveTerrain = ( height <= localCamPos.z );

      // Don't occlude if we're below the terrain.  This prevents problems when
      //  looking out from underground bases...
      if( !aboveTerrain )
         continue;

      const Box3F& oBox = object->getObjBox();
      F32 minSide = getMin(oBox.len_x(), oBox.len_y());
      if (minSide > 85.0f)
         continue;

      const Box3F& rBox = object->getWorldBox();
      Point3F ul(rBox.minExtents.x, rBox.minExtents.y, rBox.maxExtents.z);
      Point3F ur(rBox.minExtents.x, rBox.maxExtents.y, rBox.maxExtents.z);
      Point3F ll(rBox.maxExtents.x, rBox.minExtents.y, rBox.maxExtents.z);
      Point3F lr(rBox.maxExtents.x, rBox.maxExtents.y, rBox.maxExtents.z);

      terrWorldTransform.mulP(ul);
      terrWorldTransform.mulP(ur);
      terrWorldTransform.mulP(ll);
      terrWorldTransform.mulP(lr);

      Point3F xBaseL0_s = ul - localCamPos;
      Point3F xBaseL0_e = lr - localCamPos;
      Point3F xBaseL1_s = ur - localCamPos;
      Point3F xBaseL1_e = ll - localCamPos;

      static F32 checkPoints[3] = {0.75, 0.5, 0.25};
      RayInfo rinfo;
      for( U32 i = 0; i < 3; i ++ )
      {
         Point3F start = (xBaseL0_s * checkPoints[i]) + localCamPos;
         Point3F end   = (xBaseL0_e * checkPoints[i]) + localCamPos;

         if (terrain->castRay(start, end, &rinfo))
            continue;

         terrain->getHeight(Point2F(start.x, start.y), &height);
         if ((height <= start.z) == aboveTerrain)
            continue;

         start = (xBaseL1_s * checkPoints[i]) + localCamPos;
         end   = (xBaseL1_e * checkPoints[i]) + localCamPos;

         if (terrain->castRay(start, end, &rinfo))
            continue;

         Point3F test = (start + end) * 0.5;
         if (terrain->castRay(localCamPos, test, &rinfo) == false)
            continue;

         return true;
      }
   }

   return false;
}
Beispiel #14
0
//-----------------------------------------------------------------------------
// Draw Rectangle Fill
//-----------------------------------------------------------------------------
void GFXDrawUtil::drawRectFill( const RectF &rect, const ColorI &color )
{
   drawRectFill(rect.point, Point2F(rect.extent.x + rect.point.x - 1, rect.extent.y + rect.point.y - 1), color );
}
void EditTSCtrl::renderGrid()
{
   if( !isOrthoDisplayType() )
      return;

   GFXDEBUGEVENT_SCOPE( Editor_renderGrid, ColorI::WHITE );

   // Calculate the displayed grid size based on view
   F32 drawnGridSize = mGridPlaneSize;
   F32 gridPixelSize = projectRadius(1.0f, mGridPlaneSize);
   if(gridPixelSize < mGridPlaneSizePixelBias)
   {
      U32 counter = 1;
      while(gridPixelSize < mGridPlaneSizePixelBias)
      {
         drawnGridSize = mGridPlaneSize * counter * 10.0f;
         gridPixelSize = projectRadius(1.0f, drawnGridSize);

         ++counter;

         // No infinite loops here
         if(counter > 1000)
            break;
      }
   }

   F32 minorTickSize = 0;
   F32 gridSize = drawnGridSize;
   U32 minorTickMax = mGridPlaneMinorTicks + 1;
   if(minorTickMax > 0)
   {
      minorTickSize = drawnGridSize;
      gridSize = drawnGridSize * minorTickMax;
   }

   // Build the view-based origin
   VectorF dir;
   smCamMatrix.getColumn( 1, &dir );

   Point3F gridPlanePos = smCamPos + dir;
   Point2F size(mOrthoWidth + 2 * gridSize, mOrthoHeight + 2 * gridSize);

   GFXStateBlockDesc desc;
   desc.setBlend( true );
   desc.setZReadWrite( true, false );

   GFXDrawUtil::Plane plane = GFXDrawUtil::PlaneXY;
   switch( getDisplayType() )
   {
      case DisplayTypeTop:
      case DisplayTypeBottom:
         plane = GFXDrawUtil::PlaneXY;
         break;

      case DisplayTypeLeft:
      case DisplayTypeRight:
         plane = GFXDrawUtil::PlaneYZ;
         break;

      case DisplayTypeFront:
      case DisplayTypeBack:
         plane = GFXDrawUtil::PlaneXZ;
         break;
         
      default:
         break;
   }

   GFX->getDrawUtil()->drawPlaneGrid( desc, gridPlanePos, size, Point2F( minorTickSize, minorTickSize ), mGridPlaneMinorTickColor, plane );
   GFX->getDrawUtil()->drawPlaneGrid( desc, gridPlanePos, size, Point2F( gridSize, gridSize ), mGridPlaneColor, plane );
}
Beispiel #16
0
void ClipMap::calculateClipMapLevels(const F32 near, const F32 far, 
                                          const RectF &texBounds, 
                                          S32 &outStartLevel, S32 &outEndLevel)
{
   PROFILE_START(ClipMap_calculateClipMapLevels);

   // We also have to deal w/ the available data. So let's figure out if our
   // desired TCs are in the loaded textureset.

   // Adjust the specified TC range into a texel range.
   F32 ftexsize = F32(mTextureSize);
   RectF tcR(Point2F(texBounds.point.y * ftexsize, texBounds.point.x * ftexsize), ftexsize * texBounds.extent);

   // If we're tiling, make sure we're only insetting away from the clipmap bounds.
   // This avoids making bad LOD selections at clipmap boundaries.
   // Note: compress several compares into one since a*b=0 iff a==0 or b==0
   bool doInset = true;//mTile || (tcR.point.x * tcR.point.y * (tcR.extent.x+tcR.point.x-mTextureSize) * (tcR.extent.y+tcR.point.y-mTextureSize) != 0); 

   if(doInset)
      tcR.inset(-1, -1);

   // Put some safe defaults in for starters.
   outEndLevel   = mClipStackDepth-1;
   outStartLevel = getMax(outEndLevel-3, S32(0));

   // Now iterate over every clipstack entry and find the smallest that contains
   // the relevant TCs.
   S32 minLevelOverlap = mClipStackDepth - 1;
   S32 maxLevelOverlap = mClipStackDepth - 1;

   for(S32 i=mClipStackDepth-2; i>=0; i--)
   {
      // Find region for entry at this level.
      RectF r;
      F32 biti = F32(BIT(i));
      F32 biticms = F32(BIT(i) * mClipMapSize);
      r.point = Point2F(
         biti * mLevels[i].mToroidalOffset.x, 
         biti * mLevels[i].mToroidalOffset.y);
      r.extent.set(biticms,biticms);

      // Is our tex region fully contained?
      if(r.contains(tcR))
      {
         // If we're fully contained, then this is our new max.
         maxLevelOverlap = i;
         minLevelOverlap = i;
         continue;
      }

      // Or else maybe we've got overlap?
      if (!r.overlaps(tcR))
         break;

      // If we're overlapping then this is our new min...
      minLevelOverlap = getMin(minLevelOverlap, i);
   }

   // Given our level range, do a best fit. We ALWAYS have to have
   // enough for the minimum detail, so we fit that constraint then
   // do our best to give additional detail on top of that.

   // bias the minimum detail to allow smooth transitions to work properly,
   // this avoids a LOT of texture popping.
   maxLevelOverlap++;

   outEndLevel   = mClamp(maxLevelOverlap, 0, mClipStackDepth-1);
   outStartLevel = mClamp(minLevelOverlap, outEndLevel - 3, outEndLevel - 1);

   // Make sure we're not exceeding our max delta.
   const S32 delta = outEndLevel - outStartLevel;
   AssertFatal(delta >= 1 && delta <= 4, 
      "ClipMap::calculateClipMapLevels - range in levels outside of 2..4 range!");

   PROFILE_END();
}
Beispiel #17
0
void ScatterSky::_render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat )
{
   if ( overrideMat || (!mShader && !_initShader()) )
      return;

   GFXTransformSaver saver;

   if ( mVB.isNull() || mPrimBuffer.isNull() )
      _initVBIB();

   GFX->setShader( mShader );
   GFX->setShaderConstBuffer( mShaderConsts );

   Point4F sphereRadii( mSphereOuterRadius, mSphereOuterRadius * mSphereOuterRadius,
                        mSphereInnerRadius, mSphereInnerRadius * mSphereInnerRadius );

   Point4F scatteringCoeffs( mRayleighScattering * mSkyBrightness, mRayleighScattering4PI,
                             mMieScattering * mSkyBrightness, mMieScattering4PI );

   Point4F invWavelength(  1.0f / mWavelength4[0],
                           1.0f / mWavelength4[1],
                           1.0f / mWavelength4[2], 1.0f );

   Point3F camPos( 0, 0, smViewerHeight );
   Point4F miscParams( camPos.z, camPos.z * camPos.z, mScale, mScale / mRayleighScaleDepth );

   Frustum frust = state->getFrustum();
   frust.setFarDist( smEarthRadius + smAtmosphereRadius );
   MatrixF proj( true );
   frust.getProjectionMatrix( &proj );

   Point3F camPos2 = state->getCameraPosition();
   MatrixF xfm(true);
   xfm.setPosition(camPos2);//-Point3F( 0, 0, 200000.0f));
   GFX->multWorld(xfm);
   MatrixF xform(proj);//GFX->getProjectionMatrix());
   xform *= GFX->getViewMatrix();
   xform *=  GFX->getWorldMatrix();

   mShaderConsts->setSafe( mModelViewProjSC, xform );
   mShaderConsts->setSafe( mMiscSC, miscParams );
   mShaderConsts->setSafe( mSphereRadiiSC, sphereRadii );
   mShaderConsts->setSafe( mScatteringCoefficientsSC, scatteringCoeffs );
   mShaderConsts->setSafe( mCamPosSC, camPos );
   mShaderConsts->setSafe( mLightDirSC, mLightDir );
   mShaderConsts->setSafe( mSunDirSC, mSunDir );
   mShaderConsts->setSafe( mNightColorSC, mNightColor );
   mShaderConsts->setSafe( mInverseWavelengthSC, invWavelength );
   mShaderConsts->setSafe( mNightInterpolantAndExposureSC, Point2F( mExposure, mNightInterpolant ) );
   mShaderConsts->setSafe( mColorizeSC, mColorize*mColorizeAmt );

   if ( GFXDevice::getWireframe() )
   {
      GFXStateBlockDesc desc( mStateBlock->getDesc() );
      desc.setFillModeWireframe();
      GFX->setStateBlockByDesc( desc );
   }
   else
      GFX->setStateBlock( mStateBlock );

   if ( mUseNightCubemap && mNightCubemap )
   {
      mShaderConsts->setSafe( mUseCubemapSC, 1.0f );

      if ( !mNightCubemap->mCubemap )
         mNightCubemap->createMap();

      GFX->setCubeTexture( 0, mNightCubemap->mCubemap );
   }
   else
   {
      GFX->setCubeTexture( 0, NULL );
      mShaderConsts->setSafe( mUseCubemapSC, 0.0f );
   }

	GFX->setPrimitiveBuffer( mPrimBuffer );
   GFX->setVertexBuffer( mVB );

   GFX->drawIndexedPrimitive( GFXTriangleList, 0, 0, mVertCount, 0, mPrimCount );
}
Beispiel #18
0
void PlaneReflector::updateReflection( const ReflectParams &params )
{
   PROFILE_SCOPE(PlaneReflector_updateReflection);   
   GFXDEBUGEVENT_SCOPE( PlaneReflector_updateReflection, ColorI::WHITE );

   mIsRendering = true;

   S32 texDim = mDesc->texSize;
   texDim = getMax( texDim, 32 );

   // Protect against the reflection texture being bigger
   // than the current game back buffer.
   texDim = getMin( texDim, params.viewportExtent.x );
   texDim = getMin( texDim, params.viewportExtent.y );

   bool texResize = ( texDim != mLastTexSize );  
   mLastTexSize = texDim;

   const Point2I texSize( texDim, texDim );

   if (  texResize || 
         reflectTex.isNull() ||
         reflectTex->getFormat() != REFLECTMGR->getReflectFormat() )
      reflectTex = REFLECTMGR->allocRenderTarget( texSize );

   GFXTexHandle depthBuff = LightShadowMap::_getDepthTarget( texSize.x, texSize.y );

   // store current matrices
   GFXTransformSaver saver;
   
   Point2I viewport(params.viewportExtent);
   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      viewport.x *= 0.5f;
   }
   F32 aspectRatio = F32( viewport.x ) / F32( viewport.y );

   Frustum frustum;
   frustum.set(false, params.query->fov, aspectRatio, params.query->nearPlane, params.query->farPlane);

   // Manipulate the frustum for tiled screenshots
   const bool screenShotMode = gScreenShot && gScreenShot->isPending();
   if ( screenShotMode )
      gScreenShot->tileFrustum( frustum );

   GFX->setFrustum( frustum );
      
   // Store the last view info for scoring.
   mLastDir = params.query->cameraMatrix.getForwardVector();
   mLastPos = params.query->cameraMatrix.getPosition();

   setGFXMatrices( params.query->cameraMatrix );

   // Adjust the detail amount
   F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust;
   TSShapeInstance::smDetailAdjust *= mDesc->detailAdjust;


   if(reflectTarget.isNull())
      reflectTarget = GFX->allocRenderToTextureTarget();
   reflectTarget->attachTexture( GFXTextureTarget::Color0, reflectTex );
   reflectTarget->attachTexture( GFXTextureTarget::DepthStencil, depthBuff );
   GFX->pushActiveRenderTarget();
   GFX->setActiveRenderTarget( reflectTarget );   

   U32 objTypeFlag = -1;
   SceneCameraState reflectCameraState = SceneCameraState::fromGFX();
   LIGHTMGR->registerGlobalLights( &reflectCameraState.getFrustum(), false );

   // Since we can sometime be rendering a reflection for 1 or 2 frames before
   // it gets updated do to the lag associated with getting the results from
   // a HOQ we can sometimes see into parts of the reflection texture that
   // have nothing but clear color ( eg. under the water ).
   // To make this look less crappy use the ambient color of the sun.
   //
   // In the future we may want to fix this instead by having the scatterSky
   // render a skirt or something in its lower half.
   //
   ColorF clearColor = gClientSceneGraph->getAmbientLightColor();
   GFX->clear( GFXClearZBuffer | GFXClearStencil | GFXClearTarget, clearColor, 1.0f, 0 );

   if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
   {
      // Store previous values
      RectI originalVP = GFX->getViewport();

      Point2F projOffset = GFX->getCurrentProjectionOffset();
      Point3F eyeOffset = GFX->getStereoEyeOffset();

      // Render left half of display
      RectI leftVP = originalVP;
      leftVP.extent.x *= 0.5;
      GFX->setViewport(leftVP);

      MatrixF leftWorldTrans(true);
      leftWorldTrans.setPosition(Point3F(eyeOffset.x, eyeOffset.y, eyeOffset.z));
      MatrixF leftWorld(params.query->cameraMatrix);
      leftWorld.mulL(leftWorldTrans);

      Frustum gfxFrustum = GFX->getFrustum();
      gfxFrustum.setProjectionOffset(Point2F(projOffset.x, projOffset.y));
      GFX->setFrustum(gfxFrustum);

      setGFXMatrices( leftWorld );

      SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
      SceneRenderState renderStateLeft( gClientSceneGraph, SPT_Reflect, cameraStateLeft );
      renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
      renderStateLeft.setSceneRenderField(0);
      renderStateLeft.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      renderStateLeft.setDiffuseCameraTransform( params.query->cameraMatrix );
      renderStateLeft.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &renderStateLeft, objTypeFlag );

      // Render right half of display
      RectI rightVP = originalVP;
      rightVP.extent.x *= 0.5;
      rightVP.point.x += rightVP.extent.x;
      GFX->setViewport(rightVP);

      MatrixF rightWorldTrans(true);
      rightWorldTrans.setPosition(Point3F(-eyeOffset.x, eyeOffset.y, eyeOffset.z));
      MatrixF rightWorld(params.query->cameraMatrix);
      rightWorld.mulL(rightWorldTrans);

      gfxFrustum = GFX->getFrustum();
      gfxFrustum.setProjectionOffset(Point2F(-projOffset.x, projOffset.y));
      GFX->setFrustum(gfxFrustum);

      setGFXMatrices( rightWorld );

      SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
      SceneRenderState renderStateRight( gClientSceneGraph, SPT_Reflect, cameraStateRight );
      renderStateRight.setSceneRenderStyle(SRS_SideBySide);
      renderStateRight.setSceneRenderField(1);
      renderStateRight.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      renderStateRight.setDiffuseCameraTransform( params.query->cameraMatrix );
      renderStateRight.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &renderStateRight, objTypeFlag );

      // Restore previous values
      gfxFrustum.clearProjectionOffset();
      GFX->setFrustum(gfxFrustum);
      GFX->setViewport(originalVP);
   }
   else
   {
      SceneRenderState reflectRenderState
      (
         gClientSceneGraph,
         SPT_Reflect,
         SceneCameraState::fromGFX()
      );

      reflectRenderState.getMaterialDelegate().bind( REFLECTMGR, &ReflectionManager::getReflectionMaterial );
      reflectRenderState.setDiffuseCameraTransform( params.query->cameraMatrix );
      reflectRenderState.disableAdvancedLightingBins(true);

      gClientSceneGraph->renderSceneNoLights( &reflectRenderState, objTypeFlag );
   }

   LIGHTMGR->unregisterAllLights();

   // Clean up.
   reflectTarget->resolve();
   GFX->popActiveRenderTarget();

   // Restore detail adjust amount.
   TSShapeInstance::smDetailAdjust = detailAdjustBackup;

   mIsRendering = false;
}
Beispiel #19
0
bool DecalManager::clipDecal( DecalInstance *decal, Vector<Point3F> *edgeVerts, const Point2F *clipDepth )
{
   PROFILE_SCOPE( DecalManager_clipDecal );

   // Free old verts and indices.
   _freeBuffers( decal );

   ClippedPolyList clipper;

   clipper.mNormal.set( Point3F( 0, 0, 0 ) );
   clipper.mPlaneList.setSize(6);

   F32 halfSize = decal->mSize * 0.5f;
   
   // Ugly hack for ProjectedShadow!
   F32 halfSizeZ = clipDepth ? clipDepth->x : halfSize;
   F32 negHalfSize = clipDepth ? clipDepth->y : halfSize;
   Point3F decalHalfSize( halfSize, halfSize, halfSize );
   Point3F decalHalfSizeZ( halfSizeZ, halfSizeZ, halfSizeZ );

   MatrixF projMat( true );
   decal->getWorldMatrix( &projMat );

   const VectorF &crossVec = decal->mNormal;
   const Point3F &decalPos = decal->mPosition;

   VectorF newFwd, newRight;
   projMat.getColumn( 0, &newRight );
   projMat.getColumn( 1, &newFwd );   

   VectorF objRight( 1.0f, 0, 0 );
   VectorF objFwd( 0, 1.0f, 0 );
   VectorF objUp( 0, 0, 1.0f );

   // See above re: decalHalfSizeZ hack.
   clipper.mPlaneList[0].set( ( decalPos + ( -newRight * halfSize ) ), -newRight );
   clipper.mPlaneList[1].set( ( decalPos + ( -newFwd * halfSize ) ), -newFwd );
   clipper.mPlaneList[2].set( ( decalPos + ( -crossVec * decalHalfSizeZ ) ), -crossVec );
   clipper.mPlaneList[3].set( ( decalPos + ( newRight * halfSize ) ), newRight );
   clipper.mPlaneList[4].set( ( decalPos + ( newFwd * halfSize ) ), newFwd );
   clipper.mPlaneList[5].set( ( decalPos + ( crossVec * negHalfSize ) ), crossVec );

   clipper.mNormal = -decal->mNormal;

   Box3F box( -decalHalfSizeZ, decalHalfSizeZ );

   projMat.mul( box );

   DecalData *decalData = decal->mDataBlock;

   PROFILE_START( DecalManager_clipDecal_buildPolyList );
   getContainer()->buildPolyList( box, decalData->clippingMasks, &clipper );   
   PROFILE_END();

   clipper.cullUnusedVerts();
   clipper.triangulate();
   clipper.generateNormals();
   
   if ( clipper.mVertexList.empty() )
      return false;

#ifdef DECALMANAGER_DEBUG
   mDebugPlanes.clear();
   mDebugPlanes.merge( clipper.mPlaneList );
#endif

   decal->mVertCount = clipper.mVertexList.size();
   decal->mIndxCount = clipper.mIndexList.size();
   
   Vector<Point3F> tmpPoints;

   tmpPoints.push_back(( objFwd * decalHalfSize ) + ( objRight * decalHalfSize ));
   tmpPoints.push_back(( objFwd * decalHalfSize ) + ( -objRight * decalHalfSize ));
   tmpPoints.push_back(( -objFwd * decalHalfSize ) + ( -objRight * decalHalfSize ));
   
   Point3F lowerLeft(( -objFwd * decalHalfSize ) + ( objRight * decalHalfSize ));

   projMat.inverse();

   _generateWindingOrder( lowerLeft, &tmpPoints );

   BiQuadToSqr quadToSquare( Point2F( lowerLeft.x, lowerLeft.y ),
                             Point2F( tmpPoints[0].x, tmpPoints[0].y ), 
                             Point2F( tmpPoints[1].x, tmpPoints[1].y ), 
                             Point2F( tmpPoints[2].x, tmpPoints[2].y ) );  

   Point2F uv( 0, 0 );
   Point3F vecX(0.0f, 0.0f, 0.0f);

   // Allocate memory for vert and index arrays
   _allocBuffers( decal );  
   
   Point3F vertPoint( 0, 0, 0 );

   for ( U32 i = 0; i < clipper.mVertexList.size(); i++ )
   {
      const ClippedPolyList::Vertex &vert = clipper.mVertexList[i];
      vertPoint = vert.point;

      // Transform this point to
      // object space to look up the
      // UV coordinate for this vertex.
      projMat.mulP( vertPoint );

      // Clamp the point to be within the quad.
      vertPoint.x = mClampF( vertPoint.x, -decalHalfSize.x, decalHalfSize.x );
      vertPoint.y = mClampF( vertPoint.y, -decalHalfSize.y, decalHalfSize.y );

      // Get our UV.
      uv = quadToSquare.transform( Point2F( vertPoint.x, vertPoint.y ) );

      const RectF &rect = decal->mDataBlock->texRect[decal->mTextureRectIdx];

      uv *= rect.extent;
      uv += rect.point;      

      // Set the world space vertex position.
      decal->mVerts[i].point = vert.point;
      
      decal->mVerts[i].texCoord.set( uv.x, uv.y );
      
      decal->mVerts[i].normal = clipper.mNormalList[i];
      
      decal->mVerts[i].normal.normalize();

      if( mFabs( decal->mVerts[i].normal.z ) > 0.8f ) 
         mCross( decal->mVerts[i].normal, Point3F( 1.0f, 0.0f, 0.0f ), &vecX );
      else if ( mFabs( decal->mVerts[i].normal.x ) > 0.8f )
         mCross( decal->mVerts[i].normal, Point3F( 0.0f, 1.0f, 0.0f ), &vecX );
      else if ( mFabs( decal->mVerts[i].normal.y ) > 0.8f )
         mCross( decal->mVerts[i].normal, Point3F( 0.0f, 0.0f, 1.0f ), &vecX );
   
      decal->mVerts[i].tangent = mCross( decal->mVerts[i].normal, vecX );
   }

   U32 curIdx = 0;
   for ( U32 j = 0; j < clipper.mPolyList.size(); j++ )
   {
      // Write indices for each Poly
      ClippedPolyList::Poly *poly = &clipper.mPolyList[j];                  

      AssertFatal( poly->vertexCount == 3, "Got non-triangle poly!" );

      decal->mIndices[curIdx] = clipper.mIndexList[poly->vertexStart];         
      curIdx++;
      decal->mIndices[curIdx] = clipper.mIndexList[poly->vertexStart + 1];            
      curIdx++;
      decal->mIndices[curIdx] = clipper.mIndexList[poly->vertexStart + 2];                
      curIdx++;
   } 

   if ( !edgeVerts )
      return true;

   Point3F tmpHullPt( 0, 0, 0 );
   Vector<Point3F> tmpHullPts;

   for ( U32 i = 0; i < clipper.mVertexList.size(); i++ )
   {
      const ClippedPolyList::Vertex &vert = clipper.mVertexList[i];
      tmpHullPt = vert.point;
      projMat.mulP( tmpHullPt );
      tmpHullPts.push_back( tmpHullPt );
   }

   edgeVerts->clear();
   U32 verts = _generateConvexHull( tmpHullPts, edgeVerts );
   edgeVerts->setSize( verts );

   projMat.inverse();
   for ( U32 i = 0; i < edgeVerts->size(); i++ )
      projMat.mulP( (*edgeVerts)[i] );

   return true;
}
Beispiel #20
0
 Point2F Square::RB() const {
     return Point2F(center.GetX() + maxDistance, center.GetY() + maxDistance);
 }
void PSSMLightShadowMap::_calcPlanesCullForShadowCasters(Vector< Vector<PlaneF> > &out, const Frustum &viewFrustum, const Point3F &_ligthDir)
{

#define ENABLE_CULL_ASSERT

   PROFILE_SCOPE(PSSMLightShadowMap_render_getCullFrustrum);

   Point3F ligthDir = _ligthDir;
   PlaneF lightFarPlane, lightNearPlane;
   MatrixF lightFarPlaneMat(true);
   MatrixF invLightFarPlaneMat(true);

   // init data
   {
      ligthDir.normalize();
      Point3F viewDir = viewFrustum.getTransform().getForwardVector();
      viewDir.normalize();
      const Point3F viewPosition = viewFrustum.getPosition();
      const F32 viewDistance = viewFrustum.getBounds().len();
      lightNearPlane = PlaneF(viewPosition + (viewDistance * -ligthDir), ligthDir);

      const Point3F lightFarPlanePos = viewPosition + (viewDistance * ligthDir);
      lightFarPlane = PlaneF(lightFarPlanePos, -ligthDir);

      lightFarPlaneMat = MathUtils::createOrientFromDir(-ligthDir);
      lightFarPlaneMat.setPosition(lightFarPlanePos);
      lightFarPlaneMat.invertTo(&invLightFarPlaneMat);
   }

   Vector<Point2F> projVertices;

   //project all frustum vertices into plane
   // all vertices are 2d and local to far plane
   projVertices.setSize(8);
   for (int i = 0; i < 8; ++i) //
   {
      const Point3F &point = viewFrustum.getPoints()[i];
#ifdef ENABLE_CULL_ASSERT
      AssertFatal( PlaneF::Front == lightNearPlane.whichSide(point), "" );
      AssertFatal( PlaneF::Front == lightFarPlane.whichSide(point), "" );
#endif

      Point3F localPoint(lightFarPlane.project(point));
      invLightFarPlaneMat.mulP(localPoint);
      projVertices[i] = Point2F(localPoint.x, localPoint.z);
   }

   //create hull arround projected proints
   Vector<Point2F> hullVerts;
   MathUtils::mBuildHull2D(projVertices, hullVerts);

   Vector<PlaneF> planes;
   planes.push_back(lightNearPlane);
   planes.push_back(lightFarPlane);

   //build planes
   for (int i = 0; i < (hullVerts.size() - 1); ++i)
   {
      Point2F pos2D = (hullVerts[i] + hullVerts[i + 1]) / 2;
      Point3F pos3D(pos2D.x, 0, pos2D.y);

      Point3F pos3DA(hullVerts[i].x, 0, hullVerts[i].y);
      Point3F pos3DB(hullVerts[i + 1].x, 0, hullVerts[i + 1].y);

      // move hull points to 3d space
      lightFarPlaneMat.mulP(pos3D);
      lightFarPlaneMat.mulP(pos3DA);
      lightFarPlaneMat.mulP(pos3DB);

      PlaneF plane(pos3D, MathUtils::mTriangleNormal(pos3DB, pos3DA, (pos3DA - ligthDir)));
      planes.push_back(plane);
   }

   //recalculate planes for each splits
   for (int split = 0; split < mNumSplits; ++split)
   {
      Frustum subFrustum(viewFrustum);
      subFrustum.cropNearFar(mSplitDist[split], mSplitDist[split + 1]);
      subFrustum.setFarDist(getMin(subFrustum.getFarDist()*2.5f, viewFrustum.getFarDist()));
      subFrustum.update();

      Vector<PlaneF> subPlanes = planes;

      for (int planeIdx = 0; planeIdx < subPlanes.size(); ++planeIdx)
      {
         PlaneF &plane = subPlanes[planeIdx];
         F32 minDist = 0;

         //calculate near vertex distance
         for (int vertexIdx = 0; vertexIdx < 8; ++vertexIdx)
         {
            Point3F point = subFrustum.getPoints()[vertexIdx];
            minDist = getMin(plane.distToPlane(point), minDist);
         }

         // move plane to near vertex
         Point3F newPos = plane.getPosition() + (plane.getNormal() * minDist);
         plane = PlaneF(newPos, plane.getNormal());

#ifdef ENABLE_CULL_ASSERT
         for(int x = 0; x < 8; ++x)
         {
            AssertFatal( PlaneF::Back != plane.whichSide( subFrustum.getPoints()[x] ), "");
         }
#endif
      }

      out.push_back(subPlanes);
   }

#undef ENABLE_CULL_ASSERT

}
Beispiel #22
0
bool TerrainBlock::castRayI(const Point3F &start, const Point3F &end, RayInfo *info, bool collideEmpty)
{
   lineCount = 0;
   lineStart = start;
   lineEnd = end;

   info->object = this;

   if(start.x == end.x && start.y == end.y)
   {
      if (end.z == start.z)
         return false;

      F32 height;
      if(!getNormalAndHeight(Point2F(start.x, start.y), &info->normal, &height, true))
         return false;
      F32 t = (height - start.z) / (end.z - start.z);
      if(t < 0 || t > 1)
         return false;
      info->t = t;
      return true;
   }

   F32 invBlockWorldSize = 1 / F32(mSquareSize * BlockSquareWidth);

   Point3F pStart(start.x * invBlockWorldSize, start.y * invBlockWorldSize, start.z);
   Point3F pEnd(end.x * invBlockWorldSize, end.y * invBlockWorldSize, end.z);

   int blockX = (S32)mFloor(pStart.x);
   int blockY = (S32)mFloor(pStart.y);

   int dx, dy;

   F32 invDeltaX;
   if(pEnd.x == pStart.x)
   {
      calcInterceptX = calcInterceptNone;
      invDeltaX = 0;
      dx = 0;
   }
   else
   {
      invDeltaX = 1 / (pEnd.x - pStart.x);
      calcInterceptX = calcInterceptV;
      if(pEnd.x < pStart.x)
         dx = -1;
      else
         dx = 1;
   }

   F32 invDeltaY;
   if(pEnd.y == pStart.y)
   {
      calcInterceptY = calcInterceptNone;
      invDeltaY = 0;
      dy = 0;
   }
   else
   {
      invDeltaY = 1 / (pEnd.y - pStart.y);
      calcInterceptY = calcInterceptV;
      if(pEnd.y < pStart.y)
         dy = -1;
      else
         dy = 1;
   }
   F32 startT = 0;
   for(;;)
   {
      F32 nextXInt = calcInterceptX(pStart.x, invDeltaX, (F32)(blockX + (dx == 1)));
      F32 nextYInt = calcInterceptY(pStart.y, invDeltaY, (F32)(blockY + (dy == 1)));

      F32 intersectT = 1;

      if(nextXInt < intersectT)
         intersectT = nextXInt;
      if(nextYInt < intersectT)
         intersectT = nextYInt;

      if(castRayBlock(pStart, pEnd, Point2I(blockX * BlockSquareWidth, blockY * BlockSquareWidth), BlockShift, invDeltaX, invDeltaY, startT, intersectT, info, collideEmpty)) {
         info->normal.z *= BlockSquareWidth * mSquareSize;
         info->normal.normalize();
         return true;
      }

      startT = intersectT;
      if(intersectT >= 1)
         break;
      if(nextXInt < nextYInt)
         blockX += dx;
      else if(nextYInt < nextXInt)
         blockY += dy;
      else
      {
         blockX += dx;
         blockY += dy;
      }
   }
   return false;
}
Beispiel #23
0
void Sun::_renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat )
{   
   // Calculate Billboard Radius (in world units) to be constant, independent of distance.
   // Takes into account distance, viewport size, and specified size in editor
   F32 BBRadius = mCoronaWorldRadius;

   mMatrixSet->restoreSceneViewProjection();   
   
   if ( state->isReflectPass() )
      mMatrixSet->setProjection( state->getSceneManager()->getNonClipProjection() );

   //mMatrixSet->setWorld( MatrixF::Identity );

   // Initialize points with basic info
   Point3F points[4];
   points[0] = Point3F(-BBRadius, 0.0, -BBRadius);
   points[1] = Point3F( -BBRadius, 0.0, BBRadius);
   points[2] = Point3F( BBRadius, 0.0,  BBRadius);
   points[3] = Point3F( BBRadius, 0.0,  -BBRadius);

   static const Point2F sCoords[4] = 
   {
      Point2F( 0.0f, 0.0f ),
      Point2F( 0.0f, 1.0f ),      
      Point2F( 1.0f, 1.0f ),
      Point2F( 1.0f, 0.0f )
   };

   // Get info we need to adjust points
   const MatrixF &camView = state->getCameraTransform();

   // Finalize points
   for(S32 i = 0; i < 4; i++)
   {
      // align with camera
      camView.mulV(points[i]);
      // offset
      points[i] += mLightWorldPos;
   }

   ColorF vertColor;
   if ( mCoronaUseLightColor )
      vertColor = mLightColor;
   else
      vertColor = mCoronaTint;

   GFXVertexBufferHandle< GFXVertexPCT > vb;
   vb.set( GFX, 4, GFXBufferTypeVolatile );
   GFXVertexPCT *pVert = vb.lock();
   if(!pVert) return;

   for ( S32 i = 0; i < 4; i++ )
   {
      pVert->color.set( vertColor );
      pVert->point.set( points[i] );
      pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
      pVert++;
   }

   vb.unlock();

   // Setup SceneData struct.

   SceneData sgData;
   sgData.wireframe = GFXDevice::getWireframe();
   sgData.visibility = 1.0f;

   // Draw it

   while ( mCoronaMatInst->setupPass( state, sgData ) )
   {
      mCoronaMatInst->setTransforms( *mMatrixSet, state );
      mCoronaMatInst->setSceneInfo( state, sgData );

      GFX->setVertexBuffer( vb );      
      GFX->drawPrimitive( GFXTriangleFan, 0, 2 );
   }
}
Beispiel #24
0
void GFXDrawUtil::drawRectFill( const Point2I &upperLeft, const Point2I &lowerRight, const ColorI &color ) 
{   
   drawRectFill(Point2F((F32)upperLeft.x, (F32)upperLeft.y), Point2F((F32)lowerRight.x, (F32)lowerRight.y), color);
}
Beispiel #25
0
void ScatterSky::_renderMoon( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat )
{
   if ( !mMoonMatInst )
      return;

   Point3F moonlightPosition = state->getCameraPosition() - /*mLight->getDirection()*/ mMoonLightDir * state->getFarPlane() * 0.9f;
   F32 dist = (moonlightPosition - state->getCameraPosition()).len();

   // worldRadius = screenRadius * dist / worldToScreen
   // screenRadius = worldRadius / dist * worldToScreen

   //
   F32 screenRadius = GFX->getViewport().extent.y * mMoonScale * 0.5f;
   F32 worldRadius = screenRadius * dist / state->getWorldToScreenScale().y;

   // Calculate Billboard Radius (in world units) to be constant, independent of distance.
   // Takes into account distance, viewport size, and specified size in editor

   F32 BBRadius = worldRadius;


   mMatrixSet->restoreSceneViewProjection();

   if ( state->isReflectPass() )
      mMatrixSet->setProjection( state->getSceneManager()->getNonClipProjection() );

   mMatrixSet->setWorld( MatrixF::Identity );

   // Initialize points with basic info
   Point3F points[4];
   points[0] = Point3F(-BBRadius, 0.0, -BBRadius);
   points[1] = Point3F( -BBRadius, 0.0, BBRadius);
   points[2] = Point3F( BBRadius, 0.0,  BBRadius);
   points[3] = Point3F( BBRadius, 0.0,  -BBRadius);

   static const Point2F sCoords[4] =
   {
      Point2F( 0.0f, 0.0f ),
      Point2F( 0.0f, 1.0f ),
      Point2F( 1.0f, 1.0f ),
      Point2F( 1.0f, 0.0f )
   };

   // Get info we need to adjust points
   const MatrixF &camView = state->getCameraTransform();

   // Finalize points
   for(int i = 0; i < 4; i++)
   {
      // align with camera
      camView.mulV(points[i]);
      // offset
      points[i] += moonlightPosition;
   }

   // Vertex color.
   ColorF moonVertColor( 1.0f, 1.0f, 1.0f, mNightInterpolant );

   // Copy points to buffer.

   GFXVertexBufferHandle< GFXVertexPCT > vb;
   vb.set( GFX, 4, GFXBufferTypeVolatile );
   GFXVertexPCT *pVert = vb.lock();

   for ( S32 i = 0; i < 4; i++ )
   {
      pVert->color.set( moonVertColor );
      pVert->point.set( points[i] );
      pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
      pVert++;
   }

   vb.unlock();

   // Setup SceneData struct.

   SceneData sgData;
   sgData.wireframe = GFXDevice::getWireframe();
   sgData.visibility = 1.0f;

   // Draw it

   while ( mMoonMatInst->setupPass( state, sgData ) )
   {
      mMoonMatInst->setTransforms( *mMatrixSet, state );
      mMoonMatInst->setSceneInfo( state, sgData );

      GFX->setVertexBuffer( vb );
      GFX->drawPrimitive( GFXTriangleFan, 0, 2 );
   }
}
Beispiel #26
0
void DecalRoad::_captureVerts()
{  
   PROFILE_SCOPE( DecalRoad_captureVerts );

   //Con::warnf( "%s - captureVerts", isServerObject() ? "server" : "client" );

   if ( isServerObject() )
   {
      //Con::errorf( "DecalRoad::_captureVerts - called on the server side!" );
      return;
   }

   if ( mEdges.size() == 0 )
      return;

   //
   // Construct ClippedPolyList objects for each pair
   // of roadEdges.
   // Use them to capture Terrain verts.
   //
   SphereF sphere;
   RoadEdge *edge = NULL;
   RoadEdge *nextEdge = NULL;

   mTriangleCount = 0;
   mVertCount = 0;

   Vector<ClippedPolyList> clipperList;

   for ( U32 i = 0; i < mEdges.size() - 1; i++ )
   {      
      Box3F box;
      edge = &mEdges[i];
      nextEdge = &mEdges[i+1];

      box.minExtents = edge->p1;
      box.maxExtents = edge->p1;
      box.extend( edge->p0 );
      box.extend( edge->p2 );
      box.extend( nextEdge->p0 );
      box.extend( nextEdge->p1 );
      box.extend( nextEdge->p2 );
      box.minExtents.z -= 5.0f;
      box.maxExtents.z += 5.0f;

      sphere.center = ( nextEdge->p1 + edge->p1 ) * 0.5f;
      sphere.radius = 100.0f; // NOTE: no idea how to calculate this

      ClippedPolyList clipper;
      clipper.mNormal.set(0.0f, 0.0f, 0.0f);
      VectorF n;
      PlaneF plane0, plane1;

      // Construct Back Plane
      n = edge->p2 - edge->p0;
      n.normalize();
      n = mCross( n, edge->uvec );      
      plane0.set( edge->p0, n );   
      clipper.mPlaneList.push_back( plane0 );

      // Construct Front Plane
      n = nextEdge->p2 - nextEdge->p0;
      n.normalize();
      n = -mCross( edge->uvec, n );
      plane1.set( nextEdge->p0, -n );
      //clipper.mPlaneList.push_back( plane1 );

      // Test if / where the planes intersect.
      bool discardLeft = false;
      bool discardRight = false;
      Point3F iPos; 
      VectorF iDir;

      if ( plane0.intersect( plane1, iPos, iDir ) )
      {                  
         Point2F iPos2F( iPos.x, iPos.y );
         Point2F cPos2F( edge->p1.x, edge->p1.y );
         Point2F rVec2F( edge->rvec.x, edge->rvec.y );

         Point2F iVec2F = iPos2F - cPos2F;
         F32 iLen = iVec2F.len();
         iVec2F.normalize();

         if ( iLen < edge->width * 0.5f )
         {
            F32 dot = mDot( rVec2F, iVec2F );

            // The clipping planes intersected on the right side,
            // discard the right side clipping plane.
            if ( dot > 0.0f )
               discardRight = true;         
            // The clipping planes intersected on the left side,
            // discard the left side clipping plane.
            else
               discardLeft = true;
         }
      }

      // Left Plane
      if ( !discardLeft )
      {
         n = ( nextEdge->p0 - edge->p0 );
         n.normalize();
         n = mCross( edge->uvec, n );
         clipper.mPlaneList.push_back( PlaneF(edge->p0, n) );
      }
      else
      {
         nextEdge->p0 = edge->p0;         
      }

      // Right Plane
      if ( !discardRight )
      {
         n = ( nextEdge->p2 - edge->p2 );
         n.normalize();            
         n = -mCross( n, edge->uvec );
         clipper.mPlaneList.push_back( PlaneF(edge->p2, -n) );
      }
      else
      {
         nextEdge->p2 = edge->p2;         
      }

      n = nextEdge->p2 - nextEdge->p0;
      n.normalize();
      n = -mCross( edge->uvec, n );
      plane1.set( nextEdge->p0, -n );
      clipper.mPlaneList.push_back( plane1 );

      // We have constructed the clipping planes,
      // now grab/clip the terrain geometry
      getContainer()->buildPolyList( PLC_Decal, box, TerrainObjectType, &clipper );         
      clipper.cullUnusedVerts();
      clipper.triangulate();
      clipper.generateNormals();

      // If we got something, add it to the ClippedPolyList Vector
      if ( !clipper.isEmpty() && !( smDiscardAll && ( discardRight || discardLeft ) ) )
      {
         clipperList.push_back( clipper );       
      
         mVertCount += clipper.mVertexList.size();
         mTriangleCount += clipper.mPolyList.size();
      }
   }

   //
   // Set the roadEdge height to be flush with terrain
   // This is not really necessary but makes the debug spline rendering better.
   //
   for ( U32 i = 0; i < mEdges.size() - 1; i++ )
   {            
      edge = &mEdges[i];      
      
      _getTerrainHeight( edge->p0.x, edge->p0.y, edge->p0.z );

      _getTerrainHeight( edge->p2.x, edge->p2.y, edge->p2.z );
   }

   //
   // Allocate the RoadBatch(s)   
   //

   // If we captured no verts, then we can return here without
   // allocating any RoadBatches or the Vert/Index Buffers.
   // PreprenderImage will not allocate a render instance while
   // mBatches.size() is zero.
   U32 numClippers = clipperList.size();
   if ( numClippers == 0 )
      return;

   mBatches.clear();

   // Allocate the VertexBuffer and PrimitiveBuffer
   mVB.set( GFX, mVertCount, GFXBufferTypeStatic );
   mPB.set( GFX, mTriangleCount * 3, 0, GFXBufferTypeStatic );

   // Lock the VertexBuffer
   GFXVertexPNTBT *vertPtr = mVB.lock();
   if(!vertPtr) return;
   U32 vertIdx = 0;

   //
   // Fill the VertexBuffer and vertex data for the RoadBatches
   // Loop through the ClippedPolyList Vector   
   //
   RoadBatch *batch = NULL;
   F32 texStart = 0.0f;
   F32 texEnd;
   
   for ( U32 i = 0; i < clipperList.size(); i++ )
   {   
      ClippedPolyList *clipper = &clipperList[i];
      RoadEdge &edge = mEdges[i];
      RoadEdge &nextEdge = mEdges[i+1];      

      VectorF segFvec = nextEdge.p1 - edge.p1;
      F32 segLen = segFvec.len();
      segFvec.normalize();

      F32 texLen = segLen / mTextureLength;
      texEnd = texStart + texLen;

      BiQuadToSqr quadToSquare(  Point2F( edge.p0.x, edge.p0.y ), 
                                 Point2F( edge.p2.x, edge.p2.y ), 
                                 Point2F( nextEdge.p2.x, nextEdge.p2.y ), 
                                 Point2F( nextEdge.p0.x, nextEdge.p0.y ) );  

      //
      if ( i % mSegmentsPerBatch == 0 )
      {
         mBatches.increment();
         batch = &mBatches.last();

         batch->bounds.minExtents = clipper->mVertexList[0].point;
         batch->bounds.maxExtents = clipper->mVertexList[0].point;
         batch->startVert = vertIdx;
      }

      // Loop through each ClippedPolyList        
      for ( U32 j = 0; j < clipper->mVertexList.size(); j++ )
      {
         // Add each vert to the VertexBuffer
         Point3F pos = clipper->mVertexList[j].point;
         vertPtr[vertIdx].point = pos;
         vertPtr[vertIdx].normal = clipper->mNormalList[j];                     
                  
         Point2F uv = quadToSquare.transform( Point2F(pos.x,pos.y) );
         vertPtr[vertIdx].texCoord.x = uv.x;
         vertPtr[vertIdx].texCoord.y = -(( texEnd - texStart ) * uv.y + texStart);   

         vertPtr[vertIdx].tangent = mCross( segFvec, clipper->mNormalList[j] );
         vertPtr[vertIdx].binormal = segFvec;

         vertIdx++;

         // Expand the RoadBatch bounds to contain this vertex   
         batch->bounds.extend( pos );
      }    

      batch->endVert = vertIdx - 1;

      texStart = texEnd;
   }   

   // Unlock the VertexBuffer, we are done filling it.
   mVB.unlock();

   // Lock the PrimitiveBuffer
   U16 *idxBuff;
   mPB.lock(&idxBuff);     
   U32 curIdx = 0;
   U16 vertOffset = 0;   
   batch = NULL;
   S32 batchIdx = -1;

   // Fill the PrimitiveBuffer   
   // Loop through each ClippedPolyList in the Vector
   for ( U32 i = 0; i < clipperList.size(); i++ )
   {      
      ClippedPolyList *clipper = &clipperList[i];

      if ( i % mSegmentsPerBatch == 0 )
      {
         batchIdx++;
         batch = &mBatches[batchIdx];
         batch->startIndex = curIdx;         
      }        

      for ( U32 j = 0; j < clipper->mPolyList.size(); j++ )
      {
         // Write indices for each Poly
         ClippedPolyList::Poly *poly = &clipper->mPolyList[j];                  

         AssertFatal( poly->vertexCount == 3, "Got non-triangle poly!" );

         idxBuff[curIdx] = clipper->mIndexList[poly->vertexStart] + vertOffset;         
         curIdx++;
         idxBuff[curIdx] = clipper->mIndexList[poly->vertexStart + 1] + vertOffset;            
         curIdx++;
         idxBuff[curIdx] = clipper->mIndexList[poly->vertexStart + 2] + vertOffset;                
         curIdx++;
      } 

      batch->endIndex = curIdx - 1;

      vertOffset += clipper->mVertexList.size();
   }

   // Unlock the PrimitiveBuffer, we are done filling it.
   mPB.unlock();

   // Generate the object/world bounds
   // Is the union of all batch bounding boxes.

   Box3F box;
   for ( U32 i = 0; i < mBatches.size(); i++ )
   {
      const RoadBatch &batch = mBatches[i];

      if ( i == 0 )      
         box = batch.bounds;               
      else      
         box.intersect( batch.bounds );               
   }

   Point3F pos = getPosition();

   mWorldBox = box;
   resetObjectBox();

   // Make sure we are in the correct bins given our world box.
   if( getSceneManager() != NULL )
      getSceneManager()->notifyObjectDirty( this );
}
Beispiel #27
0
//-----------------------------------------------------------------------------
// Draw Bitmaps
//-----------------------------------------------------------------------------
void GFXDrawUtil::drawBitmap( GFXTextureObject* texture, const Point2I &in_rAt, const GFXBitmapFlip in_flip, const GFXTextureFilterType filter , bool in_wrap /*= true*/ )
{
   drawBitmap(texture,Point2F((F32)in_rAt.x,(F32)in_rAt.y),in_flip,filter,in_wrap);
}
Beispiel #28
0
void GFXDrawUtil::drawBitmapSR( GFXTextureObject* texture, const Point2I &in_rAt, const RectI &srcRect, const GFXBitmapFlip in_flip, const GFXTextureFilterType filter , bool in_wrap /*= true*/ )
{
   drawBitmapSR(texture,Point2F((F32)in_rAt.x,(F32)in_rAt.y),RectF((F32)srcRect.point.x,(F32)srcRect.point.y,(F32)srcRect.extent.x,(F32)srcRect.extent.y),in_flip,filter,in_wrap);
}
Beispiel #29
0
DecalInstance* DecalManager::raycast( const Point3F &start, const Point3F &end, bool savedDecalsOnly )
{
   if ( !mData )
      return NULL;

   const Vector<DecalSphere*> &grid = mData->getGrid();

   DecalInstance *inst = NULL;
   SphereF worldSphere( Point3F( 0, 0, 0 ), 1.0f );

   Vector<DecalInstance*> hitDecals;

   for ( U32 i = 0; i < grid.size(); i++ )
   {
      DecalSphere *decalSphere = grid[i];
      if ( !decalSphere->mWorldSphere.intersectsRay( start, end ) )
         continue;

      const Vector<DecalInstance*> &items = decalSphere->mItems;
      for ( U32 n = 0; n < items.size(); n++ )
      {
         inst = items[n];
         if ( !inst )
            continue;

         if ( savedDecalsOnly && !(inst->mFlags & SaveDecal) )
            continue;

         worldSphere.center = inst->mPosition;
         worldSphere.radius = inst->mSize;

         if ( !worldSphere.intersectsRay( start, end ) )
            continue;
			
			RayInfo ri;
			bool containsPoint = false;
			if ( gServerContainer.castRayRendered( start, end, STATIC_COLLISION_MASK, &ri ) )
			{        
				Point2F poly[4];
				poly[0].set( inst->mPosition.x - (inst->mSize / 2), inst->mPosition.y + (inst->mSize / 2));
				poly[1].set( inst->mPosition.x - (inst->mSize / 2), inst->mPosition.y - (inst->mSize / 2));
				poly[2].set( inst->mPosition.x + (inst->mSize / 2), inst->mPosition.y - (inst->mSize / 2));
				poly[3].set( inst->mPosition.x + (inst->mSize / 2), inst->mPosition.y + (inst->mSize / 2));
				
				if ( MathUtils::pointInPolygon( poly, 4, Point2F(ri.point.x, ri.point.y) ) )
					containsPoint = true;
			}

			if( !containsPoint )
				continue;

         hitDecals.push_back( inst );
      }
   }

   if ( hitDecals.empty() )
      return NULL;

   gSortPoint = start;
   dQsort( hitDecals.address(), hitDecals.size(), sizeof(DecalInstance*), cmpDecalDistance );
   return hitDecals[0];
}
Beispiel #30
0
void Scene::render() {
#ifdef GL_33
	//Light
	glUniform3fv(lightDirectionLocation, 1, &lightDirection.x);
	glUniform4fv(lightColorLocation, 1, &lightColor.red);
	glUniform4fv(ambientColorLocation, 1, &ambientColor.red);

	glUniform3fv(sunPositionLocation, 1, &sunPosition.x);
	glUniform1f(sunPowerLocation, sunPower);
	glUniform1f(specularExponentLocation, specularExponent);

	//Camera
	viewMatrix = glm::mat4x4(1);
	viewMatrix = glm::rotate(viewMatrix, pitch, glm::vec3(1, 0, 0));
	viewMatrix = glm::rotate(viewMatrix, yaw, glm::vec3(0, 1, 0));
	viewMatrix = glm::rotate(viewMatrix, -90.0f, glm::vec3(1, 0, 0));
	viewMatrix = glm::translate(viewMatrix, -cameraPosition);

	//Model
	modelMatrix = glm::mat4x4(1);

	//Combined
	glm::mat4x4 mvpMat = projectionMatrix * viewMatrix * modelMatrix;
	glm::mat3x3 mv3Mat = glm::mat3(viewMatrix * modelMatrix);

	//Send to OpenGL
	glUniformMatrix4fv(mvpMatrixLocation, 1, GL_FALSE, &mvpMat[0][0]);
	glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]);
	glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);
	glUniformMatrix3fv(modelView3Location, 1, GL_FALSE, &mv3Mat[0][0]);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

	glEnable(GL_CULL_FACE);
	glEnable(GL_ALPHA);
	glEnable(GL_MULTISAMPLE);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	for (U32 index = 0; index < difCount; index ++) {
		difs[index]->render();
	}

#ifdef BUILD_PHYSICS
	Point3F pos = sphere->getPosition();
	AngAxisF rot = sphere->getRotation();

	//Model
	modelMatrix = glm::mat4x4(1);
	modelMatrix = glm::translate(modelMatrix, glm::vec3(pos.x, pos.y, pos.z));
	modelMatrix = glm::rotate(modelMatrix, rot.angle * (F32)(180.0f / M_PI), glm::vec3(rot.axis.x, rot.axis.y, rot.axis.z));

	//Combined
	mvpMat = projectionMatrix * viewMatrix * modelMatrix;

	//Send to OpenGL
	glUniformMatrix4fv(mvpMatrixLocation, 1, GL_FALSE, &mvpMat[0][0]);
	glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]);
	glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);

	sphere->render(ColorF(1, 1, 0, 1));
#endif
#else
	//Load the model matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glEnable(GL_CULL_FACE);
	glEnable(GL_ALPHA);
	glEnable(GL_MULTISAMPLE);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	//Camera
	viewMatrix = glm::mat4x4(1);
	viewMatrix = glm::rotate(viewMatrix, pitch, glm::vec3(1, 0, 0));
	viewMatrix = glm::rotate(viewMatrix, yaw, glm::vec3(0, 1, 0));
	viewMatrix = glm::rotate(viewMatrix, -90.0f, glm::vec3(1, 0, 0));
	//	viewMatrix = glm::translate(viewMatrix, -cameraPosition);
	viewMatrix = glm::translate(viewMatrix, cameraPosition);

	glLoadMatrixf(&modelviewMatrix[0][0]);

	//Clear
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
	glLightfv(GL_LIGHT0, GL_POSITION, gLightDirection);

	Point3F offset = {0.f, 0.f, 0.f};

	if (listNeedsDisplay) {
		displayList = glGenLists(1);
		glNewList(displayList, GL_COMPILE_AND_EXECUTE);
		for (U32 index = 0; index < difCount; index ++) {
			difs[index]->render();
		}
		glEndList();
		listNeedsDisplay = false;
	} else {
		glCallList(displayList);
	}

	sphere->render(ColorF(1, 1, 0, 1));
	glDisable(GL_CULL_FACE);

	if (selection.hasSelection) {
		Surface surface = selection.interior->surface[selection.surfaceIndex];
		TexGenEq texGenEq = selection.interior->texGenEq[surface.texGenIndex];
		Point3F normal = selection.interior->normal[selection.interior->plane[surface.planeIndex].normalIndex];
		Point3F first = selection.interior->point[selection.interior->index[surface.windingStart]];
		F32 len = 0;

		glBegin(GL_TRIANGLE_STRIP);
		for (U32 i = 0; i < surface.windingCount; i ++) {
			Point3F vert = selection.interior->point[selection.interior->index[surface.windingStart + i]];

			glVertex3f(vert.x, vert.y, vert.z);

			Point2F point = point3F_project_plane(vert, normal, first);
			F32 distance = point.length();
			len = (distance > len ? distance : len);
		}
		glEnd();

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glOrtho(-1, 1, -1, 1, -100, 100);
		glMatrixMode(GL_MODELVIEW);
		glDisable(GL_LIGHTING);
		glEnable(GL_TEXTURE_2D);
		glLoadIdentity();

		Texture *texture = selection.interior->texture[surface.textureIndex];
		if (texture) {
			if (!texture->generated) {
				texture->generateBuffer();
			}
			texture->activate();
		}

		glBegin(GL_TRIANGLE_STRIP);

		int w, h;
		SDL_GetWindowSize(window, &w, &h);

		GLfloat aspect = (GLfloat)w / (GLfloat)h;

		for (U32 i = 0; i < surface.windingCount; i ++) {
			Point3F vert = selection.interior->point[selection.interior->index[surface.windingStart + i]];

			Point2F texuv = Point2F(planeF_distance_to_point(texGenEq.planeX, vert), planeF_distance_to_point(texGenEq.planeY, vert));
			glTexCoord2fv(&texuv.x);

			Point2F point = point3F_project_plane(vert, (surface.planeFlipped ? normal * -1 : normal), first);
			glVertex3f(point.x / len / aspect, point.y / len, 0);
		}
		glEnd();

		if (texture)
			texture->deactivate();
		glDisable(GL_TEXTURE_2D);
		glEnable(GL_LIGHTING);
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
	}
#endif
}