Beispiel #1
0
int main () {
    std::cout << "Basic EmbeddedTime testing" << std::endl;
    std::cout << std::endl;

    std::cout << "Testing constructors..." << std::endl;
    Time _t1;
    Time _t2(1, 23, 30, 300);    
    Time _t2bis(0, 23, 30, 300);    
    Time _t3(1, 23, 30, 300, 500);     
    Time _t4("01:23:30:300");    
    Time _t5(_t3);
    std::cout << std::endl;

    std::cout << "Testing operators..." << std::endl;
    std::cout << (_t2 - _t2bis) << std::endl;
    std::cout << (_t2 + _t2bis) << std::endl;
    _t1 = _t4;
    std::cout << _t1 << std::endl;
    std::cout << (_t4 == _t2) << std::endl;
    std::cout << (_t4 != _t2) << std::endl;
    std::cout << (_t2 < _t2bis) << std::endl;
    std::cout << std::endl;

    std::ifstream input_stream("input.ev");
    Time t;
    int a;

    input_stream >> t >> a;
    assert(t.hours() == 1);
    assert(t.minutes() == 59);
    assert(t.seconds() == 59);
    assert(t.mseconds() == 37);
    assert(a = 42);
    while (input_stream >> t >> a) {
        std::cout << "reading line" << std::endl;
        assert(t.hours() == 2);
        assert(t.minutes() == 42);
        assert(t.seconds() == 42);
        assert(t.mseconds() == 42);
        assert(a = 42);
    }
    

    std::cout << "Testing realtime..." << std::endl;
    Time::initializeTimer();
    Time t1 = Time::currentTime();
    sleep(1);
    Time t2 = Time::currentTime();
    sleep(1);
    Time t3 = Time::currentTime();
    std::cout << "Current time and difference with the previous" << std::endl;
    std::cout << t1 << std::endl;
    std::cout << t2 << ": " << (t2 - t1) << std::endl;
    std::cout << t3 << ": " << (t3 - t2) << std::endl;

    return 0;
}
	ECBody& ECScene::loadHeightMap(
	      std::string FilePath,
	      const chrono::ChVector<>& Scale) {
		Ogre::TexturePtr l_tex = Ogre::TextureManager::getSingleton().load(FilePath, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

		if (l_tex->getFormat() != Ogre::PF_L16 && l_tex->getFormat() != Ogre::PF_L8) {
			l_tex->unload();
			l_tex = Ogre::TextureManager::getSingleton().load(FilePath, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, -1, 1.0f, false, Ogre::PF_L8);
		}

		Ogre::HardwarePixelBufferSharedPtr l_pixels = l_tex->getBuffer();
		size_t l_byte_size = l_pixels->getSizeInBytes();
		Ogre::PixelFormat l_format = l_tex->getFormat();

		assert(l_format == Ogre::PF_L16 || l_format == Ogre::PF_L8); // Garuntee grayscale

		size_t l_vertex_count = l_pixels->getHeight() * l_pixels->getWidth();
		std::vector<Ogre::Real> l_vertex_heights;
		Ogre::PixelBox l_temp_pixel_buffer(l_tex->getWidth(), l_tex->getHeight(), l_tex->getDepth(), l_format);
		void* l_pPixels = nullptr;
		bool catfish = l_tex->isLoaded();

		
		l_pPixels = new unsigned char[l_byte_size];


		//l_pixels->lock(l_temp_pixel_buffer, Ogre::HardwareBuffer::HBL_NORMAL);

		//Ogre::PixelBox const &pixel_box = l_pixels->getCurrentLock();
		//l_pixels->blitToMemory(pixel_box);
		//l_pixels->unlock();
		//l_pPixels = pixel_box.data;

		

		memcpy(l_pPixels, l_pixels->lock(Ogre::HardwareBuffer::HBL_NORMAL), l_byte_size);

		double l_height_w = l_format == Ogre::PF_L16 ? (double)USHRT_MAX : (double)UCHAR_MAX;

		for (unsigned int i = 0; i < l_vertex_count; i++) { // Fill vector with normalized heights
			if (l_format == Ogre::PF_L8) {
				l_vertex_heights.push_back( (Ogre::Real) ( ( (double)( (unsigned char*)l_pPixels )[i] ) / l_height_w ) );
			}
			else {
				l_vertex_heights.push_back( (Ogre::Real) ( ( (double)( (unsigned short*)l_pPixels )[i] ) / l_height_w ) );
			}
		}

		delete[] l_pPixels;

		std::vector<Ogre::Vector3> l_vertices;
		l_vertices.resize(l_vertex_count);

		typedef struct {
			unsigned int a;
			unsigned int b;
			unsigned int c;
		} triangle_index_set;

		std::vector<triangle_index_set> l_indices;
		unsigned int l_square_width = l_pixels->getWidth() - 1;
		unsigned int l_square_height = l_pixels->getHeight() - 1;
		unsigned int l_square_count = l_square_width * l_square_height;
		l_indices.resize(l_square_count * 2);

		std::vector<Ogre::Vector3> l_triangle_normals;
		l_triangle_normals.resize(l_square_count * 2);

		std::vector<Ogre::Vector3> l_vertex_normals;
		l_vertex_normals.resize(l_vertex_count);

		for (unsigned int i = 0; i < l_vertex_count; i++) { // Fill vertices

			unsigned int l_w = (i % l_pixels->getWidth());
			unsigned int l_h = (i / l_pixels->getWidth());

			Ogre::Real l_wa = (Ogre::Real)l_w - (Ogre::Real)(l_pixels->getWidth()) / 2.0;
			Ogre::Real l_ha = (Ogre::Real)l_h - (Ogre::Real)(l_pixels->getHeight()) / 2.0;

			l_vertices[i] = Ogre::Vector3(l_wa, std::abs(l_vertex_heights[i]), l_ha);
		}

		for (unsigned int i = 0; i < l_square_count * 2; i += 2) { // Fill indices
			unsigned int l_triangle_width = l_square_width * 2;
			unsigned int l_iteration_y_position = i / l_triangle_width;
			unsigned int l_triangle_to_pixel = (i + (2 * l_iteration_y_position)) / 2;

			l_indices[i + 0].a = l_triangle_to_pixel;
			l_indices[i + 0].b = l_triangle_to_pixel + l_pixels->getWidth();
			l_indices[i + 0].c = l_triangle_to_pixel + 1;
			l_indices[i + 1].a = l_triangle_to_pixel + 1;
			l_indices[i + 1].b = l_triangle_to_pixel + l_pixels->getWidth();
			l_indices[i + 1].c = l_triangle_to_pixel + l_pixels->getWidth() + 1;
		}

		for (unsigned int i = 0; i < l_triangle_normals.size(); i++) { // Calculate normals of all triangles
			Ogre::Vector3 _t1(l_vertices[l_indices[i].a]);
			Ogre::Vector3 _t2(l_vertices[l_indices[i].b]);
			Ogre::Vector3 _t3(l_vertices[l_indices[i].c]);
			Ogre::Vector3 _ret = (_t1 - _t2).crossProduct(_t1 - _t3);
			_ret.normalise();
			l_triangle_normals[i] = _ret;
		}

		//!!!!
		//	This algorithm takes ungodly long single-threaded in larger heightmaps.
		//!!!!
		{ // Calculate normals of all vertices
			typedef struct __thread_set_t {
				size_t _start;
				size_t _end;
				std::thread _thread;
			} __thread_set;

			size_t _thread_count = std::thread::hardware_concurrency();

			std::function<void(size_t, size_t)> _worker_thread = [&](size_t start, size_t end) {
				Ogre::Vector3 _ret(0, 0, 0);
				for (unsigned int i = start; i < end; i++) {
					for (unsigned int j = 0; j < l_indices.size(); j++) {
						if (l_indices[j].a == i || l_indices[j].b == i || l_indices[j].c == i) {
							_ret = _ret + l_triangle_normals[j];
						}
					}
					_ret.normalise();
					l_vertex_normals[i] = _ret;
				}
			};

			std::vector<__thread_set*> threads;

			for (unsigned int i = 0; i < _thread_count; i++) {
				__thread_set* pthread = new __thread_set;

				if (i == 0) {
					pthread->_start = 0;
					pthread->_end = l_vertex_count / _thread_count;
				}
				else {
					pthread->_start = threads[i - 1]->_end + 1;
					pthread->_end = (l_vertex_count / _thread_count) * (i + 1);
				}

				if (i == _thread_count) {
					pthread->_end = l_vertex_count;
				}

				pthread->_thread = std::thread(_worker_thread, pthread->_start, pthread->_end);
				threads.push_back(pthread);
			}

			for (unsigned int i = 0; i < threads.size(); i++) {
				threads[i]->_thread.join();
				delete threads[i];
				threads[i] = nullptr;
			}

		}

		/*for (unsigned int i = 0; i < l_vertex_normals.size(); i++) {
			Ogre::Vector3 _ret(0, 0, 0);
			for (unsigned int j = 0; j < l_indices.size(); j++) {
				if (l_indices[j].a == i || l_indices[j].b == i || l_indices[j].c == i) {
					_ret = _ret + l_triangle_normals[j];
				}
			}
			_ret.normalise();
			l_vertex_normals[i] = _ret;
		}*/

		Ogre::ManualObject* terrain_object = m_pSceneManager->createManualObject("");

		terrain_object->begin("lambert1", Ogre::RenderOperation::OT_TRIANGLE_LIST);

		for (unsigned int i = 0; i < l_vertex_count; i++) {
			Ogre::Real _x = (Ogre::Real)(i % l_tex->getWidth());
			Ogre::Real _y = (Ogre::Real)(i / l_tex->getWidth());

			terrain_object->position(l_vertices[i]);
			terrain_object->normal(l_vertex_normals[i]);
			terrain_object->colour(Ogre::ColourValue(0.5, 0.5, 0.5));
			terrain_object->textureCoord(_x/(Ogre::Real)l_tex->getWidth(), _y/(Ogre::Real)l_tex->getHeight());
		}

		for (unsigned int i = 0; i < l_indices.size(); i++) {
			terrain_object->index(l_indices[i].a);
			terrain_object->index(l_indices[i].b);
			terrain_object->index(l_indices[i].c);
		}

		terrain_object->end();

		//terrain_object->getSection(0)->getMaterial()->getTechnique(0)->getPass(0)->createTextureUnitState("white.png");
		//terrain_object->getSection(0)->getMaterial()->getTechnique(0)->getPass(0)->setLightingEnabled(true);

		ECBody& _ret = createBody();

		_ret.setMesh(terrain_object, Scale);

		chrono::geometry::ChTriangleMeshConnected l_triangle_mesh;

		for (unsigned int i = 0; i < l_indices.size(); i++) {
			l_triangle_mesh.addTriangle(
				chrono::ChVector<>(									// Vertex 0
				(double)l_vertices[l_indices[i].a].x,					// Index a.x
				(double)l_vertices[l_indices[i].a].y,					// Index a.y
				(double)l_vertices[l_indices[i].a].z					// Index a.z
				) * Scale,
				chrono::ChVector<>(									// Vertex 1
				(double)l_vertices[l_indices[i].b].x,					// Index b.x
				(double)l_vertices[l_indices[i].b].y,					// Index b.y
				(double)l_vertices[l_indices[i].b].z					// Index b.z
				) * Scale,
				chrono::ChVector<>(									// Vertex 2
				(double)l_vertices[l_indices[i].c].x,					// Index c.x
				(double)l_vertices[l_indices[i].c].y,					// Index c.y
				(double)l_vertices[l_indices[i].c].z					// Index c.z
				) * Scale
				);
		}

		_ret->GetCollisionModel()->ClearModel();
		_ret->GetCollisionModel()->AddTriangleMesh(l_triangle_mesh, true, false, chrono::ChVector<>(), chrono::QUNIT);
		_ret->GetCollisionModel()->BuildModel();
		_ret->SetCollide(true);
		_ret->SetBodyFixed(true);

		return _ret;
	}