Пример #1
0
void mango_main(){
  Geometry::Box *platform;
  BouncingBall *ball;

  platform = new Geometry::Box();
  ball = new BouncingBall();

  platform->setDimensions(1.0, 0.1, 1.0);
  ball->setRadius(0.2);

  ball->set(RENDER | STEP);
  platform->set(RENDER);
}
Пример #2
0
void drawBox(RenderingContext & rc, const Geometry::Box & box) {
	static Util::Reference<Mesh> mesh;
	if (mesh.isNull()) {
		VertexDescription vertexDescription;
		vertexDescription.appendPosition3D();
		vertexDescription.appendNormalFloat();
		const Geometry::Box unitBox(Geometry::Vec3(-0.5f, -0.5f, -0.5f), Geometry::Vec3(0.5f, 0.5f, 0.5f));
		mesh = MeshUtils::MeshBuilder::createBox(vertexDescription, unitBox);
	}

	Geometry::Matrix4x4 matrix;
	matrix.translate(box.getCenter());
	matrix.scale(box.getExtentX(), box.getExtentY(), box.getExtentZ());
	rc.pushMatrix_modelToCamera();
	rc.multMatrix_modelToCamera(matrix);
	rc.displayMesh(mesh.get());
	rc.popMatrix_modelToCamera();
}
Пример #3
0
void drawWireframeBox(RenderingContext & rc, const Geometry::Box & box) {
	static Util::Reference<Mesh> mesh;
	if (mesh.isNull()) {
		VertexDescription vertexDescription;
		vertexDescription.appendPosition3D();
		mesh = new Mesh(vertexDescription, 8, 16);
		mesh->setDataStrategy(SimpleMeshDataStrategy::getPureLocalStrategy());
		mesh->setDrawMode(Mesh::DRAW_LINE_STRIP);

		MeshIndexData & id = mesh->openIndexData();
		uint32_t * indices = id.data();
		/*
		 *  Corners:
		 *     6---------7
		 *    /|        /|
		 *   / |       / |
		 *  2---------3  |
		 *  |  |      |  |
		 *  |  4------|--5
		 *  | /       | /
		 *  |/        |/
		 *  0---------1
		 */
		indices[0] = 0;
		indices[1] = 2;
		indices[2] = 3;
		indices[3] = 1;
		indices[4] = 5;
		indices[5] = 7;
		indices[6] = 6;
		indices[7] = 4;
		indices[8] = 0;
		indices[9] = 1;
		indices[10] = 3;
		indices[11] = 7;
		indices[12] = 5;
		indices[13] = 4;
		indices[14] = 6;
		indices[15] = 2;
		id.updateIndexRange();
		id.markAsChanged();
	}

	MeshVertexData & vd = mesh->openVertexData();
	float * vertices = reinterpret_cast<float *>(vd.data());
	for (uint_fast8_t c = 0; c < 8; ++c) {
		const Geometry::Vec3 & corner = box.getCorner(static_cast<Geometry::corner_t> (c));
		*vertices++ = corner.getX();
		*vertices++ = corner.getY();
		*vertices++ = corner.getZ();
	}
	vd._setBoundingBox(box);
	vd.markAsChanged();

	rc.displayMesh(mesh.get());
}
Пример #4
0
static void describeGeometryNode(ExporterContext & /*ctxt*/,DescriptionMap & desc, Node * node) {
	desc.setString(Consts::ATTR_NODE_TYPE, Consts::NODE_TYPE_GEOMETRY);

	std::unique_ptr<DescriptionMap> dataDesc(new DescriptionMap);

	GeometryNode * gn = dynamic_cast<GeometryNode*>(node);

	// annotate with bounding box
	const Geometry::Box bb = gn->getBB();
	const Geometry::Vec3 center = bb.getCenter();
	std::stringstream s;
	s << center.getX() << " " << center.getY() << " " << center.getZ() << " " << bb.getExtentX() << " " << bb.getExtentY() << " " << bb.getExtentZ();
	dataDesc->setString(Consts::ATTR_MESH_BB, s.str());

	Rendering::Mesh * m = gn->getMesh();
	if(m!=nullptr) { // mesh present?
		// no filename -> store data in .minsg
		if(m->getFileName().empty()) {
			std::ostringstream meshStream;
			if(Rendering::Serialization::saveMesh(gn->getMesh(), "mmf", meshStream)) {
				dataDesc->setString(Consts::ATTR_DATA_TYPE,"mesh");
				dataDesc->setString(Consts::ATTR_DATA_ENCODING,"base64");
				const std::string streamString = meshStream.str();
				const std::string meshString = Util::encodeBase64(std::vector<uint8_t>(streamString.begin(), streamString.end()));
				dataDesc->setString(Consts::DATA_BLOCK,meshString);
			}
		} else { // filename given?
			Util::FileName meshFilename(m->getFileName());

//			// make path to mesh relative to scene (if mesh lies below the scene)
//			Util::FileUtils::makeRelativeIfPossible(ctxt.sceneFile, meshFilename);

			dataDesc->setString(Consts::ATTR_DATA_TYPE,"mesh");
			dataDesc->setString(Consts::ATTR_MESH_FILENAME,meshFilename.toShortString());
		}
		ExporterTools::addDataEntry(desc, std::move(dataDesc));
	}

}
Пример #5
0
void PolygonDensityEvaluator::calcPriority(Region * r)
{
	int testsPerAxis = getAttribute(Util::StringIdentifier("#Tests per axis"))->toUnsignedInt();
	Geometry::Box box = r->getBounds();

	PrioSplit px = calcPriority(Geometry::Helper::splitUpBox(box, testsPerAxis,1,1));
	PrioSplit py = calcPriority(Geometry::Helper::splitUpBox(box, 1,testsPerAxis,1));
	PrioSplit pz = calcPriority(Geometry::Helper::splitUpBox(box, 1,1,testsPerAxis));

	float volumePower = pow(box.getVolume(), getAttribute(Util::StringIdentifier("Volume Power"))->toFloat());
	px.prio *= volumePower;
	py.prio *= volumePower;
	pz.prio *= volumePower;

	float p = std::max(std::max(px.prio,py.prio),pz.prio);
	r->setAttribute(Util::StringIdentifier("PolygonDensityPrio"), GenericAttribute::createNumber<float>(p));

	float f = getAttribute(Util::StringIdentifier("Extent Power"))->toFloat();
	px.prio *= pow(box.getExtentX(),f);
	py.prio *= pow(box.getExtentY(),f);
	pz.prio *= pow(box.getExtentZ(),f);


	p = std::max(std::max(px.prio,py.prio),pz.prio);
	if(p==px.prio) {
		r->setAttribute(Util::StringIdentifier("PolygonDensitySplit"), GenericAttribute::createNumber<int>(0));
		r->setAttribute(Util::StringIdentifier("PolygonDensityRatio"), GenericAttribute::createNumber<float>(px.ratio));
	}
	else if(p==py.prio) {
		r->setAttribute(Util::StringIdentifier("PolygonDensitySplit"), GenericAttribute::createNumber<int>(1));
		r->setAttribute(Util::StringIdentifier("PolygonDensityRatio"), GenericAttribute::createNumber<float>(py.ratio));
	}
	else if(p==pz.prio) {
		r->setAttribute(Util::StringIdentifier("PolygonDensitySplit"), GenericAttribute::createNumber<int>(2));
		r->setAttribute(Util::StringIdentifier("PolygonDensityRatio"), GenericAttribute::createNumber<float>(pz.ratio));
	}
	else            FAIL();
}
Пример #6
0
float PolygonDensityEvaluator::calcDensity(const Geometry::Box & b)
{
	return countPolygons(b) / b.getVolume();
}
Пример #7
0
void BoxTest::testGetters() {
	const Geometry::Box b1(-1.0f, 1.0f, -2.0f, 2.0f, -3.0f, 3.0f);
	const Geometry::Box b2;

	CPPUNIT_ASSERT(b1.getMaxX() == 1.0f);
	CPPUNIT_ASSERT(b1.getMax(Geometry::dimension_t::X) == 1.0f);
	CPPUNIT_ASSERT(b1.getMaxY() == 2.0f);
	CPPUNIT_ASSERT(b1.getMax(Geometry::dimension_t::Y) == 2.0f);
	CPPUNIT_ASSERT(b1.getMaxZ() == 3.0f);
	CPPUNIT_ASSERT(b1.getMax(Geometry::dimension_t::Z) == 3.0f);

	CPPUNIT_ASSERT(b1.getMinX() == -1.0f);
	CPPUNIT_ASSERT(b1.getMin(Geometry::dimension_t::X) == -1.0f);
	CPPUNIT_ASSERT(b1.getMinY() == -2.0f);
	CPPUNIT_ASSERT(b1.getMin(Geometry::dimension_t::Y) == -2.0f);
	CPPUNIT_ASSERT(b1.getMinZ() == -3.0f);
	CPPUNIT_ASSERT(b1.getMin(Geometry::dimension_t::Z) == -3.0f);

	CPPUNIT_ASSERT(b1.getExtentMax() == 6.0f);
	CPPUNIT_ASSERT(b1.getExtentMin() == 2.0f);

	CPPUNIT_ASSERT(b1.getExtentX() == 2.0f);
	CPPUNIT_ASSERT(b1.getExtent(Geometry::dimension_t::X) == 2.0f);
	CPPUNIT_ASSERT(b1.getExtentY() == 4.0f);
	CPPUNIT_ASSERT(b1.getExtent(Geometry::dimension_t::Y) == 4.0f);
	CPPUNIT_ASSERT(b1.getExtentZ() == 6.0f);
	CPPUNIT_ASSERT(b1.getExtent(Geometry::dimension_t::Z) == 6.0f);

	CPPUNIT_ASSERT(b1.getVolume() == 48.0f);
	CPPUNIT_ASSERT(b1.getSurfaceArea() == 88.0f);

	CPPUNIT_ASSERT(b1.getCenter() == Geometry::Vec3(0.0f, 0.0f, 0.0f));
	CPPUNIT_ASSERT(b1.getBoundingSphereRadius() == 0.5f * std::sqrt(56.0f));
}
Пример #8
0
void BoxTest::testMisc() {
	const Geometry::Box b1(-1.0f, 1.0f, -2.0f, 2.0f, -3.0f, 3.0f);
	Geometry::Box b2;

	b2 = Geometry::Box();
	CPPUNIT_ASSERT(b2.isValid());
	b2.invalidate();
	CPPUNIT_ASSERT(b2.isInvalid());

	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::xyz) == Geometry::Vec3(b1.getMinX(), b1.getMinY(), b1.getMinZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::Xyz) == Geometry::Vec3(b1.getMaxX(), b1.getMinY(), b1.getMinZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::xYz) == Geometry::Vec3(b1.getMinX(), b1.getMaxY(), b1.getMinZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::XYz) == Geometry::Vec3(b1.getMaxX(), b1.getMaxY(), b1.getMinZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::xyZ) == Geometry::Vec3(b1.getMinX(), b1.getMinY(), b1.getMaxZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::XyZ) == Geometry::Vec3(b1.getMaxX(), b1.getMinY(), b1.getMaxZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::xYZ) == Geometry::Vec3(b1.getMinX(), b1.getMaxY(), b1.getMaxZ()));
	CPPUNIT_ASSERT(b1.getCorner(Geometry::corner_t::XYZ) == Geometry::Vec3(b1.getMaxX(), b1.getMaxY(), b1.getMaxZ()));

	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::xyz) == Geometry::corner_t::XYZ);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::Xyz) == Geometry::corner_t::xYZ);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::xYz) == Geometry::corner_t::XyZ);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::XYz) == Geometry::corner_t::xyZ);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::xyZ) == Geometry::corner_t::XYz);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::XyZ) == Geometry::corner_t::xYz);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::xYZ) == Geometry::corner_t::Xyz);
	CPPUNIT_ASSERT(Geometry::Box::getOppositeCorner(Geometry::corner_t::XYZ) == Geometry::corner_t::xyz);

	CPPUNIT_ASSERT(Geometry::Helper::getNormal(Geometry::side_t::X_NEG) == Geometry::Vec3(-1.0f, 0.0f, 0.0f));
	CPPUNIT_ASSERT(Geometry::Helper::getNormal(Geometry::side_t::X_POS) == Geometry::Vec3(1.0f, 0.0f, 0.0f));
	CPPUNIT_ASSERT(Geometry::Helper::getNormal(Geometry::side_t::Y_NEG) == Geometry::Vec3(0.0f, -1.0f, 0.0f));
	CPPUNIT_ASSERT(Geometry::Helper::getNormal(Geometry::side_t::Y_POS) == Geometry::Vec3(0.0f, 1.0f, 0.0f));
	CPPUNIT_ASSERT(Geometry::Helper::getNormal(Geometry::side_t::Z_NEG) == Geometry::Vec3(0.0f, 0.0f, -1.0f));
	CPPUNIT_ASSERT(Geometry::Helper::getNormal(Geometry::side_t::Z_POS) == Geometry::Vec3(0.0f, 0.0f, 1.0f));

	for (uint_fast8_t s = 0; s < 6; ++s) {
		const Geometry::side_t side = static_cast<const Geometry::side_t>(s);
		const Geometry::corner_t * corners = Geometry::Helper::getCornerIndices(side);
		for (uint_fast8_t i = 0; i < 4; ++i) {
			const uint_fast8_t prevCorner = i % 4;
			const uint_fast8_t currentCorner = (i + 1) % 4;
			const uint_fast8_t nextCorner = (i + 2) % 4;
			const Geometry::Vec3 edgeA = b1.getCorner(corners[nextCorner]) - b1.getCorner(corners[currentCorner]);
			const Geometry::Vec3 edgeB = b1.getCorner(corners[prevCorner]) - b1.getCorner(corners[currentCorner]);
			Geometry::Vec3 normal = edgeA.cross(edgeB);
			normal.normalize();
			CPPUNIT_ASSERT(Geometry::Helper::getNormal(side) == normal);
		}
	}

	const Geometry::Vec3 v1(-1.1f, 0.0f, 0.0f);
	const Geometry::Vec3 v2(0.0f, 0.0f, 0.0f);
	const Geometry::Vec3 v3(1.1f, 0.0f, 0.0f);
	CPPUNIT_ASSERT(!b1.contains(-1.1f, 0.0f, 0.0f));
	CPPUNIT_ASSERT(b1.contains(0.0f, 0.0f, 0.0f));
	CPPUNIT_ASSERT(!b1.contains(1.1f, 0.0f, 0.0f));
	CPPUNIT_ASSERT(!b1.contains(v1));
	CPPUNIT_ASSERT(b1.contains(v2));
	CPPUNIT_ASSERT(!b1.contains(v3));

	CPPUNIT_ASSERT(
			Geometry::Intersection::isBoxIntersectingTriangle(b1, Geometry::Triangle<Geometry::Vec3>(v1, v2, v3)));

	CPPUNIT_ASSERT(b1.contains(Geometry::Box()));
	CPPUNIT_ASSERT(b1.contains(b1));
	CPPUNIT_ASSERT(!b1.contains(Geometry::Box(-1.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)));

	CPPUNIT_ASSERT(Geometry::Intersection::isBoxIntersectingBox(Geometry::Box(0, 1, 0, 1, 0, 1),
																Geometry::Box(0, 1, 0, 1, 0, 1)));
	CPPUNIT_ASSERT(!Geometry::Intersection::isBoxIntersectingBox(Geometry::Box(0, 1, 0, 1, 0, 1),
																 Geometry::Box(2, 3, 2, 3, 2, 3)));
	CPPUNIT_ASSERT(!Geometry::Intersection::isBoxIntersectingBox(Geometry::Box(0, 1, 0, 1, 0, 1),
																 Geometry::Box(0, 3, 2, 3, 2, 3)));
	CPPUNIT_ASSERT(!Geometry::Intersection::isBoxIntersectingBox(Geometry::Box(0, 1, 0, 1, 0, 1),
																 Geometry::Box(2, 3, 0, 3, 2, 3)));
	CPPUNIT_ASSERT(!Geometry::Intersection::isBoxIntersectingBox(Geometry::Box(0, 1, 0, 1, 0, 1),
																 Geometry::Box(2, 3, 2, 3, 0, 3)));
	CPPUNIT_ASSERT(Geometry::Intersection::isBoxIntersectingBox(Geometry::Box(0, 1, 0, 1, 0, 1),
																Geometry::Box(-1, 2, -1, 2, -1, 2)));

	CPPUNIT_ASSERT(
			Geometry::Intersection::isBoxIntersectingBox(b1, Geometry::Box(-1.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)));
	CPPUNIT_ASSERT(
			!Geometry::Intersection::isBoxIntersectingBox(b1, Geometry::Box(-1.1f, -1.0f, -2.1f, -2.0f, -3.0f, -3.0f)));
	b2 = Geometry::Box(0.5f, 1.5f, 1.5f, 2.5f, 2.5f, 3.5f);
	CPPUNIT_ASSERT(Geometry::Intersection::isBoxIntersectingBox(b1, b2));
	CPPUNIT_ASSERT(Geometry::Intersection::getBoxBoxIntersection(b1, b2)
				   == Geometry::Box(0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f));

	CPPUNIT_ASSERT(b1.getDistance(Geometry::Vec3(-2.0f, 0.0f, 0.0f)) == 1.0f);
	CPPUNIT_ASSERT(b1.getDistance(Geometry::Vec3(2.0f, 0.0f, 0.0f)) == 1.0f);
	CPPUNIT_ASSERT(b1.getDistance(Geometry::Vec3(0.0f, -3.0f, 0.0f)) == 1.0f);
	CPPUNIT_ASSERT(b1.getDistance(Geometry::Vec3(0.0f, 3.0f, 0.0f)) == 1.0f);
	CPPUNIT_ASSERT(b1.getDistance(Geometry::Vec3(0.0f, 0.0f, -4.0f)) == 1.0f);
	CPPUNIT_ASSERT(b1.getDistance(Geometry::Vec3(0.0f, 0.0f, 4.0f)) == 1.0f);
	CPPUNIT_ASSERT(b1.getDistanceSquared(Geometry::Vec3(-2.0f, -3.0f, -4.0f)) == 3.0f);
	CPPUNIT_ASSERT(b1.getDistanceSquared(Geometry::Vec3(2.0f, 3.0f, 4.0f)) == 3.0f);

	// Make sure the box b1 was never changed.
	CPPUNIT_ASSERT(b1 == Geometry::Box(-1.0f, 1.0f, -2.0f, 2.0f, -3.0f, 3.0f));
}
Пример #9
0
int main(int argc, char *argv[]){
  Geometry::Box *b;
  Geometry::Sphere *s;
  Geometry::Cylinder *c;
  Geometry::Shell *sh;
  Geometry::Arrow *a[3];
  Geometry::CoordinateSystem *cs;
  Geometry::VertexArray *va;
  Geometry::Circle *ci[2];
  Geometry::NGon *n[2];
  Geometry::Rectangle *r[2];

  // Setup
  Mango::initialize();
  Mango::OnGlut::initialize(argc, argv);
		
  // Create a box and set its render event
  b = new Geometry::Box();		
  b->set(RENDER);
	
  // Create a sphere and set its render event
  s = new Geometry::Sphere();
  s->setRadius(0.7);
  s->position = Vector(2, 0, 0);
  s->set(RENDER);
	
  // Create a cylinder and set its render event
  c = new Geometry::Cylinder();
  c->position = Vector(0, 0, -2);	
  c->setHeight(1.0);
  c->setRadius(0.5);
  c->set(RENDER);	
	
  // Create a shell and set its render event		
  sh = new Geometry::Shell();		
  sh->position = Vector(2, 0, -2);
  sh->setRadius(0.7);
  sh->setFraction(0.6);
  sh->setThickness(0.05);
  sh->setOrientation(-25, 205, 0);
  sh->set(RENDER);
	
  // Create a few arrows
  a[0] = new Geometry::Arrow();
  a[0]->position = Vector(-2, -0.5, -2);
  a[0]->set(RENDER);
	
  a[1] = new Geometry::Arrow();
  a[1]->position = Vector(-1.6, -0.5, -2);
  a[1]->setLength(0.4);
  a[1]->setBlueComponent(0.8);
  a[1]->set(RENDER);
	
  a[2] = new Geometry::Arrow();
  a[2]->position = Vector(-1.8, -0.5, -1.6);
  a[2]->setLength(1.75);
  a[2]->setThickness(0.3);
  a[2]->setRedComponent(0.6);
  a[2]->set(RENDER);
	
  // Create a coordinate system
  cs = new Geometry::CoordinateSystem();
  cs->position = Vector(2, -0.3, 1.6);
  cs->setAxisLength(0.8);
  cs->setAxisThickness(0.1);
  cs->setRightHanded(1);
  cs->set(RENDER);
	
  // Create a vertex array
  va = new Geometry::VertexArray();	
  va->add(-0.5, 0.0, 0.0);
  va->add(0.0, 0.5, 0.0);
  va->add(0.0, 1.5, 0.0);
	
  va->add(0.0, 0.5, 0.0);
  va->add(0.5, 0.0, 0.0);
  va->add(0.0, 1.5, 0.0);							
	
  va->setRenderReverseOrientation(true);
  va->setStyle(GL_TRIANGLES);
  va->position = Vector(0, -0.5, 2);
  va->set(RENDER);	
	
  // Create circles 
  ci[0] = new Geometry::Circle();
  ci[0]->position = Vector(-2.0, 0, 2.0);
  ci[0]->setRadius(0.7);		
  ci[0]->setGreenComponent(0.9);
  ci[0]->set(RENDER);	
	
  ci[1] = new Geometry::Circle();
  ci[1]->position = Vector(-2.0, 0, 2.0);
  ci[1]->setRadius(0.2);
  ci[1]->setStyle(FILL);
  ci[1]->setOrientation(0, 90, 0);
  ci[1]->setRenderReverseOrientation(true);
  ci[1]->set(RENDER);
	
  // Create ngons
  n[0] = new Geometry::NGon();
  n[0]->position = Vector(-2.0, 0, 0);
  n[0]->setRadius(0.3);
  n[0]->setStyle(FILL);
  n[0]->setNumberOfSides(6);
  n[0]->setRenderReverseOrientation(true);
  n[0]->set(RENDER);
	
  n[1] = new Geometry::NGon();
  n[1]->position = Vector(-2.0, 0, 0);
  n[1]->setOrientation(0, 90, 0);
  n[1]->set(RENDER);
	
  // Create rectangles
  r[0] = new Geometry::Rectangle();
  r[0]->position = Vector(-4.0, 0, 0);
  r[0]->setOrientation(0, 45, 0);
  r[0]->set(RENDER);
	
  r[1] = new Geometry::Rectangle();
  r[1]->position = Vector(-4.0, 0, 0);
  r[1]->setOrientation(0, 135, 0);
  r[1]->setDimensions(0.5, 0.5/1.1618);
  r[1]->setStyle(FILL);
  r[1]->set(RENDER);
	
  // Start the main loop
  Mango::OnGlut::start();
	
  // Teardown
  Mango::finalize();
}
Пример #10
0
void drawFastAbsBox(RenderingContext & rc, const Geometry::Box & b){
	#ifdef LIB_GL
	rc.pushAndSetShader(nullptr);

//  Too slow:
//	rc.pushMatrix_modelToCamera();
//	rc.resetMatrix();
//	rc.applyChanges();

	glPushMatrix();
	glLoadTransposeMatrixf( rc.getMatrix_worldToCamera().getData());

	static const unsigned int indices[]={
		1,3,2,0,
		5,7,3,1,
		4,6,7,5,
		0,2,6,4,
		7,6,2,3,
		4,5,1,0
	};
	float corners[8][3] = {{b.getMaxX(), b.getMaxY(), b.getMaxZ()},
					{b.getMinX(), b.getMaxY(), b.getMaxZ()},
					{b.getMaxX(), b.getMinY(), b.getMaxZ()},
					{b.getMinX(), b.getMinY(), b.getMaxZ()},
					{b.getMaxX(), b.getMaxY(), b.getMinZ()},
					{b.getMinX(), b.getMaxY(), b.getMinZ()},
					{b.getMaxX(), b.getMinY(), b.getMinZ()},
					{b.getMinX(), b.getMinY(), b.getMinZ()}};

	glBegin(GL_QUADS);
	for(auto & index : indices){
		glVertex3fv(corners[index]);
	}
	glEnd();

	glPopMatrix();
//	rc.popMatrix_modelToCamera();
	rc.popShader();
	#else
	drawAbsBox(rc,b);
	#endif
}
Пример #11
0
//! ---|> [State]
State::stateResult_t CHCRenderer::doEnableState(FrameContext & context,Node * rootNode, const RenderParam & rp){
	if(rp.getFlag(SKIP_RENDERER))
		return State::STATE_SKIPPED;
	if(debugShowVisible){
		std::deque<Node *> nodes;
		{
			const auto children = getChildNodes(rootNode);
			nodes.insert(nodes.end(), children.begin(), children.end());
		}
		while(!nodes.empty()){
			Node& node = *nodes.front();
			nodes.pop_front();
			auto& nodeInfo = getNodeInfo(node);
			if(nodeInfo.frameNr == frameNr && nodeInfo.visible){
				if(node.isClosed())
					context.displayNode(&node,rp);
				else {
					const auto children = getChildNodes(&node);
					nodes.insert(nodes.end(), children.begin(), children.end());
				}
			}
		}
	}else{
		++frameNr;
		
		// used for statistics
		unsigned int stat_numTests = 0;
		unsigned int stat_numTestsInvisible = 0;
		unsigned int stat_numTestsVisible = 0;
		Statistics & statistics = context.getStatistics();

		RenderParam childParam = rp + USE_WORLD_MATRIX;

		const auto& camera = *context.getCamera();
		const Geometry::Vec3 camPos = camera.getWorldOrigin();
		const float bbEnlargement = camera.getNearPlane();
		NodeDistancePriorityQueue_F2B distanceQueue(camPos);
		std::queue<std::pair<Rendering::OcclusionQuery, Node*>> queryQueue;

		const auto traverseNode = [&](Node& node){
			if( node.isClosed() ){ // leaf node
				context.displayNode(&node, childParam );
			}else{
				for(auto & child : getChildNodes(&node))
					distanceQueue.push(child);
			}
		};
		const auto pullUpVisibility = [&](Node& node){
			for(Node* n=&node; n&&n!=rootNode; n = n->getParent()){
				auto& nodeInfo = getNodeInfo(*n);
				if(nodeInfo.frameNr == frameNr && nodeInfo.visible)
					break;
				nodeInfo.visible = true;
				nodeInfo.frameNr = frameNr;
				
			};
		};
		const auto startQuery = [&](Node& node,const Geometry::Box& worldBoundingBox){
			Rendering::OcclusionQuery query;
			Rendering::OcclusionQuery::enableTestMode(context.getRenderingContext());
			query.begin();
			Rendering::drawAbsBox(context.getRenderingContext(), worldBoundingBox );
			query.end();
			Rendering::OcclusionQuery::disableTestMode(context.getRenderingContext());
			return std::make_pair(std::move(query),&node);
		};
		
		traverseNode(*rootNode);
		while(!distanceQueue.empty() || !queryQueue.empty()){
				
			// ---- PART 1: process finished occlusion queries
			while( !queryQueue.empty() && (distanceQueue.empty() || queryQueue.front().first.isResultAvailable()) ){
				if( queryQueue.front().first.getResult()>0 ){
					++stat_numTestsVisible;
					statistics.pushEvent( Statistics::EVENT_TYPE_END_TEST_VISIBLE, 1);

					Node& node = *queryQueue.front().second;
					pullUpVisibility(node);
					auto& nodeInfo = getNodeInfo( node );
					if( !nodeInfo.wasVisible )
						traverseNode(node);
				}else{
					++stat_numTestsInvisible;
					statistics.pushEvent( Statistics::EVENT_TYPE_END_TEST_INVISIBLE, 1);
				}
				queryQueue.pop();
			}
			
			// ---- PART 2: tree traversal
			if( !distanceQueue.empty() ){
				Node& node = *distanceQueue.top();
				distanceQueue.pop();
				const Geometry::Box worldBoundingBox = node.getWorldBB();
				if (camera.testBoxFrustumIntersection( node.getWorldBB()) == Geometry::Frustum::intersection_t::OUTSIDE) {
					continue;
				}
				Geometry::Box enlargedBox = worldBoundingBox;
				enlargedBox.resizeAbs( bbEnlargement );
				if( enlargedBox.contains(camPos) ){
					pullUpVisibility(node);
					traverseNode(node);
					continue;
				}
				auto& nodeInfo = getNodeInfo( node );
				// identify previously visible nodes
				const bool wasVisible = nodeInfo.frameNr == frameNr-1 && nodeInfo.visible;
				nodeInfo.wasVisible = wasVisible;
				
				// reset node's visibility flag
				nodeInfo.visible = false;
				// update node's visited flag
				nodeInfo.frameNr = frameNr;
				
				// test leafs and previously invisible nodes
				if( node.isClosed() || !wasVisible){ // on testing front
					// start test
					++stat_numTests;
					statistics.pushEvent(Statistics::EVENT_TYPE_START_TEST, 1);
					queryQueue.push( std::move(startQuery(node,worldBoundingBox)) );
				}
				// traverse a node unless it was invisible
				if( wasVisible )
					traverseNode( node );
			}
		}

		statistics.addValue(OcclusionCullingStatistics::instance(statistics).getOccTestVisibleCounter(), stat_numTestsVisible);
		statistics.addValue(OcclusionCullingStatistics::instance(statistics).getOccTestInvisibleCounter(), stat_numTestsInvisible);
		statistics.addValue(OcclusionCullingStatistics::instance(statistics).getOccTestCounter(), stat_numTests);
	}
//			std::cout << std::endl;

	return State::STATE_SKIP_RENDERING;
}