Example #1
0
    void ModelContainer::fillContainer(const AABSPTree<SubModel *>::Node& pNode, int &pSubModelPos, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi, Vector3& pFinalLo, Vector3& pFinalHi)
    {
        // TreeNode for the SubModel
        TreeNode treeNode = TreeNode(pNode.valueArray.size(), pSubModelPos);
        treeNode.setSplitAxis(pNode.splitAxis);
        treeNode.setSplitLocation(pNode.splitLocation);
        int currentTreeNodePos = pTreeNodePos++;

        Vector3 lo = Vector3(inf(),inf(),inf());
        Vector3 hi = Vector3(-inf(),-inf(),-inf());

        for (int i=0; i<pNode.valueArray.size(); i++)
        {
            G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i];
            SubModel *m = h->value;

            memcpy(&getTreeNodes()[pTreeNodePos], &m->getTreeNode(0), sizeof(TreeNode) * m->getNNodes());
            memcpy(&getTriangles()[pTrianglePos], &m->getTriangle(0), sizeof(TriangleBox) * m->getNTriangles());

            SubModel newModel = SubModel(m->getNTriangles(), getTriangles(), pTrianglePos, m->getNNodes(), getTreeNodes(), pTreeNodePos);
            newModel.setReletiveBounds(m->getReletiveBounds().getLo(), m->getReletiveBounds().getHi());
            newModel.setBasePosition(m->getBasePosition());
            iSubModel[pSubModelPos++] = newModel;

            pTreeNodePos += m->getNNodes();
            pTrianglePos += m->getNTriangles();

            AABox box = m->getAABoxBounds();
            lo = lo.min(box.low());
            hi = hi.max(box.high());
            pFinalLo = pFinalLo.min(lo);
            pFinalHi = pFinalHi.max(hi);
        }
        /*
        if(pNode.valueArray.size() == 0) {
        int xxx = 0; // just for the breakpoint
        }
        */
        // get absolute bounds

        if(pNode.child[0] != 0)
        {
            treeNode.setChildPos(0, pTreeNodePos);
            fillContainer(*pNode.child[0], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi);
        }
        if(pNode.child[1] != 0)
        {
            treeNode.setChildPos(1, pTreeNodePos);
            fillContainer(*pNode.child[1], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi);
        }

        pLo = pLo.min(lo);
        pHi = pHi.max(hi);

        treeNode.setBounds(lo,hi);

        setTreeNode(treeNode, currentTreeNodePos);

    }
Example #2
0
Box::Box(
    const Vector3& min,
    const Vector3& max) {

    init(min.min(max), min.max(max));

}
Example #3
0
		const Vector3 Vector3::clamp(const Vector3& min, const Vector3& max) const
		{
			Vector3 vector = *this;
			vector.min(max);
			vector.max(min);
			return vector;
		}
Example #4
0
    void fillSubModelArary(const ModelContainer* pModelContainer, const TreeNode *root, Array<SubModel>& array, Vector3& pLo, Vector3& pHi) {
        Vector3 lo = Vector3(inf(), inf(), inf());
        Vector3 hi = Vector3(-inf(), -inf(), -inf());

        for(int i=0; i<	root->getNValues(); i++) {
            SubModel sm = pModelContainer->getSubModel(root->getStartPosition() + i);
            lo = lo.min(sm.getAABoxBounds().low());
            hi = hi.max(sm.getAABoxBounds().high());
            array.append(sm);
        }

        if(root->getChild((TreeNode *) &pModelContainer->getTreeNode(0), 0)) {
            fillSubModelArary(pModelContainer, root->getChild((TreeNode *)&pModelContainer->getTreeNode(0), 0), array, lo, hi);
        }
        if(root->getChild((TreeNode *)&pModelContainer->getTreeNode(0), 1)) {
            fillSubModelArary(pModelContainer, root->getChild((TreeNode *)&pModelContainer->getTreeNode(0), 1), array, lo, hi);
        }

        float dist1 = (hi -lo).magnitude();
        AABox b;
        root->getBounds(b);
        float dist2 = (b.high() -b.low()).magnitude();
        if(dist1 > dist2) {
            // error
            int xxx = 0;
        }

    }
