//============================================ void CWaterShape::getShapeInWorldSpace(NLMISC::CPolygon &poly) const { poly.Vertices.resize(_Poly.Vertices.size()); // compute the matrix of the object in world space, by using the default tracks NLMISC::CMatrix objMat; objMat.identity(); objMat.translate(_DefaultPos.getDefaultValue()); objMat.rotate(_DefaultRotQuat.getDefaultValue()); objMat.scale(_DefaultScale.getDefaultValue()); for (uint k = 0; k < _Poly.Vertices.size(); ++k) { poly.Vertices[k] = objMat * NLMISC::CVector(_Poly.Vertices[k].x, _Poly.Vertices[k].y, 0); } }
/** 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); } } } }