// *************************************************************************** void NLPACS::CZoneTessellation::build() { sint el; uint i, j; NL3D::CLandscape landscape; landscape.init(); vector<CVector> normals; vector<CVector> vectorCheck; bool useNoHmZones = true; { NL3D::CLandscape landscapeNoHm; landscapeNoHm.init(); // // load the 9 landscape zones // for (i=0; i<_ZoneIds.size(); ++i) { string filename = getZoneNameById(_ZoneIds[i])+ZoneExt; CIFile file(CPath::lookup(filename)); CZone zone; zone.serial(file); file.close(); if (Verbose) nlinfo("use zone %s %d", filename.c_str(), zone.getZoneId()); if (zone.getZoneId() != _ZoneIds[i]) { nlwarning ("Zone %s ID is wrong. Abort.", filename.c_str()); return; } landscape.addZone(zone); if (useNoHmZones) { string filenameNH = getZoneNameById(_ZoneIds[i])+ZoneNHExt; string loadZ = CPath::lookup(filenameNH, false, false); if (!loadZ.empty()) { CIFile fileNH(loadZ); CZone zoneNH; zoneNH.serial(fileNH); fileNH.close(); if (zoneNH.getZoneId() != _ZoneIds[i]) { nlwarning ("Zone %s ID is wrong. Abort.", filenameNH.c_str()); return; } landscapeNoHm.addZone(zoneNH); } else { useNoHmZones = false; } } _ZonePtrs.push_back(landscape.getZone(_ZoneIds[i])); } landscape.setNoiseMode(false); landscape.checkBinds(); if (useNoHmZones) { landscapeNoHm.setNoiseMode(false); landscapeNoHm.checkBinds(); } BestFittingBBox.setCenter(CVector::Null); BestFittingBBox.setHalfSize(CVector::Null); BestFittingBBoxSetuped= false; // Compute best fitting bbox for (i=0; i<_ZoneIds.size(); ++i) { if (_ZoneIds[i] == CentralZoneId) { if(_ZonePtrs[i]->getNumPatchs()>0) { BestFittingBBox = _ZonePtrs[i]->getZoneBB().getAABBox(); BestFittingBBoxSetuped= true; } } } CAABBox enlBBox = BestFittingBBox; enlBBox.setHalfSize(enlBBox.getHalfSize()+CVector(8.0f, 8.0f, 1000.0f)); // Add neighbor patch for (i=0; i<_ZoneIds.size(); ++i) { if (_ZoneIds[i] == CentralZoneId) { for (j=0; (sint)j<_ZonePtrs[i]->getNumPatchs(); ++j) { landscape.excludePatchFromRefineAll(_ZoneIds[i], j, false); if (useNoHmZones) landscapeNoHm.excludePatchFromRefineAll(_ZoneIds[i], j, false); } if (Verbose) nlinfo(" - selected %d/%d patches for zone %d", _ZonePtrs[i]->getNumPatchs(), _ZonePtrs[i]->getNumPatchs(), _ZoneIds[i]); } else { uint nump = 0; for (j=0; (sint)j<_ZonePtrs[i]->getNumPatchs(); ++j) { CAABBox pbox = _ZonePtrs[i]->getPatch(j)->buildBBox(); bool inters = enlBBox.intersect(pbox); if (inters) { landscape.excludePatchFromRefineAll(_ZoneIds[i], j, false); if (useNoHmZones) landscapeNoHm.excludePatchFromRefineAll(_ZoneIds[i], j, false); ++nump; } else { landscape.excludePatchFromRefineAll(_ZoneIds[i], j, true); if (useNoHmZones) landscapeNoHm.excludePatchFromRefineAll(_ZoneIds[i], j, true); } } if (Verbose) nlinfo(" - selected %d/%d patches for zone %d", nump, _ZonePtrs[i]->getNumPatchs(), _ZoneIds[i]); } } // tessellate the landscape, get the leaves (the tessellation faces), and convert them // into surf elements if (Verbose) nlinfo("Compute landscape tessellation"); if (Verbose) nlinfo(" - tessellate landscape"); if (useNoHmZones) { // Before tesselate, verify that the 2 landscape zones have at least the same binds! // Else there will be errors because of not the same tesselation checkSameLandscapeHmBinds(landscape, landscapeNoHm); // Tesselate landscapeNoHm.setThreshold(0.0f); landscapeNoHm.setTileMaxSubdivision(TessellateLevel); landscapeNoHm.refineAll(CVector::Null); landscapeNoHm.averageTesselationVertices(); // get the faces vector<const CTessFace *> leavesNoHm; landscapeNoHm.getTessellationLeaves(leavesNoHm); for (el=0; el<(sint)leavesNoHm.size(); ++el) { const CTessFace *face = leavesNoHm[el]; const CVector *v[3]; // get the vertices of the face v[0] = &(face->VBase->EndPos); v[1] = &(face->VLeft->EndPos); v[2] = &(face->VRight->EndPos); normals.push_back( ((*(v[1])-*(v[0])) ^ (*(v[2])-*(v[0]))).normed() ); vectorCheck.push_back(*(v[0])); vectorCheck.push_back(*(v[1])); vectorCheck.push_back(*(v[2])); } } } // Build the lanscape with heightmap landscape.setThreshold(0.0f); landscape.setTileMaxSubdivision(TessellateLevel); landscape.refineAll(CVector::Null); landscape.averageTesselationVertices(); vector<const CTessFace *> leaves; landscape.getTessellationLeaves(leaves); if (Verbose) { if (useNoHmZones) nlinfo(" - used no height map zones"); nlinfo(" - generated %d leaves", leaves.size()); } // If don't use NoHm zones, build normals and vectorCheck directly from std landscape if (!useNoHmZones) { for (el=0; el<(sint)leaves.size(); ++el) { const CTessFace *face = leaves[el]; const CVector *v[3]; // get the vertices of the face v[0] = &(face->VBase->EndPos); v[1] = &(face->VLeft->EndPos); v[2] = &(face->VRight->EndPos); normals.push_back( ((*(v[1])-*(v[0])) ^ (*(v[2])-*(v[0]))).normed() ); vectorCheck.push_back(*(v[0])); vectorCheck.push_back(*(v[1])); vectorCheck.push_back(*(v[2])); } } // check that there is the same number of faces from landscape with and without heightmap if (normals.size() != leaves.size()) { nlwarning ("ERROR : The heightmaped landscape has not the same number of polygon than the nonheightmaped landscape: %d/%d.", normals.size(), leaves.size()); exit (0); } // generate a vector of vertices and of surf element CHashMap<const CVector *, uint32, CHashPtr<const CVector> > vremap; CHashMap<const CVector *, uint32, CHashPtr<const CVector> >::iterator vremapit; CHashMap<const CTessFace *, CSurfElement *, CHashPtr<const CTessFace> > fremap; CHashMap<const CTessFace *, CSurfElement *, CHashPtr<const CTessFace> >::iterator fremapit; _Vertices.clear(); _Tessellation.resize(leaves.size()); if (Verbose) nlinfo(" - make and remap surface elements"); for (el=0; el<(sint)leaves.size(); ++el) fremap[leaves[el]] = &(_Tessellation[el]); uint check = 0; float dist, maxdist = 0.0f; for (el=0; el<(sint)leaves.size(); ++el) { const CTessFace *face = leaves[el]; const CVector *v[3]; CSurfElement &element = _Tessellation[el]; // setup zone id element.ZoneId = face->Patch->getZone()->getZoneId(); // get the vertices of the face v[0] = &(face->VBase->EndPos); v[1] = &(face->VLeft->EndPos); v[2] = &(face->VRight->EndPos); { CVector vcheck; vcheck = vectorCheck[check++] - *(v[0]); vcheck.z = 0; dist = vcheck.norm(); if (dist > maxdist) maxdist = dist; //nlassert(vcheck.norm() < 0.1f); vcheck = vectorCheck[check++] - *(v[1]); vcheck.z = 0; dist = vcheck.norm(); if (dist > maxdist) maxdist = dist; //nlassert(vcheck.norm() < 0.1f); vcheck = vectorCheck[check++] - *(v[2]); vcheck.z = 0; dist = vcheck.norm(); if (dist > maxdist) maxdist = dist; //nlassert(vcheck.norm() < 0.1f); } //element.Normal = ((*(v[1])-*(v[0])) ^ (*(v[2])-*(v[0]))).normed(); element.Normal = normals[el]; // search the vertices in the map for (i=0; i<3; ++i) { // if doesn't exist, create a new vertex if ((vremapit = vremap.find(v[i])) == vremap.end()) { element.Tri[i] = (uint32)_Vertices.size(); _Vertices.push_back(*(v[i])); vremap.insert(make_pair(v[i], element.Tri[i])); } // else use previous else { element.Tri[i] = vremapit->second; } } // setup the vertices pointer element.Vertices = &_Vertices; CTessFace *edge[3]; edge[0] = face->FBase; edge[1] = face->FRight; edge[2] = face->FLeft; for (i=0; i<3; ++i) { fremapit = fremap.find(edge[i]); element.EdgeLinks[i] = (fremapit != fremap.end() ? fremapit->second : NULL); } } for (el=0; el<(sint)_Tessellation.size(); ++el) { // add the element to the list of valid elements Elements.push_back(&(_Tessellation[el])); } landscape.clear(); }
/////////////////////////////////////////////////////////////// // // CResourceChecker::CheckLuaSourceForIssues // // Look for function names not in comment blocks // Note: Ignores quotes // /////////////////////////////////////////////////////////////// void CResourceChecker::CheckLuaSourceForIssues ( string strLuaSource, const string& strFileName, const string& strResourceName, bool bClientScript, bool bCompiledScript, ECheckerModeType checkerMode, string* pstrOutResult ) { CHashMap < SString, long > doneWarningMap; long lLineNumber = 1; // Check if this is a UTF-8 script bool bUTF8 = IsUTF8BOM( strLuaSource.c_str(), strLuaSource.length() ); // If it's not a UTF8 script, does it contain foreign language characters that should be upgraded? if ( !bCompiledScript && !bUTF8 && GetUTF8Confidence ( (const unsigned char*)&strLuaSource.at ( 0 ), strLuaSource.length() ) < 80 ) { std::wstring strUTF16Script = ANSIToUTF16 ( strLuaSource ); #ifdef WIN32 std::setlocale(LC_CTYPE,""); // Temporarilly use locales to read the script std::string strUTFScript = UTF16ToMbUTF8 ( strUTF16Script ); std::setlocale(LC_CTYPE,"C"); #else std::string strUTFScript = UTF16ToMbUTF8 ( strUTF16Script ); #endif if ( strLuaSource.length () != strUTFScript.size() ) { // In-place upgrade... if ( checkerMode == ECheckerMode::UPGRADE ) { // Upgrade only if there is no problem ( setlocale() issue? ) if ( strUTF16Script != L"?" ) { // Convert our script to ANSI, appending a BOM at the beginning strLuaSource = "\xEF\xBB\xBF" + strUTFScript; } } if ( checkerMode == ECheckerMode::WARNINGS ) { m_ulDeprecatedWarningCount++; CLogger::LogPrintf ( "WARNING: %s/%s [%s] is encoded in ANSI instead of UTF-8. Please convert your file to UTF-8.\n", strResourceName.c_str (), strFileName.c_str (), bClientScript ? "Client" : "Server" ); } } } // Step through each identifier in the file. for ( long lPos = 0 ; lPos < (long)strLuaSource.length () ; lPos++ ) { long lNameLength; long lNameOffset = FindLuaIdentifier ( strLuaSource.c_str () + lPos, &lNameLength, &lLineNumber ); if ( lNameOffset == - 1 ) break; lNameOffset += lPos; // Make offset absolute from the start of the file lPos = lNameOffset + lNameLength; // Adjust so the next pass starts from just after this identifier string strIdentifierName( strLuaSource.c_str () + lNameOffset, lNameLength ); // In-place upgrade... if ( checkerMode == ECheckerMode::UPGRADE ) { assert ( !bCompiledScript ); string strUpgraded; if ( UpgradeLuaFunctionName( strIdentifierName, bClientScript, strUpgraded ) ) { // Old head string strHead( strLuaSource.c_str (), lNameOffset ); // Old tail string strTail( strLuaSource.c_str () + lNameOffset + lNameLength ); // New source strLuaSource = strHead + strUpgraded + strTail; lPos += -lNameLength + strUpgraded.length (); } CheckVersionRequirements ( strIdentifierName, bClientScript ); } // Log warnings... if ( checkerMode == ECheckerMode::WARNINGS ) { // Only do the identifier once per file if ( doneWarningMap.find ( strIdentifierName ) == doneWarningMap.end () ) { doneWarningMap[strIdentifierName] = 1; if ( !bCompiledScript ) // Don't issue deprecated function warnings if the script is compiled, because we can't upgrade it IssueLuaFunctionNameWarnings ( strIdentifierName, strFileName, strResourceName, bClientScript, lLineNumber ); CheckVersionRequirements ( strIdentifierName, bClientScript ); } } } if ( pstrOutResult ) *pstrOutResult = strLuaSource; }