Welder::Welder(    
    const Array<Vector3>& _oldVertexArray,
    Array<Vector3>&       _newVertexArray,
    Array<int>&           _toNew,
    Array<int>&           _toOld,
    double                _radius) :
    oldVertexArray(_oldVertexArray),
    newVertexArray(_newVertexArray),
    toNew(_toNew),
    toOld(_toOld),
    radius(_radius) {

    // Compute a scale factor that moves the range
    // of all ordinates to [0, 1]
    Vector3 minBound = Vector3::inf();
    Vector3 maxBound = -minBound;

    for (int i = 0; i < oldVertexArray.size(); ++i) {
        minBound = minBound.min(oldVertexArray[i]);
        maxBound = maxBound.max(oldVertexArray[i]);
    }

    offset = minBound;
    scale  = maxBound - minBound;
    for (int i = 0; i < 3; ++i) {
        // The model might have zero extent along some axis
        if (fuzzyEq(scale[i], 0.0)) {
            scale[i] = 1.0;
        } else {
            scale[i] = 1.0 / scale[i];
        }
    }
}
Example #6
0
  void
  fillSubModelArary (const ModelContainer* pModelContainer, const TreeNode *root, Array<SubModel>& array, Vector3& pLo, Vector3& pHi)
  {
    Vector3 lo = Vector3 (inf (), inf (), inf ());
    Vector3 hi = Vector3 (-inf (), -inf (), -inf ());
    //printf("[VMAP] %i Submodels\n", root->getNValues ());
    for (int i = 0; i < root->getNValues (); i++)
      {
        SubModel sm = pModelContainer->getSubModel (root->getStartPosition () + i);
        lo = lo.min (sm.getAABoxBounds ().low ());
        hi = hi.max (sm.getAABoxBounds ().high ());
        array.append (sm);
      }

    if (root->getChild ((TreeNode *) & pModelContainer->getTreeNode (0), 0))
      {
        fillSubModelArary (pModelContainer, root->getChild ((TreeNode *) & pModelContainer->getTreeNode (0), 0), array, lo, hi);
      }
    if (root->getChild ((TreeNode *) & pModelContainer->getTreeNode (0), 1))
      {
        fillSubModelArary (pModelContainer, root->getChild ((TreeNode *) & pModelContainer->getTreeNode (0), 1), array, lo, hi);
      }

    float dist1 = (hi - lo).magnitude ();
    AABox b;
    root->getBounds (b);
    float dist2 = (b.high () - b.low ()).magnitude ();
    if (dist1 > dist2)
      {
        // error
        //printf("error in boundingbox size vs. hi-lo size.");
        // this error seems to happen alot! maybe need to do something against it?
        int xxx = 0;
      }
  }
Example #7
0
void MeshBuilder::computeBounds(Vector3& min, Vector3& max) {
    min = Vector3::inf(); 
    max = -min;

    int v;
    for (v = 0; v < triList.size(); ++v) {
        min = min.min(triList[v]);
        max = max.max(triList[v]);
    }
}
Example #8
0
	void Triangle::getBounds(AABox& out) const {
		Vector3 lo = _vertex[0];
		Vector3 hi = lo;

		for (int i = 1; i < 3; ++i) {
			lo = lo.min(_vertex[i]);
			hi = hi.max(_vertex[i]);
		}

		out = AABox(lo, hi);
	}
Example #9
0
    void SubModel::fillContainer(const AABSPTree<Triangle>::Node& pNode, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi)
    {
        TreeNode treeNode = TreeNode(pNode.valueArray.size(), pTrianglePos);
        treeNode.setSplitAxis(pNode.splitAxis);
        treeNode.setSplitLocation(pNode.splitLocation);

        int currentTreeNodePos = pTreeNodePos++;

        Vector3 lo = Vector3(inf(),inf(),inf());
        Vector3 hi = Vector3(-inf(),-inf(),-inf());

        for(int i=0;i<pNode.valueArray.size(); i++)
        {
            G3D::_AABSPTree::Handle<Triangle>* h= pNode.valueArray[i];
            Triangle t = h->value;
            TriangleBox triangleBox = TriangleBox(t.vertex(0),t.vertex(1), t.vertex(2));
            lo = lo.min(triangleBox.getBounds().getLo().getVector3());
            hi = hi.max(triangleBox.getBounds().getHi().getVector3());

            getTriangles()[pTrianglePos++] = triangleBox;
        }

        if(pNode.child[0] != 0)
        {
            treeNode.setChildPos(0, pTreeNodePos);
            fillContainer(*pNode.child[0], pTreeNodePos, pTrianglePos, lo, hi);
        }
        if(pNode.child[1] != 0)
        {
            treeNode.setChildPos(1, pTreeNodePos);
            fillContainer(*pNode.child[1], pTreeNodePos, pTrianglePos, lo, hi);
        }

        treeNode.setBounds(lo,hi);

        // get absolute bounds
        pLo = pLo.min(lo);
        pHi = pHi.max(hi);

        getTreeNodes()[currentTreeNodePos] = treeNode;
    }
