Beispiel #1
0
void BGGraphics::pushCirclePart(ofMesh& mesh, ofVec2f position, float nodeRadius, float minAngle, float deltaAngle) {

    mesh.setMode(OF_PRIMITIVE_TRIANGLES);

    pushVertex(mesh, position.x, position.y, 1, 0, 0, 1, 0, 0);

    float innerRadius = nodeRadius - NETWORK_OFFSET;

    float internalOffsetY = .5;// innerRadius / nodeRadius;

    int samples = (int)(15 * deltaAngle / M_PI);
    samples = max(1, samples);

    for(int i=0; i<samples; ++i) {
        float angle = minAngle + deltaAngle * i / (float)(samples - 1);
        ofVec2f to(cosf(angle), sinf(angle));

        ofVec2f p1 = position + to * innerRadius;
        ofVec2f p2 = position + to * nodeRadius;

        //pushVertex(ofMesh & mesh, float x, float y, float z, float nx, float ny, float nz, float offsetX, float offsetY) 
        pushVertex(mesh, p1.x, p1.y, 1, 0, 0, 1, 0, internalOffsetY);
        pushVertex(mesh, p2.x, p2.y, 0, to.x, to.y, 0, 0, 1);

        if(i > 0) {
            int offset = 1 + 2 * i;
            mesh.addTriangle(0, offset - 2, offset);
            mesh.addTriangle(offset - 2, offset - 1, offset);
            mesh.addTriangle(offset - 1, offset, offset + 1);
        }
    }
}
Beispiel #2
0
void BGGraphics::pushDoubleConnectedNode(ofMesh& mesh, ofVec2f position, ofVec2f startEdgePoint, ofVec2f endEdgePoint) {

    int samples = 10;
    for(int i=0; i<samples; ++i) {

        float t = i / (float)(samples - 1);

        float localDepth = -.5 + t;

        ofVec2f pt, normal;
        sampleSpline(startEdgePoint, position, endEdgePoint, t, pt, normal);

        pushVertex(mesh, pt.x + NETWORK_OFFSET * normal.x, pt.y + NETWORK_OFFSET * normal.y, 0, normal.x, normal.y, 0, localDepth, 1);
        pushVertex(mesh, pt.x, pt.y, 1, 0, 0, 1, localDepth, 0);
        pushVertex(mesh, pt.x - NETWORK_OFFSET * normal.x, pt.y - NETWORK_OFFSET * normal.y, 0, -normal.x, -normal.y, 0, localDepth, 1);

        if(i > 0) {
            int offset = 3 * i;
            for(int j=0; j<2; ++j) {
                mesh.addTriangle(offset + j, offset - 3 + j, offset - 2 + j);
                mesh.addTriangle(offset + j, offset + 1 + j, offset - 2 + j);
            }
        }
    }
}
Beispiel #3
0
void Canvas::drawLine(const float width, Color const& color, geom::Point const& start, geom::Point const& end, const float depth)
{
	if(color.isInvalid() || !(width > 0)){
		return;
	}
	this->setLineWidth(width);
	this->setColor(color);
	this->setOperation(Lines);
	pushVertex(start.x(), start.y(), depth);
	pushVertex(end.x()  , end.y(), depth);
}
void OpenGLTextureBuilder::push4Vertices(CUSTOMVERTEX2D *pVertices,
                                  int pPosVert,
                                  int pPosX,
                                  int pPosY,
                                  int pPosZ,
                                  int pWidthBlock,
                                  int pHeightBlock,
                                  float pU,
                                  float pV){
    // Push the 4 vertex of the quad
	// The pushing order is important

	// Upper-right
	pushVertex(pVertices,
	           pPosVert,
	           pPosX + pWidthBlock,
	           pPosY - pHeightBlock,
	           pPosZ,
	           pU,
	           pV);

	// Lower-right
	pushVertex(pVertices,
	           pPosVert + 1,
	           pPosX + pWidthBlock,
	           pPosY,
	           pPosZ,
	           pU,
	           0.0f);

	// Upper-left
	pushVertex(pVertices,
	           pPosVert + 2,
	           pPosX,
	           pPosY - pHeightBlock,
	           pPosZ,
	           0.0f,
	           pV);

	// Lower-left
	pushVertex(pVertices,
	           pPosVert + 3,
	           pPosX,
	           pPosY,
	           pPosZ,
	           0.0f,
	           0.0f);
}
Beispiel #5
0
/*
==================
Push 4 vertices into the buffer creating a quad
==================
*/
void IND_Surface::push4Vertices(CUSTOMVERTEX2D *pVertices,
                                int pPosVert,
                                int pX,
                                int pY,
                                int pZ,
                                int pWidthBlock,
                                int pHeightBlock,
                                int pWidth,
                                int pHeight) {
	// Push the 4 vertex of the quad
	// The pushing order is important

	// Upper-right
	pushVertex(pVertices,
	           pPosVert,
	           pX + pWidthBlock,
	           pY - pHeightBlock,
	           pZ,
	           (float)(pX + pWidthBlock) / pWidth,
	           1.0f - ((float)(pY - pHeightBlock) / pHeight));

	// Lower-right
	pushVertex(pVertices,
	           pPosVert + 1,
	           pX + pWidthBlock,
	           pY,
	           pZ,
	           (float)(pX + pWidthBlock) / pWidth,
	           1.0f - ((float) pY / pHeight));

	// Upper-left
	pushVertex(pVertices,
	           pPosVert + 2,
	           pX,
	           pY - pHeightBlock,
	           pZ,
	           (float) pX / pWidth,
	           1.0f - ((float)(pY - pHeightBlock) / pHeight));

	// Lower-left
	pushVertex(pVertices,
	           pPosVert + 3,
	           pX,
	           pY,
	           pZ,
	           (float) pX / pWidth,
	           1.0f - ((float) pY / pHeight));
}
Beispiel #6
0
void Canvas::drawLines(const float width, Color const& color, std::vector<geom::Point> const& pts, const float depth)
{
	if(color.isInvalid() || !(width > 0)){
		return;
	}
	this->setLineWidth(width);
	this->setColor(color);
	this->setOperation(LineStrip);
	for(geom::Point const& pt : pts){
		pushVertex(pt.x(), pt.y(), depth);
	}
	flushGL();
}
void polyFixWidth::addPoint( ofPoint pt )
{
	if( pts.size() < 2)
	{
		pushVertex( pt );
		selectedPoint = pts.size()-1;
		
	}
	
	if( pts.size() == 2 ) makeRectangle();
	
	//cout << "pts added " << pts.size() << endl;
}
Beispiel #8
0
void polyEditable::addPoint( ofPoint pt )
{
	if( bUseClosePoly && pts.size() > 2)
	{
		if( abs( (int)(pts[0].x-pt.x) ) <= selectDist && abs( (int)(pts[0].y-pt.y) ) <= selectDist )
		{
			bClosed = true;
		}
	
	}
	
	if(!bClosed) pushVertex( pt );
	selectedPoint = pts.size()-1;
	//cout << "editable add " << endl;
	
}
void ShapeCube::rebuildVerts(){

    if (m_t1 < 1){
        m_t1 = 1;
    }

    m_vertices.clear();
    //2 * t1 * t1 triangles per face
    for (int face = 0; face < 6; face++){ //do same generation for each face, just rotate
        glm::mat4 faceMat;
        switch (face){
        case 0:
            faceMat = glm::mat4(); //identity
            break;
        case 1:
            faceMat = glm::rotate(static_cast<float>(M_PI), glm::vec3(0.f, 1.f, 0.f));
            break;
        case 2:
            faceMat = glm::rotate(static_cast<float>(M_PI/2.f), glm::vec3(0, 1, 0));
            break;
        case 3:
            faceMat = glm::rotate(static_cast<float>(-M_PI/2.f), glm::vec3(0, 1, 0));
            break;
        case 4:
            faceMat = glm::rotate(static_cast<float>(M_PI/2.f), glm::vec3(1, 0, 0));
            break;
        case 5:
            faceMat = glm::rotate(static_cast<float>(-M_PI/2.f), glm::vec3(1, 0, 0));
            break;
        }

        for (float ind1 = 0; ind1 < m_t1; ind1++){
            for (float ind2 = 0; ind2 < m_t1; ind2++){
                float i = -.5 + ind1 * 1.f/m_t1; //x/y values
                float j = -.5 + ind2 * 1.f/m_t1;

                glm::vec4 normal = faceMat * glm::vec4(0, 0, 1, 1);
                glm::vec4 botleft = faceMat * glm::vec4(i, j, .5f, 1);
                glm::vec4 botright = faceMat * glm::vec4(i + 1.f/m_t1, j, .5f, 1);
                glm::vec4 topright = faceMat * glm::vec4(i + 1.f/m_t1, j + 1.f/m_t1, .5f, 1);
                glm::vec4 topleft = faceMat * glm::vec4(i, j + 1.f/m_t1, .5f, 1);

                pushVertex(botleft, normal);
                pushVertex(botright, normal);
                pushVertex(topleft, normal);

                pushVertex(topleft, normal);
                pushVertex(botright, normal);
                pushVertex(topright, normal);

            }
        }
    }
}
Beispiel #10
0
void Canvas::drawRect(const float width, Color const& color, geom::Area const& area, const float depth)
{
	if(color.isInvalid() || !(width > 0)){
		return;
	}
	float const sx = area.x();
	float const ex = area.x()+area.width();
	float const sy = area.y();
	float const ey = area.y()+area.height();
	this->setColor(color);
	this->setLineWidth(width);
	this->setOperation(Lines);
	pushVertex(sx, sy, depth);
	pushVertex(ex, sy, depth);

	pushVertex(ex, sy, depth);
	pushVertex(ex, ey, depth);

	pushVertex(ex, ey, depth);
	pushVertex(sx, ey, depth);

	pushVertex(sx, ey, depth);
	pushVertex(sx, sy, depth);
}
Beispiel #11
0
void CMC_MeshData::loadFromTZW(const rapidjson::Value &value)
{
    //load material index.
    m_materialIndex = value["material_index"].GetInt ();

    //load vertices
    auto& verticesObj = value["vertices"];
    for(auto iter = verticesObj.Begin ();iter!= verticesObj.End ();iter++)
    {
        auto& vertexObj = *iter;
        CMC_Vertex vertex;
        vertex.loadFromTZW (vertexObj);
        pushVertex (vertex);
    }

    //load indices
    auto& indicesObj = value["indices"];
    for(auto iter = indicesObj.Begin ();iter != indicesObj.End ();iter++)
    {
        auto& indexObj = * iter;
        pushIndex (indexObj.GetInt ());
    }
}
Beispiel #12
0
void Canvas::fillRect(Color const& color, geom::Area const& area, const float depth)
{
	if(color.isInvalid() || area.empty()){
		return;
	}
	float const sx = area.x();
	float const ex = area.x()+area.width();
	float const sy = area.y();
	float const ey = area.y()+area.height();
	this->setColor(color);
	this->setOperation(Rect);
	pushVertex(sx, sy, depth);
	pushVertex(sx, ey, depth);
	pushVertex(ex, sy, depth);

	pushVertex(ex, sy, depth);
	pushVertex(sx, ey, depth);
	pushVertex(ex, ey, depth);
}
Beispiel #13
0
Pan::Pan(const glm::vec2 &repeat)
  : AGeometry::AGeometry("pan.geo")
{
  pushVertex(glm::vec3(1.0f, 1.0f, 0.0f)).pushNormal(glm::vec3(0.0, 0.0, -1.0));
  pushVertex(glm::vec3(-1.0f, 1.0f, 0.0f)).pushNormal(glm::vec3(0.0, 0.0, -1.0));
  pushVertex(glm::vec3(-1.0f, -1.0f, 0.0f)).pushNormal(glm::vec3(0.0, 0.0, -1.0));

  pushVertex(glm::vec3(-1.0f, -1.0f, 0.0f)).pushNormal(glm::vec3(0.0, 0.0, -1.0));
  pushVertex(glm::vec3(1.0f,  -1.0f, 0.0f)).pushNormal(glm::vec3(0.0, 0.0, -1.0));
  pushVertex(glm::vec3(1.0f, 1.0f, 0.0f)).pushNormal(glm::vec3(0.0, 0.0, -1.0));

  pushUv(glm::vec2(0.0f, 0.0f));
  pushUv(glm::vec2(repeat.y, 0.0f));
  pushUv(glm::vec2(repeat.y, repeat.x));

  pushUv(glm::vec2(repeat.y, repeat.x));
  pushUv(glm::vec2(0.0f, repeat.x));
  pushUv(glm::vec2(0.0f, 0.0f));

  build();
}
Beispiel #14
0
void Canvas::drawTexture(unsigned int texId, geom::Area const& areaInRoot, geom::Area const& coordinateInSprite, const float depth, Color const& color)
{
	const float x=areaInRoot.x();
	const float y=areaInRoot.y();
	const float width = areaInRoot.width();
	const float height = areaInRoot.height();

	const float top = coordinateInSprite.y();
	const float left = coordinateInSprite.x();
	const float right = coordinateInSprite.x()+coordinateInSprite.width();
	const float bottom = coordinateInSprite.y()+coordinateInSprite.height();
	this->bindTexture(texId);
	this->setColor(color);
	this->setOperation(Texture);
	pushTexCoord(left ,top   );pushVertex(x      , y       , depth);
	pushTexCoord(left ,bottom);pushVertex(x      , y+height, depth);
	pushTexCoord(right,top   );pushVertex(x+width, y       , depth);

	pushTexCoord(right,top   );pushVertex(x+width, y       , depth);
	pushTexCoord(left ,bottom);pushVertex(x      , y+height, depth);
	pushTexCoord(right,bottom);pushVertex(x+width, y+height, depth);
	flushGL();
}
Beispiel #15
0
void BGGraphics::pushTripleConnectedNode(ofMesh& mesh, ofVec2f position, ofVec2f startEdgePoint, ofVec2f endEdgePoint1, ofVec2f endEdgePoint2) {
 
    ofVec2f orderedPts[3] = {
        startEdgePoint,
        endEdgePoint1,
        endEdgePoint2
    };

    /*
    ofMesh centerTriangleMesh;
    centerTriangleMesh.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
    ofVec2f centerTriangleTexPt = calculateInternalTexOffset(0.5, true, true, -1);
    pushVertex(centerTriangleMesh, position.x, position.y, 1, 0, 0, 1, centerTriangleTexPt.x, centerTriangleTexPt.y);
    */

    ofVec2f sumCenterPosition(0,0);

    int centerIndices[9];

    int halfSamples = 8;
    for(int idx=0; idx<3; ++idx) {

        int prevIdx = idx == 0 ? 2 : (idx - 1);
        int nextIdx = (idx + 1) % 3;

        //ofVec2f focus1 = focusPts[idx];
        //ofVec2f focus2 = focusPts[prevIdx];

        for(int i=0; i<halfSamples; ++i) {

            float t = .5 * i / (float)(halfSamples - 1);

            ofVec2f pt1, normal1, pt2, normal2;
            sampleSpline(orderedPts[idx], position, orderedPts[nextIdx], t, pt1, normal1);
            sampleSpline(orderedPts[idx], position, orderedPts[prevIdx], t, pt2, normal2);
            normal2 = -normal2;

            ofVec2f center = (pt1 + pt2) / 2.0;

            /*
            float offAngle1 = focusAngles[idx] + t * deltaAngle;
            ofVec2f offVector1 = ofVec2f(cosf(offAngle1), sinf(offAngle1));
            float offAngle2 = focusAngles[prevIdx] + (1. - t) * deltaAngle;
            ofVec2f offVector2 = ofVec2f(cosf(offAngle2), sinf(offAngle2));
            */

            //ofVec2f BGGraphics::calculateInternalTexOffset(float t, bool isSourceSpline, int offsetIndex)

            bool isSourceSegment = idx == 0;
            bool isSourceSpline1 = true, isSourceSpline2 = true;
            float t1 = t, t2 = t;

            if(idx == 1) {
                isSourceSpline1 = false;
                t2 = 1. - t;
            }
            else if(idx == 2) {
                //mirrored version of idx == 1
                isSourceSpline2 = false;
                t1 = 1. - t;
            }


            ofVec2f centerTexPt = calculateInternalTexOffset(t1, isSourceSpline1, isSourceSegment, 0);
            ofVec2f innerTexPt1 = calculateInternalTexOffset(t1, isSourceSpline1, isSourceSegment, 1);
            ofVec2f outerTexPt1 = calculateInternalTexOffset(t1, isSourceSpline1, isSourceSegment, 2);
            ofVec2f innerTexPt2 = calculateInternalTexOffset(t2, isSourceSpline2, isSourceSegment, 1);
            ofVec2f outerTexPt2 = calculateInternalTexOffset(t2, isSourceSpline2, isSourceSegment, 2);

            //TODO: remove!!
            //centerTexPt = (innerTexPt1 + innerTexPt2) / 2.0;

            //innerTexPt2 = ofVec2f(-10000,-10000);
            //outerTexPt2 = innerTexPt2;

            /*
            ofVec2f innerTexPt1 = focus1 + baseSize * offVector1;
            ofVec2f outerTexPt1 = focus1 + .5 * baseSize * offVector1;
            ofVec2f innerTexPt2 = focus2 + baseSize * offVector2;
            ofVec2f outerTexPt2 = focus2 + .5 * baseSize * offVector2;
            ofVec2f centerTexPt = (innerTexPt1 + innerTexPt2) / 2.0;
            */

            pushVertex(mesh, pt1.x + NETWORK_OFFSET * normal1.x, pt1.y + NETWORK_OFFSET * normal1.y, 0, normal1.x, normal1.y, 0, outerTexPt1.x, outerTexPt1.y);
            pushVertex(mesh, pt1.x, pt1.y, 1, 0, 0, 1, innerTexPt1.x, innerTexPt1.y);
            pushVertex(mesh, center.x, center.y, 1, 0, 0, 1, centerTexPt.x, centerTexPt.y);
            pushVertex(mesh, pt2.x, pt2.y, 1, 0, 0, 1, innerTexPt2.x, innerTexPt2.y);
            pushVertex(mesh, pt2.x + NETWORK_OFFSET * normal2.x, pt2.y + NETWORK_OFFSET * normal2.y, 0, normal2.x, normal2.y, 0, outerTexPt2.x, outerTexPt2.y);

            if(i > 0) {
                int offset = (5 * idx * halfSamples) + 5 * i;
                for(int j=0; j<4; ++j) {
                    mesh.addTriangle(offset + j, offset - 5 + j, offset - 4 + j);
                    mesh.addTriangle(offset + j, offset + 1 + j, offset - 4 + j);
                }

                if(i == halfSamples - 1) {
                    sumCenterPosition += pt1;
                    for(int j=0; j<3; ++j) {
                        centerIndices[3 * idx + j] = offset + 1 + j;
                    }
                }
            }
        }
    }

    //add center point:
    ofVec2f avgCenter = sumCenterPosition / 3.0;
    ofVec2f centerTriangleTexPt = calculateInternalTexOffset(0.5, true, true, -1);
    pushVertex(mesh, avgCenter.x, avgCenter.y, 1, 0, 0, 1, centerTriangleTexPt.x, centerTriangleTexPt.y);

    //stitch to bounds:
    int centerOffset = mesh.getVertices().size() - 1;
    for(int i=0; i<9; ++i)
         mesh.addTriangle(centerOffset, centerIndices[i], centerIndices[(i + 1) % 9]);


    //centerTriangleMesh.setVertex(0, ofVec3f(avgCenter.x, avgCenter.y, 1));

    /*
    ofVec2f avgCenter = sumCenterPosition / 3.0;
    centerTriangleMesh.setVertex(0, ofVec3f(avgCenter.x, avgCenter.y, 1));

    //stitch up center triangle fan:
    centerTriangleMesh.addVertex(centerTriangleMesh.getVertex(1));
    centerTriangleMesh.addTexCoord(centerTriangleMesh.getTexCoord(1));
    centerTriangleMesh.addNormal(centerTriangleMesh.getNormal(1));
    centerTriangleMesh.addColor(centerTriangleMesh.getColor(1));

    drawMesh(centerTriangleMesh, depth);
    */
}
Beispiel #16
0
bool Loader::loadFromModel(const char *fileName)
{
    printf("load %s begin\n",fileName);
    printf("parsing..\n");
    const aiScene* pScene = m_Importer.ReadFile(fileName,aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenSmoothNormals |aiProcess_CalcTangentSpace);
    this->m_pScene = (aiScene*)pScene;
    if(!m_pScene)
    {
        printf("parsing failure!\n");
        return false;
    }
    else
    {
        printf("parsing succes!\n");
        printf("extracting data to memory...\n");
        m_model = new CMC_ModelData();

        auto inverseTransform = pScene->mRootNode->mTransformation;
        inverseTransform = inverseTransform.Inverse();
        m_model->setGlobalInverseTransform (toQMatrix(inverseTransform));
        LoadMaterial(pScene,fileName);

        const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);
        for(int i =0 ;i< pScene->mNumMeshes ;i++)
        {
            const aiMesh* the_mesh = pScene->mMeshes[i];
            auto mesh = new CMC_MeshData;
            m_model->addMesh(mesh);
            //set material
            mesh->setMaterialIndex (the_mesh->mMaterialIndex);
            for(int j =0; j<the_mesh->mNumVertices;j++)
            {
                const aiVector3D* pPos = &(the_mesh->mVertices[j]);
                const aiVector3D* pNormal = &(the_mesh->mNormals[j]);
                const aiVector3D* pTexCoord = the_mesh->HasTextureCoords(0) ? &(the_mesh->mTextureCoords[0][j]) : &Zero3D;
                const aiVector3D* pTangent = &(the_mesh->mTangents[i]);
                CMC_Vertex  vec;
                vec.setPos (QVector3D(pPos->x,pPos->y,pPos->z));
                vec.setNormal (QVector3D(pNormal->x,pNormal->y,pNormal->z));
                vec.setUV (QVector2D(pTexCoord->x,pTexCoord->y));
            if(pTangent)
            {
                 vec.setTangent (QVector3D(pTangent->x,pTangent->y,pTangent->z));
            }
            mesh->pushVertex (vec);
            }

            for (unsigned int k = 0 ; k < the_mesh->mNumFaces ; k++) {
                const aiFace& Face = the_mesh->mFaces[k];
                assert(Face.mNumIndices == 3);
                mesh->pushIndex (Face.mIndices[0]);
                mesh->pushIndex(Face.mIndices[1]);
                mesh->pushIndex(Face.mIndices[2]);
            }
            //load bones
            loadBoneList(the_mesh,mesh);
            //mesh->finish();
        }
        loadNodeHeirarchy(nullptr,m_pScene->mRootNode);
        loadAnimations ();
        printf("extracting finish..\n");
        return true;
    }
}
Beispiel #17
0
void BGGraphics::pushSingleConnectedNode(ofMesh& mesh, ofVec2f position, float nodeRadius, ofVec2f edgePoint, bool isRoot) {

    float innerRadius = nodeRadius - NETWORK_OFFSET;

    ofVec2f to = edgePoint - position;
    float toDist = to.length();
    to /= toDist;
    ofVec2f perp = ofVec2f(-to.y, to.x);

    float depthFactor = isRoot ? .5 : -.5;

    float proj = sqrtf(.5 * innerRadius * innerRadius);

    if(toDist > innerRadius + NETWORK_OFFSET) {

        float offset = min(innerRadius + .5f * (toDist - innerRadius), 2 * proj);

        
        //perform spline traversal...
        ofVec2f controlPoint = position + offset * to;// .5 * (position + innerRadius * to) + .5 * edgePoint;
        float angle = acosf(innerRadius / offset);

        pushCirclePart(mesh, position, nodeRadius, atan2f(to.y, to.x) + angle, 2 * (M_PI - angle));
        int splineOffset = mesh.getVertices().size();

/*
        ofVec2f anchorLeft  = position + proj * to + proj * perp;
        ofVec2f anchorRight = position + proj * to - proj * perp;
        ofVec2f toA1 = (anchorLeft - position).normalize();
        ofVec2f toA2 = (anchorRight - position).normalize();
            */

        
        float toAng = atan2f(to.y, to.x);
        ofVec2f toA1(cosf(toAng + angle), sinf(toAng + angle));
        ofVec2f toA2(cosf(toAng - angle), sinf(toAng - angle));

        float facU = innerRadius * cosf(angle);
        float facV = innerRadius * sinf(angle);

        float anchorProj = sqrtf(.5 * innerRadius * innerRadius);
        ofVec2f anchorLeft  = position + innerRadius * toA1;
        ofVec2f anchorRight = position + innerRadius * toA2;
        

        float innerRadiusFactor = .5;// innerRadius / nodeRadius;

        //add first point:
        pushVertex(mesh, anchorLeft.x + NETWORK_OFFSET * toA1.x, anchorLeft.y + NETWORK_OFFSET * toA1.y, 0, toA1.x, toA1.y, 0, 0, 1);
        pushVertex(mesh, anchorLeft.x, anchorLeft.y, 1, 0, 0, 1, 0, innerRadiusFactor);
        pushVertex(mesh, position.x, position.y, 1, 0, 0, 1, 0, 0);
        pushVertex(mesh, anchorRight.x, anchorRight.y, 1, 0, 0, 1, 0, innerRadiusFactor);
        pushVertex(mesh, anchorRight.x + NETWORK_OFFSET * toA2.x, anchorRight.y + NETWORK_OFFSET * toA2.y, 0, toA2.x, toA2.y, 0, 0, 1);

        int samples = 8;
        for(int i=1; i<samples; ++i) {

            float t = i / (float)(samples - 1);

            float localDepth = depthFactor * t;

            ofVec2f pt, normal;
            sampleSpline(anchorLeft, controlPoint, edgePoint, t, pt, normal);
            normal = -normal;
/*
            //project point on skeleton:
            //float projDistance = dot(pt - position, to);
            float innerSampleOffset = dot(pt - position, to);//(pt - centerSample).length();
            ofVec2f centerSample = position + innerSampleOffset * to;



            float centerSampleDepth = depth + depthFactor * (innerSampleOffset / toDist);
            centerSampleDepth = (centerSampleDepth + localDepth) * .5;
            */
            ofVec2f centerSample;
            getIntersection(position, to, pt, normal, centerSample);
            

            //float innerSampleOffset = (pt - centerSample).length();
            float innerSampleOffsetFactor = (1 - t) * .5;// innerSampleOffset / (innerSampleOffset + NETWORK_OFFSET);

            ofVec2f otherPt = position + reflect(pt - position, to);
            ofVec2f otherNormal = reflect(normal, to);

            pushVertex(mesh, pt.x + NETWORK_OFFSET * normal.x, pt.y + NETWORK_OFFSET * normal.y, 0, normal.x, normal.y, 0, localDepth, 1);
            pushVertex(mesh, pt.x, pt.y, 1, 0, 0, 1, localDepth, innerSampleOffsetFactor);
            pushVertex(mesh, centerSample.x, centerSample.y, 1, 0, 0, 1, localDepth, 0);
            pushVertex(mesh, otherPt.x, otherPt.y, 1, 0, 0, 1, localDepth, innerSampleOffsetFactor);
            pushVertex(mesh, otherPt.x + NETWORK_OFFSET * otherNormal.x, otherPt.y + NETWORK_OFFSET * otherNormal.y, 0, otherNormal.x, otherNormal.y, 0, localDepth, 1);

            if(i > 0) {
                int offset = splineOffset + 5 * i;

                for(int j=0; j<4; ++j) {
                     mesh.addTriangle(offset + j, offset - 5 + j, offset - 4 + j);
                     mesh.addTriangle(offset + j, offset + 1 + j, offset - 4 + j);
                }
            }
        }
    }
    else
        pushSeparateNode(mesh, position, nodeRadius);
}