Ejemplo n.º 1
0
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);
}
Ejemplo n.º 3
0
 const V&            operator[]          (int vidx) const                { return vertex(vidx); }
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 6
0
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();
}
Ejemplo n.º 7
0
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

}
Ejemplo n.º 8
0
 // 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);}
Ejemplo n.º 9
0
 vertex_descriptor goal() const {
   return vertex(num_vertices(m_grid)-1, m_grid);
 }
Ejemplo n.º 10
0
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;
      }
    }
Ejemplo n.º 11
0
typename DIRECTED_GRAPH::vertex_descriptor
vertex(typename DIRECTED_GRAPH::vertices_size_type n,
       DIRECTED_GRAPH const& g)
{ return vertex(n, g.impl()); }
Ejemplo n.º 12
0
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();
    }
}
Ejemplo n.º 13
0
/*******************************************************************
* 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);
}
Ejemplo n.º 14
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();
}
Ejemplo n.º 16
0
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;
}