vector<int*> outPut::choosePoints() { glfwEnable( GLFW_KEY_REPEAT ); _points.clear(); TwBar *b_points = TwNewBar("Points stratégiques"); coords<int> curPoint((float)_dimensions.x/2.0, (float)_dimensions.y/2.0); bool done(false), addCurrent(false), addRandom(false); coords3d<float> vertex(0,0,0); TwAddVarRW(b_points, "x", TW_TYPE_INT32, &(curPoint.x), "keyincr = RIGHT keydecr = LEFT" ); TwAddVarRW(b_points, "y", TW_TYPE_INT32, &(curPoint.y), "keyincr = UP keydecr = DOWN" ); TwAddVarRW(b_points, "Fini", TW_TYPE_BOOLCPP, &(done), "key = RETURN" ); TwAddVarRW(b_points, "Ajouter courant", TW_TYPE_BOOLCPP, &(addCurrent), "key = SPACE" ); TwAddVarRW(b_points, "Ajouter au hasard", TW_TYPE_BOOLCPP, &(addRandom), "key = 'r'" ); TwAddVarRW(b_points, "Pente max", TW_TYPE_INT32, &(_status.maxDiff), "keyincr=o keydecr=l"); while((!done || _points.size() < 2) && _status.running) { setScene(); drawScene(); glDisable(GL_DEPTH_TEST); glUseProgram(_sNolight.getProgramID()); curPoint.x = clamp(curPoint.x, 1, _dimensions.x-1); curPoint.y = clamp(curPoint.y, 1, _dimensions.y-1); vertex = getVertex<float>(curPoint.x,curPoint.y); _scene3d.focus.x = curPoint.x; _scene3d.focus.y = curPoint.y; if(addRandom) { addCurrent = true; addRandom = false; curPoint.x = rand()%(_dimensions.x-1); curPoint.y = rand()%(_dimensions.y-1); } if(addCurrent) { _points.push_back(curPoint); addCurrent = false; } glBegin(GL_POINTS); glColor3ub(0,255,0); glVertex3d(vertex.x, vertex.y, vertex.z); glEnd(); display(); } unsigned int n = _points.size(); std::cout << "nb de bombes : " << n << std::endl; vector<int*> bombList(n, NULL); for(unsigned int i = 0; i<n;i++) { bombList[i] = new int[n+2]; for(unsigned int j = 0; j < n+2; ++j) { bombList[i][j] = 0; } bombList[i][n+2-2] = _points[i].x; bombList[i][n+2-1] = _points[i].y; } TwDeleteBar(b_points); TwDefine(" Scene/x keyincr = RIGHT keydecr = LEFT"); TwDefine(" Scene/y keyincr = UP keydecr = DOWN"); return bombList; }
pair<btVector3,btConvexHullShape*> createConvexHullShapeFromConvexResult(ConvexResult &result, btVector3 localScaling ) { btTriangleMesh* trimesh = new btTriangleMesh(); //m_convexDemo->m_trimeshes.push_back(trimesh); btConvexHullShape* convexShape = NULL; btVector3 centroid(0,0,0); //calc centroid, to shift vertices around center of mass btAlignedObjectArray<btVector3> vertices; if ( 1 ) { //const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullVcount; i++) { btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]); vertex *= localScaling; centroid += vertex; } } centroid *= 1.f/(float(result.mHullVcount) ); if ( 1 ) { //const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullVcount; i++) { btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]); vertex *= localScaling; vertex -= centroid ; vertices.push_back(vertex); } } if ( 1 ) { const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullTcount; i++) { unsigned int index0 = *src++; unsigned int index1 = *src++; unsigned int index2 = *src++; btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]); btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]); btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]); vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; vertex0 -= centroid; vertex1 -= centroid; vertex2 -= centroid; trimesh->addTriangle(vertex0,vertex1,vertex2); } } // float mass = 1.f; //this is a tools issue: due to collision margin, convex objects overlap, compensate for it here: //#define SHRINK_OBJECT_INWARDS 1 #ifdef SHRINK_OBJECT_INWARDS float collisionMargin = 0.01f; btAlignedObjectArray<btVector3> planeEquations; btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations); btAlignedObjectArray<btVector3> shiftedPlaneEquations; for (int p=0;p<planeEquations.size();p++) { btVector3 plane = planeEquations[p]; plane[3] += collisionMargin; shiftedPlaneEquations.push_back(plane); } btAlignedObjectArray<btVector3> shiftedVertices; btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices); convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size()); #else //SHRINK_OBJECT_INWARDS convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); #endif convexShape->setMargin(0.01f); delete trimesh; return make_pair(centroid,convexShape); }
const V& operator[] (int vidx) const { return vertex(vidx); }
void tDxfSpline::UpdateControlPoints() { controlPoints.clear(); //tList<tVector> controlPoints; int n = nVertices(); if(isClosed && n < 3) { if(n > 0) controlPoints.append(vertex(0)->vector()); if(n > 1) controlPoints.append(vertex(1)->vector()); return; } if(isClosed && n < 4) { if(n > 0) controlPoints.append(vertex(0)->vector()); if(n > 2) { tVector x1 = vertex(0)->vector(), x2 = vertex(1)->vector(), x3 = vertex(2)->vector(); double dl1 = (x2 - x1).length(); double dl2 = (x3 - x2).length(); double dt = dl1/(dl1 + dl2); if(dt < RS_TOLERANCE || dt > 1.0 - RS_TOLERANCE) //return RS_Vector(false); controlPoints.append((x2 - x1*(1.0 - dt)*(1.0 - dt) - x3*dt*dt)*(1./dt/(1 - dt)/2.0)); } if(n > 1) { controlPoints.append(vertex(n - 1)->vector()); } return; } int iDim = 0; if(isClosed) { iDim = n; } else { iDim = n - 2; } double *dt = new double[iDim]; double dl1, dl2; if(isClosed) { dl1 = (vertex(n - 1)->vector() - vertex(0)->vector()).length(); dl2 = (vertex(1)->vector() - vertex(0)->vector()).length(); dt[0] = dl1/(dl1 + dl2); for(int i = 1; i < iDim - 1; i++) { dl1 = dl2; dl2 = (vertex(i + 1)->vector() - vertex(i)->vector()).length(); dt[i] = dl1/(dl1 + dl2); } dl1 = (vertex(n - 1)->vector() - vertex(n - 2)->vector()).length(); dl2 = (vertex(0)->vector() - vertex(n - 1)->vector()).length(); dt[iDim - 1] = dl1/(dl1 + dl2); } else { dl1 = (vertex(1)->vector() - vertex(0)->vector()).length(); dl2 = (vertex(2)->vector() - vertex(1)->vector()).length(); dt[0] = dl1/(dl1 + dl2/2.0); for(int i = 1; i < iDim - 1; i++) { dl1 = dl2; dl2 = (vertex(i + 2)->vector() - vertex(i + 1)->vector()).length(); dt[i] = dl1/(dl1 + dl2); } dl1 = dl2; dl2 = (vertex(iDim)->vector() - vertex(iDim + 1)->vector()).length(); dt[iDim - 1] = dl1/(dl1 + 2.0*dl2); } double *pdMatrix = GetMatrix(n, dt); if(!pdMatrix) return; tVector *dx = new tVector[iDim], *dx2 = new tVector[iDim]; /*double *dx = new double[iDim]; double *dy = new double[iDim]; double *dx2 = new double[iDim]; double *dy2 = new double[iDim];*/ if(isClosed) { double *pdDiag = pdMatrix; double *pdDiag1 = &pdMatrix[n]; double *pdDiag2 = &pdMatrix[2*n - 1]; double *pdLastCol1 = &pdMatrix[3*n - 2]; double *pdLastCol2 = &pdMatrix[4*n - 4]; dx[0] = vertex(0)->vector() * (1./pdDiag[0]); //dx[0] = vertex(0).x/pdDiag[0]; //dy[0] = vertex(0).y/pdDiag[0]; for(int i = 1; i < iDim - 1; i++) { dx[i] = (vertex(i)->vector() - dx[i-1]*pdDiag2[i-1])*(1./pdDiag[i]); //dx[i] = (vertex(i).x - pdDiag2[i - 1]*dx[i - 1])/pdDiag[i]; //dy[i] = (vertex(i).y - pdDiag2[i - 1]*dy[i - 1])/pdDiag[i]; } dx[iDim-1] = vertex(iDim - 1)->vector() - dx[iDim - 2]*pdDiag2[iDim - 2]; //dx[iDim - 1] = vertex(iDim - 1).x - pdDiag2[iDim - 2]*dx[iDim - 2]; //dy[iDim - 1] = vertex(iDim - 1).y - pdDiag2[iDim - 2]*dy[iDim - 2]; for(int i = 0; i < iDim - 2; i++) { dx[iDim-1] = dx[iDim-1] - (dx[i] * pdLastCol2[i]); //dx[iDim - 1] -= (dx[i]*pdLastCol2[i]); //dy[iDim - 1] -= (dy[i]*pdLastCol2[i]); } dx[iDim-1] = dx[iDim-1] * (1./pdDiag[iDim - 1]); //dx[iDim - 1] /= pdDiag[iDim - 1]; //dy[iDim - 1] /= pdDiag[iDim - 1]; dx2[iDim-1] = dx[iDim-1]*(1./pdDiag[iDim-1]); //dx2[iDim - 1] = dx[iDim - 1]/pdDiag[iDim - 1]; //dy2[iDim - 1] = dy[iDim - 1]/pdDiag[iDim - 1]; dx2[iDim-2] = (dx[iDim-2]-dx2[iDim-1]*pdDiag1[iDim-2])*(1./pdDiag[iDim - 2]); //dx2[iDim - 2] = (dx[iDim - 2] - pdDiag1[iDim - 2]*dx2[iDim - 1])/pdDiag[iDim - 2]; //dy2[iDim - 2] = (dy[iDim - 2] - pdDiag1[iDim - 2]*dy2[iDim - 1])/pdDiag[iDim - 2]; for(int i = iDim - 3; i >= 0; i--) { dx2[i] = (dx[i] - dx2[i + 1]*pdDiag1[i] - dx2[iDim - 1]*pdLastCol1[i])*(1./pdDiag[i]); //dx2[i] = (dx[i] - pdDiag1[i]*dx2[i + 1] - pdLastCol1[i]*dx2[iDim - 1])/pdDiag[i]; //dy2[i] = (dy[i] - pdDiag1[i]*dy2[i + 1] - pdLastCol1[i]*dy2[iDim - 1])/pdDiag[i]; } for(int i = 0; i < iDim; i++) { controlPoints.append(dx2[i]); } } else { double *pdDiag = pdMatrix; double *pdDiag1 = &pdMatrix[n - 2]; double *pdDiag2 = &pdMatrix[2*n - 5]; dx[0] = (vertex(1)->vector() - vertex(0)->vector()*(1.0-dt[0]) * (1.0 - dt[0]))*(1./pdDiag[0]); //dx[0] = (vertex(1).x - vertex(0).x*(1.0 - dt[0])*(1.0 - dt[0]))/pdDiag[0]; //dy[0] = (vertex(1).y - vertex(0).y*(1.0 - dt[0])*(1.0 - dt[0]))/pdDiag[0]; for(int i = 1; i < iDim - 1; i++) { dx[i] = (vertex(i + 1)->vector() - dx[i-1]*pdDiag2[i-1])*(1./pdDiag[i]); //dx[i] = (vertex(i + 1).x - pdDiag2[i - 1]*dx[i - 1])/pdDiag[i]; //dy[i] = (vertex(i + 1).y - pdDiag2[i - 1]*dy[i - 1])/pdDiag[i]; } dx[iDim-1] = ((vertex(iDim)->vector() - vertex(iDim + 1)->vector()*dt[n-3]*dt[n-3]) - dx[iDim-2]*pdDiag2[iDim-2])*(1./pdDiag[iDim-1]); //dx[iDim - 1] = ((vertex(iDim).x - vertex(iDim + 1).x*dt[n - 3]*dt[n - 3]) - // pdDiag2[iDim - 2]*dx[iDim - 2])/pdDiag[iDim - 1]; //dy[iDim - 1] = ((vertex(iDim).y - vertex(iDim + 1).y*dt[n - 3]*dt[n - 3]) - // pdDiag2[iDim - 2]*dy[iDim - 2])/pdDiag[iDim - 1]; dx2[iDim-1] = dx[iDim-1]*(1./pdDiag[iDim - 1]); //dx2[iDim - 1] = dx[iDim - 1]/pdDiag[iDim - 1]; //dy2[iDim - 1] = dy[iDim - 1]/pdDiag[iDim - 1]; for(int i = iDim - 2; i >= 0; i--) { dx2[i] = (dx[i]-dx2[i+1]*pdDiag1[i])*(1./pdDiag[i]); //dx2[i] = (dx[i] - pdDiag1[i]*dx2[i + 1])/pdDiag[i]; //dy2[i] = (dy[i] - pdDiag1[i]*dy2[i + 1])/pdDiag[i]; } controlPoints.append(vertex(0)->vector()); for(int i = 0; i < iDim; i++) { controlPoints.append(dx2[i]); } controlPoints.append(vertex(n - 1)->vector()); } delete[] pdMatrix; delete[] dt; //delete[] dy2; delete[] dx2; //delete[] dy; delete[] dx; }
vector<pair<btVector3, btConvexHullShape*> > ofxBulletConvexDecomposer::decompose(const ofMesh &meshToDecompose, btVector3 scale ) { assert( meshToDecompose.getMode() == OF_TRIANGLES_MODE ); vector<pair<btVector3, btConvexHullShape*> > convexShapes; int tcount = meshToDecompose.getNumIndices()/3; if ( tcount == 0 ) // nothing to do return convexShapes; // adapted from bullet-2.81-rev2613/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp /* unsigned int depth = 5; float cpercent = 5; float ppercent = 15; unsigned int maxv = 16; float skinWidth = 0.0; // ConvexDecomposition::WavefrontObj wo; ConvexDecomposition::DecompDesc desc; desc.mVcount = meshToDecompose.getNumVertices(); desc.mVertices = (float*)(meshToDecompose.getVerticesPointer()); desc.mTcount = meshToDecompose.getNumIndices()/3; desc.mIndices = meshToDecompose.getIndexPointer(); desc.mDepth = depth; desc.mCpercent = cpercent; desc.mPpercent = ppercent; desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; desc.mCallback = this; */ //----------------------------------------------- // HACD //----------------------------------------------- std::vector< HACD::Vec3<HACD::Real> > points; std::vector< HACD::Vec3<long> > triangles; for(int i=0; i<meshToDecompose.getNumVertices(); i++ ) { ofVec3f meshVert = meshToDecompose.getVertex(i); HACD::Vec3<HACD::Real> vertex( meshVert.x, meshVert.y, meshVert.z ); points.push_back(vertex); } for(int i=0;i<meshToDecompose.getNumIndices(); i+=3 ) { HACD::Vec3<long> triangle(meshToDecompose.getIndex(i), meshToDecompose.getIndex(i+1), meshToDecompose.getIndex(i+2) ); triangles.push_back(triangle); } assert(triangles.size()==tcount); HACD::HACD myHACD; myHACD.SetPoints(&points[0]); myHACD.SetNPoints(points.size()); myHACD.SetTriangles(&triangles[0]); myHACD.SetNTriangles(triangles.size()); myHACD.SetCompacityWeight(0.1); myHACD.SetVolumeWeight(0.0); // HACD parameters // Recommended parameters: 2 100 0 0 0 0 size_t nClusters = 2; double concavity = 100; bool invert = false; bool addExtraDistPoints = false; bool addNeighboursDistPoints = false; bool addFacesPoints = false; myHACD.SetNClusters(nClusters); // minimum number of clusters myHACD.SetNVerticesPerCH(100); // max of 100 vertices per convex-hull myHACD.SetConcavity(concavity); // maximum concavity myHACD.SetAddExtraDistPoints(addExtraDistPoints); myHACD.SetAddNeighboursDistPoints(addNeighboursDistPoints); myHACD.SetAddFacesPoints(addFacesPoints); myHACD.SetCallBack( hacdCallback ); myHACD.Compute(); nClusters = myHACD.GetNClusters(); int totalTriangles = 0; int totalPoints = 0; for (int c=0;c<nClusters;c++) { //generate convex result size_t nPoints = myHACD.GetNPointsCH(c); size_t nTriangles = myHACD.GetNTrianglesCH(c); ofLogVerbose("ofxBulletConvexDecomposer") << "cluster " << c <<"/" << nClusters << " points " << nPoints << " triangles " << nTriangles; float* vertices = new float[nPoints*3]; unsigned int* triangles = new unsigned int[nTriangles*3]; HACD::Vec3<HACD::Real> * pointsCH = new HACD::Vec3<HACD::Real>[nPoints]; HACD::Vec3<long> * trianglesCH = new HACD::Vec3<long>[nTriangles]; myHACD.GetCH(c, pointsCH, trianglesCH); // points for(size_t v = 0; v < nPoints; v++) { vertices[3*v] = pointsCH[v].X(); vertices[3*v+1] = pointsCH[v].Y(); vertices[3*v+2] = pointsCH[v].Z(); } // triangles for(size_t f = 0; f < nTriangles; f++) { triangles[3*f] = trianglesCH[f].X(); triangles[3*f+1] = trianglesCH[f].Y(); triangles[3*f+2] = trianglesCH[f].Z(); } ConvexResult r(nPoints, vertices, nTriangles, triangles); convexShapes.push_back( createConvexHullShapeFromConvexResult(r, scale) ); delete [] pointsCH; delete [] trianglesCH; delete [] vertices; delete [] triangles; totalTriangles += nTriangles; } return convexShapes; }
PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutSize& logicalBoxSize, WritingMode writingMode, float margin) { ASSERT(basicShape); bool horizontalWritingMode = isHorizontalWritingMode(writingMode); float boxWidth = horizontalWritingMode ? logicalBoxSize.width().toFloat() : logicalBoxSize.height().toFloat(); float boxHeight = horizontalWritingMode ? logicalBoxSize.height().toFloat() : logicalBoxSize.width().toFloat(); OwnPtr<Shape> shape; switch (basicShape->type()) { case BasicShape::BasicShapeCircleType: { const BasicShapeCircle* circle = toBasicShapeCircle(basicShape); FloatPoint center = floatPointForCenterCoordinate(circle->centerX(), circle->centerY(), FloatSize(boxWidth, boxHeight)); float radius = circle->floatValueForRadiusInBox(FloatSize(boxWidth, boxHeight)); FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize.height().toFloat(), writingMode); shape = createCircleShape(logicalCenter, radius); break; } case BasicShape::BasicShapeEllipseType: { const BasicShapeEllipse* ellipse = toBasicShapeEllipse(basicShape); FloatPoint center = floatPointForCenterCoordinate(ellipse->centerX(), ellipse->centerY(), FloatSize(boxWidth, boxHeight)); float radiusX = ellipse->floatValueForRadiusInBox(ellipse->radiusX(), center.x(), boxWidth); float radiusY = ellipse->floatValueForRadiusInBox(ellipse->radiusY(), center.y(), boxHeight); FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize.height().toFloat(), writingMode); shape = createEllipseShape(logicalCenter, FloatSize(radiusX, radiusY)); break; } case BasicShape::BasicShapePolygonType: { const BasicShapePolygon* polygon = toBasicShapePolygon(basicShape); const Vector<Length>& values = polygon->values(); size_t valuesSize = values.size(); ASSERT(!(valuesSize % 2)); OwnPtr<Vector<FloatPoint> > vertices = adoptPtr(new Vector<FloatPoint>(valuesSize / 2)); for (unsigned i = 0; i < valuesSize; i += 2) { FloatPoint vertex( floatValueForLength(values.at(i), boxWidth), floatValueForLength(values.at(i + 1), boxHeight)); (*vertices)[i / 2] = physicalPointToLogical(vertex, logicalBoxSize.height().toFloat(), writingMode); } shape = createPolygonShape(vertices.release(), polygon->windRule()); break; } case BasicShape::BasicShapeInsetType: { const BasicShapeInset& inset = *toBasicShapeInset(basicShape); float left = floatValueForLength(inset.left(), boxWidth); float top = floatValueForLength(inset.top(), boxHeight); float right = floatValueForLength(inset.right(), boxWidth); float bottom = floatValueForLength(inset.bottom(), boxHeight); FloatRect rect(left, top, std::max<float>(boxWidth - left - right, 0), std::max<float>(boxHeight - top - bottom, 0)); FloatRect logicalRect = physicalRectToLogical(rect, logicalBoxSize.height().toFloat(), writingMode); FloatSize boxSize(boxWidth, boxHeight); FloatSize topLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topLeftRadius(), boxSize), writingMode); FloatSize topRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topRightRadius(), boxSize), writingMode); FloatSize bottomLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomLeftRadius(), boxSize), writingMode); FloatSize bottomRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomRightRadius(), boxSize), writingMode); FloatRoundedRect::Radii cornerRadii(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); cornerRadii.scale(calcBorderRadiiConstraintScaleFor(logicalRect, cornerRadii)); shape = createInsetShape(FloatRoundedRect(logicalRect, cornerRadii)); break; } default: ASSERT_NOT_REACHED(); } shape->m_writingMode = writingMode; shape->m_margin = margin; return shape.release(); }
static hkpShapeCollection* createMeshShape( const int side, hkArray<hkReferencedObject*>& delayedCleanup ) { #ifdef CLIENT_LANDSCAPE hkString assetFile = hkAssetManagementUtil::getFilePath(CLIENT_LANDSCAPE); hkIfstream fileIn(assetFile.cString()); hkResource* data = hkSerializeUtil::load(assetFile.cString()); delayedCleanup.pushBack( data ); hkpSimpleMeshShape* meshShape = data->getContents<hkpSimpleMeshShape>(); hkpStorageExtendedMeshShape* extendedMesh = new hkpStorageExtendedMeshShape(); hkpExtendedMeshShape::TrianglesSubpart part; part.m_numTriangleShapes = meshShape->m_triangles.getSize(); part.m_numVertices = meshShape->m_vertices.getSize(); part.m_vertexBase = (float*)meshShape->m_vertices.begin(); part.m_stridingType = hkpExtendedMeshShape::INDICES_INT32; part.m_vertexStriding = sizeof(hkVector4); part.m_indexBase = meshShape->m_triangles.begin(); part.m_indexStriding = sizeof(hkpSimpleMeshShape::Triangle); extendedMesh->addTrianglesSubpart( part ); return extendedMesh; #else hkpSimpleMeshShape* meshShape = new hkpSimpleMeshShape( 0.05f /*radius*/); hkReal scaleHoriz = 400.0f / side; hkReal scaleVert = 1.0f; { meshShape->m_vertices.setSize( side * side ); for(int i = 0; i < side; i++) { for (int j = 0; j < side; j++ ) { hkVector4 vertex ( scaleHoriz * (i * 1.0f - (side-1) * 0.5f), scaleVert * (0.6f * hkMath::cos((hkReal)j + i) + 0.3f * hkMath::sin( 2.0f * i) ), scaleHoriz * (j * 1.0f - (side-1) * 0.5f)); meshShape->m_vertices[i*side + j] = vertex ; } } } { meshShape->m_triangles.setSize( (side-1) * (side-1) * 2); int corner = 0; int curTri = 0; for(int i = 0; i < side - 1; i++) { for (int j = 0; j < side - 1; j++ ) { meshShape->m_triangles[curTri].m_a = corner+1; meshShape->m_triangles[curTri].m_b = corner+side; meshShape->m_triangles[curTri].m_c = corner; curTri++; meshShape->m_triangles[curTri].m_a = corner+side+1; meshShape->m_triangles[curTri].m_b = corner+side; meshShape->m_triangles[curTri].m_c = corner+1; curTri++; corner++; } corner++; } } return meshShape; #endif }
// Try to find a path from the lower-left-hand corner source (0,0) to the // upper-right-hand corner goal (x-1, y-1). vertex_descriptor source() const {return vertex(0, m_grid);}
vertex_descriptor goal() const { return vertex(num_vertices(m_grid)-1, m_grid); }
bool OptimizableGraph::load(istream& is, bool createEdges) { // scna for the paramers in the whole file if (!_parameters.read(is)) return false; cerr << "Loaded " << _parameters.size() << " parameters" << endl; is.clear(); is.seekg(ios_base::beg); set<string> warnedUnknownTypes; stringstream currentLine; string token; Factory* factory = Factory::instance(); HyperGraph::GraphElemBitset elemBitset; elemBitset[HyperGraph::HGET_PARAMETER] = 1; elemBitset.flip(); Vertex* previousVertex = 0; while (1) { int bytesRead = readLine(is, currentLine); if (bytesRead == -1) break; currentLine >> token; if (bytesRead == 0 || token.size() == 0 || token[0] == '#') continue; // handle commands encoded in the file bool handledCommand = false; if (token == "FIX") { handledCommand = true; int id; while (currentLine >> id) { OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(vertex(id)); if (v) { # ifndef NDEBUG cerr << "Fixing vertex " << v->id() << endl; # endif v->setFixed(true); } else { cerr << "Warning: Unable to fix vertex with id " << id << ". Not found in the graph." << endl; } } } if (handledCommand) continue; // do the mapping to an internal type if it matches if (_renamedTypesLookup.size() > 0) { map<string, string>::const_iterator foundIt = _renamedTypesLookup.find(token); if (foundIt != _renamedTypesLookup.end()) { token = foundIt->second; } } if (! factory->knowsTag(token)) { if (warnedUnknownTypes.count(token) != 1) { warnedUnknownTypes.insert(token); cerr << CL_RED(__PRETTY_FUNCTION__ << " unknown type: " << token) << endl; } continue; } HyperGraph::HyperGraphElement* element = factory->construct(token, elemBitset); if (dynamic_cast<Vertex*>(element)) { // it's a vertex type Vertex* v = static_cast<Vertex*>(element); int id; currentLine >> id; bool r = v->read(currentLine); if (! r) cerr << __PRETTY_FUNCTION__ << ": Error reading vertex " << token << " " << id << endl; v->setId(id); if (!addVertex(v)) { cerr << __PRETTY_FUNCTION__ << ": Failure adding Vertex, " << token << " " << id << endl; delete v; } else { previousVertex = v; } }
typename DIRECTED_GRAPH::vertex_descriptor vertex(typename DIRECTED_GRAPH::vertices_size_type n, DIRECTED_GRAPH const& g) { return vertex(n, g.impl()); }
void ConvexPolygon::booleanDifference(const ConvexPolygon &hole, std::vector<ConvexPolygon> &list) const { // Special case: this polygon is entirely swallowed by the hole if(hole.envelopes(*this)) return; // Special case: the hole is entirely inside this polygon if(envelopes(hole)) { Points p1, p2; splitPolygon(*this, hole, p1, p2); ConvexPolygon::make(p1, list); ConvexPolygon::make(p2, list); return; } // Common case: hole intersects with this polygon. std::vector<bool> visited(vertexCount()); std::queue<unsigned int> queue; queue.push(0); // Perform intersection unsigned int oldsize = list.size(); Points poly; while(!queue.empty()) { int i = queue.front(); while(i < vertexCount()) { // Stop if we've already been here if(visited[i]) break; visited[i] = true; // Include point if it is not inside the hole bool inhole = hole.hasPoint(vertex(i)); if(!inhole) poly.push_back(vertex(i)); // Check for intersections Point isect[2]; int isectv[2]; findIntersections(*this, i, i+1, hole, isect, isectv); if(isectv[0] >= 0) { // Intersection found: this is the start of a hole, // except when this edge started inside the hole. poly.push_back(isect[0]); if(!inhole) { // Start tracing the hole int j = isectv[0]; do { // Check for intersections // The first hole edge may intersect with another edges Point hisect[2]; int hisectv[2]; findIntersections(hole, j+1, j, *this, hisect, hisectv); // There is always one intersection (the one that got us here) if((j == isectv[0] && hisectv[1] >= 0) || (j != isectv[0] && hisectv[0] >= 0)) { // Pick the intersection that is not the one we came in on Point ip; int iv; if(hisectv[1] < 0 || glm::distance2(hisect[0],isect[0]) > glm::distance(hisect[1],isect[0])) { ip = hisect[0]; iv = hisectv[0]; } else { ip = hisect[1]; iv = hisectv[1]; } queue.push(i+1); // Avoid adding duplicate point of origin if(glm::distance2(poly.front(), ip) > 0.0001) poly.push_back(ip); i = iv; break; } else { // No intersections? Just add the hole vertex then poly.push_back(hole.vertex(j)); } if(--j < 0) j = hole.vertexCount() - 1; } while(j != isectv[0]); } } ++i; } // Partition the generated polygon into convex polygons // and add them to the list. if(poly.size() >= 3) { try { ConvexPolygon::make(poly, list); } catch(const algorithm::GeometryException &e) { // Bad polygons generated... The algorithm works well // enough most of the time, let's just roll back the error. int changes = list.size() - oldsize; #ifndef NDEBUG cerr << "booleanDifference error: " << e.what() << " (" << changes << " change(s) rolled back)\n"; #endif while(changes-->0) list.pop_back(); list.push_back(*this); return; } } poly.clear(); queue.pop(); } }
/******************************************************************* * Scene Renderer *******************************************************************/ void dxManager::renderScene() { //clear scene pD3DDevice->ClearRenderTargetView( pRenderTargetView, D3DXCOLOR(0,0,0,0) ); //create world matrix static float r; D3DXMATRIX w; D3DXMatrixIdentity(&w); D3DXMatrixRotationY(&w, r); r += 0.001f; //Added D3DXMATRIX w2, w3; D3DXMatrixIdentity(&w2); D3DXMatrixIdentity(&w3); D3DXMatrixRotationY(&w3, -r); D3DXMatrixRotationY(&w2, r); D3DXMatrixTranslation(&w2, 3, 3, 0); w2 = w3*w2*w; //set effect matrices pWorldMatrixEffectVariable->SetMatrix(w); pViewMatrixEffectVariable->SetMatrix(viewMatrix); pProjectionMatrixEffectVariable->SetMatrix(projectionMatrix); //fill vertex buffer with vertices UINT numVertices = 3; vertex* v = NULL; //lock vertex buffer for CPU use pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v ); v[0] = vertex( D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1) ); v[1] = vertex( D3DXVECTOR3(0,1,0), D3DXVECTOR4(0,1,0,1) ); v[2] = vertex( D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1) ); pVertexBuffer->Unmap(); // Set primitive topology pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ); //get technique desc D3D10_TECHNIQUE_DESC techDesc; pBasicTechnique->GetDesc( &techDesc ); for( UINT p = 0; p < techDesc.Passes; ++p ) { //apply technique pBasicTechnique->GetPassByIndex( p )->Apply( 0 ); //draw pD3DDevice->Draw( numVertices, 0 ); } //Added //DO THIS FOR EACH PIECE OF GEOMETRY pWorldMatrixEffectVariable->SetMatrix(w2); for( UINT p = 0; p < techDesc.Passes; ++p ) { //apply technique pBasicTechnique->GetPassByIndex( p )->Apply( 0 ); //draw pD3DDevice->Draw( numVertices, 0 ); } //flip buffers pSwapChain->Present(0,0); }
bool MeshTopologyTests::test3DMesh() { bool success = true; unsigned spaceDim = 3; unsigned hexNodeCount = 1 << spaceDim; FieldContainer<double> refHexPoints(hexNodeCount,spaceDim); CellTopoPtr hexTopo = Camellia::CellTopology::hexahedron(); CamelliaCellTools::refCellNodesForTopology(refHexPoints, hexTopo); vector< vector<double> > vertices; vector< unsigned > hexVertexIndices(hexNodeCount); vector< vector<unsigned> > elementVertices; for (unsigned nodeIndex=0; nodeIndex<hexNodeCount; nodeIndex++) { vector<double> vertex(spaceDim); for (unsigned d=0; d<spaceDim; d++) { vertex[d] = refHexPoints(nodeIndex,d); } hexVertexIndices[nodeIndex] = vertices.size(); vertices.push_back(vertex); } elementVertices.push_back(hexVertexIndices); // // note that the following will create some repeated vertices, and that's not OK -- we'll need to do something different // vector<double> eastOffset = makeVertex(2,0,0); // for (unsigned nodeIndex=0; nodeIndex<hexNodeCount; nodeIndex++) { // vector<double> vertex(spaceDim); // for (unsigned d=0; d<spaceDim; d++) { // vertex[d] = refHexPoints(nodeIndex,d) + eastOffset[d]; // } // hexVertexIndices[nodeIndex] = vertices.size(); // vertices.push_back(vertex); // } // elementVertices.push_back(hexVertexIndices); vector< CellTopoPtr > cellTopos(1,hexTopo); MeshGeometryPtr meshGeometry = Teuchos::rcp( new MeshGeometry(vertices, elementVertices, cellTopos) ); MeshTopology mesh(meshGeometry); if (mesh.cellCount() != 1) { success = false; cout << "After initialization, mesh doesn't have the expected number of cells.\n"; } if (mesh.activeCellCount() != 1) { success = false; cout << "After initialization, mesh doesn't have the expected number of active cells.\n"; } RefinementPatternPtr hexRefPattern = RefinementPattern::regularRefinementPatternHexahedron(); mesh.refineCell(0, hexRefPattern, mesh.cellCount()); if (mesh.cellCount() != 9) { success = false; cout << "After refinement, mesh doesn't have the expected number of cells.\n"; } if (mesh.activeCellCount() != 8) { success = false; cout << "After refinement, mesh doesn't have the expected number of active cells.\n"; } mesh.refineCell(1, hexRefPattern, mesh.cellCount()); if (mesh.cellCount() != 17) { success = false; cout << "After second refinement, mesh doesn't have the expected number of cells.\n"; } if (mesh.activeCellCount() != 15) { success = false; cout << "After second refinement, mesh doesn't have the expected number of active cells.\n"; } // TODO: test more than just the count. Test vertex locations, say. Test constraint counts (should be 0 here after first refinement, and there should be some constraints after the second). return success; }
// Constructor. Copy the provided picoSurface_t structure into this object RenderablePicoSurface::RenderablePicoSurface(picoSurface_t* surf, const std::string& fExt) : _shaderName(""), _dlRegular(0), _dlProgramVcol(0), _dlProgramNoVCol(0) { // Get the shader from the picomodel struct. If this is a LWO model, use // the material name to select the shader, while for an ASE model the // bitmap path should be used. picoShader_t* shader = PicoGetSurfaceShader(surf); std::string rawName = ""; if (shader != 0) { if (fExt == "lwo") { _shaderName = PicoGetShaderName(shader); } else if (fExt == "ase") { rawName = PicoGetShaderName(shader); std::string rawMapName = PicoGetShaderMapName(shader); _shaderName = cleanupShaderName(rawMapName); } } // If shader not found, fallback to alternative if available // _shaderName is empty if the ase material has no BITMAP // materialIsValid is false if _shaderName is not an existing shader if ((_shaderName.empty() || !GlobalMaterialManager().materialExists(_shaderName)) && !rawName.empty()) { _shaderName = cleanupShaderName(rawName); } // Capturing the shader happens later on when we have a RenderSystem reference // Get the number of vertices and indices, and reserve capacity in our // vectors in advance by populating them with empty structs. int nVerts = PicoGetSurfaceNumVertexes(surf); _nIndices = PicoGetSurfaceNumIndexes(surf); _vertices.resize(nVerts); _indices.resize(_nIndices); // Stream in the vertex data from the raw struct, expanding the local AABB // to include each vertex. for (int vNum = 0; vNum < nVerts; ++vNum) { // Get the vertex position and colour Vertex3f vertex(PicoGetSurfaceXYZ(surf, vNum)); // Expand the AABB to include this new vertex _localAABB.includePoint(vertex); _vertices[vNum].vertex = vertex; _vertices[vNum].normal = Normal3f(PicoGetSurfaceNormal(surf, vNum)); _vertices[vNum].texcoord = TexCoord2f(PicoGetSurfaceST(surf, 0, vNum)); _vertices[vNum].colour = getColourVector(PicoGetSurfaceColor(surf, 0, vNum)); } // Stream in the index data picoIndex_t* ind = PicoGetSurfaceIndexes(surf, 0); for (unsigned int i = 0; i < _nIndices; i++) _indices[i] = ind[i]; // Calculate the tangent and bitangent vectors calculateTangents(); // Construct the DLs createDisplayLists(); }
void gen6_gs_visitor::emit_thread_end() { /* Make sure the current primitive is ended: we know it is not ended when * first_vertex is not zero. This is only relevant for outputs other than * points because in the point case we set PrimEnd on all vertices. */ if (c->gp->program.OutputType != GL_POINTS) { emit(CMP(dst_null_d(), this->first_vertex, 0u, BRW_CONDITIONAL_Z)); emit(IF(BRW_PREDICATE_NORMAL)); { visit((ir_end_primitive *) NULL); } emit(BRW_OPCODE_ENDIF); } /* Here we have to: * 1) Emit an FF_SYNC messsage to obtain an initial VUE handle. * 2) Loop over all buffered vertex data and write it to corresponding * URB entries. * 3) Allocate new VUE handles for all vertices other than the first. * 4) Send a final EOT message. */ /* MRF 0 is reserved for the debugger, so start with message header * in MRF 1. */ int base_mrf = 1; /* In the process of generating our URB write message contents, we * may need to unspill a register or load from an array. Those * reads would use MRFs 14-15. */ int max_usable_mrf = 13; /* Issue the FF_SYNC message and obtain the initial VUE handle. */ emit(CMP(dst_null_d(), this->vertex_count, 0u, BRW_CONDITIONAL_G)); emit(IF(BRW_PREDICATE_NORMAL)); { this->current_annotation = "gen6 thread end: ff_sync"; vec4_instruction *inst; if (c->prog_data.gen6_xfb_enabled) { src_reg sol_temp(this, glsl_type::uvec4_type); emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES, dst_reg(this->svbi), this->vertex_count, this->prim_count, sol_temp); inst = emit(GS_OPCODE_FF_SYNC, dst_reg(this->temp), this->prim_count, this->svbi); } else { inst = emit(GS_OPCODE_FF_SYNC, dst_reg(this->temp), this->prim_count, src_reg(0u)); } inst->base_mrf = base_mrf; /* Loop over all buffered vertices and emit URB write messages */ this->current_annotation = "gen6 thread end: urb writes init"; src_reg vertex(this, glsl_type::uint_type); emit(MOV(dst_reg(vertex), 0u)); emit(MOV(dst_reg(this->vertex_output_offset), 0u)); this->current_annotation = "gen6 thread end: urb writes"; emit(BRW_OPCODE_DO); { emit(CMP(dst_null_d(), vertex, this->vertex_count, BRW_CONDITIONAL_GE)); inst = emit(BRW_OPCODE_BREAK); inst->predicate = BRW_PREDICATE_NORMAL; /* First we prepare the message header */ emit_urb_write_header(base_mrf); /* Then add vertex data to the message in interleaved fashion */ int slot = 0; bool complete = false; do { int mrf = base_mrf + 1; /* URB offset is in URB row increments, and each of our MRFs is half * of one of those, since we're doing interleaved writes. */ int urb_offset = slot / 2; for (; slot < prog_data->vue_map.num_slots; ++slot) { int varying = prog_data->vue_map.slot_to_varying[slot]; current_annotation = output_reg_annotation[varying]; /* Compute offset of this slot for the current vertex * in vertex_output */ src_reg data(this->vertex_output); data.reladdr = ralloc(mem_ctx, src_reg); memcpy(data.reladdr, &this->vertex_output_offset, sizeof(src_reg)); /* Copy this slot to the appropriate message register */ dst_reg reg = dst_reg(MRF, mrf); reg.type = output_reg[varying].type; data.type = reg.type; vec4_instruction *inst = emit(MOV(reg, data)); inst->force_writemask_all = true; mrf++; emit(ADD(dst_reg(this->vertex_output_offset), this->vertex_output_offset, 1u)); /* If this was max_usable_mrf, we can't fit anything more into * this URB WRITE. */ if (mrf > max_usable_mrf) { slot++; break; } } complete = slot >= prog_data->vue_map.num_slots; emit_urb_write_opcode(complete, base_mrf, mrf, urb_offset); } while (!complete); /* Skip over the flags data item so that vertex_output_offset points * to the first data item of the next vertex, so that we can start * writing the next vertex. */ emit(ADD(dst_reg(this->vertex_output_offset), this->vertex_output_offset, 1u)); emit(ADD(dst_reg(vertex), vertex, 1u)); } emit(BRW_OPCODE_WHILE); if (c->prog_data.gen6_xfb_enabled) xfb_write(); } emit(BRW_OPCODE_ENDIF); /* Finally, emit EOT message. * * In gen6 we need to end the thread differently depending on whether we have * emitted at least one vertex or not. In case we did, the EOT message must * always include the COMPLETE flag or else the GPU hangs. If we have not * produced any output we can't use the COMPLETE flag. * * However, this would lead us to end the program with an ENDIF opcode, * which we want to avoid, so what we do is that we always request a new * VUE handle every time we do a URB WRITE, even for the last vertex we emit. * With this we make sure that whether we have emitted at least one vertex * or none at all, we have to finish the thread without writing to the URB, * which works for both cases by setting the COMPLETE and UNUSED flags in * the EOT message. */ this->current_annotation = "gen6 thread end: EOT"; if (c->prog_data.gen6_xfb_enabled) { /* When emitting EOT, set SONumPrimsWritten Increment Value. */ src_reg data(this, glsl_type::uint_type); emit(AND(dst_reg(data), this->sol_prim_written, src_reg(0xffffu))); emit(SHL(dst_reg(data), data, src_reg(16u))); emit(GS_OPCODE_SET_DWORD_2, dst_reg(MRF, base_mrf), data); } vec4_instruction *inst = emit(GS_OPCODE_THREAD_END); inst->urb_write_flags = BRW_URB_WRITE_COMPLETE | BRW_URB_WRITE_UNUSED; inst->base_mrf = base_mrf; inst->mlen = 1; }