Shape * DrawTools::drawSolidArc(double startRadius, double endRadius, double startAngle, double endAngle, int steps) {
	int vertCount = steps * 6;

	BoundedArray<GLfloat> verts(2 * vertCount);

	double delta = endAngle - startAngle;
	double step = delta / steps;

	int offset = 0;

	double angle = startAngle;

	for (int i=0; i<steps; ++i) {
		float tlx = endRadius * sin(angle);
		float tly = endRadius * cos(angle);
		float trx = endRadius * sin(angle+step);
		float trY = endRadius * cos(angle+step);

		float blx = startRadius * sin(angle);
		float bly = startRadius * cos(angle);
		float brx = startRadius * sin(angle+step);
		float bry = startRadius * cos(angle+step);

		verts[offset++] = tlx;
		verts[offset++] = tly;

		verts[offset++] = blx;
		verts[offset++] = bly;

		verts[offset++] = brx;
		verts[offset++] = bry;

		verts[offset++] = brx;
		verts[offset++] = bry;

		verts[offset++] = tlx;
		verts[offset++] = tly;

		verts[offset++] = trx;
		verts[offset++] = trY;

		angle += step;
	}

	return new Shape(verts,vertCount);
}
void GFXDrawUtil::drawCylinder( const GFXStateBlockDesc &desc, const Point3F &basePnt, const Point3F &tipPnt, F32 radius, const ColorI &color )
{
   VectorF uvec = tipPnt - basePnt;
   F32 height = uvec.len();
   uvec.normalize();
   MatrixF mat( true );
   MathUtils::getMatrixFromUpVector( uvec, &mat );   
   mat.setPosition(basePnt);

   Point3F scale( radius, radius, height * 2 );
   mat.scale(scale);
   GFXTransformSaver saver;

   mDevice->pushWorldMatrix();
   mDevice->multWorld(mat);

   S32 numPoints = sizeof(circlePoints)/sizeof(Point2F);
   GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints * 4 + 4, GFXBufferTypeVolatile);
   verts.lock();
   for (S32 i=0; i<numPoints + 1; i++)
   {
      S32 imod = i % numPoints;
      verts[i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0.5f);
      verts[i].color = color;
      verts[i + numPoints + 1].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0);
      verts[i + numPoints + 1].color = color;

      verts[2*numPoints + 2 + 2 * i].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0.5f);
      verts[2*numPoints + 2 + 2 * i].color = color;
      verts[2*numPoints + 2 + 2 * i + 1].point = Point3F(circlePoints[imod].x,circlePoints[imod].y, 0);
      verts[2*numPoints + 2 + 2 * i + 1].color = color;
   }
   verts.unlock();

   mDevice->setStateBlockByDesc( desc );

   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders( GFXDevice::GSModColorTexture );

   mDevice->drawPrimitive( GFXTriangleFan, 0, numPoints );
   mDevice->drawPrimitive( GFXTriangleFan, numPoints + 1, numPoints );
   mDevice->drawPrimitive( GFXTriangleStrip, 2 * numPoints + 2, 2 * numPoints);

   mDevice->popWorldMatrix();
}
void GFXDrawUtil::drawLine( F32 x1, F32 y1, F32 z1, F32 x2, F32 y2, F32 z2, const ColorI &color )
{
   GFXVertexBufferHandle<GFXVertexPC> verts( mDevice, 2, GFXBufferTypeVolatile );
   verts.lock();

   verts[0].point.set( x1, y1, z1 );
   verts[1].point.set( x2, y2, z2 );

   verts[0].color = color;
   verts[1].color = color;

   verts.unlock();

   mDevice->setVertexBuffer( verts );
   mDevice->setStateBlock( mRectFillSB );
   mDevice->setupGenericShaders();
   mDevice->drawPrimitive( GFXLineList, 0, 1 );
}
Line * DrawTools::drawArc(double radius, double beginAngle, double endAngle, int steps) {
	int vertCount = steps + 1;

	BoundedArray<GLfloat> verts(2*vertCount);

	double delta = endAngle - beginAngle;
	double step = delta / steps;

	double angle = beginAngle;

	for (int i=0; i<=steps; ++i) {
		verts[i*2] = sin(angle) * radius;
		verts[i*2+1] = cos(angle) * radius;
		angle += step;
	}

	return new Line(verts,vertCount);
}
Exemple #5
0
void Face3::init()
{
  if(myMesh != NULL)
	{
	  components(0)=myMesh->edge(verts(0),verts(1)).id_;
	  components(1)=myMesh->edge(verts(0),verts(2)).id_;
	  components(2)=myMesh->edge(verts(1),verts(2)).id_;  
	}

  for(int i=0; i < typeSpecyfic_.nComponents_; ++i) {
      myMesh->edges_.getById(components(i)).incRef();
  }
}
void GFXDrawUtil::_drawWirePolyhedron( const GFXStateBlockDesc &desc, const AnyPolyhedron &poly, const ColorI &color, const MatrixF *xfm )
{
   GFXDEBUGEVENT_SCOPE( GFXDrawUtil_DrawWirePolyhedron, ColorI::GREEN );

   const U32 numEdges = poly.getNumEdges();
   const Point3F* points = poly.getPoints();
   const Polyhedron::Edge* edges = poly.getEdges();

   // Allocate a temporary vertex buffer.

   GFXVertexBufferHandle< GFXVertexPC > verts( mDevice, numEdges * 2, GFXBufferTypeVolatile);

   // Fill it with the vertices for the edges.
   
   verts.lock();
   for( U32 i = 0; i < numEdges; ++ i )
   {
      const U32 nvert = i * 2;
      verts[ nvert + 0 ].point = points[ edges[ i ].vertex[ 0 ] ];
      verts[ nvert + 0 ].color = color;

      verts[ nvert + 1 ].point = points[ edges[ i ].vertex[ 1 ] ];
      verts[ nvert + 1 ].color = color;
   }

   if( xfm )
   {
      for( U32 i = 0; i < numEdges; ++ i )
      {
         xfm->mulP( verts[ i + 0 ].point );
         xfm->mulP( verts[ i + 1 ].point );
      }
   }
   verts.unlock();

   // Render the line list.

   mDevice->setStateBlockByDesc( desc );

   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders();

   mDevice->drawPrimitive( GFXLineList, 0, numEdges );
}
Exemple #7
0
BOOL plDistributor::IDuplicate2Sided(plMaxNode* node, Mesh* mesh) const
{
    Mtl* mtl = node->GetMtl();

    BitArray faces(mesh->getNumFaces());

    int num2Sided = 0;

    int origNumFaces = mesh->getNumFaces();

    int i;
    for( i = 0; i < mesh->getNumFaces(); i++ )
    {
        if( hsMaterialConverter::IsTwoSided(mtl, mesh->faces[i].getMatID()) )
        {
            num2Sided++;
            faces.Set(i);
        }
    }

    if( !num2Sided )
        return false;

    MeshDelta meshDelta(*mesh);
    meshDelta.CloneFaces(*mesh, faces);
    meshDelta.Apply(*mesh);

    BitArray verts(mesh->getNumVerts());
    verts.SetAll();
    const float kWeldThresh = 0.1f;
    meshDelta.WeldByThreshold(*mesh, verts, kWeldThresh);
    meshDelta.Apply(*mesh);

    hsAssert(origNumFaces + num2Sided == mesh->getNumFaces(), "Whoa, lost or gained, unexpected");

    for( i = origNumFaces; i < mesh->getNumFaces(); i++ )
    {
        meshDelta.FlipNormal(*mesh, i);
    }
    meshDelta.Apply(*mesh);

    return true;
}
Exemple #8
0
static int pyGeometrySpan_setVertices(pyGeometrySpan* self, PyObject* value, void*) {
    if (value == NULL || !PySequence_Check(value)) {
        PyErr_SetString(PyExc_TypeError, "vertices should be a sequence of TempVertex");
        return -1;
    }
    size_t count = PySequence_Size(value);
    for (size_t i = 0; i < count; ++i) {
        if (!pyTempVertex_Check(PySequence_Fast_GET_ITEM(value, i))) {
            PyErr_SetString(PyExc_TypeError, "vertices should be a sequence of TempVertex");
            return -1;
        }
    }

    std::vector<plGeometrySpan::TempVertex> verts(PySequence_Size(value));
    for (size_t i = 0; i < verts.size(); ++i)
        verts[i] = *((pyTempVertex*)PySequence_Fast_GET_ITEM(value, i))->fThis;
    self->fThis->setVertices(verts);
    return 0;
}
Exemple #9
0
bool PymolWriter::handle_triangle(TriangleGeometry *g, Color color,
                                  std::string name) {
  setup(name, TRIANGLES);
  if (!open_type_) {
    get_stream() << "BEGIN, TRIANGLES, ";
    open_type_ = TRIANGLES;
  }
  Ints tri(3);
  tri[0] = 0;
  tri[1] = 1;
  tri[2] = 2;
  algebra::Vector3Ds verts(3);
  verts[0] = g->get_geometry().get_point(0);
  verts[1] = g->get_geometry().get_point(1);
  verts[2] = g->get_geometry().get_point(2);
  algebra::Vector3Ds normals = internal::get_normals(tri, verts);
  write_triangle(tri.begin(), tri.end(), verts, normals, color, get_stream());
  return true;
}
void GFXDrawUtil::_drawWireCube( const GFXStateBlockDesc &desc, const Point3F &size, const Point3F &pos, const ColorI &color, const MatrixF *xfm )
{
   GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, 30, GFXBufferTypeVolatile);
   verts.lock();

   Point3F halfSize = size * 0.5f;

   // setup 6 line loops
   U32 vertexIndex = 0;
   for(S32 i = 0; i < 6; i++)
   {
      for(S32 j = 0; j < 5; j++)
      {
         S32 idx = cubeFaces[i][j%4];

         verts[vertexIndex].point = cubePoints[idx] * halfSize;
         verts[vertexIndex].color = color;
         vertexIndex++;
      }
   }

   // Apply xfm if we were passed one.
   if ( xfm != NULL )
   {
      for ( U32 i = 0; i < 30; i++ )
         xfm->mulP( verts[i].point );
   }

   // Apply position offset
   for ( U32 i = 0; i < 30; i++ )
      verts[i].point += pos;

   verts.unlock();

   mDevice->setStateBlockByDesc( desc );

   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders();

   for( U32 i=0; i<6; i++ )
      mDevice->drawPrimitive( GFXLineStrip, i*5, 4 );
}
void GFXDrawUtil::_drawWireCapsule( const GFXStateBlockDesc &desc, const Point3F &center, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm )
{
   MatrixF mat;
   if ( xfm )
      mat = *xfm;
   else
      mat = MatrixF::Identity;

   mat.scale( Point3F(radius,radius,height*0.5f) );
   mat.setPosition(center);
   mDevice->pushWorldMatrix();
   mDevice->multWorld(mat);

   S32 numPoints = sizeof(circlePoints)/sizeof(Point2F);
   GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints, GFXBufferTypeVolatile);
   verts.lock();
   for (S32 i=0; i< numPoints; i++)
   {
      S32 idx = i & (~1); // just draw the even ones
      F32 z = i & 1 ? 1.0f : -1.0f;
      verts[i].point = Point3F(circlePoints[idx].x,circlePoints[idx].y, z);
      verts[i].color = color;
   }
   verts.unlock();

   mDevice->setStateBlockByDesc( desc );

   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders();

   for (S32 i=0; i<numPoints; i += 2)
      mDevice->drawPrimitive(GFXLineStrip, i, 1);

   mDevice->popWorldMatrix();

   Point3F sphereCenter;
   sphereCenter.z = center.z + 0.5f * height;
   drawSphere( desc, radius,sphereCenter,color,true,false);
   sphereCenter.z = center.z - 0.5f * height;
   drawSphere( desc, radius,sphereCenter,color,false,true);
}
Exemple #12
0
static int pyCullPoly_setVerts(pyCullPoly* self, PyObject* value, void*) {
    if (value == NULL) {
        self->fThis->setVerts(std::vector<hsVector3>());
        return 0;
    }
    if (!PyList_Check(value)) {
        PyErr_SetString(PyExc_TypeError, "verts should be a list of hsVector3s");
        return -1;
    }
    std::vector<hsVector3> verts(PyList_Size(value));
    for (size_t i=0; i<verts.size(); i++) {
        PyObject* item = PyList_GetItem(value, i);
        if (!pyVector3_Check(item)) {
            PyErr_SetString(PyExc_TypeError, "verts should be a list of hsVector3s");
            return -1;
        }
        verts[i] = *((pyVector3*)item)->fThis;
    }
    self->fThis->setVerts(verts);
    return 0;
}
void CubicBezierCurve::Unpack()
{
  // demo and test

  size_t n = 0;
  n = GetPointNumber(max_subdiv_count);
  DBG_PRINT_MSG("10, points: %ld", n);

  glm::vec2 p1(0.f, 0.f);
  glm::vec2 p2(100.f, 100.f);
  glm::vec2 p3(200.f, 100.f);
  glm::vec2 p4(300.f, 0.f);
  std::vector<GLfloat> verts(n * 3, 0.f);

  size_t index = 0;
  GenerateBezierCurveVertices(p1, p2, p3, p4, 0, &index, verts);

  buffer_.bind();
  buffer_.set_data(sizeof(GLfloat) * verts.size(), &verts[0]);
  buffer_.reset();
}
void GFXDrawUtil::drawRectFill( const Point2F &upperLeft, const Point2F &lowerRight, const ColorI &color )
{
   //
   // Convert Box   a----------x
   //               |          |
   //               x----------b
   // Into Quad
   //               v0---------v1
   //               | a       x |
   //               |           |
   //               | x       b |
   //               v2---------v3
   //

   // NorthWest and NorthEast facing offset vectors
   Point2F nw(-0.5,-0.5); /*  \  */
   Point2F ne(0.5,-0.5); /*  /  */

   GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, 4, GFXBufferTypeVolatile);
   verts.lock();

   F32 ulOffset = 0.5f - mDevice->getFillConventionOffset();
   
   verts[0].point.set( upperLeft.x+nw.x+ulOffset, upperLeft.y+nw.y+ulOffset, 0.0f );
   verts[1].point.set( lowerRight.x+ne.x, upperLeft.y+ne.y+ulOffset, 0.0f );
   verts[2].point.set( upperLeft.x-ne.x+ulOffset, lowerRight.y-ne.y, 0.0f );
   verts[3].point.set( lowerRight.x-nw.x, lowerRight.y-nw.y, 0.0f );

   for (S32 i=0; i<4; i++)
      verts[i].color = color;

   verts.unlock();

   mDevice->setStateBlock(mRectFillSB);
   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders();
   mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 );
}
void GFXDrawUtil::drawSolidPlane( const GFXStateBlockDesc &desc, const Point3F &pos, const Point2F &size, const ColorI &color )
{
   GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, 4, GFXBufferTypeVolatile);
   verts.lock();

   verts[0].point = pos + Point3F( -size.x / 2.0f, -size.y / 2.0f, 0 );
   verts[0].color = color;
   verts[1].point = pos + Point3F( -size.x / 2.0f, size.y / 2.0f, 0 );
   verts[1].color = color;
   verts[2].point = pos + Point3F( size.x / 2.0f, size.y / 2.0f, 0 );
   verts[2].color = color;
   verts[3].point = pos + Point3F( size.x / 2.0f, -size.y / 2.0f, 0 );
   verts[3].color = color;

   verts.unlock();

   mDevice->setStateBlockByDesc( desc );

   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders();

   mDevice->drawPrimitive( GFXTriangleFan, 0, 2 );
}
Exemple #16
0
static PyObject* pyGBufferGroup_addVerts(pyGBufferGroup* self, PyObject* args) {
    PyObject* list;
    if (!PyArg_ParseTuple(args, "O", &list)) {
        PyErr_SetString(PyExc_TypeError, "addVertices expects a list of plGBufferVertex objects");
        return NULL;
    }
    if (!PyList_Check(list)) {
        PyErr_SetString(PyExc_TypeError, "addVertices expects a list of plGBufferVertex objects");
        return NULL;
    }

    std::vector<plGBufferVertex> verts(PyList_Size(list));
    for (size_t i=0; i<verts.size(); i++) {
        if (!pyGBufferVertex_Check(PyList_GetItem(list, i))) {
            PyErr_SetString(PyExc_TypeError, "addVertices expects a list of plGBufferVertex objects");
            return NULL;
        }
        verts[i] = *((pyGBufferVertex*)PyList_GetItem(list, i))->fThis;
    }
    self->fThis->addVertices(verts);
    Py_INCREF(Py_None);
    return Py_None;
}
void GFXDrawUtil::drawPolygon( const GFXStateBlockDesc& desc, const Point3F* points, U32 numPoints, const ColorI& color, const MatrixF* xfm /* = NULL */ )
{
   const bool isWireframe = ( desc.fillMode == GFXFillWireframe );
   const U32 numVerts = isWireframe ? numPoints + 1 : numPoints;
   GFXVertexBufferHandle< GFXVertexPC > verts( mDevice, numVerts, GFXBufferTypeVolatile );

   verts.lock();
   for( U32 i = 0; i < numPoints; ++ i )
   {
      verts[ i ].point = points[ i ];
      verts[ i ].color = color;
   }

   if( xfm )
   {
      for( U32 i = 0; i < numPoints; ++ i )
         xfm->mulP( verts[ i ].point );
   }
   
   if( isWireframe )
   {
      verts[ numVerts - 1 ].point = verts[ 0 ].point;
      verts[ numVerts - 1 ].color = color;
   }

   verts.unlock();

   mDevice->setStateBlockByDesc( desc );

   mDevice->setVertexBuffer( verts );
   mDevice->setupGenericShaders();

   if( desc.fillMode == GFXFillWireframe )
      mDevice->drawPrimitive( GFXLineStrip, 0, numPoints );
   else
      mDevice->drawPrimitive( GFXTriangleFan, 0, numPoints - 2 );
}
static PyObject* pyDrawableSpans_addVerts(pyDrawableSpans* self, PyObject* args) {
    int buf;
    PyObject* vlist;
    if (!PyArg_ParseTuple(args,  "iO", &buf, &vlist)) {
        PyErr_SetString(PyExc_TypeError, "addVerts expects int, list");
        return NULL;
    }
    if (!PyList_Check(vlist)) {
        PyErr_SetString(PyExc_TypeError, "addVerts expects int, list");
        return NULL;
    }
    std::vector<plGBufferVertex> verts(PyList_Size(vlist));
    for (size_t i=0; i<verts.size(); i++) {
        PyObject* vert = PyList_GetItem(vlist, i);
        if (!pyGBufferVertex_Check(vert)) {
            PyErr_SetString(PyExc_TypeError, "addVerts expects a list of plGBufferVertexes");
            return NULL;
        }
        verts[i] = *((pyGBufferVertex*)vert)->fThis;
    }
    self->fThis->addVerts(buf, verts);
    Py_INCREF(Py_None);
    return Py_None;
}
Exemple #19
0
bool NFFParser::readFile() const{
	
	ifstream input(fileLocation, ios::in);
	if (!input.good()){
		std::cout << "Can't find my file!\n";
		return false;
	}

	if (!input){
		cout << "Unable to open file";
		return false;
	}
	else{
		std::string line;
		while (getline(input, line)){
			std::vector<std::string> splitLine = split(line, ' ');
			std::string command = splitLine[0];
			if (command == "s"){
				Vec3f center = read3DVector(splitLine);
				float radius = static_cast<float>(atof(splitLine[4].c_str()));
				Sphere* s = new Sphere(center, radius);
				SceneObject* so = new SceneObject(scene->materialIndex, s);

				scene->octree->insertShape(so, scene->octree->root, 0);
			}
			else if (command == "c"){
				float baseX = static_cast<float>(atof(splitLine[1].c_str()));
				float baseY = static_cast<float>(atof(splitLine[2].c_str()));
				float baseZ = static_cast<float>(atof(splitLine[3].c_str()));
				float baseRadius = static_cast<float>(atof(splitLine[4].c_str()));
				Vec3f base = Vec3f(baseX, baseY, baseZ);

				float apexX = static_cast<float>(atof(splitLine[5].c_str()));
				float apexY = static_cast<float>(atof(splitLine[6].c_str()));
				float apexZ = static_cast<float>(atof(splitLine[7].c_str()));
				float apexRadius = static_cast<float>(atof(splitLine[8].c_str()));
				Vec3f apex = Vec3f(apexX, apexY, apexZ);

				if (baseRadius == apexRadius){
					Cylinder* c = new Cylinder(base, apex, baseRadius);
					SceneObject* so = new SceneObject(scene->materialIndex, static_cast<Primitive*>(c));
					scene->octree->insertShape(so, scene->octree->root, 0);
				}
				else{
					// @TODO  cone code
				}
			}
			else if (command == "p"){
				int numVerts = atoi(splitLine[1].c_str());
				if (numVerts >= 3){
					std::vector<Vec3f> verts(numVerts);
					for (int i = 0; i < numVerts; i++){
						getline(input, line);
						std::vector<std::string> splitLine = split(line, ' ');
						verts[i] = read3DVector(splitLine);
					}
					Polygon* poly = new Polygon(verts);
					std::vector<Triangle*> triangles = poly->triangles;
					for (std::vector<int>::size_type itr = 0; itr != triangles.size(); itr++) {
						Triangle* t = triangles[itr];
						SceneObject* so = new SceneObject(scene->materialIndex, static_cast<Primitive*>(t));
						scene->octree->insertShape(so, scene->octree->root, 0);
					}
				}
			}
			else if (command == "pp"){
				int numVerts = atoi(splitLine[1].c_str());
				if (numVerts >= 3){
					std::vector<Vec3f> verts(numVerts);
					std::vector<Vec3f> norms(numVerts);
					for (int i = 0; i < numVerts; i++){
						getline(input, line);
						std::vector<std::string> splitLine = split(line, ' ');
						float x = static_cast<float>(atof(splitLine[0].c_str()));
						float y = static_cast<float>(atof(splitLine[1].c_str()));
						float z = static_cast<float>(atof(splitLine[2].c_str()));
						verts.push_back(Vec3f(x, y, z));

						float nx = static_cast<float>(atof(splitLine[3].c_str()));
						float ny = static_cast<float>(atof(splitLine[4].c_str()));
						float nz = static_cast<float>(atof(splitLine[5].c_str()));
						norms.push_back(Vec3f(nx, ny, nz));
					}

					Vec3f n = Vec3f(0.f, 0.f, 0.f);
					for (std::vector<int>::size_type itr = 0; itr != norms.size(); itr++) {
						n += norms[itr];
					}
					n /= 3.f;
					Triangle* t = new Triangle(verts[0], verts[1], verts[2], n);
					SceneObject* so = new SceneObject(scene->materialIndex, static_cast<Primitive*>(t));
					scene->octree->insertShape(so, scene->octree->root, 0);
				}
			}
			else if (command == "v"){
				for (int i = 0; i < 6; i++){
					getline(input, line);
					std::vector<std::string> splitLine = split(line, ' ');
					std::string command = splitLine[0];
					if (command == "from"){
						scene->from = read3DVector(splitLine);
					}
					else if (command == "at"){
						scene->at = read3DVector(splitLine);
					}
					else if (command == "up"){
						scene->up = read3DVector(splitLine);
					}
					else if (command == "angle"){
						scene->fov =static_cast<float>(atof(splitLine[1].c_str()));
					}
					else if (command == "hither"){
						scene->hither = static_cast<float>(atof(splitLine[1].c_str()));
					}
					else if (command == "resolution"){
						scene->screenWidth = std::stoi(splitLine[1]);
						scene->screenHeight = std::stoi(splitLine[1]);
					}
				}
			}
			else if (command == "b"){
				scene->bg = read3DVector(splitLine);
			}
			else if (command == "l"){
				Light* const l = new Light(read3DVector(splitLine));
				scene->lights.push_back(l);
			}
			else if (command == "f"){
				float red = static_cast<float>(atof(splitLine[1].c_str()));
				float green = static_cast<float>(atof(splitLine[2].c_str()));
				float blue = static_cast<float>(atof(splitLine[3].c_str()));
				float kd = static_cast<float>(atof(splitLine[4].c_str()));
				float ks = static_cast<float>(atof(splitLine[5].c_str()));
				float shine = static_cast<float>(atof(splitLine[6].c_str()));
				float T = static_cast<float>(atof(splitLine[7].c_str()));
				float refraction = static_cast<float>(atof(splitLine[8].c_str()));
				Material* m = new Material(red, green, blue, kd, ks, shine, T, refraction);
				++scene->materialIndex; // incrementation here on purpose
				scene->materials.push_back(m);

			}
		}
		printf("File reading done.\n");

		input.close();
	}

	return true;
}
Exemple #20
0
bool RawSaver::Save(DxRenderer* renderer, Mesh* mesh, const std::string& filename, std::string& errors)
{
	if(!mesh){
		errors += "Null mesh passed";
		return false;
	}
	// get base name for all files
	const size_t dotPos = filename.rfind('.');
	if(dotPos == filename.npos){
		errors += "Invalid filename";
		return false;
	}

	const std::string basepath = filename.substr(0, dotPos);

	std::string basename;
	const size_t slashPos = basepath.find_last_of("\\/");
	if(slashPos != filename.npos){
		basename = basepath.substr(slashPos + 1, basepath.size() - slashPos + 1);
	}
	else {
		basename = basepath;
	}

	// open index file
	std::ofstream fout(filename);
	if(!fout.is_open()){
		errors += "Unable to create index file " + filename;
		return false;
	}

	// write vertices file
	std::string vertsPath = basepath + ".verts";
	std::string vertsName = basename + ".verts";
	std::ofstream verts(vertsPath, std::ios::binary);
	if(!verts.is_open()){
		errors += "Unable to create vertices file";
		return false;
	}

	ID3D11Buffer* vbuffer = mesh->GetVertexBuffer();
	assert(vbuffer && "Missing vertex buffer");

	HRESULT hr;
	// create a staging buffer to copy to
	ID3D11Buffer* vstaging;
	D3D11_BUFFER_DESC vdesc;
	vbuffer->GetDesc(&vdesc);
	vdesc.Usage = D3D11_USAGE_STAGING;
	vdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	vdesc.BindFlags = 0;
	hr = renderer->GetDevice()->CreateBuffer(&vdesc, nullptr, &vstaging);
	if(FAILED(hr))
	{
		errors += "Unable to create staging vertex buffer";
		return false;
	}
	ReleaseGuard<ID3D11Buffer> stguard(vstaging);

	renderer->GetImmediateContext()->CopyResource(vstaging, vbuffer);

	D3D11_MAPPED_SUBRESOURCE vmap = {0};
	hr = renderer->GetImmediateContext()->Map(stguard.Get(), 0, D3D11_MAP_READ, 0, &vmap);
	if(FAILED(hr))
	{
		errors += "Unable to map vertex buffer";
		return false;
	}

	// write the data
	verts.write((char*)vmap.pData, vmap.RowPitch);

	renderer->GetImmediateContext()->Unmap(vbuffer, 0);

	fout << vertsName << std::endl;

	// write all subsets
	for(size_t i = 0; i < mesh->GetSubsetCount(); ++i)
	{
		std::ostringstream oss;
		oss << "_" << i << ".inds";
		
		std::string subsetPath = basepath + oss.str();
		std::string subsetName = basename + oss.str();
		std::ofstream inds(subsetPath, std::ios::binary);
		if(!inds.is_open()){
			errors += "Unable to create indices file";
			return false;
		}

		ID3D11Buffer* ibuffer = mesh->GetSubset(i)->GetIndexBuffer();
		assert(ibuffer && "Missing index buffer");

		// create a staging buffer to copy to
		ID3D11Buffer* istaging;
		D3D11_BUFFER_DESC idesc;
		ibuffer->GetDesc(&idesc);
		idesc.Usage = D3D11_USAGE_STAGING;
		idesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		idesc.BindFlags = 0;
		hr = renderer->GetDevice()->CreateBuffer(&idesc, nullptr, &istaging);
		if(FAILED(hr))
		{
			errors += "Unable to create staging index buffer";
			return false;
		}
		ReleaseGuard<ID3D11Buffer> stindexguard(istaging);

		renderer->GetImmediateContext()->CopyResource(istaging, ibuffer);

		D3D11_MAPPED_SUBRESOURCE imap = {0};
		hr = renderer->GetImmediateContext()->Map(stindexguard.Get(), 0, D3D11_MAP_READ, 0, &imap);
		if(FAILED(hr))
		{
			errors += "Unable to map index buffer";
			return false;
		}

		// write material
		std::ostringstream diffuseColorStr;
		const Material& material = mesh->GetSubset(i)->GetMaterial();
		// diffuse color
		auto diffuseColor = material.GetDiffuseColor();
		diffuseColorStr << diffuseColor.x << " " << diffuseColor.y << " " << diffuseColor.z;
		auto dcStr = diffuseColorStr.str();
		unsigned strSize = dcStr.size();
		inds.write((char*)&strSize, sizeof(unsigned));
		inds.write((char*)dcStr.c_str(), dcStr.size());

		// diffuse tex
		std::string texName = renderer->GetTextureManager().GetTextureName(material.GetDiffuse());
		strSize = unsigned(texName.size());
		inds.write((char*)&strSize, sizeof(unsigned));
		inds.write((char*)texName.c_str(), texName.size());

		// normal map
		std::string normalMapName = renderer->GetTextureManager().GetTextureName(material.GetNormalMap());
		strSize = unsigned(normalMapName.size());
		inds.write((char*)&strSize, sizeof(unsigned));
		inds.write((char*)normalMapName.c_str(), normalMapName.size());
	
		// alpha mask
		std::string maskMapName = renderer->GetTextureManager().GetTextureName(material.GetAlphaMask());
		strSize = unsigned(maskMapName.size());
		inds.write((char*)&strSize, sizeof(unsigned));
		inds.write((char*)maskMapName.c_str(), maskMapName.size());
		
		// spacular map
		std::string specularMapName = renderer->GetTextureManager().GetTextureName(material.GetSpecularMap());
		strSize = unsigned(specularMapName.size());
		inds.write((char*)&strSize, sizeof(unsigned));
		inds.write((char*)specularMapName.c_str(), specularMapName.size());

		// specular power
		const float power = material.GetSpecularPower();
		inds.write((const char*)&power, sizeof(float));

		// write the data
		inds.write((char*)imap.pData, imap.RowPitch);

		renderer->GetImmediateContext()->Unmap(ibuffer, 0);

		fout << subsetName << std::endl;
	}

	return true;
}
void FontRenderBatcher::render( F32 rot, const Point2F &offset )
{
   if( mLength == 0 )
      return;

   GFX->setStateBlock(mFontSB);
   for(U32 i = 0; i < GFX->getNumSamplers(); i++)
      GFX->setTexture(i, NULL);

   MatrixF rotMatrix;

   bool doRotation = rot != 0.f;
   if(doRotation)
      rotMatrix.set( EulerF( 0.0, 0.0, mDegToRad( rot ) ) );

   // Write verts out.
   U32 currentPt = 0;
   GFXVertexBufferHandle<GFXVertexPCT> verts(GFX, mLength * 6, GFXBufferTypeVolatile);
   verts.lock();

   for( S32 i = 0; i < mSheets.size(); i++ )
   {
      // Do some early outs...
      if(!mSheets[i])
         continue;

      if(!mSheets[i]->numChars)
         continue;

      mSheets[i]->startVertex = currentPt;
      const GFXTextureObject *tex = mFont->getTextureHandle(i);

      for( S32 j = 0; j < mSheets[i]->numChars; j++ )
      {
         // Get some general info to proceed with...
         const CharMarker &m = mSheets[i]->charIndex[j];
         const PlatformFont::CharInfo &ci = mFont->getCharInfo( m.c );

         // Where are we drawing it?
         F32 drawY = offset.y + mFont->getBaseline() - ci.yOrigin * TEXT_MAG;
         F32 drawX = offset.x + m.x + ci.xOrigin;

         // Figure some values.
         const F32 texWidth = (F32)tex->getWidth();
         const F32 texHeight = (F32)tex->getHeight();
         const F32 texLeft   = (F32)(ci.xOffset)             / texWidth;
         const F32 texRight  = (F32)(ci.xOffset + ci.width)  / texWidth;
         const F32 texTop    = (F32)(ci.yOffset)             / texHeight;
         const F32 texBottom = (F32)(ci.yOffset + ci.height) / texHeight;

         const F32 fillConventionOffset = GFX->getFillConventionOffset();
         const F32 screenLeft   = drawX - fillConventionOffset;
         const F32 screenRight  = drawX - fillConventionOffset + ci.width * TEXT_MAG;
         const F32 screenTop    = drawY - fillConventionOffset;
         const F32 screenBottom = drawY - fillConventionOffset + ci.height * TEXT_MAG;

         // Build our vertices. We NEVER read back from the buffer, that's
         // incredibly slow, so for rotation do it into tmp. This code is
         // ugly as sin.
         Point3F tmp;

         tmp.set( screenLeft, screenTop, 0.f );
         if(doRotation)
            rotMatrix.mulP( tmp, &verts[currentPt].point);
         else
            verts[currentPt].point = tmp;
         verts[currentPt].color = m.color;
         verts[currentPt].texCoord.set( texLeft, texTop );
         currentPt++;

         tmp.set( screenLeft, screenBottom, 0.f );
         if(doRotation)
            rotMatrix.mulP( tmp, &verts[currentPt].point);
         else
            verts[currentPt].point = tmp;
         verts[currentPt].color = m.color;
         verts[currentPt].texCoord.set( texLeft, texBottom );
         currentPt++;

         tmp.set( screenRight, screenBottom, 0.f );
         if(doRotation)
            rotMatrix.mulP( tmp, &verts[currentPt].point);
         else
            verts[currentPt].point = tmp;
         verts[currentPt].color = m.color;
         verts[currentPt].texCoord.set( texRight, texBottom );
         currentPt++;

         tmp.set( screenRight, screenBottom, 0.f );
         if(doRotation)
            rotMatrix.mulP( tmp, &verts[currentPt].point);
         else
            verts[currentPt].point = tmp;
         verts[currentPt].color = m.color;
         verts[currentPt].texCoord.set( texRight, texBottom );
         currentPt++;

         tmp.set( screenRight, screenTop, 0.f );
         if(doRotation)
            rotMatrix.mulP( tmp, &verts[currentPt].point);
         else
            verts[currentPt].point = tmp;
         verts[currentPt].color = m.color;
         verts[currentPt].texCoord.set( texRight, texTop );
         currentPt++;

         tmp.set( screenLeft, screenTop, 0.f );
         if(doRotation)
            rotMatrix.mulP( tmp, &verts[currentPt].point);
         else
            verts[currentPt].point = tmp;
         verts[currentPt].color = m.color;
         verts[currentPt].texCoord.set( texLeft, texTop );
         currentPt++;
      }
   }

   verts->unlock();

   AssertFatal(currentPt <= mLength * 6, "FontRenderBatcher::render - too many verts for length of string!");

   GFX->setVertexBuffer(verts);
   GFX->setupGenericShaders( GFXDevice::GSAddColorTexture );

   // Now do an optimal render!
   for( S32 i = 0; i < mSheets.size(); i++ )
   {
      if(!mSheets[i])
         continue;

      if(!mSheets[i]->numChars )
         continue;
      
      GFX->setTexture( 0, mFont->getTextureHandle(i) );
      GFX->drawPrimitive(GFXTriangleList, mSheets[i]->startVertex, mSheets[i]->numChars * 2);
   }
}
void plSpanTemplate::prcParse(const pfPrcTag* tag) {
    if (tag->getName() != "plSpanTemplate")
        throw pfPrcTagException(__FILE__, __LINE__, tag->getName());

    fFormat = tag->getParam("Format", "0").toUint();
    const pfPrcTag* child = tag->getFirstChild();
    while (child != NULL) {
        if (child->getName() == "Vertices") {
            fNumVerts = child->countChildren();
            std::vector<Vertex> verts(fNumVerts);
            const pfPrcTag* vertChild = child->getFirstChild();
            for (size_t i=0; i<fNumVerts; i++) {
                if (vertChild->getName() != "Vertex")
                    throw pfPrcTagException(__FILE__, __LINE__, vertChild->getName());
                verts[i].fColor1 = tag->getParam("Color1", "0").toUint();
                verts[i].fColor2 = tag->getParam("Color2", "0").toUint();
                verts[i].fWeightIdx = tag->getParam("WeightIdx", "0").toInt();
                const pfPrcTag* subChild = vertChild->getFirstChild();
                while (subChild != NULL) {
                    if (subChild->getName() == "Position") {
                        if (subChild->hasChildren())
                            verts[i].fPosition.prcParse(subChild->getFirstChild());
                    } else if (subChild->getName() == "Normal") {
                        if (subChild->hasChildren())
                            verts[i].fNormal.prcParse(subChild->getFirstChild());
                    } else if (subChild->getName() == "UVWs") {
                        if ((fFormat & kUVWMask) / 0x10 != subChild->countChildren())
                            throw pfPrcParseException(__FILE__, __LINE__, "Incorrect Number of UVW maps");
                        const pfPrcTag* uvwChild = subChild->getFirstChild();
                        for (size_t j=0; j<(size_t)((fFormat & kUVWMask) / 0x10); j++) {
                            verts[i].fUVWs[j].prcParse(uvwChild);
                            uvwChild = uvwChild->getNextSibling();
                        }
                    } else if (subChild->getName() == "Weights") {
                        std::list<plString> wgtList = subChild->getContents();
                        if (wgtList.size() != (fFormat & kWeightMask) / 0x100)
                            throw pfPrcParseException(__FILE__, __LINE__, "Incorrect Number of Weights");
                        auto wgt = wgtList.begin();
                        for (size_t j=0; j<(size_t)((fFormat & kWeightMask) / 0x100); j++)
                            verts[i].fWeights[j] = (*wgt++).toFloat();
                    } else {
                        throw pfPrcTagException(__FILE__, __LINE__, subChild->getName());
                    }
                    subChild = subChild->getNextSibling();
                }
                vertChild = vertChild->getNextSibling();
            }
            setVertices(verts);
        } else if (child->getName() == "Indices") {
            fNumTris = child->countChildren();
            fIndices = new unsigned short[fNumTris * 3];
            const pfPrcTag* idxChild = child->getFirstChild();
            for (size_t i=0; i<(size_t)(fNumTris * 3); i += 3) {
                std::list<plString> idxList = idxChild->getContents();
                if (idxList.size() != 3)
                    throw pfPrcParseException(__FILE__, __LINE__, "Triangles should have exactly 3 indices");
                auto idx_iter = idxList.begin();
                fIndices[i] = (*idx_iter++).toUint();
                fIndices[i+1] = (*idx_iter++).toUint();
                fIndices[i+2] = (*idx_iter++).toUint();
                idxChild = idxChild->getNextSibling();
            }
        } else {
            throw pfPrcTagException(__FILE__, __LINE__, child->getName());
        }
        child = child->getNextSibling();
    }
}
Exemple #23
0
void ModelWriter::writeFace(SUMeshHelperRef mesh, const Transform& transform, bool front, bool textured) {

	size_t vertexCount=0;
	SUMeshHelperGetNumVertices(mesh,&vertexCount);
	vector<SUPoint3D> verts(vertexCount);
	SUMeshHelperGetVertices(mesh,vertexCount,verts.data(),&vertexCount);

	vector<SUVector3D> normals(vertexCount);
	SUMeshHelperGetNormals(mesh,vertexCount,normals.data(),&vertexCount);

	vector<SUPoint3D> textures(vertexCount);
	
	size_t triCount = 0;
	SUMeshHelperGetNumTriangles(mesh,&triCount);

	size_t gotIndices = 0;
	vector<size_t> indicies(triCount*3);
	SUResult res = SUMeshHelperGetVertexIndices(mesh,triCount*3,indicies.data(),&gotIndices);
	assert(res == SU_ERROR_NONE);

	if(textured) {
		if(front) {
			SUMeshHelperGetFrontSTQCoords(mesh,vertexCount,textures.data(),&vertexCount);
		} else {
			SUMeshHelperGetBackSTQCoords(mesh,vertexCount,textures.data(),&vertexCount);
		}
	}
	float normalScale = 1.0f;
	if(!front) {
		normalScale = -1.0f;
	}
	
	bool flip = !front;

	SUVector3D xFlipTest = xaxis * transform;
	if(xFlipTest.x < 0) {
		flip = !flip;
	}

	SUVector3D yFlipTest = yaxis * transform;
	if(yFlipTest.y < 0) {
		flip = !flip;
	}
	
	for(size_t t = 0; t < triCount; t++) {
			
		m_Faces << "f ";

		for(int i=0; i<3; i++) {

			int j = (t*3) + (flip ? 2-i : i);
			
			m_Faces << getIndexedPos(verts[indicies[j]]*transform) << "/";
			
			if(textured)
				m_Faces << getIndexedTex(textures[indicies[j]]);
			
			m_Faces << "/" <<  getIndexedNormal(normals[indicies[j]]*normalScale*transform) << " ";
		}

		m_Faces << endl;
	}

}
Exemple #24
0
void copy_cells_archetypes(Complex2D      & G_dst, 
			   GSRC      const& G_src,
			   VtxCorr&         vtx_corr,
			   CellCorr&        cell_corr)
{
  typedef grid_types<GSRC>                      src_gt;
  typedef typename src_gt::CellIterator         src_cell_it;
  typedef typename src_gt::VertexOnCellIterator src_vertex_on_cell_it;
  
  typedef grid_types<Complex2D>     gt;
  typedef           gt::Cell        Cell;
  typedef           gt::cell_handle cell_handle;

  typedef              gt::archetype_type   dst_archetype;
  typedef typename src_gt::archetype_type   src_archetype;
  typedef              gt::archetype_handle src_arch_handle;
  typedef typename src_gt::archetype_handle dst_arch_handle;


  //typedef typename gt::BoundaryFacetIterator BdFacetIterator;    

  friend_for_input cc(G_dst);

  // (2) copy archetypes
  typedef vertex_morphism<src_archetype, dst_archetype> arch_morphism;
  ::std::vector<arch_morphism> morphism;
  bijective_mapping<src_arch_handle, dst_arch_handle> arch_corr;
  typename src_gt::archetype_iterator arch_src = G_src.BeginArchetype();
  for(; arch_src != G_src.EndArchetype() ; ++arch_src) {
    //  dst_arch_handle a_dst = cc.add_archetype(); //G_dst.add_archetype();
    src_arch_handle a_src = G_src.handle(arch_src);

    dst_archetype  arch_dst;
    dst_arch_handle a_dst = cc.add_archetype(arch_dst, (*arch_src).NumOfVertices());
    morphism.push_back(arch_morphism(*arch_src,G_dst.Archetype(a_dst)));

    ConstructGrid0(G_dst.Archetype(a_dst),
                   G_src.Archetype(a_src),
                   morphism.back());
    arch_corr[a_src] = a_dst;
  }


  for(typename src_gt::CellIterator c_src = G_src.FirstCell(); ! c_src.IsDone(); ++c_src){
    src_arch_handle a_src = G_src.archetype_of(*c_src);
    //  dst_arch_handle a_dst = arch_corr(a_src);

    cell_handle pc = cc._new_cell(GrAL::size<typename src_gt::Vertex>(*c_src)); // correct arch gets selected automatically a_dst);
    cell_corr[c_src.handle()] = pc;
    gt::Cell c_dst(G_dst, pc);

    typedef cell2d_connectivity c2d;
    c2d::vertex_list&   verts (cc._cell_vertices(pc));
 
    src_vertex_on_cell_it vc_src((*c_src)); // .FirstVertex());
    typename grid_types<src_archetype>::VertexIterator
       lv_src(G_src.Archetype(a_src).FirstVertex());
    for(; ! vc_src.IsDone(); ++vc_src, ++lv_src) {
      int lv = morphism[a_src][lv_src.handle()];
      verts [lv] = vtx_corr[vc_src.handle()];
    }


    // initialize cell neighbors
    cell_handle boundary(cc.outer_cell_handle()); // invalid reference to a cell
                                                // (used to mark unknown neighbours)
    c2d::cell_list&  neighb(cc._cell_neighbours(pc));
    for(int ln = 0; ln < c_dst.NumOfFacets(); ++ln)
      neighb[ln] = boundary; // correct neighbour is calculated later
  }

}
Exemple #25
0
  void POVPainter::drawColorMesh(const Mesh & mesh, int mode)
  {
    // Now we draw the given mesh to the OpenGL widget
    switch (mode)
    {
      case 0: // Filled triangles
        break;
      case 1: // Lines
        break;
      case 2: // Points
        break;
    }

    // Render the triangles of the mesh
    std::vector<Eigen::Vector3f> v = mesh.vertices();
    std::vector<Eigen::Vector3f> n = mesh.normals();
    std::vector<Color3f> c = mesh.colors();

    // If there are no triangles then don't bother doing anything
    if (v.size() == 0 || v.size() != c.size())
      return;

    QString vertsStr, ivertsStr, normsStr, texturesStr;
    QTextStream verts(&vertsStr);
    verts << "vertex_vectors{" << v.size() << ",\n";
    QTextStream iverts(&ivertsStr);
    iverts << "face_indices{" << v.size() / 3 << ",\n";
    QTextStream norms(&normsStr);
    norms << "normal_vectors{" << n.size() << ",\n";
    QTextStream textures(&texturesStr);
    textures << "texture_list{" << c.size() << ",\n";
    for(unsigned int i = 0; i < v.size(); ++i) {
      verts << "<" << v[i].x() << "," << v[i].y() << "," << v[i].z() << ">";
      norms << "<" << n[i].x() << "," << n[i].y() << "," << n[i].z() << ">";
      textures << "texture{pigment{rgbt<" << c[i].red() << ","
               << c[i].green() << "," << c[i].blue() << ","
               << 1.0 - d->color.alpha() << ">}}";
      if (i != v.size()-1) {
        verts << ", ";
        norms << ", ";
        textures << ",\n";
      }
      if (i != 0 && i%3 == 0) {
        verts << '\n';
        norms << '\n';
      }
    }
    // Now to write out the indices
    for (unsigned int i = 0; i < v.size(); i += 3) {
      iverts << "<" << i << "," << i+1 << "," << i+2 << ">";
      iverts << "," << i << "," << i+1 << "," << i+2;
      if (i != v.size()-3)
        iverts << ", ";
      if (i != 0 && ((i+1)/3)%3 == 0)
        iverts << '\n';
    }
    // Now to close off all the arrays
    verts << "\n}";
    norms << "\n}";
    iverts << "\n}";
    textures << "\n}";
    // Now to write out the full mesh - could be pretty big...
    *(d->output) << "mesh2 {\n"
                 << vertsStr << '\n'
                 << normsStr << '\n'
                 << texturesStr << '\n'
                 << ivertsStr << '\n'
                 << "}\n\n";
  }
