static void AddFracturedPrimitive(DemoEntityManager* const scene, dFloat mass, const dVector& origin, const dVector& size, int xCount, int zCount, dFloat spacing, PrimitiveType type, int materialID, const dMatrix& shapeOffsetMatrix)
	{
		// create the shape and visual mesh as a common data to be re used
		NewtonWorld* const world = scene->GetNewton();
		NewtonCollision* const collision = CreateConvexCollision(world, shapeOffsetMatrix, size, type, materialID);

		// create a newton mesh from the collision primitive
		NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision);

		// apply a material map
		int externalMaterial = LoadTexture("reljef.tga");
		//int internalMaterial = LoadTexture("KAMEN-stup.tga");
		int internalMaterial = LoadTexture("concreteBrick.tga");

		dMatrix aligmentUV(dGetIdentityMatrix());
		NewtonMeshApplyBoxMapping(mesh, externalMaterial, externalMaterial, externalMaterial, &aligmentUV[0][0]);

		// create a newton mesh from the collision primitive
		VoronoidEffect fracture(world, mesh, internalMaterial);

		DemoMesh* const visualMesh = new DemoMesh(mesh);

		dFloat startElevation = 100.0f;
		dMatrix matrix(dGetIdentityMatrix());
		for (int i = 0; i < xCount; i++) {
			dFloat x = origin.m_x + (i - xCount / 2) * spacing;
			for (int j = 0; j < zCount; j++) {
				dFloat z = origin.m_z + (j - zCount / 2) * spacing;

				matrix.m_posit.m_x = x;
				matrix.m_posit.m_z = z;
				dVector floor(FindFloor(world, dVector(matrix.m_posit.m_x, startElevation, matrix.m_posit.m_z, 0.0f), 2.0f * startElevation));
				matrix.m_posit.m_y = floor.m_y + 1.0f;
				SimpleFracturedEffectEntity::AddFracturedEntity(scene, visualMesh, collision, fracture, matrix.m_posit);
			}
		}

		// do not forget to release the assets	
		NewtonMeshDestroy(mesh);
		visualMesh->Release();
		NewtonDestroyCollision(collision);
	}
Esempio n. 2
0
int main(int argc, char **argv) {

    /*
        We choose to handle simple command line input
    */

    int num_threads(0), box_length(0);

    try {

        if (argc == 5) {

            if (strcmp(argv[1], "-np") == 0 && 
                strcmp(argv[3], "-bl") == 0) {

                sscanf(argv[2], "%d", &num_threads);
                sscanf(argv[4], "%d", &box_length);
            } else
                throw std::runtime_error("Incorrect arugments");
        } else
            throw std::runtime_error("Incorrect number of arguments");

    } catch(std::runtime_error &error) {

        std::cout << error.what() << std::endl;
          std::cout << "Use the form :: ./regulus -np X -bl Y \n";
        return -1;
    }

    /*
        ... And we then build a point set to triangulate...
    */

    unsigned long int num_points = std::pow(box_length, 3);
    std::vector<mesh> meshes;

    {

        std::vector<point> tmp_point_buff;
        tmp_point_buff.reserve(num_points);

        write_sorted_set(tmp_point_buff, num_points, box_length);

        auto m = num_points % num_threads;
        auto ppp = (num_points - m) / num_threads; 

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

            unsigned long int num_per_tetra = 0;

            if (i != num_threads - 1)
                num_per_tetra = ppp;
            else
                num_per_tetra = ppp + m;

            meshes.emplace_back(num_per_tetra);

            /*
                Allocate root points
            */

            auto tl = 3 * (box_length - 1);

            meshes[i].p_buffer.emplace_back(0, 0, 0);
            meshes[i].p_buffer.emplace_back(tl, 0, 0);
            meshes[i].p_buffer.emplace_back(0, tl, 0);
            meshes[i].p_buffer.emplace_back(0, 0, tl);

            meshes[i].p_position += 4;

            /*
                Allocate root tetrahedron
            */

            new(meshes[i].t_position) tetra(&meshes[i].p_buffer[0],
                                            &meshes[i].p_buffer[1],
                                            &meshes[i].p_buffer[2],
                                            &meshes[i].p_buffer[3]);

            meshes[i].m_position = meshes[i].t_position;
            ++meshes[i].t_position;

            /*
                Copy partitioned points
            */

            for (unsigned long int j = 0; j < num_per_tetra; ++j) {

                auto &cpy = tmp_point_buff[i*ppp + j];
                meshes[i].p_buffer.emplace_back(cpy.x, cpy.y, cpy.z);
            }

            if (verbose >= 3) {

                std::cout << "\nthread : " << i << std::endl;

                for (auto it = meshes[i].p_buffer.begin(); it < meshes[i].p_buffer.end(); ++it)
                    std::cout << *it << std::endl;
            }

            std::cout << std::endl;
        }
    }    

    /*
        This is the crux of regulus
        
        We begin the triangulation
    */

    double start_time = get_wall_time();

    std::vector<std::thread> threads;

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

        threads.emplace_back([&meshes, i](void)->void {

            std::vector<std::pair<tetra*, unsigned int>> leaves;
            leaves.reserve(512);

            std::vector<tetra*> pile;
            pile.reserve(2048);

            point *p = meshes[i].p_buffer.data();

            for (unsigned long int j = 5; j < meshes[i].p_buffer.size(); ++j) {

                if (verbose >= 1)
                    std::cout << "\niterative index : " << j - 4 << std::endl;

                walk(leaves, p + j, meshes[i].m_position, &*(meshes[i].t_buffer.begin()));
                fracture(meshes[i], leaves, pile, p + j);
                delaunay(meshes[i], pile);

                leaves.clear();
                pile.clear();
            }
        });
    }

    for (auto &t : threads)
        t.join();

    unsigned long int tot_num_tetra = 0;

    for (auto &m : meshes)
        tot_num_tetra += m.num_tetra;

    double end_time = get_wall_time();

    std::cout << "\nTotal number of tetrahedra triangulated : " << tot_num_tetra << std::endl;
    std::cout<< "\nTriangulated " << num_points << " points in " << end_time - start_time << " seconds" << std::endl;
    std::cout << num_points / ((end_time - start_time) * num_threads) << " points per second per thread" << std::endl;

    return 0;
}