Example #10
0
void Box::getBounds(class AABox& aabb) const {
    Vector3 lo = _corner[0];
    Vector3 hi = lo;

    for (int v = 1; v < 8; ++v) {
        const Vector3& C = _corner[v];
        lo = lo.min(C);
        hi = hi.max(C);
    }

    aabb = AABox(lo, hi);
}
Example #11
0
void MD2Model::Part::load(const std::string& filename, float resize) {

    resize *= 0.55f;

    // If models are being reloaded it is dangerous to trust the interpolation cache.
    interpolatedModel = NULL;

    alwaysAssertM(FileSystem::exists(filename), std::string("Can't find \"") + filename + "\"");

    setNormalTable();

    // Clear out
    reset();

    BinaryInput b(filename, G3D_LITTLE_ENDIAN);

    MD2ModelHeader header;

    header.deserialize(b);
    debugAssert(header.version == 8);
    debugAssert(header.numVertices <= 4096);

    keyFrame.resize(header.numFrames);
    Array<Vector3> frameMin;
    frameMin.resize(header.numFrames); 
    Array<Vector3> frameMax;
    frameMax.resize(header.numFrames);
    Array<double>  frameRad;
    frameRad.resize(header.numFrames);

    texCoordScale.x = 1.0f / header.skinWidth;
    texCoordScale.y = 1.0f / header.skinHeight;

    Vector3 min  = Vector3::inf();
    Vector3 max  = -Vector3::inf();
    double  rad  = 0;

    if (header.numVertices < 3) {
        Log::common()->printf("\n*****************\nWarning: \"%s\" is corrupted and is not being loaded.\n", filename.c_str());
        return;
    }

    loadTextureFilenames(b, header.numSkins, header.offsetSkins);

    for (int f = 0; f < keyFrame.size(); ++f) {
        MD2Frame md2Frame;

        b.setPosition(header.offsetFrames + f * header.frameSize);
        md2Frame.deserialize(b);

        // Read the vertices for the frame
        keyFrame[f].vertexArray.resize(header.numVertices);
        keyFrame[f].normalArray.resize(header.numVertices);

        // Per-pose bounds
        Vector3 min_1  = Vector3::inf();
        Vector3 max_1  = -Vector3::inf();
        double  rad_1  = 0;

        // Quake's axes are permuted and scaled
        double scale[3]   = {-.07, .07, -.07};
        int    permute[3] = {2, 0, 1};
        int v, i;
        for (v = 0; v < header.numVertices; ++v) {

            Vector3& vertex = keyFrame[f].vertexArray[v];
            for (i = 0; i < 3; ++i) {
                vertex[permute[i]] = (b.readUInt8() * md2Frame.scale[i] + md2Frame.translate[i]) * float(scale[permute[i]]);
            }

            vertex *= resize;

            uint8 normalIndex = b.readUInt8();
            debugAssertM(normalIndex < 162, "Illegal canonical normal index in file");
            keyFrame[f].normalArray[v] = iClamp(normalIndex, 0, 161);

            min_1 = min_1.min(vertex);
            max_1 = max_1.max(vertex);

            if (vertex.squaredMagnitude() > rad_1) {
                rad_1 = vertex.squaredMagnitude();
            }
        }

        frameMin[f] = min_1;
        frameMax[f] = max_1;
        frameRad[f] = sqrt(rad_1);

        min = min.min(min_1);
        max = max.max(max_1);

        if (rad_1 > rad) {
            rad = rad_1;
        }
    }

    // Compute per-animation bounds based on frame bounds
    for (int a = 0; a < JUMP; ++a) {
        const int first = animationTable[a].first;
        const int last  = animationTable[a].last;

        if ((first < header.numFrames) && (last < header.numFrames)) {
            Vector3 min = frameMin[first];
            Vector3 max = frameMax[first];
            double rad  = frameRad[first];

            for (int i = first + 1; i <= last; ++i) {
                min = min.min(frameMin[i]);
                max = max.max(frameMax[i]);
                rad = G3D::max(rad, frameRad[i]);
            }

            animationBoundingBox[a]    = AABox(min, max);

            // Sometimes the sphere bounding the box is tighter than the one we calculated.
            const float boxRadSq = (max-min).squaredMagnitude() * 0.25f;

            if (boxRadSq >= square(rad)) {
                animationBoundingSphere[a] = Sphere(Vector3::zero(), (float)rad);
            } else {
                animationBoundingSphere[a] = Sphere((max + min) * 0.5f, sqrt(boxRadSq));
            }

        } else {
            // This animation is not supported by this model
            animationBoundingBox[a]    = AABox(Vector3::zero(), Vector3::zero());
            animationBoundingSphere[a] = Sphere(Vector3::zero(), 0);
        }
    }

    animationBoundingBox[JUMP] = animationBoundingBox[JUMP_DOWN];
    animationBoundingSphere[JUMP] = animationBoundingSphere[JUMP_DOWN];

    boundingBox    = AABox(min, max);
    boundingSphere = Sphere(Vector3::zero(), (float)sqrt(rad));

    // Load the texture coords
    Array<Vector2int16> fileTexCoords;
    fileTexCoords.resize(header.numTexCoords);
    b.setPosition(header.offsetTexCoords);
    for (int t = 0; t < fileTexCoords.size(); ++t) {
        fileTexCoords[t].x = b.readUInt16();
        fileTexCoords[t].y = b.readUInt16();
    }

    // The indices for the texture coords (which don't match the
    // vertex indices originally).
    indexArray.resize(header.numTriangles * 3);
    Array<Vector2int16> index_texCoordArray;
    index_texCoordArray.resize(indexArray.size());

    // Read the triangles, reversing them to get triangle list order
    b.setPosition(header.offsetTriangles);
    for (int t = header.numTriangles - 1; t >= 0; --t) {

        for (int i = 2; i >= 0; --i) {
            indexArray[t * 3 + i] = b.readUInt16();
        }

        for (int i = 2; i >= 0; --i) {
            index_texCoordArray[t * 3 + i] = fileTexCoords[b.readUInt16()];
        }
    }

    computeTexCoords(index_texCoordArray);

    // Read the primitives
    {
        primitiveArray.clear();
        b.setPosition(header.offsetGlCommands);
        
        int n = b.readInt32();

        while (n != 0) {
            Primitive& primitive = primitiveArray.next();

            if (n > 0) {
                primitive.type = PrimitiveType::TRIANGLE_STRIP;
            } else {
                primitive.type = PrimitiveType::TRIANGLE_FAN;
                n = -n;
            }

            primitive.pvertexArray.resize(n);

            Array<Primitive::PVertex>&  pvertex = primitive.pvertexArray;

            for (int i = 0; i < pvertex.size(); ++i) {
                pvertex[i].texCoord.x = b.readFloat32();
                pvertex[i].texCoord.y = b.readFloat32();
                pvertex[i].index      = b.readInt32();
            }

            n = b.readInt32();
        }
    }


    MeshAlg::computeAdjacency(keyFrame[0].vertexArray, indexArray, faceArray, edgeArray, vertexArray);
    weldedFaceArray = faceArray;
    weldedEdgeArray = edgeArray;
    weldedVertexArray = vertexArray;
    MeshAlg::weldAdjacency(keyFrame[0].vertexArray, weldedFaceArray, weldedEdgeArray, weldedVertexArray);

    numBoundaryEdges = MeshAlg::countBoundaryEdges(edgeArray);
    numWeldedBoundaryEdges = MeshAlg::countBoundaryEdges(weldedEdgeArray);

    shared_ptr<VertexBuffer> indexBuffer = 
        VertexBuffer::create(indexArray.size() * sizeof(int), VertexBuffer::WRITE_ONCE);
    indexVAR = IndexStream(indexArray, indexBuffer);
}
Example #12
0
void test( const std::string & meshFile, const uint_t numProcesses, const uint_t numTotalBlocks )
{
   auto mesh = make_shared<MeshType>();
   mesh::readAndBroadcast( meshFile, *mesh);

   auto aabb = computeAABB( *mesh );

   auto domainAABB = aabb.getScaled( typename MeshType::Scalar(3) );

   auto triDist = make_shared< mesh::TriangleDistance<MeshType> >( mesh );
   auto distanceOctree = make_shared< DistanceOctree< MeshType > >( triDist );

   const real_t meshVolume  = real_c( computeVolume( *mesh ) );
   const real_t blockVolume = meshVolume / real_c( numTotalBlocks );
   static const real_t cellsPersBlock = real_t(1000);
   const real_t cellVolume = blockVolume / cellsPersBlock;
   const Vector3<real_t> cellSize( std::pow( cellVolume, real_t(1) / real_t(3) ) );

   ComplexGeometryStructuredBlockforestCreator bfc( domainAABB, cellSize, makeExcludeMeshInterior( distanceOctree, cellSize.min() ) );
   auto wl = mesh::makeMeshWorkloadMemory( distanceOctree, cellSize );
   wl.setInsideCellWorkload(0);
   wl.setOutsideCellWorkload(1);
   wl.setForceZeroMemoryOnZeroWorkload(true);
   bfc.setWorkloadMemorySUIDAssignmentFunction( wl );
   bfc.setRefinementSelectionFunction( makeRefinementSelection( distanceOctree, 5, cellSize[0], cellSize[0] * real_t(5) ) );

   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with StaticLevelwiseCurveBalanceWeighted Partitioner" );
   bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseCurveBalanceWeighted() );
   auto sbf_default = bfc.createSetupBlockForest( Vector3<uint_t>(64,64,64), numProcesses );
   //sbf_default->writeVTKOutput("sbf_default");
   WALBERLA_LOG_INFO_ON_ROOT( sbf_default->toString() );

   return;