void Postprocessing_DrawRainyGlass(Texture& renderTarget, Texture& scene)
{
	Texture dropletTarget = RenderTexturePool::Get(256, 256);

	// Clear droplet render target to default front-facing direction

	const Color frontClearColor(0.5f /* x == 0 */, 0.5f /* y = 0 */, 1.0f /* z = 1 */, 0.0f);
	dropletTarget.BeginDrawing(&frontClearColor);

	// Evaporation

	if (rain->dropletBuffer.IsValid())
	{
		if (rain->rainEvaporation > 0.02f) // Apply rain evaporation
		{
			rain->material.SetTechnique("rain_evaporation");
			rain->rainEvaporation = 0;
		}
		else // Just copy previous buffer (skip evaporation step this time)
		{
			rain->material.SetTechnique("copy_texture");
		}

		rain->material.SetTextureParameter("ColorMap", rain->dropletBuffer, Sampler::DefaultPostprocess);
		rain->material.DrawFullscreenQuad();
	}

	// Droplets

	const Vec2 sizeScale( (float) dropletTarget.GetWidth(), (float) dropletTarget.GetHeight() );

	while (rain->deltaTime > 0.0f)
	{
		const float stepDeltaTime = min(rain->deltaTime, 1 / 60.0f);
		rain->deltaTime -= stepDeltaTime;
		Postprocessing_UpdateRainyGlassStep(stepDeltaTime);

		const unsigned int numDroplets = rain->droplets.size();
		if (!numDroplets)
			continue;

		std::vector<Vec2> verts(numDroplets * 4);
		std::vector<Vec2> tex(numDroplets * 4);
		std::vector<unsigned short> indices(numDroplets * 6);

		int currVertexIndex = 0;
		unsigned short* currIndex = &indices[0];

		std::vector<RainyGlass::Droplet>::iterator dropletsEnd = rain->droplets.end();
		for (std::vector<RainyGlass::Droplet>::iterator it = rain->droplets.begin(); it != dropletsEnd; ++it)
		{
			Vec2 size = Vec2(it->size, it->size);
			Vec2 pos = it->pos - size * 0.5f;

			size *= sizeScale;
			pos *= sizeScale;

			Vec2* currVertex = &verts[currVertexIndex];
			*(currVertex++) = pos;
			*(currVertex++) = pos + Vec2(size.x, 0.0f);
			*(currVertex++) = pos + size;
			*(currVertex++) = pos + Vec2(0.0f, size.y);

			Vec2* currTex = &tex[currVertexIndex];
			(currTex++)->Set(0.0f, 0.0f);
			(currTex++)->Set(1.0f, 0.0f);
			(currTex++)->Set(1.0f, 1.0f);
			(currTex++)->Set(0.0f, 1.0f);

			*(currIndex++) = currVertexIndex;
			*(currIndex++) = currVertexIndex + 1;
			*(currIndex++) = currVertexIndex + 2;
			*(currIndex++) = currVertexIndex;
			*(currIndex++) = currVertexIndex + 2;
			*(currIndex++) = currVertexIndex + 3;

			currVertexIndex += 4;
		}

		Shape::DrawParams drawParams;
		drawParams.SetGeometryType(Shape::Geometry::Type_Triangles);
		drawParams.SetNumVerts(verts.size());
		drawParams.SetPosition(&verts[0], sizeof(Vec2));
		drawParams.SetTexCoord(&tex[0], 0, sizeof(Vec2));
		drawParams.SetIndices(indices.size(), &indices[0]);

		Material& defaultMaterial = App::GetDefaultMaterial();

		defaultMaterial.SetTechnique("tex_col");
		defaultMaterial.SetFloatParameter("Color", (const float*) &Color::White, 4);
		defaultMaterial.SetTextureParameter("ColorMap", rain->dropletTexture);
		defaultMaterial.Draw(&drawParams);
	}

	dropletTarget.EndDrawing();

	// Swap droplet buffer

	if (rain->dropletBuffer.IsValid())
		RenderTexturePool::Release(rain->dropletBuffer);
	rain->dropletBuffer = dropletTarget;

	// Apply droplet buffer distortion to scene

	renderTarget.BeginDrawing();

	Sampler colorSampler = Sampler::DefaultPostprocess;
	colorSampler.minFilterLinear = true;
	colorSampler.magFilterLinear = true;

	rain->material.SetTechnique("rain_distortion");
	rain->material.SetFloatParameter("DropletColor", (const float*) &rain->dropletColor, 4);
	rain->material.SetTextureParameter("ColorMap", scene, colorSampler);
	rain->material.SetTextureParameter("NormalMap", rain->dropletBuffer);
	rain->material.DrawFullscreenQuad();

	renderTarget.EndDrawing();
}
void GuiMaterialCtrl::onRender( Point2I offset, const RectI &updateRect )
{
   Parent::onRender( offset, updateRect );

   if ( !mMaterialInst )
      return;

   // Draw a quad with the material assigned
   GFXVertexBufferHandle<GFXVertexPCT> verts( GFX, 4, GFXBufferTypeVolatile );
   verts.lock();

   F32 screenLeft   = updateRect.point.x;
   F32 screenRight  = (updateRect.point.x + updateRect.extent.x);
   F32 screenTop    = updateRect.point.y;
   F32 screenBottom = (updateRect.point.y + updateRect.extent.y);

   const F32 fillConv = GFX->getFillConventionOffset();
   verts[0].point.set( screenLeft  - fillConv, screenTop    - fillConv, 0.f );
   verts[1].point.set( screenRight - fillConv, screenTop    - fillConv, 0.f );
   verts[2].point.set( screenLeft  - fillConv, screenBottom - fillConv, 0.f );
   verts[3].point.set( screenRight - fillConv, screenBottom - fillConv, 0.f );

   verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI( 255, 255, 255, 255 );

   verts[0].texCoord.set( 0.0f, 0.0f );
   verts[1].texCoord.set( 1.0f, 0.0f );
   verts[2].texCoord.set( 0.0f, 1.0f );
   verts[3].texCoord.set( 1.0f, 1.0f );

   verts.unlock();

   GFX->setVertexBuffer( verts );

   MatrixSet matSet;
   matSet.setWorld(GFX->getWorldMatrix());
   matSet.setView(GFX->getViewMatrix());
   matSet.setProjection(GFX->getProjectionMatrix());
   
   MatrixF cameraMatrix( true );
   F32 left, right, top, bottom, nearPlane, farPlane;
   bool isOrtho;
   GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho );
   Frustum frust( isOrtho, left, right, top, bottom, nearPlane, farPlane, cameraMatrix );

   SceneRenderState state
   (
      gClientSceneGraph,
      SPT_Diffuse,
      SceneCameraState( GFX->getViewport(), frust, GFX->getWorldMatrix(), GFX->getProjectionMatrix() ),
      gClientSceneGraph->getDefaultRenderPass(),
      false
   );

   SceneData sgData;
   sgData.init( &state );
   sgData.wireframe = false; // Don't wireframe this.

   while( mMaterialInst->setupPass( &state, sgData ) )
   {
      mMaterialInst->setSceneInfo( &state, sgData );
      mMaterialInst->setTransforms( matSet, &state );
      GFX->setupGenericShaders();
      GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
   }

   // Clean up
   GFX->setShader( NULL );
   GFX->setTexture( 0, NULL );
}
	bool PhysicsGeometry::load(FS::IFile& file)
	{
		Header header;
		file.read(&header, sizeof(header));
		if (header.m_magic != HEADER_MAGIC || header.m_version > (uint32)Versions::LAST)
		{
			return false;
		}

		auto* phy_manager = m_resource_manager.get(ResourceManager::PHYSICS);
		PhysicsSystem& system = static_cast<PhysicsGeometryManager*>(phy_manager)->getSystem();

		uint32 num_verts;
		Array<Vec3> verts(getAllocator());
		file.read(&num_verts, sizeof(num_verts));
		verts.resize(num_verts);
		file.read(&verts[0], sizeof(verts[0]) * verts.size());

		m_is_convex = header.m_convex != 0;
		if (!m_is_convex)
		{
			physx::PxTriangleMeshGeometry* geom =
				LUMIX_NEW(getAllocator(), physx::PxTriangleMeshGeometry)();
			m_geometry = geom;
			uint32 num_indices;
			Array<uint32> tris(getAllocator());
			file.read(&num_indices, sizeof(num_indices));
			tris.resize(num_indices);
			file.read(&tris[0], sizeof(tris[0]) * tris.size());

			physx::PxTriangleMeshDesc meshDesc;
			meshDesc.points.count = num_verts;
			meshDesc.points.stride = sizeof(physx::PxVec3);
			meshDesc.points.data = &verts[0];

			meshDesc.triangles.count = num_indices / 3;
			meshDesc.triangles.stride = 3 * sizeof(physx::PxU32);
			meshDesc.triangles.data = &tris[0];

			OutputStream writeBuffer(getAllocator());
			system.getCooking()->cookTriangleMesh(meshDesc, writeBuffer);

			InputStream readBuffer(writeBuffer.data, writeBuffer.size);
			geom->triangleMesh = system.getPhysics()->createTriangleMesh(readBuffer);
		}
		else
		{
			physx::PxConvexMeshGeometry* geom =
				LUMIX_NEW(getAllocator(), physx::PxConvexMeshGeometry)();
			m_geometry = geom;
			physx::PxConvexMeshDesc meshDesc;
			meshDesc.points.count = verts.size();
			meshDesc.points.stride = sizeof(Vec3);
			meshDesc.points.data = &verts[0];
			meshDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;

			OutputStream writeBuffer(getAllocator());
			bool status = system.getCooking()->cookConvexMesh(meshDesc, writeBuffer);
			if (!status)
			{
				LUMIX_DELETE(getAllocator(), geom);
				m_geometry = nullptr;
				return false;
			}

			InputStream readBuffer(writeBuffer.data, writeBuffer.size);
			physx::PxConvexMesh* mesh = system.getPhysics()->createConvexMesh(readBuffer);
			geom->convexMesh = mesh;
		}

		m_size = file.size();
		return true;
	}
