/// Play from memory. bool CMusicChannelFMod::playSync(const std::string &filepath, bool loop) { CIFile ifile; ifile.allowBNPCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false); ifile.open(filepath); // try to load the music in memory uint32 fs = ifile.getFileSize(); if (!fs) { nlwarning("NLSOUND FMod Driver: Empty music file"); return false; } // read Buffer nlassert(!_MusicBuffer); _MusicBuffer = new uint8[fs]; try { ifile.serialBuffer(_MusicBuffer, fs); } catch (...) { nlwarning("NLSOUND FMod Driver: Error while reading music file"); delete[] _MusicBuffer; _MusicBuffer = NULL; return false; } // open FMOD stream _MusicStream = FSOUND_Stream_Open((const char*)_MusicBuffer, FSOUND_2D | FSOUND_LOADMEMORY | (loop ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF), 0, fs); if (!_MusicStream) { nlwarning("NLSOUND FMod Driver: Error while creating the FMOD stream for music file"); delete[] _MusicBuffer; _MusicBuffer = NULL; return false; } if (!playStream()) { nlwarning("NLSOUND FMod Driver: Error While trying to play sync music file"); FSOUND_Stream_Close(_MusicStream); _MusicStream = NULL; delete[] _MusicBuffer; _MusicBuffer = NULL; return false; } return true; }
//======================================================================================= // ryzom specific build bbox of a village in a zone static void computeBBoxFromVillage(const NLGEORGES::UFormElm *villageItem, const std::string &continentName, uint villageIndex, TShapeMap &shapeMap, CLightingBBox &result ) { result = CLightingBBox(); const NLGEORGES::UFormElm *igNamesItem; if (! (villageItem->getNodeByName (&igNamesItem, "IgList") && igNamesItem) ) { nlwarning("No list of IGs was found in the continent form %s, village #%d", continentName.c_str(), villageIndex); return; } // Get number of village uint numIgs; nlverify (igNamesItem->getArraySize (numIgs)); const NLGEORGES::UFormElm *currIg; for(uint l = 0; l < numIgs; ++l) { if (!(igNamesItem->getArrayNode (&currIg, l) && currIg)) { nlwarning("Couldn't get ig #%d in the continent form %s, in village #%d", l, continentName.c_str(), villageIndex); continue; } const NLGEORGES::UFormElm *igNameItem; currIg->getNodeByName (&igNameItem, "IgName"); std::string igName; if (!igNameItem->getValue (igName)) { nlwarning("Couldn't get ig name of ig #%d in the continent form %s, in village #%d", l, continentName.c_str(), villageIndex); continue; } if (igName.empty()) { nlwarning("Ig name of ig #%d in the continent form %s, in village #%d is an empty string", l, continentName.c_str(), villageIndex); continue; } igName = CFile::getFilenameWithoutExtension(igName) + ".ig"; string nameLookup = CPath::lookup (igName, false, true); if (!nameLookup.empty()) { CIFile inputFile; // Try to open the file if (inputFile.open (nameLookup)) { CInstanceGroup group; try { CLightingBBox currBBox; group.serial (inputFile); computeIGBBox(group, currBBox, shapeMap); result.makeUnion(currBBox); } catch(NLMISC::Exception &) { nlwarning ("Error while loading instance group %s\n", igName.c_str()); continue; } inputFile.close(); } else { // Error nlwarning ("Can't open instance group %s\n", igName.c_str()); } } } }
/** Load and compute the bbox of the models that are contained in a given instance group * \return true if the computed bbox is valid */ static void computeIGBBox(const NL3D::CInstanceGroup &ig, CLightingBBox &result, TShapeMap &shapeMap) { result = CLightingBBox(); // starts with void result bool firstBBox = true; /// now, compute the union of all bboxs for (CInstanceGroup::TInstanceArray::const_iterator it = ig._InstancesInfos.begin(); it != ig._InstancesInfos.end(); ++it) { CLightingBBox currBBox; bool validBBox = false; /// get the bbox from file or from map if (shapeMap.count(it->Name)) // already loaded ? { currBBox = shapeMap[it->Name]; validBBox = true; } else // must load the shape to get its bbox { std::string shapePathName; std::string toLoad = it->Name; if (getExt(toLoad).empty()) toLoad += ".shape"; shapePathName = NLMISC::CPath::lookup(toLoad, false, false); if (shapePathName.empty()) { nlwarning("Unable to find shape %s", it->Name.c_str()); } else { CIFile shapeInputFile; if (shapeInputFile.open (shapePathName.c_str())) { NL3D::CShapeStream shapeStream; try { shapeStream.serial (shapeInputFile); // NB Nico : // Deal with water shape -> their 'Receiving' box is set to 'void' // this prevent the case where a huge surface of water will cause the zone it is attached to (the 'Zone' // field in the villages sheets) to load all the zones that the water surface cover. (This caused // an 'out of memory error' in the zone lighter due to too many zone being loaded) // FIXME : test for water case hardcoded for now CWaterShape *ws = dynamic_cast<CWaterShape *>(shapeStream.getShapePointer()); if (ws) { CAABBox bbox; shapeStream.getShapePointer()->getAABBox(bbox); currBBox.OccludingBox = CPotentialBBox(bbox); // occluding box is used, though the water shape // doesn't cast shadow -> the tiles flag ('above', 'intersect', 'below water') // are updated inside the zone_lighter currBBox.ReceivingBox.IsVoid = true; // no lighted by the zone lighter !!! currBBox.removeVoid(); shapeMap[it->Name] = currBBox; } else { CAABBox bbox; shapeStream.getShapePointer()->getAABBox(bbox); currBBox.OccludingBox = CPotentialBBox(bbox); currBBox.ReceivingBox = CPotentialBBox(bbox); currBBox.removeVoid(); shapeMap[it->Name] = currBBox; } validBBox = true; } catch (NLMISC::Exception &e) { nlwarning("Error while loading shape %s. \n\t Reason : %s ", it->Name.c_str(), e.what()); } } else { nlwarning("Unable to open shape file %s to get its bbox", it->Name.c_str()); } } } if (validBBox) { /// build the model matrix NLMISC::CMatrix mat; mat.scale(it->Scale); NLMISC::CMatrix rotMat; rotMat.setRot(it->Rot); mat = rotMat * mat; mat.setPos(it->Pos); /// transform the bbox currBBox.transform(mat); currBBox.removeVoid(); if (firstBBox) { result = currBBox; firstBBox = false; } else // add to previous one { result.makeUnion(currBBox); } } } }
///========================================================= int main (int argc, char* argv[]) { // Filter addSearchPath NLMISC::createDebug(); InfoLog->addNegativeFilter ("adding the path"); TShapeMap shapeMap; // Check number of args if (argc<5) { // Help message printf ("zone_dependencies [properties.cfg] [firstZone.zone] [lastzone.zone] [output_dependencies.cfg]\n"); } else { NL3D::registerSerial3d(); // Light direction CVector lightDirection; // Config file handler try { // Read the properties file CConfigFile properties; // Load and parse the properties file properties.load (argv[1]); // Get the light direction CConfigFile::CVar &sun_direction = properties.getVar ("sun_direction"); lightDirection.set (sun_direction.asFloat(0), sun_direction.asFloat(1), sun_direction.asFloat(2)); lightDirection.normalize(); // Get the search pathes CConfigFile::CVar &search_pathes = properties.getVar ("search_pathes"); uint path; for (path = 0; path < (uint)search_pathes.size(); path++) { // Add to search path CPath::addSearchPath (search_pathes.asString(path)); } /* CConfigFile::CVar &ig_path = properties.getVar ("ig_path"); NLMISC::CPath::addSearchPath(ig_path.asString(), true, true); CConfigFile::CVar &shapes_path = properties.getVar ("shapes_path"); NLMISC::CPath::addSearchPath(shapes_path.asString(), true, true); */ CConfigFile::CVar &compute_dependencies_with_igs = properties.getVar ("compute_dependencies_with_igs"); bool computeDependenciesWithIgs = compute_dependencies_with_igs.asInt() != 0; // Get the file extension string ext=getExt (argv[2]); // Get the file directory string dir=getDir (argv[2]); // Get output extension string outExt=getExt (argv[4]); // Get output directory string outDir=getDir (argv[4]); // Get the first and last name string firstName=getName (argv[2]); string lastName=getName (argv[3]); // Get the coordinates uint16 firstX, firstY; uint16 lastX, lastY; if (getZoneCoordByName (firstName.c_str(), firstX, firstY)) { // Last zone if (getZoneCoordByName (lastName.c_str(), lastX, lastY)) { // Take care if (lastX<firstX) { uint16 tmp=firstX; firstX=lastX; lastX=firstX; } if (lastY<firstY) { uint16 tmp=firstY; firstY=lastY; lastY=firstY; } // Min z float minZ=FLT_MAX; // Make a quad grid CQuadGrid<CZoneDescriptorBB> quadGrid; quadGrid.create (256, 100); // The dependencies list vector< CZoneDependencies > dependencies; dependencies.resize ((lastX-firstX+1)*(lastY-firstY+1)); // Ryzom specific: build bbox for villages TString2LightingBBox villagesBBox; computeIGBBoxFromContinent(properties, shapeMap, villagesBBox); // Insert each zone in the quad tree sint y, x; for (y=firstY; y<=lastY; y++) for (x=firstX; x<=lastX; x++) { // Progress progress ("Build bounding boxes", (float)(x+y*lastX)/(float)(lastX*lastY)); // Make a zone file name string zoneName; getZoneNameByCoord (x, y, zoneName); // Open the file CIFile file; if (file.open (dir+zoneName+ext)) { // The zone CZone zone; try { // Serial the zone file.serial (zone); /// get bbox from the ig of this zone CLightingBBox igBBox; if (computeDependenciesWithIgs) { computeZoneIGBBox(zoneName.c_str(), igBBox, shapeMap, villagesBBox); } // Create a zone descriptor NLMISC::CAABBox zoneBox; zoneBox.setCenter(zone.getZoneBB().getCenter()); zoneBox.setHalfSize(zone.getZoneBB().getHalfSize()); CLightingBBox zoneLBox; zoneLBox.OccludingBox = zoneLBox.ReceivingBox = zoneBox; // can't be void zoneLBox.makeUnion(igBBox); nlassert(!zoneLBox.ReceivingBox.IsVoid); // CZoneDescriptorBB zoneDesc; zoneDesc.X=x; zoneDesc.Y=y; zoneDesc.BBox=zoneLBox.ReceivingBox.Box; // if (!zoneLBox.OccludingBox.IsVoid) { quadGrid.insert (zoneLBox.ReceivingBox.Box.getMin(), zoneLBox.ReceivingBox.Box.getMax(), zoneDesc); } // Insert in the dependencies // Index uint index=(x-firstX)+(y-firstY)*(lastX-firstX+1); // Loaded dependencies[index].Loaded=true; dependencies[index].X=x; dependencies[index].Y=y; dependencies[index].BBox=zoneLBox.OccludingBox.Box; // ZMin float newZ=zoneLBox.ReceivingBox.Box.getMin().z; if (newZ<minZ) minZ=newZ; } catch (Exception& e) { // Error handling nlwarning ("ERROR in file %s, %s", (dir+zoneName+ext).c_str(), e.what ()); } } } // Now select each zone in others and make a depencies list for (y=firstY; y<=lastY; y++) for (x=firstX; x<=lastX; x++) { // Progress progress ("Compute dependencies", (float)(x+y*lastX)/(float)(lastX*lastY)); // Index uint index=(x-firstX)+(y-firstY)*(lastX-firstX+1); // Loaded ? if (dependencies[index].Loaded) { // Min max vectors CVector vMin (dependencies[index].BBox.getMin()); CVector vMax (dependencies[index].BBox.getMax()); // Make a corner array CVector corners[4] = { CVector (vMin.x, vMin.y, vMax.z), CVector (vMax.x, vMin.y, vMax.z), CVector (vMax.x, vMax.y, vMax.z), CVector (vMin.x, vMax.y, vMax.z) }; // Extended bbox CAABBox bBox=dependencies[index].BBox.getAABBox(); // For each corner uint corner; for (corner=0; corner<4; corner++) { // Target position CVector target; if (lightDirection.z!=0) { // Not horizontal target target=corners[corner]+(lightDirection*((minZ-corners[corner].z)/lightDirection.z)); } else { // Horizontal target, select 500 meters around. target=(500*lightDirection)+corners[corner]; } // Extend the bbox bBox.extend (target); } // Clear quad tree selection quadGrid.clearSelection (); // Select quadGrid.select (bBox.getMin(), bBox.getMax()); // Check selection CQuadGrid<CZoneDescriptorBB>::CIterator it=quadGrid.begin(); while (it!=quadGrid.end()) { // Index uint targetIndex=((*it).X-firstX)+((*it).Y-firstY)*(lastX-firstX+1); // Not the same if (targetIndex!=index) { // Target min z float targetMinZ=dependencies[targetIndex].BBox.getMin().z; if (targetMinZ<vMax.z) { // Min z inf to max z ? // Target optimized bbox CAABBox bBoxOptimized=dependencies[index].BBox.getAABBox(); // For each corner for (corner=0; corner<4; corner++) { // Target position CVector target; if (lightDirection.z!=0) { // Not horizontal target target=corners[corner]+(lightDirection*((targetMinZ-corners[corner].z) /lightDirection.z)); } else { // Horizontal target, select 500 meters around. target=(500*lightDirection)+corners[corner]; } // Extend the bbox bBoxOptimized.extend (target); } // Check it more presisly //if ((*it).BBox.intersect (bBoxOptimized)) if ((*it).BBox.intersect (bBox)) { // Insert in the set dependencies[targetIndex].Dependences.insert (CZoneDependenciesValue (x, y)); } } } // Next selected it++; } } } // For each zone for (y=firstY; y<=lastY; y++) for (x=firstX; x<=lastX; x++) { // Progress progress ("Save depend files", (float)(x+y*lastX)/(float)(lastX*lastY)); // Index uint index=(x-firstX)+(y-firstY)*(lastX-firstX+1); // Loaded ? if (dependencies[index].Loaded) { // Make a file name string outputFileName; getZoneNameByCoord(x, y, outputFileName); outputFileName=outDir+outputFileName+outExt; // Write the dependencies file FILE *outputFile; if ((outputFile=fopen (toLower (outputFileName).c_str(), "w"))) { // Add a dependency entry fprintf (outputFile, "dependencies =\n{\n"); // Add dependent zones set<CZoneDependenciesValue>::iterator ite=dependencies[index].Dependences.begin(); while (ite!=dependencies[index].Dependences.end()) { // Name of the dependent zone std::string zoneName; getZoneNameByCoord(ite->first, ite->second, zoneName); // Write it string message="\t\""+zoneName+"\""; fprintf (outputFile, "%s", toLower (message).c_str()); // Next ite; ite++; if (ite!=dependencies[index].Dependences.end()) fprintf (outputFile, ",\n"); } // Close the variable fprintf (outputFile, "\n};\n\n"); } else { nlwarning ("ERROR can't open %s for writing.\n", outputFileName.c_str()); } // Close the file fclose (outputFile); } } } else { // Not valid nlwarning ("ERROR %s is not a valid zone name.\n", lastName.c_str()); } } else { // Not valid nlwarning ("ERROR %s is not a valid zone name.\n", firstName.c_str()); } } catch (Exception &ee) { nlwarning ("ERROR %s\n", ee.what()); } } return 0; }
BOOL CTexGenThumbnailDoc::OnOpenDocument(LPCTSTR lpszPathName) { CIFile file; if (file.open (lpszPathName)) { try { NLTEXGEN::CTexGenDocument doc; file.serial(doc); CFloatBitmap bitmap; CRenderParameter renderParameters (false, false, false); doc.Operators[0]->eval (bitmap, renderParameters); if ((bitmap.getWidth() != 0) && (bitmap.getHeight() != 0)) { bitmap.resample (m_sizeDoc.cx, m_sizeDoc.cy); _DibBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO); _DibBitmapInfo.bmiHeader.biWidth = m_sizeDoc.cx; _DibBitmapInfo.bmiHeader.biHeight = m_sizeDoc.cy; _DibBitmapInfo.bmiHeader.biPlanes = 1; _DibBitmapInfo.bmiHeader.biBitCount = 32; _DibBitmapInfo.bmiHeader.biCompression = BI_RGB; _DibBitmapInfo.bmiHeader.biSizeImage = 0; _DibBitmapInfo.bmiHeader.biXPelsPerMeter = 0; _DibBitmapInfo.bmiHeader.biYPelsPerMeter = 0; _DibBitmapInfo.bmiHeader.biClrUsed = 0; _DibBitmapInfo.bmiHeader.biClrImportant = 0; HWND desktop = ::GetDesktopWindow(); HDC dc = ::GetDC (desktop); nlverify(_Dib = CreateDIBSection(dc, &_DibBitmapInfo, DIB_RGB_COLORS, (void**)&_DibBits, NULL, 0)); const float *pixels = bitmap.getPixels(); if (pixels) { uint8 *dst = _DibBits; const uint height = m_sizeDoc.cy; uint y; for (y=0; y<height; y++) { const uint width = m_sizeDoc.cx*4 + y*m_sizeDoc.cx*4; uint i = y*m_sizeDoc.cx*4; uint j = (height-y-1)*m_sizeDoc.cx*4; for (;i<width; i+=4, j+=4) { /*if (alpha) { int r = (int)(pixels[i+0] * 255.f); clamp (r, 0, 255); dst[j+0] = r; dst[j+1] = r; dst[j+2] = r; } else*/ { int r = (int)(pixels[i+0] * 255.f); int g = (int)(pixels[i+1] * 255.f); int b = (int)(pixels[i+2] * 255.f); clamp (r, 0, 255); clamp (g, 0, 255); clamp (b, 0, 255); dst[j+0] = b; dst[j+1] = g; dst[j+2] = r; } } } } ::ReleaseDC (desktop, dc); return TRUE; } } catch (Exception &) { } } return FALSE; }
void CSheetId::loadSheetId () { H_AUTO(CSheetIdInit); //nldebug("Loading sheet_id.bin"); // Open the sheet id to sheet file name association CIFile file; std::string path = CPath::lookup("sheet_id.bin", false, false); if(!path.empty() && file.open(path)) { // clear entries _FileExtensions.clear (); _SheetIdToName.clear (); _SheetNameToId.clear (); // reserve space for the vector of file extensions _FileExtensions.resize(1 << (NL_SHEET_ID_TYPE_BITS)); // Get the map from the file map<uint32,string> tempMap; contReset(tempMap); file.serialCont(tempMap); file.close(); if (_RemoveUnknownSheet) { uint32 removednbfiles = 0; uint32 nbfiles = (uint32)tempMap.size(); // now we remove all files that not available map<uint32,string>::iterator itStr2; for( itStr2 = tempMap.begin(); itStr2 != tempMap.end(); ) { if (CPath::exists ((*itStr2).second)) { ++itStr2; } else { map<uint32,string>::iterator olditStr = itStr2; //nldebug ("Removing file '%s' from CSheetId because the file not exists", (*olditStr).second.c_str ()); itStr2++; tempMap.erase (olditStr); removednbfiles++; } } nlinfo ("SHEETID: Removed %d files on %d from CSheetId because these files doesn't exists", removednbfiles, nbfiles); } // Convert the map to one big string and 1 static map (id to name) { // Get the number and size of all strings vector<CChar> tempVec; // Used to initialise the first map uint32 nNb = 0; uint32 nSize = 0; map<uint32,string>::const_iterator it = tempMap.begin(); while (it != tempMap.end()) { nSize += (uint32)it->second.size()+1; nNb++; it++; } // Make the big string (composed of all strings) and a vector referencing each string tempVec.resize(nNb); _AllStrings.Ptr = new char[nSize]; it = tempMap.begin(); nSize = 0; nNb = 0; while (it != tempMap.end()) { tempVec[nNb].Ptr = _AllStrings.Ptr+nSize; strcpy(_AllStrings.Ptr+nSize, it->second.c_str()); toLower(_AllStrings.Ptr+nSize); nSize += (uint32)it->second.size()+1; nNb++; it++; } // Finally build the static map (id to name) _SheetIdToName.reserve(tempVec.size()); it = tempMap.begin(); nNb = 0; while (it != tempMap.end()) { _SheetIdToName.add(pair<uint32, CChar>(it->first, CChar(tempVec[nNb]))); nNb++; it++; } // The vector of all small string is not needed anymore we have all the info in // the static map and with the pointer AllStrings referencing the beginning. } // Build the invert map (Name to Id) & file extension vector { uint32 nSize = (uint32)_SheetIdToName.size(); _SheetNameToId.reserve(nSize); CStaticMap<uint32,CChar>::iterator itStr; for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr ) { // add entry to the inverse map _SheetNameToId.add( make_pair((*itStr).second, (*itStr).first) ); // work out the type value for this entry in the map TSheetId sheetId; sheetId.Id=(*itStr).first; uint32 type = sheetId.IdInfos.Type; // check whether we need to add an entry to the file extensions vector if (_FileExtensions[type].empty()) { // find the file extension part of the given file name _FileExtensions[type] = toLower(CFile::getExtension((*itStr).second.Ptr)); } nSize--; } _SheetNameToId.endAdd(); } } else { nlerror("<CSheetId::init> Can't open the file sheet_id.bin"); } nldebug("Finished loading sheet_id.bin: %u entries read",_SheetIdToName.size()); }
// *************************************************************************** int main(int argc, char *argv[]) { NLMISC::createDebug(); // make_anim_melee_impact animset_dir if(argc!=2) return usage(); string animSetDir= argv[1]; // *** parse the anim.txt file set<CAnimCombatSet> combatAnimSets; CIFile animFile; if(!animFile.open("anim.txt", true)) { nlwarning("Can't open anim.txt file. abort"); return 0; } else { char tmp[5000]; CAnimCombatSet lastAnimSet; // parse all lines while(!animFile.eof()) { animFile.getline(tmp, 5000); string line= tmp; if(line.empty()) continue; // new anim set? if(line[0]!=' ') { // insert the last anim state if(!lastAnimSet.States.empty()) combatAnimSets.insert(lastAnimSet); lastAnimSet.States.clear(); lastAnimSet.Name= line; } // new anim state? else if(!lastAnimSet.Name.empty()) { CAnimCombatState state; state.build(line); lastAnimSet.States.insert(state); } } // append the last anim set if needed if(!lastAnimSet.States.empty()) combatAnimSets.insert(lastAnimSet); animFile.close(); } // *** Get the list of .animset to make by race vector<string> files; files.clear(); CPath::getPathContent(animSetDir, true, false, true, files); vector<string> animSetList; InfoLog->displayRawNL(""); InfoLog->displayRawNL("*****************************"); InfoLog->displayRawNL("**** .animation_set list ****"); InfoLog->displayRawNL("*****************************"); for(uint i=0;i<files.size();i++) { if(testWildCard(files[i], "*.animation_set")) { animSetList.push_back(files[i]); InfoLog->displayRawNL(animSetList.back().c_str()); } } // *** Init StateNameToStateCode StateNameToStateCode["attack1"]= "A1"; StateNameToStateCode["attack2"]= "A2"; StateNameToStateCode["walk atk"]= "Wa"; StateNameToStateCode["run atk"]= "Ra"; StateNameToStateCode["backward atk"]= "Ba"; StateNameToStateCode["default atk low"]= "Dl"; StateNameToStateCode["default atk middle"]= "Dm"; StateNameToStateCode["default atk high"]= "Dh"; StateNameToStateCode["powerful atk low"]= "Pl"; StateNameToStateCode["powerful atk middle"]= "Pm"; StateNameToStateCode["powerful atk high"]= "Ph"; StateNameToStateCode["area atk low"]= "Al"; StateNameToStateCode["area atk middle"]= "Am"; StateNameToStateCode["area atk high"]= "Ah"; // *** For each animset, test if can replace some anim InfoLog->displayRawNL(""); InfoLog->displayRawNL("**************************"); InfoLog->displayRawNL("**** Starting Process ****"); InfoLog->displayRawNL("**************************"); for(uint i=0;i<animSetList.size();i++) { makeAnimMeleeImpact(animSetList[i], combatAnimSets); } return 0; }
// *************************************************************************** int main(int argc, char* argv[]) { // Filter addSearchPath NLMISC::createDebug(); InfoLog->addNegativeFilter ("adding the path"); // Register 3d registerSerial3d (); // Good number of args ? if (argc<4) { // Help message printf ("ig_lighter [directoryIn] [pathOut] [parameter_file] \n"); } else { try { string directoryIn= argv[1]; string pathOut= argv[2]; string paramFile= argv[3]; CInstanceLighter::CLightDesc lighterDesc; string grFile, rbankFile; // Verify directoryIn. directoryIn= CPath::standardizePath(directoryIn); if( !CFile::isDirectory(directoryIn) ) { printf("DirectoryIn %s is not a directory", directoryIn.c_str()); return -1; } // Verify pathOut. pathOut= CPath::standardizePath(pathOut); if( !CFile::isDirectory(pathOut) ) { printf("PathOut %s is not a directory", pathOut.c_str()); return -1; } // Load and setup configFile. //================= CConfigFile parameter; // Load and parse the param file parameter.load (paramFile); // Get the search pathes CConfigFile::CVar &search_pathes = parameter.getVar ("search_pathes"); uint path; for (path = 0; path < (uint)search_pathes.size(); path++) { // Add to search path CPath::addSearchPath (search_pathes.asString(path)); } // Light direction CConfigFile::CVar &sun_direction = parameter.getVar ("sun_direction"); lighterDesc.LightDirection.x=sun_direction.asFloat(0); lighterDesc.LightDirection.y=sun_direction.asFloat(1); lighterDesc.LightDirection.z=sun_direction.asFloat(2); lighterDesc.LightDirection.normalize (); // Grid size CConfigFile::CVar &quad_grid_size = parameter.getVar ("quad_grid_size"); lighterDesc.GridSize=quad_grid_size.asInt(); // Grid size CConfigFile::CVar &quad_grid_cell_size = parameter.getVar ("quad_grid_cell_size"); lighterDesc.GridCellSize=quad_grid_cell_size.asFloat(); // Shadows enabled ? CConfigFile::CVar &shadow = parameter.getVar ("shadow"); lighterDesc.Shadow=shadow.asInt ()!=0; // OverSampling CConfigFile::CVar &ig_oversampling = parameter.getVar ("ig_oversampling"); lighterDesc.OverSampling= ig_oversampling.asInt (); // validate value: 0, 2, 4, 8, 16 lighterDesc.OverSampling= raiseToNextPowerOf2(lighterDesc.OverSampling); clamp(lighterDesc.OverSampling, 0U, 16U); if(lighterDesc.OverSampling<2) lighterDesc.OverSampling= 0; // gr CConfigFile::CVar &grbank = parameter.getVar ("grbank"); grFile= grbank.asString (); // rbank CConfigFile::CVar &rbank = parameter.getVar ("rbank"); rbankFile= rbank.asString (); // CellSurfaceLightSize; CConfigFile::CVar &cell_surface_light_size = parameter.getVar ("cell_surface_light_size"); float cellSurfaceLightSize= cell_surface_light_size.asFloat (); if(cellSurfaceLightSize<=0) throw Exception("cell_surface_light_size must be > 0"); // CellRaytraceDeltaZ CConfigFile::CVar &cell_raytrace_delta_z = parameter.getVar ("cell_raytrace_delta_z"); float cellRaytraceDeltaZ= cell_raytrace_delta_z.asFloat (); // colIdentifierPrefix CConfigFile::CVar &col_identifier_prefix = parameter.getVar ("col_identifier_prefix"); string colIdentifierPrefix= col_identifier_prefix.asString (); // colIdentifierSuffix CConfigFile::CVar &col_identifier_suffix = parameter.getVar ("col_identifier_suffix"); string colIdentifierSuffix= col_identifier_suffix.asString (); // colIdentifierSuffix CConfigFile::CVar &build_debug_surface_shape = parameter.getVar ("build_debug_surface_shape"); bool buildDebugSurfaceShape= build_debug_surface_shape.asInt()!=0; // try to open gr and rbank CRetrieverBank *retrieverBank= NULL; CGlobalRetriever *globalRetriever= NULL; uint32 grFileDate= 0; uint32 rbankFileDate= 0; if( grFile!="" && rbankFile!="" ) { CIFile fin; // serial the retrieverBank. Exception if not found. fin.open(CPath::lookup(rbankFile)); retrieverBank= new CRetrieverBank; retrieverBank->setNamePrefix(CFile::getFilenameWithoutExtension(rbankFile).c_str ()); // Add the search path for LR files CPath::addSearchPath (CFile::getPath(rbankFile)); fin.serial(*retrieverBank); fin.close(); // serial the globalRetriever. Exception if not found. fin.open(CPath::lookup(grFile)); globalRetriever= new CGlobalRetriever; // set the RetrieverBank before loading globalRetriever->setRetrieverBank(retrieverBank); fin.serial(*globalRetriever); fin.close(); // Get File Dates rbankFileDate= CFile::getFileModificationDate(CPath::lookup(rbankFile)); grFileDate= CFile::getFileModificationDate(CPath::lookup(grFile)); // And init them. globalRetriever->initAll(); } // Scan and load all files .ig in directories //================= vector<string> listFile; vector<CInstanceGroup*> listIg; vector<string> listIgFileName; vector<string> listIgPathName; CPath::getPathContent(directoryIn, false, false, true, listFile); for(uint iFile=0; iFile<listFile.size(); iFile++) { string &igFile= listFile[iFile]; // verify it is a .ig. if( CFile::getExtension(igFile) == "ig" ) { // Read the InstanceGroup. CInstanceGroup *ig= new CInstanceGroup; CIFile fin; fin.open(CPath::lookup(igFile)); fin.serial(*ig); // add to list. listIg.push_back(ig); listIgPathName.push_back(igFile); listIgFileName.push_back(CFile::getFilename(igFile)); } } // For all ig, light them, and save. //================= for(uint iIg= 0; iIg<listIg.size(); iIg++) { string fileNameIn= listIgFileName[iIg]; string fileNameOut= pathOut + fileNameIn; // If File Out exist if(CFile::fileExists(fileNameOut)) { // If newer than file In (and also newer than retrieverInfos), skip uint32 fileOutDate= CFile::getFileModificationDate(fileNameOut); if( fileOutDate > CFile::getFileModificationDate(listIgPathName[iIg]) && fileOutDate > rbankFileDate && fileOutDate > grFileDate ) { printf("Skiping %s\n", fileNameIn.c_str()); continue; } } // progress printf("Processing %s\n", fileNameIn.c_str()); CInstanceGroup igOut; // Export a debugSun Name. string debugSunName; debugSunName= pathOut + "/" + CFile::getFilenameWithoutExtension(fileNameIn) + "_debug_sun_.shape"; string debugPLName; debugPLName= pathOut + "/" + CFile::getFilenameWithoutExtension(fileNameIn) + "_debug_pl_.shape"; // light the ig. CIgLighterLib::CSurfaceLightingInfo slInfo; slInfo.CellSurfaceLightSize= cellSurfaceLightSize; slInfo.CellRaytraceDeltaZ= cellRaytraceDeltaZ; slInfo.RetrieverBank= retrieverBank; slInfo.GlobalRetriever= globalRetriever; slInfo.IgFileName= CFile::getFilenameWithoutExtension(fileNameIn); slInfo.ColIdentifierPrefix= colIdentifierPrefix; slInfo.ColIdentifierSuffix= colIdentifierSuffix; slInfo.BuildDebugSurfaceShape= buildDebugSurfaceShape; slInfo.DebugSunName= debugSunName; slInfo.DebugPLName= debugPLName; lightIg(*listIg[iIg], igOut, lighterDesc, slInfo, fileNameIn.c_str ()); // Save this ig. COFile fout; fout.open(fileNameOut); fout.serial(igOut); fout.close(); // skip a line printf("\n"); } } catch (Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); } } // Landscape is not deleted, nor the instanceGroups, for faster quit. // Must disalbe BlockMemory checks (for pointLights). NL3D_BlockMemoryAssertOnPurge= false; // exit. return 0; }
int main(int argc, char* argv[]) { // Filter addSearchPath NLMISC::createDebug(); InfoLog->addNegativeFilter ("adding the path"); // Register 3d registerSerial3d (); // Good number of args ? if (argc<5) { // Help message printf ("%s [zonein.zonel] [igout.ig] [parameter_file] [dependancy_file]\n", argv[0]); } else { // Ok, read the zone CIFile inputFile; // Get extension string ext=getExt (argv[1]); string dir=getDir (argv[1]); // Open it for reading if (inputFile.open (argv[1])) { // Zone name string zoneName=toLower (string ("zone_"+getName (argv[1]))); // Load the zone try { // Read the config file CConfigFile parameter; // Load and parse the parameter file parameter.load (argv[3]); // ********** // *** Build the lighter descriptor // ********** CInstanceLighter::CLightDesc lighterDesc; // Light direction CConfigFile::CVar &sun_direction = parameter.getVar ("sun_direction"); lighterDesc.LightDirection.x=sun_direction.asFloat(0); lighterDesc.LightDirection.y=sun_direction.asFloat(1); lighterDesc.LightDirection.z=sun_direction.asFloat(2); lighterDesc.LightDirection.normalize (); // Grid size CConfigFile::CVar &quad_grid_size = parameter.getVar ("quad_grid_size"); lighterDesc.GridSize=quad_grid_size.asInt(); // Grid size CConfigFile::CVar &quad_grid_cell_size = parameter.getVar ("quad_grid_cell_size"); lighterDesc.GridCellSize=quad_grid_cell_size.asFloat(); // Shadows enabled ? CConfigFile::CVar &shadow = parameter.getVar ("shadow"); lighterDesc.Shadow=shadow.asInt ()!=0; // OverSampling CConfigFile::CVar &ig_oversampling = parameter.getVar ("ig_oversampling"); lighterDesc.OverSampling= ig_oversampling.asInt (); // validate value: 0, 2, 4, 8, 16 lighterDesc.OverSampling= raiseToNextPowerOf2(lighterDesc.OverSampling); clamp(lighterDesc.OverSampling, 0U, 16U); if(lighterDesc.OverSampling<2) lighterDesc.OverSampling= 0; // For ig of Zones, never disable Sun contrib !!! lighterDesc.DisableSunContribution= false; // Get the search pathes CConfigFile::CVar &search_pathes = parameter.getVar ("search_pathes"); uint path; for (path = 0; path < (uint)search_pathes.size(); path++) { // Add to search path CPath::addSearchPath (search_pathes.asString(path)); } // A landscape allocated with new: it is not delete because destruction take 3 secondes more! CLandscape *landscape=new CLandscape; landscape->init(); // A zone lighter CMyIgZoneLighter lighter; lighter.init (); // A vector of zone id vector<uint> listZoneId; // The zone CZone zone; // List of ig std::list<CInstanceGroup*> instanceGroup; // Load zone.serial (inputFile); inputFile.close(); // Load ig of the zone string igName = getName (argv[1])+".ig"; string igNameLookup = CPath::lookup (igName, false, false); if (!igNameLookup.empty()) igName = igNameLookup; bool zoneIgLoaded; // Try to open the file CInstanceGroup *centerInstanceGroup= NULL; if (inputFile.open (igName)) { // load the center ig centerInstanceGroup=new CInstanceGroup; // Serial it centerInstanceGroup->serial (inputFile); inputFile.close(); // Add to the list instanceGroup.push_back (centerInstanceGroup); zoneIgLoaded = true; } else { // Warning fprintf (stderr, "Warning: can't load instance group %s\n", igName.c_str()); zoneIgLoaded = false; } // If can't load the center instanceGroup, skip it. if(!zoneIgLoaded) return 0; // Get bank path CConfigFile::CVar &bank_name_var = parameter.getVar ("bank_name"); string bank_name = bank_name_var.asString (); string bank_name_lookup = CPath::lookup (bank_name); if (!bank_name_lookup.empty()) bank_name = bank_name_lookup; // Load the bank if (inputFile.open (bank_name)) { try { // Load landscape->TileBank.serial (inputFile); landscape->initTileBanks(); } catch (const Exception &e) { // Error nlwarning ("ERROR error loading tile bank %s\n%s\n", bank_name.c_str(), e.what()); } } else { // Error nlwarning ("ERROR can't load tile bank %s\n", bank_name.c_str()); } // Add the zone landscape->addZone (zone); listZoneId.push_back (zone.getZoneId()); // Load instance group ? CConfigFile::CVar &load_ig= parameter.getVar ("load_ig"); bool loadInstanceGroup = load_ig.asInt ()!=0; // Continue to build ? bool continu=true; // Try to load additionnal instance group. if (loadInstanceGroup) { // Additionnal instance group try { CConfigFile::CVar &additionnal_ig = parameter.getVar ("additionnal_ig"); for (uint add=0; add<(uint)additionnal_ig.size(); add++) { // Input file CIFile inputFile; // Name of the instance group string name = additionnal_ig.asString(add); string nameLookup = CPath::lookup (name, false, false); if (!nameLookup.empty()) name = nameLookup; // Try to open the file if (inputFile.open (name)) { // New ig CInstanceGroup *group=new CInstanceGroup; // Serial it group->serial (inputFile); inputFile.close(); // Add to the list instanceGroup.push_back (group); } else { // Error nlwarning ("ERROR can't load instance group %s\n", name.c_str()); // Stop before build continu=false; } } } catch (const NLMISC::EUnknownVar &) { nlinfo("No additionnal ig's to load"); } } // Shadow ? if (lighterDesc.Shadow) { // Load and parse the dependency file CConfigFile dependency; dependency.load (argv[4]); // *** Scan dependency file CConfigFile::CVar &dependant_zones = dependency.getVar ("dependencies"); for (uint i=0; i<(uint)dependant_zones.size(); i++) { // Get zone name string zoneName=dependant_zones.asString(i); // Load the zone CZone zoneBis; // Open it for reading if (inputFile.open (dir+zoneName+ext)) { // Read it zoneBis.serial (inputFile); inputFile.close(); // Add the zone landscape->addZone (zoneBis); listZoneId.push_back (zoneBis.getZoneId()); } else { // Error message and continue nlwarning ("ERROR can't load zone %s\n", (dir+zoneName+ext).c_str()); } // Try to load an instance group. if (loadInstanceGroup) { string name = zoneName+".ig"; string nameLookup = CPath::lookup (name, false, false); if (!nameLookup.empty()) name = nameLookup; // Name of the instance group if (inputFile.open (name)) { // New ig CInstanceGroup *group=new CInstanceGroup; // Serial it group->serial (inputFile); inputFile.close(); // Add to the list instanceGroup.push_back (group); } else { // Error message and continue nlwarning ("WARNING can't load instance group %s\n", name.c_str()); } } } } // A vector of CInstanceLighter::CTriangle vector<CInstanceLighter::CTriangle> vectorTriangle; // ********** // *** Build triangle array // ********** landscape->checkBinds (); // Add triangles from landscape, for pointLight lighting. landscape->enableAutomaticLighting (false); lighter.addTriangles (*landscape, listZoneId, 0, vectorTriangle); // Load and add shapes // Map of shape std::map<string, IShape*> shapeMap; // For each instance group std::list<CInstanceGroup*>::iterator ite=instanceGroup.begin(); while (ite!=instanceGroup.end()) { // Instance group CInstanceGroup *group=*ite; // For each instance for (uint instance=0; instance<group->getNumInstance(); instance++) { // Get the instance shape name string name=group->getShapeName (instance); // Skip it?? use the DontCastShadowForExterior flag. See doc of this flag if(group->getInstance(instance).DontCastShadow || group->getInstance(instance).DontCastShadowForExterior) continue; // Add a .shape at the end ? if (!name.empty()) { if (name.find('.') == std::string::npos) name += ".shape"; // Find the file string nameLookup = CPath::lookup (name, false, false); if (!nameLookup.empty()) name = nameLookup; // Find the shape in the bank std::map<string, IShape*>::iterator iteMap=shapeMap.find (name); if (iteMap==shapeMap.end()) { // Input file CIFile inputFile; if (inputFile.open (name)) { // Load it CShapeStream stream; stream.serial (inputFile); // Get the pointer iteMap=shapeMap.insert (std::map<string, IShape*>::value_type (name, stream.getShapePointer ())).first; } else { // Error nlwarning ("WARNING can't load shape %s\n", name.c_str()); } } // Loaded ? if (iteMap!=shapeMap.end()) { // Build the matrix CMatrix scale; scale.identity (); scale.scale (group->getInstanceScale (instance)); CMatrix rot; rot.identity (); rot.setRot (group->getInstanceRot (instance)); CMatrix pos; pos.identity (); pos.setPos (group->getInstancePos (instance)); CMatrix mt=pos*rot*scale; // If centerInstanceGroup, take good instanceId, to avoid selfShadowing sint instanceId; if(group == centerInstanceGroup) instanceId= instance; else instanceId= -1; // Add triangles lighter.addTriangles (*iteMap->second, mt, vectorTriangle, instanceId); } } } // For each point light of the ig const std::vector<CPointLightNamed> &pointLightList= group->getPointLightList(); for (uint plId=0; plId<pointLightList.size(); plId++) { // Add it to the Ig. lighter.addStaticPointLight(pointLightList[plId], igName.c_str ()); } // Next instance group ite++; } // Continue ? if (continu) { // ********** // *** Light! // ********** // Start time TTime time=CTime::getLocalTime (); // Output ig CInstanceGroup output; // Light the zone lighter.light (*centerInstanceGroup, output, lighterDesc, vectorTriangle, landscape); // Compute time printf ("\rCompute time: %d ms \r", (uint)(CTime::getLocalTime ()-time)); // Save the zone COFile outputFile; // Open it if (outputFile.open (argv[2])) { try { // Save the new ig outputFile.serial(output); } catch (const Exception& except) { // Error message nlwarning ("ERROR writing %s: %s\n", argv[2], except.what()); } } else { // Error can't open the file nlwarning ("ERROR Can't open %s for writing\n", argv[2]); } } else { // Error nlwarning ("ERROR Abort: files are missing.\n"); } } catch (const Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); } } else { // Error can't open the file nlwarning ("ERROR Can't open %s for reading\n", argv[1]); } } // Landscape is not deleted, nor the instanceGroups, for faster quit. // Must disalbe BlockMemory checks (for pointLights). NL3D_BlockMemoryAssertOnPurge= false; // exit. return 0; }
void CRingAccess::init() { if (_Initialised ) { return; } // no double initialisation _CustomNpcSheetId.clear(); //CSheetId::init() must be called first _CustomNpcSheetId.insert(CSheetId("basic_matis_male.creature")); _CustomNpcSheetId.insert(CSheetId("basic_fyros_male.creature")); _CustomNpcSheetId.insert(CSheetId("basic_tryker_male.creature")); _CustomNpcSheetId.insert(CSheetId("basic_zorai_male.creature")); _CustomNpcSheetId.insert(CSheetId("basic_matis_female.creature")); _CustomNpcSheetId.insert(CSheetId("basic_fyros_female.creature")); _CustomNpcSheetId.insert(CSheetId("basic_tryker_female.creature")); _CustomNpcSheetId.insert(CSheetId("basic_zorai_female.creature")); for (uint32 i = 0 ; i <= 184 ; ++i) { _R2PlotItemSheetId.insert( CSheetId( NLMISC::toString("r2_plot_item_%d.sitem", i))); } _SheetIdToAccess.clear();//only usefull when manualy re init file // File stream CIFile file; std::string pathFileName = CPath::lookup(RingAccessFilename, false, false, false); // Open the file if (pathFileName.empty() || !file.open(pathFileName.c_str())) { nlinfo("Can't open the file for reading : %s", RingAccessFilename.c_str()); return; } // Create the XML stream CIXml input; // Init if(input.init(file)) { xmlNodePtr entitiesAccess = input.getRootNode(); xmlNodePtr entityAccess = input.getFirstChildNode(entitiesAccess, "entityAccess"); while (entityAccess != 0) { // island name CXMLAutoPtr namePtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "name") ); CXMLAutoPtr packagePtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "package") ); CXMLAutoPtr sheetClientPtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "sheetClient") ); CXMLAutoPtr sheetPtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "sheetServer") ); if (!namePtr.getDatas()|| !packagePtr.getDatas() || !sheetPtr.getDatas() || !sheetPtr.getDatas()) { nlerror( "Syntax error in %s", pathFileName.c_str()); return; } std::string sheet( sheetPtr.getDatas() ); std::string package( packagePtr.getDatas() ); std::string sheetClient(sheetClientPtr.getDatas()); CSheetId sheetClientId(sheetClient); CSheetId sheetId; // no sheet server if (sheet.empty()) { bool ok = _SheetIdToAccess.insert( std::make_pair(std::make_pair(sheetClientId, sheetId), package)).second; if (!ok) { std::string previousPackage = _SheetIdToAccess[std::make_pair(sheetClientId, sheetId)]; // only display warning if one key has multiple package if ( previousPackage != package ) { nlwarning("%s: Entity %s sheet(%s) is defined more than once with different package definition. Previous definition is '%s', current definition is '%s'", RingAccessFilename.c_str(), namePtr.getDatas(), sheetClientPtr.getDatas(), previousPackage.c_str(), package.c_str()); } } } else { sheetId = CSheetId(sheet); if (_CustomNpcSheetId.find(sheetClientId) != _CustomNpcSheetId.end()) { bool ok = _SheetIdToAccess.insert( std::make_pair(std::make_pair(sheetClientId, sheetId), package)).second; if (!ok) { std::string previousPackage = _SheetIdToAccess[std::make_pair(sheetClientId, sheetId)]; // only display warning if one key has multiple package if ( previousPackage != package ) { nlwarning("%s: Entity %s sheet(%s) is defined more than once. Previous definition is '%s', current definition is '%s'", RingAccessFilename.c_str(), namePtr.getDatas(), sheetPtr.getDatas(), previousPackage.c_str(), package.c_str()); } } } else { nlwarning("%s: Entity %s has invalid sheets %s %s", RingAccessFilename.c_str(), namePtr.getDatas(), sheetClientPtr.getDatas(), sheetPtr.getDatas()); } } entityAccess = input.getNextChildNode(entityAccess, "entityAccess"); } } // Close the file file.close (); _Initialised = true; }
// *************************************************************************** int main(int argc, char* argv[]) { // Register 3d registerSerial3d (); // Avoid some stupids warnings. NLMISC::createDebug(); skipLog("variable \"RootConfigFilename\""); skipLog("variable \"anim_low_precision_tracks\""); skipLog("variable \"anim_sample_rate\""); InfoLog->addNegativeFilter("FEHTIMER>"); InfoLog->addNegativeFilter("adding the path"); // Good number of args ? if (argc<4) { // Help message printf ("anim_builder [directoryIn] [pathOut] [parameter_file] \n"); } else { try { string directoryIn= argv[1]; string pathOut= argv[2]; string paramFile= argv[3]; // Verify directoryIn. directoryIn= CPath::standardizePath(directoryIn); if( !CFile::isDirectory(directoryIn) ) { printf("DirectoryIn %s is not a directory", directoryIn.c_str()); return -1; } // Verify pathOut. pathOut= CPath::standardizePath(pathOut); if( !CFile::isDirectory(pathOut) ) { printf("PathOut %s is not a directory", pathOut.c_str()); return -1; } // Our Animation optimizer. //================= CAnimationOptimizer animationOptimizer; // Leave thresholds as default. animationOptimizer.clearLowPrecisionTracks(); // Load and setup configFile. //================= CConfigFile parameter; // Load and parse the param file parameter.load (paramFile); // Get the Low Precision Track Key Names try { CConfigFile::CVar &anim_low_precision_tracks = parameter.getVar ("anim_low_precision_tracks"); uint lpt; for (lpt = 0; lpt < (uint)anim_low_precision_tracks.size(); lpt++) { animationOptimizer.addLowPrecisionTrack(anim_low_precision_tracks.asString(lpt)); } } catch(EUnknownVar &) { nlwarning("\"anim_low_precision_tracks\" not found in the parameter file. Add \"Finger\" and \"Ponytail\" by default"); animationOptimizer.addLowPrecisionTrack("Finger"); animationOptimizer.addLowPrecisionTrack("Ponytail"); } // Sample Rate. try { CConfigFile::CVar &anim_sample_rate = parameter.getVar ("anim_sample_rate"); float sr= anim_sample_rate.asFloat(0); // Consider values > 1000 as error values. if(sr<=0 || sr>1000) { nlwarning("Bad \"anim_sample_rate\" value. Use Default of 30 fps."); animationOptimizer.setSampleFrameRate(30); } else { animationOptimizer.setSampleFrameRate(sr); } } catch(EUnknownVar &) { nlwarning("\"anim_sample_rate\" not found in the parameter file. Use Default of 30 fps."); animationOptimizer.setSampleFrameRate(30); } // Scan and load all files .ig in directories //================= uint numSkipped= 0; uint numBuilded= 0; vector<string> listFile; CPath::getPathContent(directoryIn, false, false, true, listFile); for(uint iFile=0; iFile<listFile.size(); iFile++) { string &igFile= listFile[iFile]; // verify it is a .anim. if( CFile::getExtension(igFile) == "anim" ) { string fileNameIn= CFile::getFilename(igFile); string fileNameOut= pathOut + fileNameIn; // skip the file? bool mustSkip= false; // If File Out exist if(CFile::fileExists(fileNameOut)) { // If newer than file In, skip uint32 fileOutDate= CFile::getFileModificationDate(fileNameOut); if( fileOutDate > CFile::getFileModificationDate(igFile) ) { mustSkip= true; } } // If must process the file. if(!mustSkip) { // Read the animation. CAnimation animIn; CIFile fin; fin.open(CPath::lookup(igFile)); fin.serial(animIn); // process. CAnimation animOut; animationOptimizer.optimize(animIn, animOut); // Save this animation. COFile fout; fout.open(fileNameOut); fout.serial(animOut); fout.close(); numBuilded++; } else { numSkipped++; } // progress printf("Anim builded: %4d. Anim Skipped: %4d\r", numBuilded, numSkipped); } } // Add some info in the log. nlinfo("Anim builded: %4d", numBuilded); nlinfo("Anim skipped: %4d", numSkipped); } catch (Exception& except) { // Error message nlwarning ("ERROR %s\n", except.what()); } } // exit. return 0; }
/* * init() */ bool CPrimChecker::build(const string &primitivesPath, const string &igLandPath, const string &igVillagePath, const string &outputDirectory, bool forceRebuild) { if (Verbose) nlinfo("Checking pacs.packed_prims consistency"); NLLIGO::Register(); // Init ligo if (!LigoConfig.readPrimitiveClass ("world_editor_classes.xml", false)) { // Should be in l:\leveldesign\world_edit_files nlwarning ("Can't load ligo primitive config file world_editor_classes.xml"); return false; } uint i, j; string outputfname = CPath::standardizePath(outputDirectory)+"pacs.packed_prims"; _Grid.clear(); vector<string> files; CPath::getPathContent(primitivesPath, true, false, true, files); for (i=0; i<files.size(); ++i) { if (CFile::getExtension(files[i]) == "primitive") { readFile(files[i]); } } files.clear(); CPath::getPathContent(igLandPath, true, false, true, files); CPath::getPathContent(igVillagePath, true, false, true, files); set<string> noWaterShapes; for (i=0; i<files.size(); ++i) { try { // load ig associated to the zone string igname = files[i]; string ignamelookup = CPath::lookup(igname); //nlinfo("Reading ig '%s'", ignamelookup.c_str()); CIFile igStream(ignamelookup); CInstanceGroup ig; igStream.serial(ig); // search in group for water instance for (j=0; j<ig._InstancesInfos.size(); ++j) { string shapeName = ig._InstancesInfos[j].Name; if (CFile::getExtension (shapeName) == "") shapeName += ".shape"; if (noWaterShapes.find(shapeName) != noWaterShapes.end()) continue; string shapeNameLookup = CPath::lookup (shapeName, false, false); if (!shapeNameLookup.empty()) { CIFile f; if (f.open (shapeNameLookup)) { CShapeStream shape; shape.serial(f); CWaterShape *wshape = dynamic_cast<CWaterShape*>(shape.getShapePointer()); if (wshape == NULL) { noWaterShapes.insert(shapeName); continue; } //nlinfo("Render water shape '%s'", shapeNameLookup.c_str()); CMatrix matrix; ig.getInstanceMatrix(j, matrix); CPolygon wpoly; //wshape->getShapeInWorldSpace(wpoly); CPolygon2D wpoly2d = wshape->getShape(); uint k; for (k=0; k<wpoly2d.Vertices.size(); ++k) { wpoly.Vertices.push_back(matrix * wpoly2d.Vertices[k]); } float zwater = wpoly.Vertices[0].z - WaterThreshold; uint16 idx = (uint16)_WaterHeight.size(); _WaterHeight.push_back(zwater); render(wpoly, idx); if (Verbose) nlinfo("Rendered water shape '%s' in instance '%s'", CFile::getFilenameWithoutExtension(shapeName).c_str(), CFile::getFilenameWithoutExtension(igname).c_str()); } else if (Verbose) { noWaterShapes.insert(shapeName); nlwarning ("Can't load shape %s", shapeNameLookup.c_str()); } } else if (Verbose) { noWaterShapes.insert(shapeName); nlwarning ("Can't find shape %s", shapeName.c_str()); } } } catch (const Exception &e) { nlwarning("%s", e.what()); } } COFile f; if (f.open(outputfname)) { f.serial(_Grid); f.serialCont(_WaterHeight); } else { nlwarning("Couldn't save pacs.packed_prims file '%s'", outputfname.c_str()); } return true; }
// *************************************************************************** void makeAnimByRace(const std::string &animSetFile, const std::vector<string> &animList) { // *** Read the animset file. CIFile iFile; iFile.open(animSetFile, true); // Read all text static vector<string> animSetText; animSetText.clear(); while(!iFile.eof()) { char tmp[50000]; iFile.getline(tmp, 50000); animSetText.push_back(tmp); } iFile.close(); bool someChangeDone= false; // *** For each possible anim for(uint i=0;i<animList.size();i++) { // get the possible anim file name (lowered) static vector<string> raceAnimNames; raceAnimNames.clear(); buildRaceAnimNames(raceAnimNames, toLower(CFile::getFilename(animList[i]))); // For each line of the animSet uint lastStructLine= 0; bool raceRestrictionFound= false; for(uint j=0;j<animSetText.size();) { string line= animSetText[j]; string lineLwr= toLower(line); // Find <LOG> TAg? => stop if(line.find("<LOG>")!=string::npos) break; // Find a STRUCT start? if(line.find("<STRUCT>")!=string::npos) { lastStructLine= j; raceRestrictionFound= false; } // Find a RaceRestriction? if( line.find("Name=\"Race Restriction\"")!=string::npos ) raceRestrictionFound= true; // Find the anim name? uint nameIndexInLine= findAnimName(lineLwr, raceAnimNames); if(nameIndexInLine!=-1) { // Find the enclosing struct nlassert(lastStructLine!=0); uint startBlock= lastStructLine; uint nameLineInBlock= j-startBlock; uint endBlock= 0; for(uint k=j+1;k<animSetText.size();k++) { string line= animSetText[k]; // Find a RaceRestriction? if( line.find("Name=\"Race Restriction\"")!=string::npos ) raceRestrictionFound= true; // end of block? if(line.find("</STRUCT>")!=string::npos) { // endBlock is exclusive endBlock= k+1; break; } } // if not found, abort if(endBlock==0) break; // if a raceRestriction has been found, no op (already done) if(raceRestrictionFound) { j= endBlock; } else { // LOG InfoLog->displayRawNL("%s: Specifying %s by race", CFile::getFilename(animSetFile).c_str(), CFile::getFilename(animList[i]).c_str()); // *** Start a copy paste ^^ // Copy static vector<string> copyText; copyText.clear(); for(uint k=startBlock;k<endBlock;k++) { // add an empty line before </STRUCT>, for race selection node (filled later) if(k==endBlock-1) copyText.push_back(string()); copyText.push_back(animSetText[k]); } // erase this part animSetText.erase(animSetText.begin()+startBlock, animSetText.begin()+endBlock); uint nextBlock= startBlock; // Append for each race for(uint k=0;k<raceAnimNames.size();k++) { appendRaceAnim(animSetText, nextBlock, copyText, nameLineInBlock, nameIndexInLine, raceAnimNames[k]); // nextBlock is then shifted nextBlock+= copyText.size(); } someChangeDone= true; // *** then let j point to next block j= nextBlock; } } else { j++; } } } // *** Write the animset file. if(someChangeDone) { COFile oFile; oFile.open(animSetFile, false, true); // Write all text for(uint i=0;i<animSetText.size();i++) { string str= animSetText[i]; str+= "\n"; oFile.serialBuffer((uint8*)str.c_str(), str.size()); } } }
void Browse::OnImportBorder() { // Select a file CFileDialog sFile (true, NULL, NULL, OFN_ENABLESIZING, "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); if (sFile.DoModal()==IDOK) { // Get the border of the bank std::vector<NLMISC::CBGRA> array(128*128); // The bitmap NLMISC::CBitmap bitmap; // Read the bitmap bool error=false; CString pathName=sFile.GetPathName(); try { CIFile file; if (file.open ((const char*)pathName)) { // Export bitmap.load (file); } else error=true; } catch (Exception& e) { const char *toto=e.what (); error=true; } // Error during import ? if (error) { // Error message char tmp[512]; sprintf (tmp, "Can't read bitmap %s", (const char*)pathName); MessageBox (tmp, "Import border", MB_OK|MB_ICONEXCLAMATION); } // Get pixel CRGBA *pPixel=(CRGBA*)&bitmap.getPixels()[0]; // Good size if ((bitmap.getWidth()==128)&&(bitmap.getHeight()==128)) { // Make a copy for (int i=0; i<128*128; i++) { // Copy the pixel array[i].R=pPixel->R; array[i].G=pPixel->G; array[i].B=pPixel->B; array[i].A=pPixel->A; pPixel++; } } else { // Error message char tmp[512]; sprintf (tmp, "The bitmap must have a size of 128x128 (%s)", (const char*)pathName); MessageBox (tmp, "Import border", MB_OK|MB_ICONEXCLAMATION); } // 256 or 128 ? CTileBorder border; border.set (128, 128, array); tileBank2.getTileSet (land)->setBorder (m_ctrl.Texture==1?CTile::diffuse:CTile::additive, border); // Message MessageBox ("The border has been changed.", "Import border", MB_OK|MB_ICONINFORMATION); } }
// --------------------------------------------------------------------------- int main(int nNbArg, char**ppArgs) { if (!NLMISC::INelContext::isContextInitialised()) new CApplicationContext(); NL3D_BlockMemoryAssertOnPurge = false; char sCurDir[MAX_PATH]; getcwd (sCurDir, MAX_PATH); if (nNbArg != 2) { printf ("Use : ig_elevation configfile.cfg\n"); printf ("\nExample of config.cfg\n\n"); printf ("InputIGDir = \"ig_land_max\";\n"); printf ("OutputIGDir = \"ig_land_max_elev\";\n"); printf ("CellSize = 160.0;\n"); printf ("HeightMapFile1 = \"w:/database/landscape/ligo/jungle/big.tga\";\n"); printf ("ZFactor1 = 1.0;\n"); printf ("HeightMapFile2 = \"w:/database/landscape/ligo/jungle/noise.tga\";\n"); printf ("ZFactor2 = 0.5;\n"); printf ("LandFile = \"w:/matis.land\";\n"); return -1; } SExportOptions options; if (!options.load(ppArgs[1])) { return -1; } // Get all ig files in the input directory and elevate to the z of the double heightmap // Load the land CZoneRegion *ZoneRegion = loadLand(options.LandFile); CZoneLimits zl; if (ZoneRegion) { zl._ZoneMinX = ZoneRegion->getMinX() < 0 ? 0 : ZoneRegion->getMinX(); zl._ZoneMaxX = ZoneRegion->getMaxX() > 255 ? 255 : ZoneRegion->getMaxX(); zl._ZoneMinY = ZoneRegion->getMinY() > 0 ? 0 : ZoneRegion->getMinY(); zl._ZoneMaxY = ZoneRegion->getMaxY() < -255 ? -255 : ZoneRegion->getMaxY(); } else { nlwarning("A ligo .land file cannot be found"); zl._ZoneMinX = 0; zl._ZoneMaxX = 255; zl._ZoneMinY = 0; zl._ZoneMaxY = 255; } // Load the 2 height maps CBitmap *HeightMap1 = NULL; if (!options.HeightMapFile1.empty()) { HeightMap1 = new CBitmap; try { CIFile inFile; if (inFile.open(options.HeightMapFile1)) { HeightMap1->load (inFile); } else { string sTmp = string("Couldn't not open ")+string(options.HeightMapFile1) +string(" : heightmap 1 map ignored"); outString(sTmp); delete HeightMap1; HeightMap1 = NULL; } } catch (const Exception &e) { string sTmp = string("Cant load height map : ") + options.HeightMapFile1 + " : " + e.what(); outString (sTmp); delete HeightMap1; HeightMap1 = NULL; } } CBitmap *HeightMap2 = NULL; if (!options.HeightMapFile2.empty()) { HeightMap2 = new CBitmap; try { CIFile inFile; if (inFile.open(options.HeightMapFile2)) { HeightMap2->load (inFile); } else { string sTmp = string("Couldn't not open ")+string(options.HeightMapFile2) +string(" : heightmap 2 map ignored\n"); outString(sTmp); delete HeightMap2; HeightMap2 = NULL; } } catch (const Exception &e) { string sTmp = string("Cant load height map : ") + options.HeightMapFile2 + " : " + e.what() + "\n"; outString (sTmp); delete HeightMap2; HeightMap1 = NULL; } } // Get all files vector<string> vAllFiles; chdir (options.InputIGDir.c_str()); dir (".ig", vAllFiles, false); chdir (sCurDir); for (uint32 i = 0; i < vAllFiles.size(); ++i) { chdir (options.InputIGDir.c_str()); CInstanceGroup *pIG = LoadInstanceGroup (vAllFiles[i].c_str()); chdir (sCurDir); if (pIG != NULL) { bool realTimeSunContribution = pIG->getRealTimeSunContribution(); // For all instances !!! CVector vGlobalPos; CInstanceGroup::TInstanceArray IA; vector<CCluster> Clusters; vector<CPortal> Portals; vector<CPointLightNamed> PLN; pIG->retrieve (vGlobalPos, IA, Clusters, Portals, PLN); if (IA.empty() && PLN.empty() && Portals.empty() && Clusters.empty()) continue; uint k; // elevate instance for(k = 0; k < IA.size(); ++k) { CVector instancePos = vGlobalPos + IA[k].Pos; IA[k].Pos.z += getHeightMapZ(instancePos.x, instancePos.y, zl, options, HeightMap1, HeightMap2); } // lights for(k = 0; k < PLN.size(); ++k) { CVector lightPos = vGlobalPos + PLN[k].getPosition(); PLN[k].setPosition( PLN[k].getPosition() + getHeightMapZ(lightPos.x, lightPos.y, zl, options, HeightMap1, HeightMap2) * CVector::K); } // portals std::vector<CVector> portal; for(k = 0; k < Portals.size(); ++k) { Portals[k].getPoly(portal); if (portal.empty()) { nlwarning("Empty portal found"); continue; } // compute mean position of the poly CVector meanPos(0, 0, 0); uint l; for(l = 0; l < portal.size(); ++l) meanPos += portal[l]; meanPos /= (float) portal.size(); meanPos += vGlobalPos; float z = getHeightMapZ(meanPos.x, meanPos.y, zl, options, HeightMap1, HeightMap2); for(l = 0; l < portal.size(); ++l) { portal[l].z += z; } Portals[k].setPoly(portal); } // clusters std::vector<CPlane> volume; CMatrix transMatrix; for(k = 0; k < Clusters.size(); ++k) { CVector clusterPos = vGlobalPos + Clusters[k].getBBox().getCenter(); float z = getHeightMapZ(clusterPos.x, clusterPos.y, zl, options, HeightMap1, HeightMap2); transMatrix.setPos(z * CVector::K); Clusters[k].applyMatrix(transMatrix); } CInstanceGroup *pIGout = new CInstanceGroup; pIGout->build (vGlobalPos, IA, Clusters, Portals, PLN); pIGout->enableRealTimeSunContribution(realTimeSunContribution); chdir (options.OutputIGDir.c_str()); SaveInstanceGroup (vAllFiles[i].c_str(), pIGout); chdir (sCurDir); delete pIG; } } return 1; }
int main(int argc, char **argv) { if (argc != 2) { printf("usage : %s file.ig\n", argv[0]); return -1; } try { uint k; CInstanceGroup ig; CIFile inputStream; if (!inputStream.open(string(argv[1]))) { printf("unable to open %s\n", argv[1]); return -1; } ig.serial(inputStream); printf("Origine\n"); printf("---------\n"); CVector gpos = ig.getGlobalPos(); printf("global pos : x = %.1f, y = %.1f, z =%.1f\n", gpos.x, gpos.y, gpos.z); printf("Instances\n"); printf("---------\n"); for(k = 0; k < ig._InstancesInfos.size(); ++k) { printf("instance %s : x = %.1f, y = %.1f, z = %.1f, sx = %.1f, sy = %.1f, sz = %.1f\n", ig._InstancesInfos[k].Name.c_str(), ig._InstancesInfos[k].Pos.x + gpos.x, ig._InstancesInfos[k].Pos.y + gpos.y, ig._InstancesInfos[k].Pos.z + gpos.z, ig._InstancesInfos[k].Scale.x, ig._InstancesInfos[k].Scale.y, ig._InstancesInfos[k].Scale.z); } printf("\n"); printf("Lights\n"); printf("---------\n"); for(k = 0; k < ig.getNumPointLights(); ++k) { const CPointLightNamed &pl = ig.getPointLightNamed(k); printf("light group = %d, anim = \"%s\" x = %.1f, y = %.1f, z = %.1f\n", pl.LightGroup, pl.AnimatedLight.c_str(), pl.getPosition().x + gpos.x, pl.getPosition().y + gpos.y, pl.getPosition().z + gpos.z); } printf("---------\n"); printf("Realtime sun contribution = %s\n", ig.getRealTimeSunContribution() ? "on" : "off"); printf("---------\n"); // IGSurfaceLight info. const CIGSurfaceLight::TRetrieverGridMap &rgm= ig.getIGSurfaceLight().getRetrieverGridMap(); printf("IGSurfaceLighting: CellSize: %f. NumGridRetriever: %u\n", ig.getIGSurfaceLight().getCellSize(), (uint)rgm.size() ); uint rgmInst= 0; uint totalCells= 0; CIGSurfaceLight::TRetrieverGridMap::const_iterator it= rgm.begin(); for(;it!=rgm.end();it++) { for(uint i=0;i<it->second.Grids.size();i++) { printf("grid(%d, %d): %dx%d\n", rgmInst, i, it->second.Grids[i].Width, it->second.Grids[i].Height ); totalCells+= it->second.Grids[i].Cells.size(); } rgmInst++; } printf("TotalCells: %d\n", totalCells); } catch (const std::exception &e) { printf("%s\n", e.what()); } }
// *************************************************************************** void CIgLighterLib::lightIg(CInstanceLighter &instanceLighter, const CInstanceGroup &igIn, CInstanceGroup &igOut, CInstanceLighter::CLightDesc &lightDesc, CSurfaceLightingInfo &slInfo, const char *igName) { sint i; // Setup. //======= // Init instanceLighter.init(); // For interiors ig, disable Sun contrib according to ig. lightDesc.DisableSunContribution= !igIn.getRealTimeSunContribution(); // Copy it to igOut, just to keep same setup data for in and out. igOut.enableRealTimeSunContribution(!lightDesc.DisableSunContribution); // Add obstacles. std::vector<CInstanceLighter::CTriangle> obstacles; // only if Shadowing On. if(lightDesc.Shadow) { // Map of shape to load std::map<string, IShape*> shapeMap; // For all instances of igIn. for(i=0; i<(sint)igIn.getNumInstance();i++) { // progress instanceLighter.progress("Loading Shapes obstacles", float(i)/igIn.getNumInstance()); // Skip it?? IgLighterLib use the DontCastShadowForInterior flag. See doc of this flag if(igIn.getInstance(i).DontCastShadow || igIn.getInstance(i).DontCastShadowForInterior) continue; // Get the instance shape name string name= igIn.getShapeName(i); bool shapeFound= true; // Try to find the shape in the UseShapeMap. std::map<string, IShape*>::const_iterator iteMap= lightDesc.UserShapeMap.find (name); // If not found in userShape map, try to load it from the temp loaded ShapeBank. if( iteMap == lightDesc.UserShapeMap.end() ) { // Add a .shape at the end ? if (name.find('.') == std::string::npos) name += ".shape"; // Lookup the file string nameLookup = CPath::lookup (name, false, false); if (!nameLookup.empty()) name = nameLookup; // Find the shape in the bank iteMap= shapeMap.find (name); if (iteMap==shapeMap.end()) { // Input file CIFile inputFile; if (inputFile.open (name)) { // Load it CShapeStream stream; stream.serial (inputFile); // Get the pointer iteMap=shapeMap.insert (std::map<string, IShape*>::value_type (name, stream.getShapePointer ())).first; } else { // Error nlwarning ("WARNING can't load shape %s\n", name.c_str()); shapeFound= false; } } } if(shapeFound) { CMatrix matInst; matInst.setPos(igIn.getInstancePos(i)); matInst.setRot(igIn.getInstanceRot(i)); matInst.scale(igIn.getInstanceScale(i)); // Add triangles of this shape CInstanceLighter::addTriangles(*iteMap->second, matInst, obstacles, i); } } // Clean Up shapes. //----------- std::map<string, IShape*>::iterator iteMap; iteMap= shapeMap.begin(); while(iteMap!= shapeMap.end()) { // delte shape delete iteMap->second; // delete entry in map shapeMap.erase(iteMap); // next iteMap= shapeMap.begin(); } } // Add pointLights of the IG. for(i=0; i<(sint)igIn.getPointLightList().size();i++) { instanceLighter.addStaticPointLight( igIn.getPointLightList()[i], igName ); } // Setup a CIGSurfaceLightBuild if needed. //======= CIGSurfaceLightBuild *igSurfaceLightBuild= NULL; CGlobalRetriever *globalRetriever= slInfo.GlobalRetriever; CRetrieverBank *retrieverBank= slInfo.RetrieverBank; float cellSurfaceLightSize= slInfo.CellSurfaceLightSize; if(retrieverBank && globalRetriever) { igSurfaceLightBuild= new CIGSurfaceLightBuild; igSurfaceLightBuild->CellSize= cellSurfaceLightSize; // col Identifier. string colIdent= slInfo.ColIdentifierPrefix + slInfo.IgFileName + slInfo.ColIdentifierSuffix; // For any retreiverInstance with this identifier. //---------------- uint numInstances= (uint)globalRetriever->getInstances().size(); for(uint instanceId=0; instanceId<numInstances; instanceId++) { const CRetrieverInstance &instance= globalRetriever->getInstance(instanceId); // If this instance is an interior if ( instance.getType() == CLocalRetriever::Interior ) { uint localRetrieverId= instance.getRetrieverId(); const CLocalRetriever &localRetriever= retrieverBank->getRetriever(localRetrieverId); // get the identifer of this localRetriever string retIdent= localRetriever.getIdentifier(); // Match the ident?? if( retIdent.find(colIdent)!=string::npos ) { // check CRetrieverLightGrid not already present CIGSurfaceLightBuild::ItRetrieverGridMap itRgm; itRgm= igSurfaceLightBuild->RetrieverGridMap.find(localRetrieverId); if( itRgm != igSurfaceLightBuild->RetrieverGridMap.end() ) { nlwarning ("ERROR Found 2 different collision retriever with same identifier: '%s'. The 2nd is discared\n", retIdent.c_str()); } else { // Append CRetrieverLightGrid. itRgm= igSurfaceLightBuild->RetrieverGridMap.insert( make_pair(localRetrieverId, CIGSurfaceLightBuild::CRetrieverLightGrid() ) ).first; CIGSurfaceLightBuild::CRetrieverLightGrid &rlg= itRgm->second; // Resize Grids. uint numSurfaces= (uint)localRetriever.getSurfaces().size(); rlg.Grids.resize( numSurfaces ); // Compute the bbox for all surfaces. (NB: local to the localRetriever). vector<CAABBox> surfaceBBoxes; localRetriever.buildInteriorSurfaceBBoxes(surfaceBBoxes); // For each surface, compute it. for(uint surfaceId=0; surfaceId<numSurfaces; surfaceId++) { // Progress. char stmp[256]; sprintf(stmp, "Sample surfaces of %s", retIdent.c_str()); instanceLighter.progress(stmp, surfaceId / float(numSurfaces)); // Compute surface and size of the grid. CIGSurfaceLightBuild::CSurface &surfDst= rlg.Grids[surfaceId]; // Snap Origin on cellSize surfDst.Origin= surfaceBBoxes[surfaceId].getMin(); surfDst.Origin.x= floorf(surfDst.Origin.x/cellSurfaceLightSize) * cellSurfaceLightSize; surfDst.Origin.y= floorf(surfDst.Origin.y/cellSurfaceLightSize) * cellSurfaceLightSize; // Snap Width / Height on cellSize. float sizex= surfaceBBoxes[surfaceId].getMax().x - surfDst.Origin.x; float sizey= surfaceBBoxes[surfaceId].getMax().y - surfDst.Origin.y; surfDst.Width= (uint)floorf(sizex/cellSurfaceLightSize) + 2; surfDst.Height= (uint)floorf(sizey/cellSurfaceLightSize) + 2; // Get Zcenter. float zCenter= surfaceBBoxes[surfaceId].getCenter().z; // Allocate elements. surfDst.Cells.resize(surfDst.Width * surfDst.Height); // For all elements for(sint yCell=0; yCell<(sint)surfDst.Height; yCell++) { for(sint xCell=0; xCell<(sint)surfDst.Width; xCell++) { // compute pos of the cell. ULocalPosition localPos; localPos.Estimation.x= surfDst.Origin.x + xCell*cellSurfaceLightSize; localPos.Estimation.y= surfDst.Origin.y + yCell*cellSurfaceLightSize; localPos.Estimation.z= zCenter; // snap the pos to the surface. localPos.Surface= surfaceId; bool snapped; localRetriever.snapToInteriorGround(localPos, snapped); // if snapped then this point is IN the surface. CIGSurfaceLightBuild::CCellCorner &cell= surfDst.Cells[yCell * surfDst.Width + xCell]; cell.InSurface= snapped; // If ok, retrieve the global (ie world) position if(snapped) { // build a valid globalPosition. UGlobalPosition globalPos; globalPos.InstanceId= instanceId; globalPos.LocalPosition= localPos; // retrieve from globalRetriever. cell.CenterPos= globalRetriever->getGlobalPosition(globalPos); // Add a delta to simulate entity center cell.CenterPos.z+= slInfo.CellRaytraceDeltaZ; // OverSample if(lightDesc.OverSampling==0) { // No OverSample, just add CenterPos to the samples. cell.NumOverSamples= 1; cell.OverSamples[0]= cell.CenterPos; } else { // OverSample. overSampleCell(cell, lightDesc.OverSampling, localRetriever, *globalRetriever, instanceId, localPos, cellSurfaceLightSize, slInfo.CellRaytraceDeltaZ); // it is possible that no samples lies in surfaces (small surface). // In this case, just copy CenterPos into samples. if(cell.NumOverSamples==0) { cell.NumOverSamples= 1; cell.OverSamples[0]= cell.CenterPos; } } } else { // For debug mesh only, get an approximate pos. cell.CenterPos= localPos.Estimation + instance.getOrigin(); cell.CenterPos.z+= slInfo.CellRaytraceDeltaZ; } // Init cell defaults cell.Dilated= false; cell.SunContribution= 0; } } } } } } } } // Run. //======= instanceLighter.light(igIn, igOut, lightDesc, obstacles, NULL, igSurfaceLightBuild); // Output a debug mesh?? if(igSurfaceLightBuild && slInfo.BuildDebugSurfaceShape && !igSurfaceLightBuild->RetrieverGridMap.empty() ) { // Do it for the sun and point lights. for(uint i=0;i<2;i++) { // compute CMesh::CMeshBuild meshBuild; CMeshBase::CMeshBaseBuild meshBaseBuild; CVector deltaPos= CVector::Null; deltaPos.z= - slInfo.CellRaytraceDeltaZ + 0.1f; // What kind of debug? if( i==0 ) igSurfaceLightBuild->buildSunDebugMesh(meshBuild, meshBaseBuild, deltaPos); else igSurfaceLightBuild->buildPLDebugMesh(meshBuild, meshBaseBuild, deltaPos, igOut); // build CMesh mesh; mesh.build(meshBaseBuild, meshBuild); // Save. CShapeStream shapeStream; shapeStream.setShapePointer(&mesh); COFile file; if( i==0 ) file.open(slInfo.DebugSunName); else file.open(slInfo.DebugPLName); shapeStream.serial(file); } } // Clean. //======= if(igSurfaceLightBuild) delete igSurfaceLightBuild; }
int main(int argc, char *argv[]) { uint i; // Avoid warnings. NLMISC::createDebug(); DebugLog->addNegativeFilter("Exception will be launched"); WarningLog->addNegativeFilter("Exception will be launched"); InfoLog->addNegativeFilter("FEHTIMER>"); InfoLog->addNegativeFilter("adding the path"); // Init serial registerSerial3d(); if(argc<4) { puts("Usage: build_clod_bank path_file.cfg config_file.cfg destfile.clodbank [bakeFrameRate=20] "); return 0; } try { // The bank to fill CLodCharacterShapeBank lodShapeBank; // Read the frameRate to process bake of anims float bakeFrameRate= 20; if(argc>=5) { bakeFrameRate= (float)atof(argv[4]); if(bakeFrameRate<=1) { nlwarning("bad bakeFrameRate value, use a default of 20"); bakeFrameRate= 20; } } // parse the path file. //================== // try to load the config file. CConfigFile pathConfig; pathConfig.load (argv[1]); // Get the search pathes CConfigFile::CVar &search_pathes = pathConfig.getVar ("search_pathes"); for (i = 0; i < (uint)search_pathes.size(); i++) { // Add to search path CPath::addSearchPath (search_pathes.asString(i)); } // parse the config file. //================== // try to load the config file. CConfigFile config; config.load (argv[2]); // For all .clod to process //================== CConfigFile::CVar &clod_list = config.getVar ("clod_list"); uint lodId; for (lodId = 0; lodId < (uint)clod_list.size(); lodId++) { string lodName= clod_list.asString(lodId); printf("Process LOD: %s\n", lodName.c_str()); // Search the variable with this name. try { CIFile iFile; // get the anim list. CConfigFile::CVar &clod_anim_list = config.getVar (lodName); // Correct format? if(clod_anim_list.size()<3) { nlwarning("%s skipped. Must have at least the skeleton file name, the lod file name, and one animation", lodName.c_str()); // go to next. continue; } // Init lod shape process //=========================== // The first variable is the name of the skeleton. string skeletonName= clod_anim_list.asString(0); CSmartPtr<CSkeletonShape> skeletonShape; // Load it. iFile.open(CPath::lookup(skeletonName)); CShapeStream strShape; strShape.serial(iFile); iFile.close(); // Get the pointer, check it's a skeleton if(dynamic_cast<CSkeletonShape*>(strShape.getShapePointer()) == NULL) throw Exception("%s is not a Skeleton", skeletonName.c_str()); skeletonShape= (CSkeletonShape*)strShape.getShapePointer(); // The second var is the filename of the lod. string lodFileName= clod_anim_list.asString(1); // Load the shape. CLodCharacterShapeBuild lodShapeBuild; iFile.open( CPath::lookup(lodFileName) ); iFile.serial(lodShapeBuild); iFile.close(); // Prepare to build the lod. CLodCharacterBuilder lodBuilder; lodBuilder.setShape(lodName, skeletonShape, &lodShapeBuild); // Traverse all anim in the list. //=========================== uint animId; for (animId = 2; animId < (uint)clod_anim_list.size(); animId++) { string animFileName= clod_anim_list.asString(animId); // display. printf("Process Anim: %d/%d\r", animId-1, clod_anim_list.size()-2); // Try to load the animation CAnimation *anim= new CAnimation; // NB: continue, to list all ANIM if anim not found try { iFile.open( CPath::lookup(animFileName) ); iFile.serial(*anim); iFile.close(); // Add to the builder. NB: animation will be delete in this method. // NB: the key name here is the entire file, with the .anim, for easier georges editing. lodBuilder.addAnim(animFileName.c_str(), anim, bakeFrameRate); } catch(EPathNotFound &) { printf("ERROR anim not found %s\n", animFileName.c_str()); delete anim; } } printf("\n"); // Add to the bank. //=========================== uint32 shapeId= lodShapeBank.addShape(); *lodShapeBank.getShapeFullAcces(shapeId)= lodBuilder.getLodShape(); } catch(EUnknownVar &evar) { nlwarning(evar.what()); // Any other exception will make the program quit. } } // Save bank. //=========================== // compile lodShapeBank.compile(); // Save COFile oFile(argv[3]); oFile.serial(lodShapeBank); oFile.close(); } catch (Exception& except) { // Error message printf ("ERROR %s.\n Aborting.\n", except.what()); } return 0; }
int main(int argc, char **argv) { // Filter addSearchPath NLMISC::createDebug(); InfoLog->addNegativeFilter("adding the path"); createDebug(); try { // Init init(); uint i, j, k; for (i=0; i<IGs.size(); ++i) { // load ig associated to the zone string igName = IGs[i]+".ig"; CIFile igStream(CPath::lookup(igName)); CInstanceGroup ig; igStream.serial(ig); CAABBox igBBox; bool boxSet = false; nlinfo("Generating BBOX for %s", igName.c_str()); // search in group for water instance for (j=0; j<ig._InstancesInfos.size(); ++j) { /* Ben: c'est degueulasse, mais c'est les coders a la 3D, y savent pas coder Hld: ouai, mais ca marche pas ton truc, alors p'tet qu'on sait pas coder mais toi non plus :p Special Dedicace to SupaGreg! string shapeName = ig._InstancesInfos[j].Name+".shape"; */ string shapeName = ig._InstancesInfos[j].Name; if (CFile::getExtension (shapeName) == "") shapeName += ".shape"; if (NonWaterShapes.find(shapeName) != NonWaterShapes.end()) continue; string shapeNameLookup = CPath::lookup (shapeName, false, false); if (!shapeNameLookup.empty()) { CIFile f; if (f.open (shapeNameLookup)) { CShapeStream shape; shape.serial(f); CWaterShape *wshape = dynamic_cast<CWaterShape *>(shape.getShapePointer()); if (wshape == NULL) { NonWaterShapes.insert(shapeName); continue; } CMatrix matrix; ig.getInstanceMatrix(j, matrix); CPolygon wpoly; wshape->getShapeInWorldSpace(wpoly); for (k=0; k<wpoly.Vertices.size(); ++k) { if (boxSet) { igBBox.extend(matrix * wpoly.Vertices[k]); } else { igBBox.setCenter(matrix * wpoly.Vertices[k]); boxSet = true; } } } else { nlwarning ("Can't load shape %s", shapeNameLookup.c_str()); } } else { NonWaterShapes.insert(shapeName); } } if (boxSet) { Boxes.push_back(CIGBox(igName, igBBox)); nlinfo("Bbox: (%.1f,%.1f)-(%.1f,%.1f)", igBBox.getMin().x, igBBox.getMin().y, igBBox.getMax().x, igBBox.getMax().y); } } COFile output(Output); output.serialCont(Boxes); } catch (Exception &e) { fprintf (stderr,"main trapped an exception: '%s'\n", e.what ()); } #ifndef NL_DEBUG catch (...) { fprintf(stderr,"main trapped an unknown exception\n"); } #endif // NL_DEBUG return 0; }
// *************************************************************************** void makeAnimMeleeImpact(const std::string &animSetFile, const set<CAnimCombatSet> &combatAnimSets) { // look if this animSetFile is in the combat list to patch string shortName= CFile::getFilenameWithoutExtension(animSetFile); strlwr(shortName); CAnimCombatSet key; key.Name= shortName; set<CAnimCombatSet>::const_iterator it= combatAnimSets.find(key); if(it == combatAnimSets.end()) return; const CAnimCombatSet ¤tCombatAnimSet= *it; InfoLog->displayRawNL("patching %s", animSetFile.c_str()); // *** Read the animset file. CIFile iFile; iFile.open(animSetFile, true); // Read all text static vector<string> animSetText; animSetText.clear(); while(!iFile.eof()) { char tmp[50000]; iFile.getline(tmp, 50000); animSetText.push_back(tmp); } iFile.close(); bool someChangeDone= false; // *** Parse the animSet { // For each line of the animSet sint structLevel= 0; sint meleeImpactDelayLine= -1; string currentStateName; for(uint j=0;j<animSetText.size();j++) { string line= animSetText[j]; string lineLwr= toLower(line); // Find <LOG> TAg? => stop if(line.find("<LOG>")!=string::npos) break; // Find a STRUCT start? if(line.find("<STRUCT")!=string::npos) { // inc struct structLevel++; // if start a new State block if(structLevel==2) { // reset info for this state currentStateName.clear(); meleeImpactDelayLine= -1; // try to get the name const string tagStart= "name=\""; std::string::size_type start= lineLwr.find(tagStart); if(start!=string::npos) { start+= tagStart.size(); std::string::size_type end= lineLwr.find("\"", start); if(end!=string::npos) currentStateName= lineLwr.substr(start, end-start); } } } // Find a STRUCT end? if(line.find("</STRUCT>")!=string::npos) { // if end a state block, may add or replace MeleeDelayImpact if(structLevel==2 && !currentStateName.empty()) { // If the state is not in the combat state, no need to patch anything static CAnimCombatState key; // must translate for instance "attack1" to "A1" key.StateCode= StateNameToStateCode[currentStateName]; set<CAnimCombatState>::const_iterator it= currentCombatAnimSet.States.find(key); if(it!=currentCombatAnimSet.States.end()) { // else take the mean anim time string format= " <ATOM Name=\"MeleeImpactDelay\" Value=\"%.3f\"/>"; string newLine= toString(format.c_str(), it->MeanAnimTime * MeleeImpactTimeFactor); // melee impact delay doesn't exist? if(meleeImpactDelayLine==-1) { // add just before this line the Melee Impact Atom animSetText.insert(animSetText.begin()+j, newLine); j++; someChangeDone= true; } // else exist and want to replace? else if(ReplaceExistingMeleeImpactDelay) { animSetText[meleeImpactDelayLine]= newLine; someChangeDone= true; } } } // dec struct level structLevel--; } // if we are in level 2 structure, try to get the line to modify (if exist) if(structLevel==2) { if( line.find("Name=\"MeleeImpactDelay\"")!=string::npos ) meleeImpactDelayLine= j; } } } // *** Write the animset file. if(someChangeDone) { COFile oFile; oFile.open(animSetFile, false, true); // Write all text for(uint i=0;i<animSetText.size();i++) { string str= animSetText[i]; str+= "\n"; oFile.serialBuffer((uint8*)str.c_str(), (uint)str.size()); } } }
//TODO titegus: What's the point in Importing a new border if there is no Pixel Compatibility check ? void CTile_browser_dlg::on_importBorderPushButton_clicked() { QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getOpenFileName(this, tr("Choose Bitmap"), QString(tileBankBrowser.getAbsPath().c_str()) , "Targa Bitmap(*.tga);;All Files (*.*);;", &selectedFilter, options); if (!fileName.isEmpty()) { fileName = QDir::toNativeSeparators(fileName); // Get the border of the bank std::vector<NLMISC::CBGRA> array(128*128); // The bitmap NLMISC::CBitmap bitmap; // Read the bitmap bool error=false; try { CIFile file; if (file.open (fileName.toStdString().c_str())) { // Export bitmap.load (file); } else error=true; } catch (Exception& e) { const char *toto=e.what (); error=true; } // Error during import ? if (error) { // Error message QString s = tr("Can't read bitmap %1").arg(fileName); QMessageBox::information (this, tr("Import border"), s); } // Get pixel CRGBA *pPixel=(CRGBA*)&bitmap.getPixels()[0]; // Good size if ((bitmap.getWidth()==128)&&(bitmap.getHeight()==128)) { // Make a copy for (int i=0; i<128*128; i++) { // Copy the pixel array[i].R=pPixel->R; array[i].G=pPixel->G; array[i].B=pPixel->B; array[i].A=pPixel->A; pPixel++; } } else { // Error message QString s = tr("The bitmap must have a size of 128x128 (%1)").arg(fileName); QMessageBox::information (this, tr("Import border"), s); } // 256 or 128 ? CTileBorder border; border.set (128, 128, array); tileBankBrowser.getTileSet (tileSetIndex)->setBorder ((CTile::TBitmap) tileTextureButtonGroup->checkedId(), border); // Message QMessageBox::information (this, tr("Import border"), tr("The border has been changed.")); } }