MeshData scaleMesh(MeshData &meshData, double scaleFactor) { std::list<Triangle> *meshTriangles = &(meshData.first); //std::list<TriangleInfo> cutInfo = meshData.second; std::list<Triangle> meshTrianglesScaled; CGAL::Aff_transformation_3<Kernel> scale(CGAL::SCALING, scaleFactor); std::list<Triangle>::iterator triangleIter; for(triangleIter = meshTriangles->begin(); triangleIter != meshTriangles->end(); ++triangleIter) { //Method 1 //Triangle t = *triangleIter; //Triangle tScaled(scale(t.vertex(0)), scale(t.vertex(1)), scale(t.vertex(2)) ); //meshTrianglesScaled.push_back(tScaled); //Method 2 meshTrianglesScaled.push_back(triangleIter->transform(scale)); //Method 3: same memory problem of method 2 //PointCGAL v0(triangleIter->vertex(0).x()*scaleFactor, triangleIter->vertex(0).y()*scaleFactor, triangleIter->vertex(0).z()*scaleFactor ); //PointCGAL v1(triangleIter->vertex(1).x()*scaleFactor, triangleIter->vertex(1).y()*scaleFactor, triangleIter->vertex(1).z()*scaleFactor ); //PointCGAL v2(triangleIter->vertex(2).x()*scaleFactor, triangleIter->vertex(2).y()*scaleFactor, triangleIter->vertex(2).z()*scaleFactor ); //meshTrianglesScaled.push_back(Triangle(v0, v1, v2)); } //return MeshData(meshTrianglesScaled, cutInfo); return MeshData(meshTrianglesScaled, meshData.second); }
void CreateWaterMesh(unsigned int size, Vector3f scle, Mesh& outM) { Vector3f offset(size * -0.5f, size * -0.5f, 0.0f); Array2D<float> terrainHeight(size, size, 0.0f); //Just create a flat terrain and let it do the math. Terrain terr(Vector2u(size, size)); terr.SetHeightmap(terrainHeight); std::vector<WaterVertex> verts; std::vector<unsigned int> indices; terr.GenerateTrianglesFull<WaterVertex>(verts, indices, [](WaterVertex& v) { return &v.Pos; }, [](WaterVertex& v) { return &v.TexCoord; }); //Convert the terrain vertices into water vertices. for (unsigned int i = 0; i < verts.size(); ++i) { verts[i].Pos = verts[i].Pos.ComponentProduct(scle) + offset; } //Upload the mesh data into vertex/index buffers. outM.SubMeshes.push_back(MeshData(false, PT_TRIANGLE_LIST)); MeshData& mDat = outM.SubMeshes[0]; mDat.SetVertexData(verts, MeshData::BUF_STATIC, WaterVertex::GetVertexAttributes()); mDat.SetIndexData(indices, MeshData::BUF_STATIC); }
MeshData ModelLoader::loadMesh(unsigned int index, unsigned int numVertices, unsigned int numIndices, const aiMesh* mesh) { MeshData data = MeshData(); if(mesh->mName.length > 0) data.name = string(mesh->mName.C_Str()); else data.name = "mesh_" + to_string(index); data.numIndices = mesh->mNumFaces * 3; data.baseVertex = numVertices; data.baseIndex = numIndices; prepareVertexContainers(mesh); return data; }
MeshData translateMesh(MeshData &meshData, PointCGAL point) { std::list<Triangle> *meshTriangles = &(meshData.first); //std::list<TriangleInfo> cutInfo = meshData.second; std::list<Triangle> meshTrianglesTranslated; CGAL::Aff_transformation_3<Kernel> translate(CGAL::TRANSLATION, Vector(point.x(), point.y(), point.z())); std::list<Triangle>::iterator triangleIter; for(triangleIter = meshTriangles->begin(); triangleIter != meshTriangles->end(); ++triangleIter) { //Method 1 //Triangle t = *triangleIter; //Triangle tTranslated(translate(t.vertex(0)), translate(t.vertex(1)), translate(t.vertex(2)) ); //meshTrianglesTranslated.push_back(tTranslated); //Method 2 meshTrianglesTranslated.push_back(triangleIter->transform(translate)); } //return MeshData(meshTrianglesTranslated, cutInfo); return MeshData(meshTrianglesTranslated, meshData.second); }
std::list<MeshData> voronoiShatter(MeshData &meshData, std::list<KDPoint> points, bool useDelaunay, double bCriteria, double sCriteria) { CGAL::Timer timer; timer.start(); std::list<MeshData> resultMeshdata; Delaunay T(points.begin(), points.end()); std::cout << "T.number_of_vertices:" << T.number_of_vertices() << std::endl; std::cout << "T.number_of_edges:" << T.number_of_finite_edges() << std::endl; std::cout << "T.is_valid:" << T.is_valid() << std::endl; int countNumberVertices = 0; //Just to count Delaunay::Finite_vertices_iterator vit; for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) { DVertex_handle vh = vit; std::list<Triangle> cutMeshTriangles = meshData.first; std::list<TriangleInfo> cutInfo = meshData.second; std::list<DEdge> segs; T.finite_incident_edges(vh, std::back_inserter(segs)); std::cout << " (" << countNumberVertices++ << ") num edges: " << segs.size() << std::endl; std::list<DEdge>::iterator segsIter; for(segsIter=segs.begin(); segsIter!= segs.end(); ++segsIter) { DEdge edg = *segsIter; DSegment_3 segment = T.segment(edg); KDVector vect = segment.to_vector(); KDPoint p1 = segment.source(); KDPoint p2 = segment.target(); //KDPoint mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0); //Plane planeCutter_voronoi(PointCGAL(mp.x(), mp.y(), mp.z()), Vector(-vect.x(), -vect.y(), -vect.z())); //TODO: potrebbe esserci un errore a causa dei punti non esatti p1 e p2 PointCGAL mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0); Plane planeCutter_voronoi(mp, Vector(-vect.x(), -vect.y(), -vect.z())); MeshData cutData = cutMesh(cutMeshTriangles, planeCutter_voronoi, cutInfo, useDelaunay, bCriteria, sCriteria); cutMeshTriangles = cutData.first; cutInfo = cutData.second; //std::cout << " temp mesh size: " << cutMeshTriangles.size() << std::endl; //TODO: change TriangleInfo adding: // int meshId, meshIdAdjacent // and populate these new two variable for the triangles into the cut plane; // each mesh piece will have a different id; // these two new variable could be used into the RejointMeshes algorithm instead of reportAdjacentIntersectionCallback: // knowing this ids it is very easy remove the the triangles in shared cut surfaces } if (cutMeshTriangles.size() > 0) { resultMeshdata.push_back(MeshData(cutMeshTriangles, cutInfo)); } else { std::cout << " Warning: Final Voronoi mesh size empty!!" << std::endl; } } timer.stop(); std::cout << "Total voronoiShatter construction took " << timer.time() << " seconds, total cells:" << resultMeshdata.size() << std::endl; return resultMeshdata; }
void operator()( DVertex_handle vh ) const { //std::cout << "TBBVoronoiCell::operator()" << std::endl; mutexforDelaunayVoronoiTbb.lock(); //The direct assign of cutMeshTriangles = meshData->first causes a crash on multiple calls of voronoiShatter, // due to the copy of the Triangle. In order to work correctly, the Triangle are recreated //std::list<Triangle> cutMeshTriangles = meshData->first; std::list<TriangleInfo> cutInfo = meshData->second; std::list<Triangle> cutMeshTriangles; //std::list<TriangleInfo> cutInfo; std::list<Triangle>::iterator triangleIter; for(triangleIter=meshData->first.begin(); triangleIter!= meshData->first.end(); ++triangleIter) { Triangle t = *triangleIter; cutMeshTriangles.push_back(Triangle(t.vertex(0),t.vertex(1),t.vertex(2))); //See the comment above } //std::list<TriangleInfo>::iterator triangleInfoIter; //for(triangleInfoIter=meshData->second.begin(); triangleInfoIter!= meshData->second.end(); ++triangleInfoIter) //{ // TriangleInfo ti = *triangleInfoIter; // cutInfo.push_back(ti); //} std::list<DEdge> segs; T->finite_incident_edges(vh, std::back_inserter(segs)); mutexforDelaunayVoronoiTbb.unlock(); std::cout << " num edges: " << segs.size() << std::endl; std::list<DEdge>::iterator segsIter; for(segsIter=segs.begin(); segsIter!= segs.end(); ++segsIter) { DEdge edg = *segsIter; mutexforDelaunayVoronoiTbb.lock(); DSegment_3 segment = T->segment(edg); mutexforDelaunayVoronoiTbb.unlock(); KDVector vect = segment.to_vector(); KDPoint p1 = segment.source(); KDPoint p2 = segment.target(); //KDPoint mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0); //Plane planeCutter_voronoi(PointCGAL(mp.x(), mp.y(), mp.z()), Vector(-vect.x(), -vect.y(), -vect.z())); //TODO: potrebbe esserci un errore a causa dei punti non esatti p1 e p2 PointCGAL mp( (p1.x() + p2.x())/2.0, (p1.y() + p2.y())/2.0, (p1.z() + p2.z())/2.0); Plane planeCutter_voronoi(mp, Vector(-vect.x(), -vect.y(), -vect.z())); MeshData cutData = cutMesh(cutMeshTriangles, planeCutter_voronoi, cutInfo, useDelaunay, bCriteria, sCriteria); cutMeshTriangles = cutData.first; cutInfo = cutData.second; //std::cout << " temp mesh size: " << cutMeshTriangles.size() << std::endl; } mutexforDelaunayVoronoiTbb.lock(); if (cutMeshTriangles.size() > 0) { //concurrentResultMeshdata->push_back(MeshData(cutMeshTriangles, cutInfo)); resultMeshdata->push_back(MeshData(cutMeshTriangles, cutInfo)); } else { std::cout << " Warning: Final Voronoi mesh size empty!!" << std::endl; } mutexforDelaunayVoronoiTbb.unlock(); }
void PlayState::createPointCloud(bool cap) { // process depth data and create mesh.... k_depth* data; byte* color; if(cap) { data = mDevice->getRawDepth(); color = mDevice->getRawColor(); memcpy(storedColor, color, sizeof(640*480*3)); memcpy(storedDepth, data, sizeof(640*480*2)); } else { data = storedDepth; color = storedColor; } MeshData d = MeshData(); //d.addTexcoordSet(); for(int i=0;i<640*480;++i) { if(data[i] > 2046) continue; /*int x = i % 640; int y = i / 640; if(x >= 1 && x <= 638 && y <= 478 && y >= 238) { // get two adjacent points Vector3 pos1 = Kinect::getApproxPos(i+1,data[i+1]); Vector3 pos2 = Kinect::getApproxPos(i+640,data[i+640]); Vector3 center = Kinect::getApproxPos(i,data[i]); // get vectors from the center to them Vector3 d1 = pos1 - center; Vector3 d2 = pos2 - center; // get a normal Vector3 normal = d1.crossProduct(d2); normal.normalize(); normal.y = -normal.y; addVert(d,center); if(normal.angleBetween(Vector3::UNIT_Y) < 40.f) { d.diffuse.push_back(1.f); d.diffuse.push_back(0.f); d.diffuse.push_back(0.f); d.diffuse.push_back(1.f); } else { d.diffuse.push_back(color[i*3]/255.f); d.diffuse.push_back(color[i*3+1]/255.f); d.diffuse.push_back(color[i*3+2]/255.f); d.diffuse.push_back(1.f); //} } else {*/ addVert(d,Kinect::getApproxPos(i,data[i])); d.diffuse.push_back(color[i*3]/255.f); d.diffuse.push_back(color[i*3+1]/255.f); d.diffuse.push_back(color[i*3+2]/255.f); d.diffuse.push_back(1.f); //} // Alternate: make an actual polygonal mesh /*int left = data[i]; int right = data[i+1]; int d_left = data[i+640]; int d_right = data[i+641]; if(left > 2046 || right > 2046 || d_left > 2046 || d_right > 2046) continue; Vector3 l_pos = Kinect::getApproxPos(i, left); Vector3 r_pos = Kinect::getApproxPos(i+1, right); Vector3 dl_pos = Kinect::getApproxPos(i+640, d_left); Vector3 dr_pos = Kinect::getApproxPos(i+641, d_right); if(l_pos.squaredDistance(r_pos) > 0.1f || dl_pos.squaredDistance(dr_pos) > 0.1f || dl_pos.squaredDistance(r_pos) > 0.1f || dr_pos.squaredDistance(l_pos) > 0.1f) continue; // clockwise winding // tri 1 addVert(d, l_pos); addVert(d, r_pos); addVert(d, dr_pos); // tri 2 addVert(d, dr_pos); addVert(d, dl_pos); addVert(d, l_pos);*/ //for(int j = 0; j < 6; ++j) //{ /*if(floor_) { d.diffuse.push_back(1.f); d.diffuse.push_back(0.f); d.diffuse.push_back(0.f); d.diffuse.push_back(1.f); } else {*/ // d.diffuse.push_back(color[i*3]/255.f); // d.diffuse.push_back(color[i*3+1]/255.f); // d.diffuse.push_back(color[i*3+2]/255.f); // d.diffuse.push_back(1.f); //} //} } if(!mMesh) { mMesh = mOgre->createMesh(d); mOgre->getRootSceneNode()->addChild(mMesh); mMesh->setMaterialName("cloud"); } else { mMesh->update(d); } }
bool BulletContent::Initialize(std::string& err) { typedef VertexPosUV BulletVertex; RenderIOAttributes vertIns = BulletVertex::GetVertexAttributes(); #pragma region Meshes for (unsigned int i = 0; i < B_NUMBER_OF_BULLETS; ++i) { bulletMesh.SubMeshes.push_back(MeshData(false, PT_TRIANGLE_LIST)); } std::vector<BulletVertex> vertices; std::vector<unsigned int> indices; Assimp::Importer importer; unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality; for (unsigned int i = 0; i < B_NUMBER_OF_BULLETS; ++i) { //Get the file for this bullet type. std::string file = "Content/Game/Meshes/Bullets/"; switch ((Bullets)i) { case B_PUNCHER: file += "Puncher.obj"; break; case B_TERRIBLE_SHOTGUN: file += "Terrible Shotgun.obj"; break; case B_SPRAY_N_PRAY: file += "Spray and Pray.obj"; break; case B_CLUSTER: file += "Cluster.obj"; break; default: assert(false); } const aiScene* scene = importer.ReadFile(file, flags); //Make sure the scene is valid. if (scene == 0) { err = "Error loading '" + file + "': " + importer.GetErrorString(); return false; } if (scene->mNumMeshes != 1) { err = "Mesh '" + file + "' has " + std::to_string(scene->mNumMeshes) + " meshes in it"; return false; } aiMesh* mesh = scene->mMeshes[0]; //Make sure the mesh is valid. assert(mesh->HasFaces()); if (!mesh->HasPositions() || !mesh->HasTextureCoords(0)) { err = "Mesh '" + file + "' is missing positions or UVs!"; return false; } //Populate the vertex/index buffer data. vertices.resize(mesh->mNumVertices); for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { vertices[j].Pos = *(Vector3f*)(&mesh->mVertices[j].x); vertices[j].UV = *(Vector2f*)(&mesh->mTextureCoords[0][j].x); } indices.resize(mesh->mNumFaces * 3); for (unsigned int j = 0; j < mesh->mNumFaces; ++j) { aiFace& fce = mesh->mFaces[j]; if (fce.mNumIndices != 3) { err = "A face in mesh '" + file + "' has a non-tri face with " + std::to_string(fce.mNumIndices) + " indices!"; return false; } indices[(j * 3)] = fce.mIndices[0]; indices[(j * 3) + 1] = fce.mIndices[1]; indices[(j * 3) + 2] = fce.mIndices[2]; } //Create the vertex/index buffers. bulletMesh.SubMeshes[i].SetVertexData(vertices, MeshData::BUF_STATIC, vertIns); bulletMesh.SubMeshes[i].SetIndexData(indices, MeshData::BUF_STATIC); } #pragma endregion #pragma region Textures { Array2D<Vector4b> values(1, 1, Vector4b((unsigned char)255, 255, 255, 255)); defaultTex.Create(); defaultTex.SetColorData(values); } #pragma endregion #pragma region Materials { SerializedMaterial serMat; serMat.VertexInputs = vertIns; DataLine vIn_Pos(VertexInputNode::GetInstance(), 0), vIn_UV(VertexInputNode::GetInstance(), 1); DataNode::Ptr screenPos = SpaceConverterNode::ObjPosToScreenPos(vIn_Pos, "screenPos"); serMat.MaterialOuts.VertexPosOutput = DataLine(screenPos, 1); serMat.MaterialOuts.VertexOutputs.push_back(ShaderOutput("fIn_UV", vIn_UV)); DataLine fIn_UV(FragmentInputNode::GetInstance(), 0); DataNode::Ptr tex(new TextureSample2DNode(fIn_UV, UNIFORM_TEXTURE, "texSample")); DataLine texRGB(tex, TextureSample2DNode::GetOutputIndex(CO_AllColorChannels)); DataNode::Ptr colorParam(new ParamNode(3, UNIFORM_COLOR)); DataNode::Ptr finalRGB(new MultiplyNode(texRGB, colorParam, "finalRGB")); DataNode::Ptr finalColor(new CombineVectorNode(finalRGB, 1.0f, "finalColor")); serMat.MaterialOuts.FragmentOutputs.push_back(ShaderOutput("fOut_Color", finalColor)); auto genMat = ShaderGenerator::GenerateMaterial(serMat, bulletParams, BlendMode::GetOpaque()); if (!genMat.ErrorMessage.empty()) { err = "Error generating bullet material: " + genMat.ErrorMessage; return false; } bulletMat = genMat.Mat; } #pragma endregion return true; }
void D3D::Create() { // CAMERA XMStoreFloat4x4(view, XMMatrixTranspose(XMMatrixLookAtLH(XMVectorSet(0.0f, 2.0f, -2.0f, 1.0f), XMVectorSet(0.0f, -1.0f, -1.0f, 0.0f), XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f)))); XMStoreFloat4x4(projection, XMMatrixTranspose(XMMatrixPerspectiveFovLH(XM_PI * 0.45f, 640.0f / 480.0f, 1.0f, 1000.0f))); projection->_11 = projection->_22 / (windowWidth / windowHeight); viewMatrix = CreateConstantBuffer(sizeof(XMFLOAT4X4), view); projectionMatrix = CreateConstantBuffer(sizeof(XMFLOAT4X4), projection); // Load bin file std::ifstream infile; infile.open("C:/New folder/pCube1.bin", std::ifstream::binary); if (infile.is_open() == true) { // Main header MainHeader mainHeader; infile.read((char*)&mainHeader, sizeof(MainHeader)); // Mesh header vector<SubMesh> submesh; infile.read((char*)&mesh.header, sizeof(MeshHeader)); // Mesh data mesh.geometry.points.resize(mesh.header.numberPoints); mesh.geometry.normals.resize(mesh.header.numberNormals); mesh.geometry.texCoords.resize(mesh.header.numberCoords); infile.read((char*)mesh.Name.data(), mesh.header.nameLength); infile.read((char*)mesh.geometry.points.data(), mesh.header.numberPoints * sizeof(Point)); infile.read((char*)mesh.geometry.normals.data(), mesh.header.numberNormals * sizeof(Normal)); infile.read((char*)mesh.geometry.texCoords.data(), mesh.header.numberCoords * sizeof(TexCoord)); submesh.resize(mainHeader.meshCount); mesh.geometry.faces.resize(mesh.header.numberFaces); for (size_t i = 0; i < mesh.header.numberFaces; i++) { for (size_t j = 0; j < 3; j++) { infile.read((char*)&mesh.geometry.faces[i].verts[j].pointID, 4); infile.read((char*)&mesh.geometry.faces[i].verts[j].normalID, 4); infile.read((char*)&mesh.geometry.faces[i].verts[j].texCoordID, 4); } } for (size_t i = 0; i < mainHeader.meshCount; i++) { // Mesh header infile.read((char*)&submesh[i].header, sizeof(MeshHeader)); // Mesh data mesh.subMeshes[i].geometry.points.resize(submesh[i].header.numberPoints); mesh.subMeshes[i].geometry.normals.resize(submesh[i].header.numberNormals); mesh.subMeshes[i].geometry.texCoords.resize(submesh[i].header.numberCoords); infile.read((char*)mesh.subMeshes[i].Name.data(), submesh[i].header.nameLength); infile.read((char*)mesh.subMeshes[i].geometry.points.data(), submesh[i].header.numberPoints * sizeof(Point)); infile.read((char*)mesh.subMeshes[i].geometry.normals.data(), submesh[i].header.numberNormals * sizeof(Normal)); infile.read((char*)mesh.subMeshes[i].geometry.texCoords.data(), submesh[i].header.numberCoords * sizeof(TexCoord)); mesh.geometry.faces.resize(submesh[i].header.numberFaces); for (size_t j = 0; j < submesh[i].header.numberFaces; j++) { for (size_t k = 0; k < 3; k++) { infile.read((char*)&submesh[i].geometry.faces[j].verts[k].pointID, 4); infile.read((char*)&submesh[i].geometry.faces[j].verts[k].normalID, 4); infile.read((char*)&submesh[i].geometry.faces[j].verts[k].texCoordID, 4); } } } MatHeader matHeader; infile.read((char*)&matHeader, sizeof(MatHeader)); infile.read((char*)&mesh.material.diffColor, 16); infile.read((char*)mesh.material.diffuseTexture.data(), matHeader.diffuseNameLength); // Crash here on reading of string. infile.read((char*)&mesh.material.specColor, 16); infile.read((char*)mesh.material.specularTexture.data(), matHeader.specularNameLength); // TEST TO PUT THE OBJERCT TOGHETER meshes.push_back(MeshData()); meshes.back().pos.resize(mesh.header.numberFaces * 3); meshes.back().normal.resize(mesh.header.numberFaces * 3); meshes.back().uv.resize(mesh.header.numberFaces * 3); size_t index = 0; for (size_t i = 0; i < mesh.header.numberFaces; i++) { for (size_t j = 0; j < 3; j++) { meshes.back().pos[index].x = mesh.geometry.points[mesh.geometry.faces[i].verts[j].pointID].x; meshes.back().pos[index].y = mesh.geometry.points[mesh.geometry.faces[i].verts[j].pointID].y; meshes.back().pos[index].z = mesh.geometry.points[mesh.geometry.faces[i].verts[j].pointID].z; meshes.back().normal[index] = mesh.geometry.normals[mesh.geometry.faces[i].verts[j].normalID]; meshes.back().uv[index] = mesh.geometry.texCoords[mesh.geometry.faces[i].verts[j].texCoordID]; index++; } } // Vertices meshes.back().meshesBuffer[0] = CreateMesh(sizeof(XMFLOAT3) * meshes.back().pos.size(), meshes.back().pos.data(), meshes.back().pos.size()); meshes.back().meshesBuffer[1] = CreateMesh(sizeof(XMFLOAT3) * meshes.back().normal.size(), meshes.back().normal.data(), meshes.back().normal.size()); meshes.back().meshesBuffer[2] = CreateMesh(sizeof(XMFLOAT2) * meshes.back().uv.size(), meshes.back().uv.data(), meshes.back().uv.size()); // Transform DirectX::XMStoreFloat4x4(&meshes.back().transform, XMMatrixIdentity()); meshes.back().transformBuffer = CreateConstantBuffer(sizeof(XMFLOAT4X4), &meshes.back().transform); // Texture CreateTexture(0); } infile.close(); }
const TSharedPtr<sMeshData> FMeshFactory::BuildMeshFromChunkB(FChunk& Chunk) { // Create a new mesh dataset TSharedPtr<sMeshData> MeshData(new sMeshData); // Loop through every block in this section and create a mesh on all sides that are visible for (int32 Z = 0; Z < 128; Z++) for (int32 Y = 0; Y < 16; Y++) for (int32 X = 0; X < 16; X++) { // Goto the next block, when the current one is not visible if (Chunk.GetBlockIDAt(X, Y, Z) == 0) continue; // The block we currently looking at sBlock Block; // Check the sides for visibility // Top if (Z == 127) Block.Top = true; else Block.Top = Chunk.GetBlockIDAt(X, Y, Z + 1) == 0 ? true : false; // Bottom if (Z == 0) Block.Bottom = false; else Block.Bottom = Chunk.GetBlockIDAt(X, Y, Z - 1) == 0 ? true : false; // Front if (X == 15) Block.Front = true; else Block.Front = Chunk.GetBlockIDAt(X + 1, Y, Z) == 0 ? true : false; // Back if (X == 0) Block.Back = true; else Block.Back = Chunk.GetBlockIDAt(X - 1, Y, Z) == 0 ? true : false; // Right side if (Y == 15) Block.RightSide = true; else Block.RightSide = Chunk.GetBlockIDAt(X, Y + 1, Z) == 0 ? true : false; // Left side if (Y == 0) Block.LeftSide = true; else Block.LeftSide = Chunk.GetBlockIDAt(X, Y - 1, Z) == 0 ? true : false; /*Block.Top = true; Block.Bottom = true; Block.Front = true; Block.Back = true; Block.LeftSide = true; Block.RightSide = true;*/ // If all sides are not visible (the block is surrounded by other blocks) don't draw anything //if (!Block.Top && !Block.Bottom && !Block.Front && !Block.Back && !Block.RightSide && !Block.LeftSide) //break; //if ((Block.Top + Block.Bottom + Block.Front + Block.Back + Block.RightSide + Block.LeftSide) == 0) //break; // The desired dimensions of the blocks float BlockDim = 50.0f; // Calculate the world positions for all verts Block.Vert[0] = FVector(X * BlockDim, Y * BlockDim, Z * BlockDim); Block.Vert[1] = FVector(X * BlockDim, (Y + 1) * BlockDim, Z * BlockDim); Block.Vert[2] = FVector((X + 1) * BlockDim, (Y + 1) * BlockDim, Z * BlockDim); Block.Vert[3] = FVector((X + 1) * BlockDim, Y * BlockDim, Z * BlockDim); Block.Vert[4] = FVector(X * BlockDim, Y * BlockDim, (Z + 1) * BlockDim); Block.Vert[5] = FVector(X * BlockDim, (Y + 1) *BlockDim, (Z + 1) * BlockDim); Block.Vert[6] = FVector((X + 1) * BlockDim, (Y + 1) * BlockDim, (Z + 1) * BlockDim); Block.Vert[7] = FVector((X + 1) * BlockDim, Y * BlockDim, (Z + 1) * BlockDim); // The first vertex we added for this side uint32 FirstVert = 0; if (Block.Top) { FirstVert = MeshData->Vertices.Add(Block.Vert[4]); MeshData->Vertices.Add(Block.Vert[5]); MeshData->Vertices.Add(Block.Vert[6]); MeshData->Vertices.Add(Block.Vert[7]); // First Triangle MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 2); // Second Triangle MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 3); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::UpVector); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.Bottom) { FirstVert = MeshData->Vertices.Add(Block.Vert[0]); MeshData->Vertices.Add(Block.Vert[1]); MeshData->Vertices.Add(Block.Vert[2]); MeshData->Vertices.Add(Block.Vert[3]); // First Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 0); // Second Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::UpVector * -1.0f); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.Front) { FirstVert = MeshData->Vertices.Add(Block.Vert[2]); MeshData->Vertices.Add(Block.Vert[3]); MeshData->Vertices.Add(Block.Vert[6]); MeshData->Vertices.Add(Block.Vert[7]); // First Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); // Second Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::ForwardVector); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.Back) { FirstVert = MeshData->Vertices.Add(Block.Vert[0]); MeshData->Vertices.Add(Block.Vert[1]); MeshData->Vertices.Add(Block.Vert[4]); MeshData->Vertices.Add(Block.Vert[5]); // First Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); // Second Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::ForwardVector * -1.0f); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.RightSide) { FirstVert = MeshData->Vertices.Add(Block.Vert[1]); MeshData->Vertices.Add(Block.Vert[2]); MeshData->Vertices.Add(Block.Vert[5]); MeshData->Vertices.Add(Block.Vert[6]); // First Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); // Second Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::RightVector); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.LeftSide) { FirstVert = MeshData->Vertices.Add(Block.Vert[0]); MeshData->Vertices.Add(Block.Vert[3]); MeshData->Vertices.Add(Block.Vert[4]); MeshData->Vertices.Add(Block.Vert[7]); // First Triangle MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 3); // Second Triangle MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 2); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::RightVector * -1.0f); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } } return MeshData; }
const TSharedPtr<sMeshData> FMeshFactory::BuildMeshFromChunkA(FChunk& Chunk) { // Create a new mesh dataset TSharedPtr<sMeshData> MeshData(new sMeshData); int32 callCount = 0; for (uint32 Section = 0; Section < 1/*Chunk.GetNumSections()*/; Section++) { // Used for caching the section we need to look in in order to check blocks for visibility FChunkSection* TargetSection = Chunk.GetSection(Section); // Loop through every block in this section and create a mesh on all sides that are visible for (int32 Z = 0; Z < 16; Z++) for (int32 Y = 0; Y < 16; Y++) for (int32 X = 0; X < 16; X++) { //UE_LOG(LogTemp, Warning, TEXT("Call Nr %d"), callCount); //callCount ++; // Goto the next block, when the current one is not visible if (TargetSection->GetBlockIDAt(X, Y, Z) == 0) { //callCount++;//2047 break; } // The block we currently looking at sBlock Block; // Check the sides for visibility // Top if (Z == 15 && Section < Chunk.GetNumSections() - 1) Block.Top = Chunk.GetSection(Section + 1)->GetBlockIDAt(X, Y, 0) == 0 ? true : false; else if (Z == 15 && Section == Chunk.GetNumSections() - 1) Block.Top = true; else Block.Top = TargetSection->GetBlockIDAt(X, Y, Z + 1) == 0 ? true : false; // Bottom if (Z == 0 && Section != 0) Block.Bottom = Chunk.GetSection(Section - 1)->GetBlockIDAt(X, Y, 15) == 0 ? true : false; else if (Z == 0 && Section == 0) Block.Bottom = false; else Block.Bottom = TargetSection->GetBlockIDAt(X, Y, Z - 1) == 0 ? true : false; // Front if (X == 15) Block.Front = true; else Block.Front = TargetSection->GetBlockIDAt(X + 1, Y, Z) == 0 ? true : false; // Back if (X == 0) Block.Back = true; else Block.Back = TargetSection->GetBlockIDAt(X - 1, Y, Z) == 0 ? true : false; // Right side if (Y == 15) Block.RightSide = true; else Block.RightSide = TargetSection->GetBlockIDAt(X, Y + 1, Z) == 0 ? true : false; // Left side if (Y == 0) Block.LeftSide = true; else Block.LeftSide = TargetSection->GetBlockIDAt(X, Y - 1, Z) == 0 ? true : false; // The first vertex we added for this side uint32 FirstVert = 0; /*Block.Top = true; Block.Bottom = true; Block.Front = true; Block.Back = true; Block.LeftSide = true; Block.RightSide = true;*/ // If all sides are not visible (the block is surrounded by other blocks) don't draw anything if (!Block.Top && !Block.Bottom && !Block.Front && !Block.Back && !Block.RightSide && !Block.LeftSide) break; // Calculate the world positions for all verts Block.Vert[0] = FVector(X * 25.0f, Y * 25.0f, Z * 25.0f + (Section * 25.0f * 16)); Block.Vert[1] = FVector(X * 25.0f, (Y + 1) * 25.0f, Z * 25.0f + (Section * 25.0f * 16)); Block.Vert[2] = FVector((X + 1) * 25.0f, (Y + 1) * 25.0f, Z * 25.0f + (Section * 25.0f * 16)); Block.Vert[3] = FVector((X + 1) * 25.0f, Y * 25.0f, Z * 25.0f + (Section * 25.0f * 16)); Block.Vert[4] = FVector(X * 25.0f, Y * 25.0f, (Z + 1) * 25.0f + (Section * 25.0f * 16)); Block.Vert[5] = FVector(X * 25.0f, (Y + 1) *25.0f, (Z + 1) * 25.0f + (Section * 25.0f * 16)); Block.Vert[6] = FVector((X + 1) * 25.0f, (Y + 1) * 25.0f, (Z + 1) * 25.0f + (Section * 25.0f * 16)); Block.Vert[7] = FVector((X + 1) * 25.0f, Y * 25.0f, (Z + 1) * 25.0f + (Section * 25.0f * 16)); if (Block.Top) { FirstVert = MeshData->Vertices.Add(Block.Vert[4]); MeshData->Vertices.Add(Block.Vert[5]); MeshData->Vertices.Add(Block.Vert[6]); MeshData->Vertices.Add(Block.Vert[7]); // First Triangle MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 2); // Second Triangle MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 3); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::UpVector); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.Bottom) { FirstVert = MeshData->Vertices.Add(Block.Vert[0]); MeshData->Vertices.Add(Block.Vert[1]); MeshData->Vertices.Add(Block.Vert[2]); MeshData->Vertices.Add(Block.Vert[3]); // First Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 0); // Second Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::UpVector * -1.0f); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.Front) { FirstVert = MeshData->Vertices.Add(Block.Vert[2]); MeshData->Vertices.Add(Block.Vert[3]); MeshData->Vertices.Add(Block.Vert[6]); MeshData->Vertices.Add(Block.Vert[7]); // First Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); // Second Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::ForwardVector); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.Back) { FirstVert = MeshData->Vertices.Add(Block.Vert[0]); MeshData->Vertices.Add(Block.Vert[1]); MeshData->Vertices.Add(Block.Vert[4]); MeshData->Vertices.Add(Block.Vert[5]); // First Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); // Second Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::ForwardVector * -1.0f); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.RightSide) { FirstVert = MeshData->Vertices.Add(Block.Vert[1]); MeshData->Vertices.Add(Block.Vert[2]); MeshData->Vertices.Add(Block.Vert[5]); MeshData->Vertices.Add(Block.Vert[6]); // First Triangle MeshData->Triangles.Add(FirstVert + 3); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 1); // Second Triangle MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 1); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::RightVector); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } if (Block.LeftSide) { FirstVert = MeshData->Vertices.Add(Block.Vert[0]); MeshData->Vertices.Add(Block.Vert[3]); MeshData->Vertices.Add(Block.Vert[4]); MeshData->Vertices.Add(Block.Vert[7]); // First Triangle MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 2); MeshData->Triangles.Add(FirstVert + 3); // Second Triangle MeshData->Triangles.Add(FirstVert + 1); MeshData->Triangles.Add(FirstVert + 0); MeshData->Triangles.Add(FirstVert + 2); for (int32 Normal = 0; Normal < 4; Normal++) MeshData->Normals.Add(FVector::RightVector * -1.0f); for (int32 UV = 0; UV < 4; UV++) MeshData->UVs.Add(FVector2D(0, 0)); } } } return MeshData; }