bool ITR3DMImport::import(const char* file, ITRGeometry* geometry, Vector<UInt32>* volumeMasks) { TPlaneF::DistancePrecision = distancePrecision; TPlaneF::NormalPrecision = normalPrecision; char buff[256]; // printf("Thred.3DM Import\n"); PolyList polyList; printf(" Importing..."); import(file,&polyList); #if 0 // This is now down by Zed. // Texture mapping printf("Texturing..."); for (int i = 0; i < polyList.size(); i++) boxMap(polyList[i]); #endif // Split polys whose textures are larger than 256x256 printf("Splitting..."); for (int i = 0; i < polyList.size(); i++) { Poly* poly = polyList[i]; if (poly->textureSize.x > splitDist) splitX(poly,&polyList); if (poly->textureSize.y > splitDist) splitY(poly,&polyList); } printf("Material Sorting..."); sortByMaterial(polyList); if (lowDetailInterior == false) { // Insert colinear vertices into polygons printf("SharedVertices..."); insertVertices(polyList); } else { printf("LowDetail (Shared Vertices not inserted)..."); geometry->setFlag(ITRGeometry::LowDetailInterior); } // printf("Export..."); exportToGeometry(polyList, geometry, volumeMasks); geometry->highestMipLevel = maxMipLevel; printf("\n"); // printf(" Vertices: %d\n", geometry->point3List.size()); printf(" Surfaces: %d\n", geometry->surfaceList.size()); printf(" Planes: %d\n", geometry->planeList.size()); return true; }
bool AddPoly() { if (poly_.size() == Settings::MaxPolygons) return false; int idx = RangeRand(poly_.size()); PolyIt it = poly_.begin(); std::advance(it, idx); poly_.insert(it, DnaPolygon()); return true; }
bool DelPoly() { if (poly_.size() == Settings::MinPolygons) return false; int idx = RangeRand(poly_.size()); PolyIt it = poly_.begin(); std::advance(it, idx); poly_.erase(it); return true; }
void dtEndComplexShape() { if (currentComplex->getBase().getPointer() == 0) { Point *ptr = new Point[pointBuf.size()]; copy(pointBuf.begin(), pointBuf.end(), ptr); currentComplex->setBase(ptr, true); pointBuf.erase(pointBuf.begin(), pointBuf.end()); } currentComplex->finish(polyList.size(), &polyList[0]); polyList.erase(polyList.begin(), polyList.end()); complexList.push_back(currentComplex); currentComplex = 0; }
bool MovePoly() { int origpos = RangeRand(poly_.size()); int newpos = RangeRand(poly_.size()); if (newpos == origpos) return false; PolyIt it = poly_.begin(); std::advance(it, origpos); DnaPolygon p(*it); poly_.erase(it); it = poly_.begin(); std::advance(it, newpos); poly_.insert(it, p); return true; }
void ITR3DMImport::insertVertices(PolyList& polyList) { ColinearList colinearList; for (int p = 0; p < polyList.size(); p++) { Poly* poly = polyList[p]; // Loop through all the edges. int v1 = poly->vertexList.size() - 1; for (int v2 = 0; v2 < poly->vertexList.size(); v2++) { // For each edge, find colinear points. Point3F &p1 = poly->vertexList[v1].point; Point3F &p2 = poly->vertexList[v2].point; if (findColinear(p1,p2,poly,polyList,&colinearList)) { Point2F tv1 = poly->vertexList[v1].texture; Point2F tv2 = poly->vertexList[v2].texture; tv2 -= tv1; // Insert new vertices in order. for (ColinearList::iterator itr = colinearList.begin(); itr != colinearList.end(); itr++) { poly->vertexList.insert(v2); PolyVertex& vertex = poly->vertexList[v2++]; float time = (*itr).time; vertex.texture.x = tv1.x + (tv2.x * time); vertex.texture.y = tv1.y + (tv2.y * time); vertex.point = (*itr).point; vertex.colinear = true; } } v1 = v2; } // Make sure first three vertices are not colinear. poly->rotate(); // for (int i = 0; i < poly->vertexList.size(); i++) { Point3F& p = poly->vertexList[i].point; float distance = poly->plane.distance(p); if (distance > distancePrecision) { printf("Doh!"); } } } }
int Poly() const { return poly_.size(); }
void ITR3DMImport::sortByMaterial(PolyList& polyList) { qsort(polyList.address(), polyList.size(), sizeof(PolyList::value_type), materialCmp); }
void ITR3DMImport::exportToGeometry(PolyList& polyList, ITRGeometry* geometry, Vector<UInt32>* volumeMasks) { AssertFatal(polyList.size() < ITRGeometry::MaxIndex, "ITR3DMImport:export: Too many polygons"); geometry->surfaceList.reserve(polyList.size()); for (int i = 0; i < polyList.size(); i++) { Poly* poly = polyList[i]; ITRBitVector bv; // Build surface geometry->surfaceList.push_back(ITRGeometry::Surface()); ITRGeometry::Surface& surface = geometry->surfaceList.last(); surface.type = ITRGeometry::Surface::Material; surface.material = (poly->material == -1)? ITRGeometry::Surface::NullMaterial: poly->material; surface.textureOffset.x = poly->textureOffset.x; surface.textureOffset.y = poly->textureOffset.y; surface.textureScaleShift = ( poly->textureScaleShift & ( ( 1 << ITRGeometry::Surface::textureScaleBits ) - 1 ) ); surface.applyAmbient = poly->applyAmbient; // Default is _not_ visible to the outside... surface.visibleToOutside = 0; volumeMasks->push_back(poly->volumeMask); // Size is 1->256 stored in UInt8 Point2I pSize; pSize.x = poly->textureSize.x >> maxMipLevel; pSize.y = poly->textureSize.y >> maxMipLevel; surface.textureSize.x = (pSize.x == 0)? 1: pSize.x - 1; surface.textureSize.y = (pSize.y == 0)? 1: pSize.y - 1; // Build poly AssertFatal(poly->vertexList.size() < 256, "ITR3DMImport::export: Vertex count on poly too large") surface.vertexCount = poly->vertexList.size(); surface.vertexIndex = geometry->vertexList.size(); geometry->vertexList.setSize(geometry->vertexList.size() + surface.vertexCount); ITRGeometry::Vertex* vp = &geometry->vertexList[surface.vertexIndex]; for (int i = 0; i < surface.vertexCount; i++) { vp[i].pointIndex = geometry->point3List.add(poly->vertexList[i].point); AssertFatal(geometry->point3List.size() < ITRGeometry::MaxIndex, "ITR3DMImport:export: Too many poly vertices"); // Texture coordinates normalized to texture size Point2F tx = poly->vertexList[i].texture; tx.x *= (1.0 / poly->textureSize.x); tx.y *= (1.0 / poly->textureSize.y); // Make sure it's not out of bounds (Zed bug?). bool clamp = false; if (tx.x < 0.0f) tx.x = 0.0f, clamp = true; if (tx.x > 1.0f) tx.x = 1.0f, clamp = true; if (tx.y < 0.0f) tx.y = 0.0f, clamp = true; if (tx.y > 1.0f) tx.y = 1.0f, clamp = true; if (clamp) printf(" Warning: Texture coordinate clamped\n"); // vp[i].textureIndex = geometry->point2List.add(tx); AssertFatal(geometry->point2List.size() < ITRGeometry::MaxIndex, "ITR3DMImport:export: Too many texture vertices"); bv.set(vp[i].pointIndex); } // Add plane to list. ITRVector<TPlaneF>::iterator itr = ::find(geometry->planeList.begin(),geometry->planeList.end(), poly->plane); if (itr == geometry->planeList.end()) { // Try too match inverted plane. poly->plane.neg(); itr = ::find(geometry->planeList.begin(), geometry->planeList.end(),poly->plane); if (itr == geometry->planeList.end()) { // No inverted either, so add original plane // to the list. surface.planeIndex = geometry->planeList.size(); surface.planeFront = true; poly->plane.neg(); geometry->planeList.push_back(poly->plane); } else { surface.planeIndex = itr - geometry->planeList.begin(); surface.planeFront = false; } } else { surface.planeIndex = itr - geometry->planeList.begin(); surface.planeFront = true; } // Build bitvec of points used by the surface surface.pointIndex = geometry->bitList.size(); int pcount = bv.compress(&geometry->bitList); AssertFatal(pcount < 256, "ITR3DMImport::export: Point bitvector too large"); surface.pointCount = pcount; } }