#ifdef WALBERLA_BUILD_WITH_PARMETIS

   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with ParMetis (PART_KWAY, no commweights)" );
   bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseParMetis( blockforest::StaticLevelwiseParMetis::PARMETIS_PART_KWAY ) );
   auto sbf = bfc.createSetupBlockForest( numTotalBlocks, numProcesses );
   //sbf->writeVTKOutput("sbf");
   WALBERLA_LOG_INFO_ON_ROOT( sbf->toString() );


   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with ParMetis (PART_KWAY, commweights)" );
   bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseParMetis( commInXDirection, blockforest::StaticLevelwiseParMetis::PARMETIS_PART_KWAY ) );
   auto sbf_edge = bfc.createSetupBlockForest( numTotalBlocks, numProcesses );
   //sbf_edge->writeVTKOutput("sbf_edge");
   WALBERLA_LOG_INFO_ON_ROOT( sbf_edge->toString() );

   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with ParMetis (PART_GEOM_KWAY, no commweights)" );
   bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseParMetis( blockforest::StaticLevelwiseParMetis::PARMETIS_PART_GEOM_KWAY ) );
   auto sbf_geom = bfc.createSetupBlockForest( numTotalBlocks, numProcesses );
   //sbf_geom->writeVTKOutput("sbf_geom");
   WALBERLA_LOG_INFO_ON_ROOT( sbf_geom->toString() );


   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with ParMetis (PART_GEOM_KWAY, commweights)" );
   bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseParMetis( commInXDirection, blockforest::StaticLevelwiseParMetis::PARMETIS_PART_GEOM_KWAY ) );
   auto sbf_geom_edge = bfc.createSetupBlockForest( numTotalBlocks, numProcesses );
   //sbf_geom_edge->writeVTKOutput("sbf_geom_edge");
   WALBERLA_LOG_INFO_ON_ROOT( sbf_geom_edge->toString() );

#endif
}