std::shared_ptr<Model<Vertex3DNormTex>> ModelLoader::load(const std::string &filePath, float scale, bool deleteLocalData) { std::ifstream f(filePath); if (f.fail()) { std::ostringstream oStringStream; oStringStream << "couldn't open " << filePath << std::endl; log(oStringStream.str()); return std::shared_ptr<Model<Vertex3DNormTex>>(); } else { f.close(); } const aiScene *scene = importer.ReadFile(filePath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality); if (scene == nullptr) { log(importer.GetErrorString()); } std::map<std::string, std::shared_ptr<Texture>> textures(loadTextures(scene, filePath)); std::vector<std::shared_ptr<Material>> materials(loadMaterials(scene, textures)); const aiNode *rootNode = scene->mRootNode; std::shared_ptr<Model<Vertex3DNormTex>> output(std::make_shared<Model<Vertex3DNormTex>>()); addMeshesFromNode(scene, rootNode, glm::scale(glm::mat4(), glm::vec3(scale)), output, materials, scale, deleteLocalData); return output; }
/* ======================================================================================================================= ======================================================================================================================= */ void CDialogTextures::addMaterials( bool rootItems ) { idStrList textures(1024); idStrList materials(1024); textures.SetGranularity( 1024 ); materials.SetGranularity( 1024 ); int count = declManager->GetNumDecls( DECL_MATERIAL ); if ( count > 0 ) { for ( int i = 0; i < count; i++ ) { const idMaterial *mat = declManager->MaterialByIndex( i, false ); if ( !rootItems ) { if ( strchr( mat->GetName(), '/' ) == NULL && strchr( mat->GetName(), '\\' ) == NULL ) { continue; } } // add everything except the textures/ materials if ( idStr::Icmpn( mat->GetName(), "textures/", 9 ) == 0 ) { textures.Append( mat->GetName() ); } else { materials.Append( mat->GetName() ); } } idStrListSortPaths( textures ); addStrList( TypeNames[TEXTURES], textures, TEXTURES ); idStrListSortPaths( materials ); addStrList( TypeNames[MATERIALS], materials, MATERIALS ); } }
_Use_decl_annotations_ StaticLevelData* AssetLoader::LoadStaticLevel(const char* filename) const { char source[MAX_PATH]; sprintf_s(source, "%s%s", GetConfig().ContentRoot, filename); // TODO: Replace this with real level data file GeometryFileData data; LoadGeometryFileData(source, &data); uint32_t numMaterials = data.NumMaterials; std::unique_ptr<MaterialSource[]> materials(new MaterialSource[numMaterials]); MaterialSource* material = materials.get(); for (uint32_t i = 0; i < numMaterials; ++i, ++material) { strcpy_s(material->Diffuse, data.MaterialTextures[i]); } StaticLevelData* level = new StaticLevelData(GetGraphics().GetContext(), reinterpret_cast<StaticGeometryVertex*>(data.Vertices), data.NumVertices, data.Indices, data.NumIndices, materials, numMaterials, 256 * 1024 * 1024); FreeGeometryFileData(&data); return level; }
bool Assembly::on_frame_begin( const Project& project, #ifdef WITH_OSL OSL::ShadingSystem& shading_system, #endif AbortSwitch* abort_switch) { bool success = true; success = success && invoke_on_frame_begin(project, texture_instances(), abort_switch); success = success && invoke_on_frame_begin(project, *this, surface_shaders(), abort_switch); success = success && invoke_on_frame_begin(project, *this, bsdfs(), abort_switch); success = success && invoke_on_frame_begin(project, *this, edfs(), abort_switch); #ifdef WITH_OSL success = success && invoke_on_frame_begin(project, *this, shading_system, shader_groups(), abort_switch); #endif success = success && invoke_on_frame_begin(project, *this, materials(), abort_switch); success = success && invoke_on_frame_begin(project, *this, lights(), abort_switch); success = success && invoke_on_frame_begin(project, *this, object_instances(), abort_switch); #ifdef WITH_OSL success = success && invoke_on_frame_begin(project, assemblies(), shading_system, abort_switch); #else success = success && invoke_on_frame_begin(project, assemblies(), abort_switch); #endif success = success && invoke_on_frame_begin(project, assembly_instances(), abort_switch); return success; }
bool Assembly::on_render_begin( const Project& project, const BaseGroup* parent, OnRenderBeginRecorder& recorder, IAbortSwitch* abort_switch) { if (!Entity::on_render_begin(project, parent, recorder, abort_switch)) return false; if (!BaseGroup::on_render_begin(project, parent, recorder, abort_switch)) return false; bool success = true; success = success && invoke_on_render_begin(bsdfs(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(bssrdfs(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(edfs(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(surface_shaders(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(materials(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(lights(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(objects(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(object_instances(), project, this, recorder, abort_switch); success = success && invoke_on_render_begin(volumes(), project, this, recorder, abort_switch); return success; }
void write() { Abc::OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), "MaterialNetworkNodes.abc" ); Abc::OObject root(archive, Abc::kTop); //make a dummy enclosing object Abc::OObject materials(root, "materials"); Mat::OMaterial matObj(materials, "material1"); matObj.getSchema().addNetworkNode("mainshader", "abc", "blinn"); matObj.getSchema().addNetworkNode("colormap", "abc", "texture_read"); matObj.getSchema().setNetworkNodeConnection("mainshader", "Cs", "colormap", "color_out"); { Abc::OFloatProperty prop( matObj.getSchema().getNetworkNodeParameters("mainshader"), "Kd"); prop.set(0.5); } { Abc::OStringProperty prop( matObj.getSchema().getNetworkNodeParameters("colormap"), "map_name"); prop.set("/tmp/original.tx"); } matObj.getSchema().setNetworkTerminal( "abc", "surface", "mainshader", "out"); matObj.getSchema().setNetworkInterfaceParameterMapping( "ColorMapName", "colormap", "map_name"); { Abc::OStringProperty prop( matObj.getSchema().getNetworkInterfaceParameters(), "ColorMapName"); prop.set("/from/public.tx"); } }
void Assembly::on_frame_end(const Project& project) { invoke_on_frame_end(project, assembly_instances()); invoke_on_frame_end(project, assemblies()); invoke_on_frame_end(project, *this, lights()); invoke_on_frame_end(project, *this, materials()); invoke_on_frame_end(project, *this, edfs()); invoke_on_frame_end(project, *this, bsdfs()); invoke_on_frame_end(project, *this, surface_shaders()); }
void write() { Abc::OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), "FlattenMaterial.abc" ); Abc::OObject root(archive, Abc::kTop); //make a dummy enclosing object Abc::OObject materials(root, "materials"); Mat::OMaterial parentMaterial(materials, "parentMaterial"); parentMaterial.getSchema().setShader("prman", "surface", "paintedplastic"); parentMaterial.getSchema().setShader("prman", "displacement", "knobby"); { Abc::OFloatProperty prop( parentMaterial.getSchema().getShaderParameters( "prman", "surface"), "Kd"); prop.set(0.5); } { Abc::OStringProperty prop( parentMaterial.getSchema().getShaderParameters( "prman", "surface"), "texname"); prop.set("taco"); } { Abc::OFloatProperty prop( parentMaterial.getSchema().getShaderParameters( "prman", "displacement"), "height"); prop.set(0.75); } Mat::OMaterial childMaterial(parentMaterial, "childMaterial"); childMaterial.getSchema().setShader("prman", "surface", "betterpaintedplastic"); { Abc::OStringProperty prop( childMaterial.getSchema().getShaderParameters( "prman", "surface"), "texname"); prop.set("cheese"); } }
void Assembly::collect_asset_paths(StringArray& paths) const { BaseGroup::collect_asset_paths(paths); invoke_collect_asset_paths(bsdfs(), paths); invoke_collect_asset_paths(bssrdfs(), paths); invoke_collect_asset_paths(edfs(), paths); invoke_collect_asset_paths(surface_shaders(), paths); invoke_collect_asset_paths(materials(), paths); invoke_collect_asset_paths(lights(), paths); invoke_collect_asset_paths(objects(), paths); invoke_collect_asset_paths(object_instances(), paths); invoke_collect_asset_paths(volumes(), paths); }
void Assembly::update_asset_paths(const StringDictionary& mappings) { BaseGroup::update_asset_paths(mappings); invoke_update_asset_paths(bsdfs(), mappings); invoke_update_asset_paths(bssrdfs(), mappings); invoke_update_asset_paths(edfs(), mappings); invoke_update_asset_paths(surface_shaders(), mappings); invoke_update_asset_paths(materials(), mappings); invoke_update_asset_paths(lights(), mappings); invoke_update_asset_paths(objects(), mappings); invoke_update_asset_paths(object_instances(), mappings); invoke_update_asset_paths(volumes(), mappings); }
bool Assembly::on_frame_begin(const Project& project) { bool success = true; success = success && invoke_on_frame_begin(project, *this, surface_shaders()); success = success && invoke_on_frame_begin(project, *this, bsdfs()); success = success && invoke_on_frame_begin(project, *this, edfs()); success = success && invoke_on_frame_begin(project, *this, materials()); success = success && invoke_on_frame_begin(project, *this, lights()); success = success && invoke_on_frame_begin(project, assemblies()); success = success && invoke_on_frame_begin(project, assembly_instances()); return success; }
void Assembly::on_frame_end(const Project& project) { invoke_on_frame_end(project, assembly_instances()); invoke_on_frame_end(project, assemblies()); invoke_on_frame_end(project, object_instances()); invoke_on_frame_end(project, *this, lights()); invoke_on_frame_end(project, *this, materials()); #ifdef WITH_OSL invoke_on_frame_end(project, *this, shader_groups()); #endif invoke_on_frame_end(project, *this, edfs()); invoke_on_frame_end(project, *this, bsdfs()); invoke_on_frame_end(project, *this, surface_shaders()); invoke_on_frame_end(project, texture_instances()); }
/*Draws the outside shark shape of the shark, with the option to show its skeleton instead =* */ void Shark::drawSkin(int frame) { //float startSeg = mesh.lengthMax, endSeg = mesh.lengthMax, length = 0; //GLfloat rotate; //glPushMatrix(); /*if(showSkin) { materials(Grey); //kfSys.draw(); } else {*/ materials(White); skeleton.draw(); //} //glPopMatrix(); }
bool RadFileData::writeRadFile(std::string file) { std::ofstream oFile; oFile.open(file); if (!oFile.is_open()) { STADIC_LOG(Severity::Error, "The opening of the rad file named " + file + " has failed."); } // Write a header oFile << "## Radiance geometry file \"" + file + "\"" << std::endl; // It would be nice to write out more detail about what is going on here. A minimum would be // to write the date, time and the version of the library. We could also include the // filenames of any files that were added with addRad (but we'd need to start storing that). shared_vector<RadPrimitive> primitives=materials(); size_t count = primitives.size(); if(count > 0) { oFile << "## Materials" << std::endl; for(auto ptr : primitives) { oFile << ptr->toRad() << std::endl; } } primitives=geometry(); count += primitives.size(); if(primitives.size() > 0) { oFile << "## Geometry" << std::endl; for(auto ptr : primitives) { oFile << ptr->toRad() << std::endl; } } if(count != m_Primitives.size()) { STADIC_LOG(Severity::Warning, "Only materials and geometry were written to " + file + ", " + toString(m_Primitives.size() - count) + " primitives were not written out"); } oFile << "## End of Radiance geometry file \"" + file + "\"" << std::endl; return true; }
void write() { Abc::OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), "MaterialAssignment.abc" ); Abc::OObject root(archive, Abc::kTop); Abc::OObject materials(root, "materials"); Abc::OObject geometry(root, "geometry"); //parent material Mat::OMaterial materialA(materials, "materialA"); materialA.getSchema().setShader("prman", "surface", "paintedplastic"); setFloatParameter(materialA.getSchema(), "prman", "surface", "Kd", 0.5); setFloatParameter(materialA.getSchema(), "prman", "surface", "roughness", 0.1); //child material Mat::OMaterial materialB(materialA, "materialB"); materialB.getSchema().setShader("prman", "displacement", "knobby"); setFloatParameter(materialB.getSchema(), "prman", "surface", "roughness", 0.2); Abc::OObject geoA(geometry, "geoA"); Mat::addMaterialAssignment(geoA, "/materials/materialA"); Abc::OObject geoB(geometry, "geoB"); Mat::addMaterialAssignment(geoB, "/materials/materialA/materialB"); Abc::OObject geoC(geometry, "geoC"); Mat::addMaterialAssignment(geoC, "/materials/materialA/materialB"); Mat::OMaterialSchema geoCMat = Mat::addMaterial(geoC); setFloatParameter(geoCMat, "prman", "surface", "roughness", 0.3); }
bool Assembly::on_frame_begin( const Project& project, const BaseGroup* parent, OnFrameBeginRecorder& recorder, IAbortSwitch* abort_switch) { if (!Entity::on_frame_begin(project, parent, recorder, abort_switch)) return false; if (!BaseGroup::on_frame_begin(project, parent, recorder, abort_switch)) return false; bool success = true; success = success && invoke_on_frame_begin(bsdfs(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(bssrdfs(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(edfs(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(surface_shaders(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(materials(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(lights(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(objects(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(object_instances(), project, this, recorder, abort_switch); success = success && invoke_on_frame_begin(volumes(), project, this, recorder, abort_switch); if (!success) return false; // Collect procedural object instances. assert(!m_has_render_data); for (size_t i = 0, e = object_instances().size(); i < e; ++i) { const ObjectInstance* object_instance = object_instances().get_by_index(i); const Object& object = object_instance->get_object(); if (dynamic_cast<const ProceduralObject*>(&object) != nullptr) m_render_data.m_procedural_object_instances.push_back(make_pair(object_instance, i)); } m_has_render_data = true; return true; }
void GeometryGather::changeMaterial(const String& material, const ParameterArray& materialOverrideParameters) { currentQueue_ = nullptr; if (materialOverrideParameters.empty()) { // Try and find an existing queue that uses the specified material, the current priority, and has no custom // parameters for (auto& q : materialQueueInfos_) { if (q.queue->getPriority() == currentPriority_ && q.material == material && !q.queue->hasCustomParams() && !q.queue->getInternalParams().size()) { currentQueue_ = &q; currentQueue_->isTransformCurrent = false; return; } } } // No existing material queue can be used, so create a new one newMaterial(&materials().getMaterial(material), materialOverrideParameters); }
dgCollisionDeformableMesh::dgCollisionDeformableMesh(dgWorld* const world, dgMeshEffect* const mesh, dgCollisionID collsionID) :dgCollisionConvex (mesh->GetAllocator(), 0, collsionID) ,m_particles (mesh->GetVertexCount ()) ,m_visualSegments(mesh->GetAllocator()) ,m_skinThickness(DG_DEFORMABLE_DEFAULT_SKIN_THICKNESS) ,m_nodesCount(0) ,m_trianglesCount(0) ,m_visualVertexCount(0) ,m_world (world) ,m_myBody(NULL) ,m_indexList(NULL) ,m_faceNormals(NULL) ,m_rootNode(NULL) ,m_nodesMemory(NULL) ,m_visualVertexData(NULL) ,m_onDebugDisplay(NULL) ,m_isdoubleSided(false) { m_rtti |= dgCollisionDeformableMesh_RTTI; dgDeformableBodiesUpdate& softBodyList = *m_world; softBodyList.AddShape (this); dgMeshEffect meshCopy (*mesh); meshCopy.Triangulate(); m_trianglesCount = meshCopy.GetTotalFaceCount (); m_nodesMemory = (dgDeformableNode*) dgMallocStack((m_trianglesCount * 2 - 1) * sizeof (dgDeformableNode)); m_indexList = (dgInt32*) dgMallocStack (3 * m_trianglesCount * sizeof (dgInt32)); m_faceNormals = (dgVector*) dgMallocStack (m_trianglesCount * sizeof (dgVector)); dgInt32 stride = meshCopy.GetVertexStrideInByte() / sizeof (dgFloat64); dgFloat64* const vertex = meshCopy.GetVertexPool(); for (dgInt32 i = 0; i < m_particles.m_count; i ++) { m_particles.m_unitMass[i] = dgFloat32 (1.0f); m_particles.m_veloc[i] = dgVector (dgFloat32 (0.0f)); m_particles.m_posit[i] = dgVector (&vertex[i * stride]) & dgVector::m_triplexMask; } dgInt32 indexCount = meshCopy.GetTotalIndexCount (); dgStack<dgInt32> faceArray (m_trianglesCount); dgStack<dgInt32> materials (m_trianglesCount); dgStack<void*>indexArray (indexCount); meshCopy.GetFaces (&faceArray[0], &materials[0], &indexArray[0]); for (dgInt32 i = 0; i < m_trianglesCount; i ++) { dgInt32 count = faceArray[i]; dgAssert (faceArray[i]); for (dgInt32 j = 0; j < count; j ++) { dgInt32 k = meshCopy.GetVertexIndex(indexArray[i * 3 + j]); m_indexList[i * 3 + j] = k; } //dgTrace (("%d %d %d\n", m_indexList[i * 3 + 0], m_indexList[i * 3 + 1], m_indexList[i * 3 + 2])); dgDeformableNode& node = m_nodesMemory[i]; node.m_left = NULL; node.m_right = NULL; node.m_parent = NULL; node.m_indexStart = i * 3; node.CalculateBox(m_particles.m_posit, &m_indexList[i * 3]); } m_nodesCount = m_trianglesCount; m_rootNode = BuildTopDown (m_nodesCount, m_nodesMemory, NULL); ImproveTotalFitness(); SetCollisionBBox (m_rootNode->m_minBox, m_rootNode->m_maxBox); // create visual vertex data m_visualVertexCount = meshCopy.GetPropertiesCount(); m_visualVertexData = (dgVisualVertexData*) dgMallocStack(m_visualVertexCount * sizeof (dgVisualVertexData)); for (dgInt32 i = 0; i < m_visualVertexCount; i ++) { dgMeshEffect::dgVertexAtribute& attribute = meshCopy.GetAttribute (i); m_visualVertexData[i].m_uv0[0] = dgFloat32 (attribute.m_u0); m_visualVertexData[i].m_uv0[1] = dgFloat32 (attribute.m_v0); } for (void* point = meshCopy.GetFirstPoint(); point; point = meshCopy.GetNextPoint(point)) { dgInt32 pointIndex = meshCopy.GetPointIndex (point); dgInt32 vertexIndex = meshCopy.GetVertexIndexFromPoint (point); m_visualVertexData[pointIndex].m_vertexIndex = vertexIndex; } for (dgInt32 i = 0; i < m_trianglesCount; i ++) { dgInt32 mat = materials[i]; if (mat != -1) { dgInt32 count = 0; for (dgInt32 j = i; j < m_trianglesCount; j ++) { dgInt32 mat1 = materials[j]; if (mat == mat1) { materials[j] = -1; count ++; } } dgMeshSegment& segment = m_visualSegments.Append()->GetInfo(); segment.m_material = mat; segment.m_indexCount = count * 3; segment.m_indexList = (dgInt32*) dgMallocStack( 2 * segment.m_indexCount * sizeof (dgInt32)); dgInt32 index0 = 0; dgInt32 index1 = m_trianglesCount * 3; for (dgInt32 j = i; j < m_trianglesCount; j ++) { if (materials[j] == -1) { dgInt32 m0 = meshCopy.GetPointIndex(indexArray[j * 3 + 0]); dgInt32 m1 = meshCopy.GetPointIndex(indexArray[j * 3 + 1]); dgInt32 m2 = meshCopy.GetPointIndex(indexArray[j * 3 + 2]); segment.m_indexList[index0 + 0] = dgInt16 (m0); segment.m_indexList[index0 + 1] = dgInt16 (m1); segment.m_indexList[index0 + 2] = dgInt16 (m2); index0 += 3; segment.m_indexList[index1 + 0] = dgInt16 (m0); segment.m_indexList[index1 + 1] = dgInt16 (m2); segment.m_indexList[index1 + 2] = dgInt16 (m1); index1 += 3; } } } } // SetVolumeAndCG (); }
void CBuild::BuildCForm () { // Collecting data Phase ("CFORM: creating..."); vecFace* cfFaces = new vecFace(); vecVertex* cfVertices = new vecVertex(); { xr_vector<bool> cfVertexMarks; cfVertexMarks.assign (lc_global_data()->g_vertices().size(),false); Status("Sorting..."); std::sort(lc_global_data()->g_vertices().begin(),lc_global_data()->g_vertices().end()); Status("Collecting faces..."); cfFaces->reserve (lc_global_data()->g_faces().size()); for (vecFaceIt I=lc_global_data()->g_faces().begin(); I!=lc_global_data()->g_faces().end(); ++I) { Face* F = *I; if (F->Shader().flags.bCollision) { cfFaces->push_back(F); int index = GetVertexIndex(F->v[0]); cfVertexMarks[index] = true; index = GetVertexIndex(F->v[1]); cfVertexMarks[index] = true; index = GetVertexIndex(F->v[2]); cfVertexMarks[index] = true; } } Status("Collecting vertices..."); cfVertices->reserve (lc_global_data()->g_vertices().size()); std::sort(cfFaces->begin(),cfFaces->end()); for (u32 V=0; V<lc_global_data()->g_vertices().size(); V++) if (cfVertexMarks[V]) cfVertices->push_back(lc_global_data()->g_vertices()[V]); } float p_total = 0; float p_cost = 1.f/(cfVertices->size()); Fbox BB; BB.invalidate(); for (vecVertexIt it = cfVertices->begin(); it!=cfVertices->end(); it++) BB.modify((*it)->P ); // CForm Phase ("CFORM: collision model..."); Status ("Items to process: %d", cfFaces->size()); p_total = 0; p_cost = 1.f/(cfFaces->size()); // Collect faces CDB::CollectorPacked CL (BB,cfVertices->size(),cfFaces->size()); for (vecFaceIt F = cfFaces->begin(); F!=cfFaces->end(); F++) { Face* T = *F; TestEdge (T->v[0],T->v[1],T); TestEdge (T->v[1],T->v[2],T); TestEdge (T->v[2],T->v[0],T); CL.add_face ( T->v[0]->P, T->v[1]->P, T->v[2]->P, T->dwMaterialGame, materials()[T->dwMaterial].sector, T->sm_group ); Progress(p_total+=p_cost); // progress } if (bCriticalErrCnt) { err_save (); clMsg ("MultipleEdges: %d faces",bCriticalErrCnt); } xr_delete (cfFaces); xr_delete (cfVertices); // Models Status ("Models..."); for (u32 ref=0; ref<mu_refs().size(); ref++) mu_refs()[ref]->export_cform_game(CL); // Simplification if (g_params().m_quality!=ebqDraft) SimplifyCFORM (CL); // bb? BB.invalidate (); for (size_t it = 0; it<CL.getVS(); it++) BB.modify( CL.getV()[it] ); // Saving string_path fn; IWriter* MFS = FS.w_open (strconcat(sizeof(fn),fn,pBuild->path,"level.cform")); Status ("Saving..."); // Header hdrCFORM hdr; hdr.version = CFORM_CURRENT_VERSION; hdr.vertcount = (u32)CL.getVS(); hdr.facecount = (u32)CL.getTS(); hdr.aabb = BB; MFS->w (&hdr,sizeof(hdr)); // Data MFS->w (CL.getV(),(u32)CL.getVS()*sizeof(Fvector)); MFS->w (CL.getT(),(u32)CL.getTS()*sizeof(CDB::TRI)); // Clear pDeflector (it is stored in the same memory space with dwMaterialGame) for (vecFaceIt I=lc_global_data()->g_faces().begin(); I!=lc_global_data()->g_faces().end(); I++) { Face* F = *I; F->pDeflector = NULL; } FS.w_close (MFS); }
std::shared_ptr<room_entity> create_room_entity( ID3D11Device* device, const gx::shader_database* database, std::istream& in ) { uint32_t version = 0; int8_t header[9] = {"AtiModel"}; int8_t read_header[9]; int32_t animation_type = 0; offset_table offsets = {}; thread_local_context_initializer initializer(device); concurrency::combinable<thread_local_context> ctx ( initializer ); concurrency::structured_task_group tasks; d3d11::itexture2d_ptr m_textures[7]; auto task0 = concurrency::make_task( wic_loader( device, &m_textures[0], L"media/giroom/lopal.bmp", &ctx )); auto task1 = concurrency::make_task( wic_loader( device, &m_textures[1], L"media/giroom/headpal.bmp", &ctx )); auto task2 = concurrency::make_task( dds_loader( device, &m_textures[2], L"media/giroom/picture.dds") ); auto task3 = concurrency::make_task( dds_loader( device, &m_textures[3], L"media/giroom/floor.dds") ) ; auto task4 = concurrency::make_task( dds_loader( device, &m_textures[4], L"media/giroom/globe.dds") ) ; auto task5 = concurrency::make_task( wic_loader( device, &m_textures[5], L"media/giroom/wall_lm.bmp", &ctx )); auto task6 = concurrency::make_task( dds_loader( device, &m_textures[6], L"media/giroom/ceiling_lm.dds")); tasks.run(task0); tasks.run(task1); tasks.run(task2); tasks.run(task3); tasks.run(task4); tasks.run(task5); tasks.run(task6); in.read((char*) &read_header[0], 8); if ( in.eof() ) { return nullptr; } read_header[8] = '\0'; if ( _strnicmp( (char*) &read_header[0], (char*) &header[0], 8 ) !=0 ) { return nullptr; } in.read( (char*) &animation_type, sizeof(animation_type)); in.read( (char*) &version, sizeof(version)); in.read( (char*) &offsets, sizeof(offsets) ); in.seekg(offsets.m_material_chunk, std::ios_base::beg); uint32_t material_count = 0; in.read( (char*) &material_count, sizeof(material_count) ); std::vector<material> materials( material_count ); for (uint32_t i = 0 ; i < material_count; ++i) { in.seekg(64, std::ios_base::cur); in.seekg(sizeof(float4), std::ios_base::cur); in.seekg(sizeof(float4), std::ios_base::cur); in.seekg(sizeof(float), std::ios_base::cur); in.read( (char*) &materials[i].diffuse_mp_file, 64 ); in.seekg(64, std::ios_base::cur); in.read( (char*) &materials[i].bump_map_file, 64 ); in.seekg(64, std::ios_base::cur); in.seekg(64, std::ios_base::cur); } in.seekg(offsets.m_vertex_chunk, std::ios_base::beg); uint32_t vertex_count = 0; in.read( (char*) &vertex_count, sizeof(vertex_count) ); std::vector<float3> positions( vertex_count ); std::vector<float3> normal( vertex_count ); std::vector<float3> tangent( vertex_count ); std::vector<float3> binormal( vertex_count ); std::vector<float2> uv( vertex_count ); std::vector<float4> color( vertex_count ); in.read( (char*) &positions[0], vertex_count * sizeof(float3) ); in.read( (char*) &normal[0], vertex_count * sizeof(float3) ); in.read( (char*) &tangent[0], vertex_count * sizeof(float3) ); in.read( (char*) &binormal[0], vertex_count * sizeof(float3) ); in.read( (char*) &uv[0], vertex_count * sizeof(float2) ); in.read( (char*) &color[0], vertex_count * sizeof(float4) ); size_t size = positions.size(); size_t padded_size = 24 * ( ( size + 23 ) / 24 ) ; for (uint32_t i = 0; i < padded_size - size; ++i) { float3 pad3 = {0.0f, 0.0f, 0.0f}; float2 pad2 = {0.0f, 0.0f}; float4 pad4 = {1.0f, 1.0f,1.0f,1.0f}; positions.push_back(pad3); normal.push_back(pad3); tangent.push_back(pad3); binormal.push_back(pad3); uv.push_back(pad2); color.push_back(pad4); } in.seekg(offsets.m_triangle_chunk, std::ios_base::beg); uint32_t triangle_count = 0; in.read( (char*) &triangle_count, sizeof(triangle_count) ); std::vector<triangle> triangles(triangle_count); in.read( (char*) &triangles[0], triangle_count * sizeof(triangle) ); in.seekg(offsets.m_mesh_chunk, std::ios_base::beg); uint32_t mesh_count = 0; in.read( (char*) &mesh_count, sizeof(mesh_count) ); std::vector<mesh> meshes(mesh_count); for ( uint32_t i = 0; i < mesh_count; ++i) { meshes[i].m_id = i; in.read( (char*) &meshes[i].m_name[0], 64 ); in.read( (char*) &meshes[i].m_material_index, sizeof(uint32_t) ); in.read( (char*) &meshes[i].m_base_vertex, sizeof(uint32_t) ); in.read( (char*) &meshes[i].m_vertex_count, sizeof(uint32_t) ); in.read( (char*) &meshes[i].m_base_triangle, sizeof(uint32_t) ); in.read( (char*) &meshes[i].m_triangle_count, sizeof(uint32_t) ); uint32_t bone_count = 0; in.read( (char*) &bone_count, sizeof(uint32_t) ); meshes[i].m_bones.resize(bone_count); if (bone_count > 0 ) { in.read( (char*) &meshes[i].m_bones[0], bone_count * sizeof(uint32_t) ); } in.read( (char*) &meshes[i].m_parent_id, sizeof(uint32_t) ); uint32_t child_count = 0; in.read( (char*) &child_count, sizeof(uint32_t) ); meshes[i].m_children.resize(child_count); if (child_count > 0) { in.read( (char*) &meshes[i].m_children[0], child_count * sizeof(uint32_t) ); } uint32_t primitive_count = 0; in.read( (char*) &primitive_count, sizeof(uint32_t) ); meshes[i].m_primitives.resize(primitive_count); for(uint32_t j = 0; j < primitive_count;++j) { uint32_t type = 0; in.read( (char*) &type, sizeof(uint32_t) ); switch (type) { case PL_TRIANGLE_STRIP: meshes[i].m_primitives[j].m_type = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break; case PL_TRIANGLE_LIST: default: meshes[i].m_primitives[j].m_type = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; } uint32_t indices_count = 0; in.read( (char*) &indices_count, sizeof(uint32_t) ); meshes[i].m_primitives[j].m_indices.resize(indices_count); if (indices_count > 0) { in.read( (char*) &meshes[i].m_primitives[j].m_indices[0], indices_count * sizeof(uint32_t) ); } } uint32_t position_key_count = 0; in.read( (char*) &position_key_count, sizeof(uint32_t) ); meshes[i].m_position_keys.resize(position_key_count); if (position_key_count > 0) { in.read( (char*) &meshes[i].m_position_keys[0], position_key_count * sizeof(animation_key) ); } uint32_t rotation_key_count = 0; in.read( (char*) &rotation_key_count, sizeof(uint32_t) ); meshes[i].m_rotation_keys.resize(rotation_key_count); if ( rotation_key_count > 0) { in.read( (char*) &meshes[i].m_rotation_keys[0], rotation_key_count * sizeof(animation_key) ); } uint32_t scale_key_count = 0; in.read( (char*) &scale_key_count, sizeof(uint32_t) ); meshes[i].m_scale_keys.resize(scale_key_count); if (scale_key_count > 0) { in.read( (char*) &meshes[i].m_scale_keys[0], scale_key_count * sizeof(animation_key) ); } } std::vector<math::half> positions_h( 4 * padded_size ); std::vector<math::half> normals_h( 4 * padded_size ); std::vector<math::half> uv_h( 2 * padded_size ); math::convert_3_x_f32_f16_stream( reinterpret_cast<float*> ( &positions[0]), 3 * padded_size, 1.0f, &positions_h[0]); math::convert_3_x_f32_f16_stream( reinterpret_cast<float*> ( &normal[0]), 3 * padded_size, 1.0f, &normals_h[0]); math::convert_f32_f16_stream( reinterpret_cast<float*> ( &uv[0]), 2 * padded_size, &uv_h[0]); //combine normals and uvs std::vector<math::half> normals_uv( 6 * padded_size); uint32_t j = 0; uint32_t k = 0; for ( uint32_t i = 0; i < 6 * padded_size; i+=6, j+=4, k+=2) { normals_uv[i] = normals_h[j]; normals_uv[i+1] = normals_h[j+1]; normals_uv[i+2] = normals_h[j+2]; normals_uv[i+3] = normals_h[j+3]; normals_uv[i+4] = uv_h[k]; normals_uv[i+5] = uv_h[k+1]; } uint32_t material_range[14]; std::vector<uint32_t> indices( triangle_count * 3); uint32_t index = 0; material_range[0] = 0; // Untextured materials add_to_material_range(&indices[0], index, 0, 19, 1, &meshes[0], &triangles[0], &material_range[0]); // Hand add_to_material_range(&indices[0], index, 1, 20, 1, &meshes[0], &triangles[0], &material_range[0]); // Ball add_to_material_range(&indices[0], index, 1, 23, 1, &meshes[0], &triangles[0], &material_range[0]); // Horse add_to_material_range(&indices[0], index, 1, 25, 1, &meshes[0], &triangles[0], &material_range[0]); // Sci-Fi weirdo add_to_material_range(&indices[0], index, 1, 28, 1, &meshes[0], &triangles[0], &material_range[0]); // Bench add_to_material_range(&indices[0], index, 1, 30, 1, &meshes[0], &triangles[0], &material_range[0]); // Frame add_to_material_range(&indices[0], index, 2, 24, 1, &meshes[0], &triangles[0], &material_range[0]); // Horse stand add_to_material_range(&indices[0], index, 2, 26, 1, &meshes[0], &triangles[0], &material_range[0]); // Sci-Fi weirdo stand add_to_material_range(&indices[0], index, 2, 32, 1, &meshes[0], &triangles[0], &material_range[0]); // Globe stand add_to_material_range(&indices[0], index, 3, 3, 15, &meshes[0], &triangles[0], &material_range[0]); // Ceiling, Pillars, Stands, Wall lights add_to_material_range(&indices[0], index, 4, 0, 1, &meshes[0], &triangles[0], &material_range[0]); // Walls add_to_material_range(&indices[0], index, 5, 21, 1, &meshes[0], &triangles[0], &material_range[0]); // Teapot // Masked materials add_to_material_range(&indices[0], index, 6, 27, 1, &meshes[0], &triangles[0], &material_range[0]); // Globe // Textured materials add_to_material_range(&indices[0], index, 7, 18, 1, &meshes[0], &triangles[0], &material_range[0]); // Ball-horse add_to_material_range(&indices[0], index, 8, 22, 1, &meshes[0], &triangles[0], &material_range[0]); // Head add_to_material_range(&indices[0], index, 9, 29, 1, &meshes[0], &triangles[0], &material_range[0]); // Picture add_to_material_range(&indices[0], index, 10, 1, 1, &meshes[0], &triangles[0], &material_range[0]); // Floor // Lightmapped materials add_to_material_range(&indices[0], index, 11, 2, 1, &meshes[0], &triangles[0], &material_range[0]); // Ceiling add_to_material_range(&indices[0], index, 12, 31, 1, &meshes[0], &triangles[0], &material_range[0]); // Wall light quads //create buffers auto positions_vb = d3d11::create_immutable_vertex_buffer( device, &positions_h[0], positions_h.size() * sizeof(math::half) ); auto normals_uvs_vb = d3d11::create_immutable_vertex_buffer( device, &normals_uv[0], normals_uv.size() * sizeof(math::half) ); auto indices_ib = d3d11::create_immutable_index_buffer( device, &indices[0], indices.size() * sizeof(uint32_t) ); //wait until initializer lists are supported in vs2012 std::vector<room_entity::material> materials_shade; room_entity::material materials_shade_[10]= { { math::set( 0.816f, 0.216f, 0.227f, 0.0f), math::set( 0.45f, 0.15f, 0.15f, gx::encode_specular_power(16.0f)) }, { math::set( 0.435f, 0.443f, 0.682f, 0.0f), math::set( 0.3f, 0.3f, 0.6f, gx::encode_specular_power(16.0f)) }, { math::set( 0.29f, 0.482f, 0.298f, 0.0f), math::set( 0.15f, 0.3f, 0.15f, gx::encode_specular_power(16.0f)) }, { math::set( 0.973f, 0.894f, 0.8f, 0.0f), math::set( 0.5f, 0.5f, 0.5f, gx::encode_specular_power(16.0f)) }, { math::set( 1.0f, 0.6f, 0.2f, 0.0f), math::set( 4.0f, 2.4f, 1.6f, gx::encode_specular_power(24.0f)) }, { math::set( 1.0f, 1.0f, 1.0f, 0.0f), math::set( 0.3f, 0.4f, 0.6f, gx::encode_specular_power(4.0f)) }, { math::set( 0.25f, 0.7f, 0.8f, 0.0f), math::set( 0.7f, 0.7f, 0.8f, gx::encode_specular_power(4.0f)) }, { math::set( 0.2f, 0.2f, 0.2f, 0.0f), math::set( 0.7f, 0.7f, 0.7f, gx::encode_specular_power(16.0f)) }, { math::set( 0.616f, 0.494f, 0.361f, 0.0f), math::set( 0.1f, 0.1f, 0.1f, gx::encode_specular_power(32.0f)) }, { math::set( 0.5f, 0.5f, 0.5f, 0.0f), math::set( 0.7f, 0.7f, 0.7f, gx::encode_specular_power(16.0f)) } }; std::copy ( &materials_shade_[0], &materials_shade_[0] + 10, std::back_insert_iterator<std::vector<room_entity::material>>(materials_shade)); std::vector<room_entity::draw_call> indexed_draw_calls; indexed_draw_calls.reserve(13); for(uint32_t i = 0; i < 13; ++i) { room_entity::draw_call::index_info info = {}; info.m_vertex_size[0] = 8; info.m_vertex_size[1] = 12; uint32_t start = material_range[i]; uint32_t end = material_range[i+1]; info.m_start_index_location = start; info.m_index_count = end - start; d3d11::ibuffer_ptr vertex_buffer_s[] = { positions_vb, normals_uvs_vb } ; indexed_draw_calls.push_back ( room_entity::draw_call( info, vertex_buffer_s, indices_ib ) ) ; } if ( in.eof() ) { return nullptr; } tasks.wait(); ctx.combine_each([&](thread_local_context& local) { d3d11::icommandlist_ptr command_list; local.m_device_context->FinishCommandList( false, dx::get_pointer(command_list)); d3d11::idevicecontext_ptr immediate_context; device->GetImmediateContext(dx::get_pointer(immediate_context) ); immediate_context->ExecuteCommandList(command_list.get(), true ); } ); float specular_power = gx::encode_specular_power(25.0f); std::vector<gx::gbuffer_dt_ng_sc_gc_material> textures_materials; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[0], math::set(0.05f, 0.05f, 0.05f, specular_power ), false ) ) ; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[1], math::set(0.05f, 0.05f, 0.05f, specular_power ), false ) ) ; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[2], math::set(0.05f, 0.05f, 0.05f, specular_power ), false ) ) ; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[3], math::set(0.05f, 0.05f, 0.05f, specular_power ), false ) ) ; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[4], math::set(0.05f, 0.05f, 0.05f, specular_power ), true ) ) ; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[5], math::set(0.05f, 0.05f, 0.05f, specular_power ), false ) ) ; textures_materials.push_back( gx::create_gbuffer_dt_ng_sc_gc_material( device, database, m_textures[6], math::set(0.05f, 0.05f, 0.05f, specular_power ), false ) ) ; return std::make_shared<room_entity> ( std::begin(indexed_draw_calls), std::end(indexed_draw_calls), gx::create_blinn_phong_shift_invairant_material( database, math::set( 1.0f, 0.0f, 0.0f, 0.0f), math::set(0.05f, 0.05f, 0.05f, specular_power )), std::move(materials_shade), std::move(textures_materials) ); }
void CBuild::Flex2OGF() { float p_total = 0; float p_cost = 1/float(g_XSplit.size()); validate_splits (); g_tree.clear (); g_tree.reserve (4096); for (splitIt it=g_XSplit.begin(); it!=g_XSplit.end(); it++) { R_ASSERT ( ! (*it)->empty() ); u32 MODEL_ID = u32(it-g_XSplit.begin()); OGF* pOGF = new OGF(); Face* F = *((*it)->begin()); // first face b_material* M = &(materials()[F->dwMaterial]); // and it's material R_ASSERT (F && M); try { // Common data pOGF->Sector = M->sector; pOGF->material = F->dwMaterial; // Collect textures OGF_Texture T; //pOGF->shader = M->shader; //pOGF->shader_xrlc = &F->Shader(); TRY(T.name = textures()[M->surfidx].name); TRY(T.pSurface = &(textures()[M->surfidx])); TRY(pOGF->textures.push_back(T)); try { if (F->hasImplicitLighting()) { // specific lmap string_path tn; strconcat (sizeof(tn),tn,*T.name,"_lm.dds"); T.name = tn; T.pSurface = T.pSurface; // Leave surface intact R_ASSERT (pOGF); pOGF->textures.push_back(T); } else { // If lightmaps persist CLightmap* LM = F->lmap_layer; if (LM) { string_path fn; sprintf_s (fn,"%s_1",LM->lm_texture.name); T.name = fn; T.pSurface = &(LM->lm_texture); R_ASSERT (T.pSurface); R_ASSERT (pOGF); pOGF->textures.push_back(T); //. sprintf (fn,"%s_2",LM->lm_texture.name); T.name = fn; pOGF->textures.push_back(T); } } } catch (...) { clMsg("* ERROR: Flex2OGF, model# %d, *textures*",MODEL_ID); } // Collect faces & vertices F->CacheOpacity (); bool _tc_ = !(F->flags.bOpaque); try { BuildOGFGeom( *pOGF, *(*it), _tc_ ); } catch (...) { clMsg("* ERROR: Flex2OGF, model# %d, *faces*",MODEL_ID); } } catch (...) { clMsg("* ERROR: Flex2OGF, 1st part, model# %d",MODEL_ID); } try { clMsg ("%3d: opt : v(%d)-f(%d)", MODEL_ID,pOGF->data.vertices.size(),pOGF->data.faces.size()); pOGF->Optimize (); clMsg ("%3d: cb : v(%d)-f(%d)", MODEL_ID,pOGF->data.vertices.size(),pOGF->data.faces.size()); pOGF->CalcBounds (); clMsg ("%3d: prog: v(%d)-f(%d)", MODEL_ID,pOGF->data.vertices.size(),pOGF->data.faces.size()); if (!b_noise) pOGF->MakeProgressive (c_PM_MetricLimit_static); clMsg ("%3d: strp: v(%d)-f(%d)", MODEL_ID,pOGF->data.vertices.size(),pOGF->data.faces.size()); pOGF->Stripify (); } catch (...) { clMsg("* ERROR: Flex2OGF, 2nd part, model# %d",MODEL_ID); } g_tree.push_back (pOGF); xr_delete (*it); Progress (p_total+=p_cost); } g_XSplit.clear (); }
void userSettings(void) { lighting(currentLighting); materials(currentMaterials); if ( lightingEnabled ) { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } else { glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); } if ( smoothEnabled ) { glShadeModel(GL_SMOOTH); } else { glShadeModel(GL_FLOAT); } if ( idleSpin ) { glutIdleFunc(spinCube); } else { glutIdleFunc(NULL); } if ( texEnabled ) { glEnable(GL_TEXTURE_2D); } else { glDisable(GL_TEXTURE_2D); } if ( fastTexture ) { glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); } else { glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } if ( mipmapEnabled ) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); } else { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } if ( fogEnabled ) { float fogColor[] = {0.7, 0.6, 0.6, 1.0}; glClearColor(fogColor[0], fogColor[1], fogColor[2], fogColor[3]); glEnable(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_DENSITY, 1.0); glFogf(GL_FOG_START, zNear); glFogf(GL_FOG_END, zFar); glFogfv(GL_FOG_COLOR, fogColor); } else { glDisable(GL_FOG); glClearColor(0.0, 0.0, 0.0, 1.0 ); } if ( lineAAEnabled ) glEnable(GL_BLEND); else glDisable(GL_BLEND); if ( lineAAEnabled ) { glEnable( GL_LINE_SMOOTH ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } else { glDisable( GL_LINE_SMOOTH ); } if ( depthEnabled ) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if ( perspectiveXform ) { glFrustum(-1.25, 1.25, -1.25, 1.25, zNear, zFar); viewxform_z = -5.0; } else { glOrtho(-2.0, 2.0, -2.0, 2.0, zNear, zFar); viewxform_z = -5.0; } glMatrixMode(GL_MODELVIEW); }
std::list<VoronoiShard> voronoi_convex_hull_shatter(const gl::MeshPtr &the_mesh, const std::vector<glm::vec3>& the_voronoi_points) { // points define voronoi cells in world space (avoid duplicates) // verts = source (convex hull) mesh vertices in local space std::list<VoronoiShard> ret; std::vector<glm::vec3> mesh_verts = the_mesh->geometry()->vertices(); auto convexHC = std::make_shared<btConvexHullComputer>(); btAlignedObjectArray<btVector3> vertices; btVector3 rbb, nrbb; btScalar nlength, maxDistance, distance; std::vector<glm::vec3> sortedVoronoiPoints = the_voronoi_points; btVector3 normal, plane; btAlignedObjectArray<btVector3> planes, convexPlanes; std::set<int> planeIndices; std::set<int>::iterator planeIndicesIter; int numplaneIndices; int i, j, k; // Normalize verts (numerical stability), convert to world space and get convexPlanes int numverts = mesh_verts.size(); // auto aabb = the_mesh->boundingBox(); // float scale_val = 1.f;//std::max(std::max(aabb.width(), aabb.height()), aabb.depth()); auto mesh_transform = the_mesh->global_transform() ;//* scale(glm::mat4(), vec3(1.f / scale_val)); std::vector<glm::vec3> world_space_verts; world_space_verts.resize(mesh_verts.size()); for (i = 0; i < numverts ;i++) { world_space_verts[i] = (mesh_transform * vec4(mesh_verts[i], 1.f)).xyz(); } //btGeometryUtil::getPlaneEquationsFromVertices(chverts, convexPlanes); // Using convexHullComputer faster than getPlaneEquationsFromVertices for large meshes... convexHC->compute(&world_space_verts[0].x, sizeof(world_space_verts[0]), numverts, 0.0, 0.0); int numFaces = convexHC->faces.size(); int v0, v1, v2; // vertices // get plane equations for the convex-hull n-gons for (i = 0; i < numFaces; i++) { const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[i]]; v0 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); edge = edge->getNextEdgeOfFace(); v2 = edge->getTargetVertex(); plane = (convexHC->vertices[v1]-convexHC->vertices[v0]).cross(convexHC->vertices[v2]-convexHC->vertices[v0]).normalize(); plane[3] = -plane.dot(convexHC->vertices[v0]); convexPlanes.push_back(plane); } const int numconvexPlanes = convexPlanes.size(); int numpoints = the_voronoi_points.size(); for (i = 0; i < numpoints ; i++) { auto curVoronoiPoint = the_voronoi_points[i]; planes.copyFromArray(convexPlanes); for (j = 0; j < numconvexPlanes; j++) { planes[j][3] += planes[j].dot(type_cast(the_voronoi_points[i])); } maxDistance = SIMD_INFINITY; // sort voronoi points std::sort(sortedVoronoiPoints.begin(), sortedVoronoiPoints.end(), pointCmp(curVoronoiPoint)); for (j=1; j < numpoints; j++) { normal = type_cast(sortedVoronoiPoints[j] - curVoronoiPoint); nlength = normal.length(); if (nlength > maxDistance) break; plane = normal.normalized(); plane[3] = -nlength / btScalar(2.); planes.push_back(plane); getVerticesInsidePlanes(planes, vertices, planeIndices); if (vertices.size() == 0) break; numplaneIndices = planeIndices.size(); if (numplaneIndices != planes.size()) { planeIndicesIter = planeIndices.begin(); for (k=0; k < numplaneIndices; k++) { if (k != *planeIndicesIter) planes[k] = planes[*planeIndicesIter]; planeIndicesIter++; } planes.resize(numplaneIndices); } maxDistance = vertices[0].length(); for (k=1; k < vertices.size(); k++) { distance = vertices[k].length(); if (maxDistance < distance) maxDistance = distance; } maxDistance *= btScalar(2.); } if (vertices.size() == 0) continue; // Clean-up voronoi convex shard vertices and generate edges & faces convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),0.0,0.0); // At this point we have a complete 3D voronoi shard mesh contained in convexHC // Calculate volume and center of mass (Stan Melax volume integration) numFaces = convexHC->faces.size(); btScalar volume = btScalar(0.); btVector3 com(0., 0., 0.); for (j = 0; j < numFaces; j++) { const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]]; v0 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); edge = edge->getNextEdgeOfFace(); v2 = edge->getTargetVertex(); while (v2 != v0) { // Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here... btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]); volume += vol; com += vol * (convexHC->vertices[v0] + convexHC->vertices[v1] + convexHC->vertices[v2]); edge = edge->getNextEdgeOfFace(); v1 = v2; v2 = edge->getTargetVertex(); } } com /= volume * btScalar(4.); volume /= btScalar(6.); // Shift all vertices relative to center of mass int numVerts = convexHC->vertices.size(); for (j = 0; j < numVerts; j++) { convexHC->vertices[j] -= com; } // now create our output geometry with indices std::vector<gl::Face3> outer_faces, inner_faces; std::vector<glm::vec3> outer_vertices, inner_vertices; int cur_outer_index = 0, cur_inner_index = 0; for (j = 0; j < numFaces; j++) { const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]]; v0 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); edge = edge->getNextEdgeOfFace(); v2 = edge->getTargetVertex(); // determine if it is an inner or outer face btVector3 cur_plane = (convexHC->vertices[v1] - convexHC->vertices[v0]).cross(convexHC->vertices[v2]-convexHC->vertices[v0]).normalize(); cur_plane[3] = -cur_plane.dot(convexHC->vertices[v0]); bool is_outside = false; for(uint32_t q = 0; q < convexPlanes.size(); q++) { if(is_equal(convexPlanes[q], cur_plane, 0.01f)){ is_outside = true; break;} } std::vector<gl::Face3> *shard_faces = &outer_faces; std::vector<glm::vec3> *shard_vertices = &outer_vertices; int *shard_index = &cur_outer_index; if(!is_outside) { shard_faces = &inner_faces; shard_vertices = &inner_vertices; shard_index = &cur_inner_index; } int face_start_index = *shard_index; // advance index *shard_index += 3; // first 3 verts of n-gon glm::vec3 tmp[] = { type_cast(convexHC->vertices[v0]), type_cast(convexHC->vertices[v1]), type_cast(convexHC->vertices[v2])}; shard_vertices->insert(shard_vertices->end(), tmp, tmp + 3); shard_faces->push_back(gl::Face3(face_start_index, face_start_index + 1, face_start_index + 2)); // add remaining triangles of face (if any) while (true) { edge = edge->getNextEdgeOfFace(); v1 = v2; v2 = edge->getTargetVertex(); // end of n-gon if(v2 == v0) break; shard_vertices->push_back(type_cast(convexHC->vertices[v2])); shard_faces->push_back(gl::Face3(face_start_index, *shard_index - 1, *shard_index)); (*shard_index)++; } } // entry construction gl::Mesh::Entry e0, e1; // outer entry e0.num_vertices = outer_vertices.size(); e0.num_indices = outer_faces.size() * 3; e0.material_index = 0; // inner entry e1.base_index = e0.num_indices; e1.base_vertex = e0.num_vertices; e1.num_vertices = inner_vertices.size(); e1.num_indices = inner_faces.size() * 3; e1.material_index = 1; // create gl::Mesh object for the shard auto inner_geom = gl::Geometry::create(), outer_geom = gl::Geometry::create(); // append verts and indices outer_geom->append_faces(outer_faces); outer_geom->vertices() = outer_vertices; outer_geom->compute_face_normals(); inner_geom->append_faces(inner_faces); inner_geom->append_vertices(inner_vertices); inner_geom->compute_face_normals(); // merge geometries outer_geom->append_vertices(inner_geom->vertices()); outer_geom->append_normals(inner_geom->normals()); outer_geom->append_indices(inner_geom->indices()); outer_geom->faces().insert(outer_geom->faces().end(), inner_geom->faces().begin(), inner_geom->faces().end()); outer_geom->compute_bounding_box(); auto inner_mat = gl::Material::create(); auto m = gl::Mesh::create(outer_geom, gl::Material::create()); m->entries() = {e0, e1}; m->materials().push_back(inner_mat); m->set_position(curVoronoiPoint + type_cast(com)); // m->transform() *= glm::scale(mat4(), vec3(scale_val)); // compute projected texcoords (outside) gl::project_texcoords(the_mesh, m); // compute box mapped texcoords for inside vertices auto &indices = m->geometry()->indices(); auto &vertices = m->geometry()->vertices(); // aabb auto out_aabb = the_mesh->bounding_box(); vec3 aabb_extents = out_aabb.halfExtents() * 2.f; uint32_t base_vertex = m->entries()[1].base_vertex; uint32_t k = m->entries()[1].base_index, kl = k + m->entries()[1].num_indices; for(;k < kl; k += 3) { gl::Face3 f(indices[k] + base_vertex, indices[k] + base_vertex + 1, indices[k] + base_vertex + 2); // normal const vec3 &v0 = vertices[f.a]; const vec3 &v1 = vertices[f.b]; const vec3 &v2 = vertices[f.c]; vec3 n = glm::normalize(glm::cross(v1 - v0, v2 - v0)); float abs_vals[3] = {fabsf(n[0]), fabsf(n[1]), fabsf(n[2])}; // get principal direction int principle_axis = std::distance(abs_vals, std::max_element(abs_vals, abs_vals + 3)); // switch (principle_axis) // { // // X-axis // case 0: // //ZY plane // m->geometry()->texCoords()[f.a] = vec2(v0.z - out_aabb.min.z / aabb_extents.z, // v0.y - out_aabb.min.y / aabb_extents.y); // m->geometry()->texCoords()[f.b] = vec2(v1.z - out_aabb.min.z / aabb_extents.z, // v1.y - out_aabb.min.y / aabb_extents.y); // m->geometry()->texCoords()[f.c] = vec2(v2.z - out_aabb.min.z / aabb_extents.z, // v2.y - out_aabb.min.y / aabb_extents.y); // break; // // // Y-axis // case 1: // // XZ plane // m->geometry()->texCoords()[f.a] = vec2(v0.x - out_aabb.min.x / aabb_extents.x, // v0.z - out_aabb.min.z / aabb_extents.z); // m->geometry()->texCoords()[f.b] = vec2(v1.x - out_aabb.min.x / aabb_extents.x, // v1.z - out_aabb.min.z / aabb_extents.z); // m->geometry()->texCoords()[f.c] = vec2(v2.x - out_aabb.min.x / aabb_extents.x, // v2.z - out_aabb.min.z / aabb_extents.z); // break; // // // Z-axis // case 2: // //XY plane // m->geometry()->texCoords()[f.a] = vec2(v0.x - out_aabb.min.x / aabb_extents.x, // v0.y - out_aabb.min.y / aabb_extents.y); // m->geometry()->texCoords()[f.b] = vec2(v1.x - out_aabb.min.x / aabb_extents.x, // v1.y - out_aabb.min.y / aabb_extents.y); // m->geometry()->texCoords()[f.c] = vec2(v2.x - out_aabb.min.x / aabb_extents.x, // v2.y - out_aabb.min.y / aabb_extents.y); // break; // // default: // break; // } } // push to return structure ret.push_back({m, volume}); } LOG_DEBUG << "Generated " << ret.size() <<" voronoi shards"; return ret; }
void compile(const char* path, CompileOptions& opts) { Buffer buf = opts.read(path); TempAllocator4096 ta; JsonObject object(ta); sjson::parse(buf, object); Array<PhysicsConfigMaterial> materials(default_allocator()); Array<PhysicsConfigShape> shapes(default_allocator()); Array<PhysicsConfigActor> actors(default_allocator()); CollisionFilterCompiler cfc(opts); // Parse materials if (map::has(object, FixedString("collision_filters"))) cfc.parse(object["collision_filters"]); if (map::has(object, FixedString("materials"))) parse_materials(object["materials"], materials); if (map::has(object, FixedString("shapes"))) parse_shapes(object["shapes"], shapes); if (map::has(object, FixedString("actors"))) parse_actors(object["actors"], actors); // Setup struct for writing PhysicsConfigResource pcr; pcr.version = RESOURCE_VERSION_PHYSICS_CONFIG; pcr.num_materials = array::size(materials); pcr.num_shapes = array::size(shapes); pcr.num_actors = array::size(actors); pcr.num_filters = array::size(cfc._filters); u32 offt = sizeof(PhysicsConfigResource); pcr.materials_offset = offt; offt += sizeof(PhysicsConfigMaterial) * pcr.num_materials; pcr.shapes_offset = offt; offt += sizeof(PhysicsConfigShape) * pcr.num_shapes; pcr.actors_offset = offt; offt += sizeof(PhysicsConfigActor) * pcr.num_actors; pcr.filters_offset = offt; offt += sizeof(PhysicsCollisionFilter) * pcr.num_filters; // Write all opts.write(pcr.version); opts.write(pcr.num_materials); opts.write(pcr.materials_offset); opts.write(pcr.num_shapes); opts.write(pcr.shapes_offset); opts.write(pcr.num_actors); opts.write(pcr.actors_offset); opts.write(pcr.num_filters); opts.write(pcr.filters_offset); // Write material objects for (u32 i = 0; i < pcr.num_materials; ++i) { opts.write(materials[i].name._id); opts.write(materials[i].static_friction); opts.write(materials[i].dynamic_friction); opts.write(materials[i].restitution); } // Write material objects for (u32 i = 0; i < pcr.num_shapes; ++i) { opts.write(shapes[i].name._id); opts.write(shapes[i].trigger); opts.write(shapes[i]._pad[0]); opts.write(shapes[i]._pad[1]); opts.write(shapes[i]._pad[2]); } // Write actor objects for (u32 i = 0; i < pcr.num_actors; ++i) { opts.write(actors[i].name._id); opts.write(actors[i].linear_damping); opts.write(actors[i].angular_damping); opts.write(actors[i].flags); } for (u32 i = 0; i < array::size(cfc._filters); ++i) { opts.write(cfc._filters[i].name._id); opts.write(cfc._filters[i].me); opts.write(cfc._filters[i].mask); } }
void CBuild::BuildSectors() { Status("Determining sectors..."); Progress(0); u32 SectorMax=0; for (u32 I=0; I<g_tree.size(); I++) if (g_tree[I]->Sector>SectorMax) SectorMax=g_tree[I]->Sector; R_ASSERT(SectorMax<0xffff); u32 SectorCount = SectorMax+1; g_sectors.resize(SectorCount); ZeroMemory(&*g_sectors.begin(),(u32)g_sectors.size()*sizeof(void*)); clMsg("%d sectors accepted.",SectorCount); Status("Spatializing geometry..."); for (u32 I=0; I<g_tree.size(); I++) { u32 Sector = g_tree[I]->Sector; if (0==g_sectors[Sector]) g_sectors[Sector] = new CSector(Sector); } Status("Building hierrarhy..."); for (u32 I=0; I<g_sectors.size(); I++) { R_ASSERT(g_sectors[I]); g_sectors[I]->BuildHierrarhy(); Progress(float(I)/float(g_sectors.size())); } Status("Assigning portals, occluders, glows, lights..."); // portals for (u32 I=0; I<portals.size(); I++) { b_portal &P = portals[I]; R_ASSERT(u32(P.sector_front)<g_sectors.size()); R_ASSERT(u32(P.sector_back) <g_sectors.size()); g_sectors[u32(P.sector_front)]->add_portal (u16(I)); g_sectors[u32(P.sector_back)]->add_portal (u16(I)); } // glows for (u32 I=0; I<glows.size(); I++) { b_glow &G = glows[I]; b_material &M = materials()[G.dwMaterial]; R_ASSERT(M.sector<g_sectors.size()); g_sectors[M.sector]->add_glow (u16(I)); } // lights for (u32 I=0; I<L_dynamic.size(); I++) { b_light_dynamic &L = L_dynamic[I]; if (L.data.type == D3DLIGHT_DIRECTIONAL) { for (u32 j=0; j<g_sectors.size(); j++) { R_ASSERT(g_sectors[j]); g_sectors[j]->add_light(u16(I)); } } else { if (L.sectors.size()) { for (u32 j=0; j<L.sectors.size(); j++) { R_ASSERT (L.sectors[j]<g_sectors.size()); g_sectors [L.sectors[j]]->add_light(u16(I)); } } else { clMsg("F**k!!! Light at position %f,%f,%f non associated!!!", L.data.position.x,L.data.position.y,L.data.position.z ); } } } }