/*
================
idRenderWorldLocal::ParseModel
================
*/
idRenderModel* idRenderWorldLocal::ParseModel( idLexer* src, const char* mapName, ID_TIME_T mapTimeStamp, idFile* fileOut )
{
	idToken token;
	
	src->ExpectTokenString( "{" );
	
	// parse the name
	src->ExpectAnyToken( &token );
	
	idRenderModel* model = renderModelManager->AllocModel();
	model->InitEmpty( token );
	
	if( fileOut != NULL )
	{
		// write out the type so the binary reader knows what to instantiate
		fileOut->WriteString( "shadowmodel" );
		fileOut->WriteString( token );
	}
	
	int numSurfaces = src->ParseInt();
	if( numSurfaces < 0 )
	{
		src->Error( "R_ParseModel: bad numSurfaces" );
	}
	
	for( int i = 0; i < numSurfaces; i++ )
	{
		src->ExpectTokenString( "{" );
		
		src->ExpectAnyToken( &token );
		
		modelSurface_t surf;
		surf.shader = declManager->FindMaterial( token );
		
		( ( idMaterial* )surf.shader )->AddReference();
		
		srfTriangles_t* tri = R_AllocStaticTriSurf();
		surf.geometry = tri;
		
		tri->numVerts = src->ParseInt();
		tri->numIndexes = src->ParseInt();
		
		// parse the vertices
		idTempArray<float> verts( tri->numVerts * 8 );
		for( int j = 0; j < tri->numVerts; j++ )
		{
			src->Parse1DMatrix( 8, &verts[j * 8] );
		}
		
		// parse the indices
		idTempArray<triIndex_t> indexes( tri->numIndexes );
		for( int j = 0; j < tri->numIndexes; j++ )
		{
			indexes[j] = src->ParseInt();
		}
		
#if 1
		// find the island that each vertex belongs to
		idTempArray<int> vertIslands( tri->numVerts );
		idTempArray<bool> trisVisited( tri->numIndexes );
		vertIslands.Zero();
		trisVisited.Zero();
		int numIslands = 0;
		for( int j = 0; j < tri->numIndexes; j += 3 )
		{
			if( trisVisited[j] )
			{
				continue;
			}
			
			int islandNum = ++numIslands;
			vertIslands[indexes[j + 0]] = islandNum;
			vertIslands[indexes[j + 1]] = islandNum;
			vertIslands[indexes[j + 2]] = islandNum;
			trisVisited[j] = true;
			
			idList<int> queue;
			queue.Append( j );
			for( int n = 0; n < queue.Num(); n++ )
			{
				int t = queue[n];
				for( int k = 0; k < tri->numIndexes; k += 3 )
				{
					if( trisVisited[k] )
					{
						continue;
					}
					bool connected =	indexes[t + 0] == indexes[k + 0] || indexes[t + 0] == indexes[k + 1] || indexes[t + 0] == indexes[k + 2] ||
										indexes[t + 1] == indexes[k + 0] || indexes[t + 1] == indexes[k + 1] || indexes[t + 1] == indexes[k + 2] ||
										indexes[t + 2] == indexes[k + 0] || indexes[t + 2] == indexes[k + 1] || indexes[t + 2] == indexes[k + 2];
					if( connected )
					{
						vertIslands[indexes[k + 0]] = islandNum;
						vertIslands[indexes[k + 1]] = islandNum;
						vertIslands[indexes[k + 2]] = islandNum;
						trisVisited[k] = true;
						queue.Append( k );
					}
				}
			}
		}
		
		// center the texture coordinates for each island for maximum 16-bit precision
		for( int j = 1; j <= numIslands; j++ )
		{
			float minS = idMath::INFINITY;
			float minT = idMath::INFINITY;
			float maxS = -idMath::INFINITY;
			float maxT = -idMath::INFINITY;
			for( int k = 0; k < tri->numVerts; k++ )
			{
				if( vertIslands[k] == j )
				{
					minS = Min( minS, verts[k * 8 + 3] );
					maxS = Max( maxS, verts[k * 8 + 3] );
					minT = Min( minT, verts[k * 8 + 4] );
					maxT = Max( maxT, verts[k * 8 + 4] );
				}
			}
			const float averageS = idMath::Ftoi( ( minS + maxS ) * 0.5f );
			const float averageT = idMath::Ftoi( ( minT + maxT ) * 0.5f );
			for( int k = 0; k < tri->numVerts; k++ )
			{
				if( vertIslands[k] == j )
				{
					verts[k * 8 + 3] -= averageS;
					verts[k * 8 + 4] -= averageT;
				}
			}
		}
#endif
		
		R_AllocStaticTriSurfVerts( tri, tri->numVerts );
		for( int j = 0; j < tri->numVerts; j++ )
		{
			tri->verts[j].xyz[0] = verts[j * 8 + 0];
			tri->verts[j].xyz[1] = verts[j * 8 + 1];
			tri->verts[j].xyz[2] = verts[j * 8 + 2];
			tri->verts[j].SetTexCoord( verts[j * 8 + 3], verts[j * 8 + 4] );
			tri->verts[j].SetNormal( verts[j * 8 + 5], verts[j * 8 + 6], verts[j * 8 + 7] );
		}
		
		R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
		for( int j = 0; j < tri->numIndexes; j++ )
		{
			tri->indexes[j] = indexes[j];
		}
		src->ExpectTokenString( "}" );
		
		// add the completed surface to the model
		model->AddSurface( surf );
	}
	
	src->ExpectTokenString( "}" );
	
	model->FinishSurfaces();
	
	if( fileOut != NULL && model->SupportsBinaryModel() && r_binaryLoadRenderModels.GetBool() )
	{
		model->WriteBinaryModel( fileOut, &mapTimeStamp );
	}
	
	return model;
}
void FrustumCullingTask::FrustrumCull(CCamera* cam, BaseState* state)
{
	Renderer* renderer = Renderer::getInstance();

	// Points of the AABB in world space
	std::vector<Vector3> verts(8);
	Vector3 origin, scaledHalfVec, rotatedX, rotatedY, rotatedZ;
	Quaternion rot;

  std::vector<CRenderer*>* deferredQueue;
  std::vector<CRenderer*>* forwardQueue;
  std::vector<CRenderer*>* diffuseQueue;
  std::vector<CRenderer*>* fontQueue;
	std::vector<CLight*>* lightQueue;

	//the only thread sensitive area should be here
	{
		ThreadUtils::ThreadLockVisitor tlv(4);
		deferredQueue = &renderer->mMapDeferredQueues[cam];
		forwardQueue = &renderer->mMapForwardQueues[cam];
		diffuseQueue = &renderer->mMapDiffuseQueues[cam];
   fontQueue = &renderer->mMapFontQueues[cam];
		lightQueue = &renderer->mMapLightQueues[cam];
	}

	const std::list<CRenderer*>* listRenderers = state->GetListOfComponentsOfType<CRenderer>();

	if (listRenderers)
	{
		// Get vertices in world space
		for (auto& iter : *listRenderers)
		{
			if (!iter->isEnabled() || !iter->mMesh.Valid())
				continue;

			origin = iter->GetMesh()->GetOrigin();
			rot = iter->gameObject->transform->GetRotationQuaternion();
			scaledHalfVec = iter->GetMesh()->GetAABB().maxPoint - origin;
			scaledHalfVec *= iter->gameObject->transform->scale;
			origin *= iter->gameObject->transform->scale;

			rotatedX = rot.RotatedVector(Vector3::cXAxis * scaledHalfVec.x);
			rotatedY = rot.RotatedVector(Vector3::cYAxis * scaledHalfVec.y);
			rotatedZ = rot.RotatedVector(Vector3::cZAxis * scaledHalfVec.z);
			rot.RotateVector(&origin);
			origin += iter->gameObject->transform->GetGlobalPosition();

			// + + +
			verts[0] = origin + rotatedX + rotatedY + rotatedZ;
			// + + -
			verts[1] = origin + rotatedX + rotatedY - rotatedZ;
			// + - +
			verts[2] = origin + rotatedX - rotatedY + rotatedZ;
			// - + +
			verts[3] = origin - rotatedX + rotatedY + rotatedZ;
			// - - +
			verts[4] = origin - rotatedX - rotatedY + rotatedZ;
			// - + -
			verts[5] = origin - rotatedX + rotatedY - rotatedZ;
			// + - -
			verts[6] = origin + rotatedX - rotatedY - rotatedZ;
			// - - -
			verts[7] = origin - rotatedX - rotatedY - rotatedZ;

			// AABB cull check
			if (cam->CullAABB(verts))
			{
        if (iter->mymeta() == CMeshRenderer::getmeta() || iter->mymeta() == CSkinMeshRenderer::getmeta())
          deferredQueue->push_back(iter);

				else if (iter->mymeta() == CForwardRenderer::getmeta())
          forwardQueue->push_back(iter);

        else if (iter->mymeta() == CDiffuseRenderer::getmeta())
          diffuseQueue->push_back(iter);

        else if (iter->mymeta() == CFontRenderer::getmeta())
          fontQueue->push_back(iter);
			}
		}
	}

	const std::list<CLight*>* listLight = state->GetListOfComponentsOfType<CLight>();
	if (listLight)
	{
		// Iterate through all Lights
		for (auto& light : *listLight)
		{
			if (!light->isEnabled())
				continue;


			if (light->mLightType == CLight::DIRECTIONAL)
			{
				lightQueue->push_back(light);
				continue;
			}

			Vector3 lightPos = light->gameObject->transform->GetGlobalPosition();

			if (cam->CullSphere(lightPos, light->GetRange()))
				lightQueue->push_back(light);
		}
  }  
}