Ejemplo n.º 1
0
// NOTE: Assumes that this mesh has enough capacity
void eMesh::merge(const eMesh &other, const eMatrix4x4& mtx, const eMatrix4x4& mtxRotOnly) {
    eU32 vtxCntBefore = m_vertices.size();
    for(eU32 i = 0; i < other.getVertexCount(); i++) {
        m_vertices.append(other.getVertex(i));
        eVertex& v = m_vertices.lastElement();
        v.position = eVector3(v.position) * mtx;
        v.normal = eVector3(v.normal) * mtxRotOnly;
        m_bbox.updateExtentFast(v.position);
    }

    for(eU32 d = 0; d < other.getDrawSectionCount(); d++) {
        const DrawSection& ods = other.getDrawSection(d);
        DrawSection &ds = _findDrawSection(ods.material, ods.type);
        ds.primitives.reserve(ods.primitives.size());

        for(eU32 i = 0; i < ods.primitives.size(); i++) {
            const Primitive& oprim = other.getPrimitive(ods.primitives[i]);
            m_primitives.append(oprim);
            Primitive& prim = m_primitives.lastElement();
            prim.material = ods.material;
            for(eU32 k = 0; k < 3; k++)
                prim.indices[k] = oprim.indices[k] + vtxCntBefore;

            ds.primitives.append(m_primitives.size()-1);
        }
    }
}
void eDeferredRenderer::renderQuad(const eRect &r, const eSize &size, eTexture2dDx11 *tex, const eVector2 &tileUv, const eVector2 &scrollUv) const
{
    // set render states
    eRenderState &rs = eGfx->getRenderState();
    rs.cullMode = eCULL_NONE;
    rs.depthTest = eFALSE;
    rs.viewport.set(0, 0, size.width, size.height);

    if (tex)
        rs.textures[0] = tex;

    // use default shaders if no other shaders set
    if (!rs.ps)
        rs.ps = m_psQuad;
    if (!rs.vs)
        rs.vs = m_vsQuad;

    // render quad
    const eCamera cam(0.0f, (eF32)size.width, 0.0f, (eF32)size.height, -1.0f, 1.0f);
    cam.activate();

    eSimpleVtx *vp = nullptr;
    eGfx->beginLoadGeometry(m_geoQuad, 4, (ePtr *)&vp);
    {
        vp[0].set(eVector3((eF32)r.left,  (eF32)r.top,    0.0f), eVector2(scrollUv.u,          scrollUv.v+tileUv.v));
        vp[1].set(eVector3((eF32)r.left,  (eF32)r.bottom, 0.0f), eVector2(scrollUv.u,          scrollUv.v));
        vp[2].set(eVector3((eF32)r.right, (eF32)r.bottom, 0.0f), eVector2(scrollUv.u+tileUv.u, scrollUv.v));
        vp[3].set(eVector3((eF32)r.right, (eF32)r.top,    0.0f), eVector2(scrollUv.u+tileUv.u, scrollUv.v+tileUv.v));
    }
    eGfx->endLoadGeometry(m_geoQuad);
    eGfx->renderGeometry(m_geoQuad);
}
void convert(const KDL::Frame &in, eMatrixHom &out) {
    double x,y,z,w;
    in.M.GetQuaternion(x, y, z, w);
    out =  createMatrix(eQuaternion(w, x, y, z),
                        eVector3(in.p.x(), in.p.y(), in.p.z()));

}
Ejemplo n.º 4
0
void eLSystem::applyForce(tSymbol& symbol, const eQuat& curRot, eQuat& targetRot, eVector3& targetPos) {
    ePROFILER_ZONE("L-System - Apply Force");
	for(eS32 a = -1; a < (eS32)m_forces.size(); a++) {

        eF32 attractAmount = m_gravity;
        eU32 axis = 2;
        eVector3 attractionVec = eVector3(0,-1,0);

        if(a != -1) {
    		const tForceGenerator& attractor = m_forces[a];
            eVector3 attractorPos = (*attractor.triDefs)[0];
            attractAmount = attractor.mass;
            axis = attractor.attractAxis;
/*
#ifdef eEDITOR
            if(attractor.gen_type == FG_CLOSEST_FACE) {
                eU32     bestFaceOffset = 0;
                eVector3 bestFaceStats(eF32_MAX, 0, 0);
                for(eU32 i = 0; i < attractor.triDefs->size(); i += 3) {
                    const eVector3& B = (*attractor.triDefs)[i];
                    const eVector3& E0 = (*attractor.triDefs)[i+1];
                    const eVector3& E1 = (*attractor.triDefs)[i+2];
                    eVector3 distTest = targetPos.distanceToTriangle(B, E0, E1);
                    if(distTest.x < bestFaceStats.x) {
                        bestFaceStats = distTest;
                        bestFaceOffset = i;
                    }
                }
                // calculate attractor face
                const eVector3& B = (*attractor.triDefs)[bestFaceOffset];
                const eVector3& E0 = (*attractor.triDefs)[bestFaceOffset+1];
                const eVector3& E1 = (*attractor.triDefs)[bestFaceOffset+2];
                attractorPos = B + E0 * bestFaceStats.y + E1 * bestFaceStats.z;
                attractAmount = attractor.mass * (1.0f / bestFaceStats.x);
            }
#endif
*/
    		attractionVec = attractorPos - targetPos;
        }

		eVector3 look = curRot.getVector(axis);
		eVector3 side = look^attractionVec;

		eF32 cosAngleAttrLen = look * attractionVec;
		eF32 cosAngleSqr = (cosAngleAttrLen * cosAngleAttrLen / attractionVec.sqrLength());
        eF32 sinAngleSqr = 1.0f - cosAngleSqr;
		eF32 amount = (1.0f - (1.0f / (1.0f + attractAmount)));

		// |side| = sin(alpha)
		eF32 sideLen = side.length();
		if(sideLen > eALMOST_ZERO) {
			side /= sideLen;
			eQuat rotation(side, ePI * 0.5f * sinAngleSqr * amount);
			targetRot = rotation * targetRot;
		}
	}						

}
Ejemplo n.º 5
0
    OP_INTERACT(eGraphicsApiDx9 *gfx, eSceneData &sd)
    {
        static eMesh::Instance mi(m_lightMesh);

        eMatrix4x4 mtx;

        mtx.scale(eVector3(getParameter(1).getValue().flt)*0.5f);
        mtx.translate(getParameter(0).getValue().fxyz);

        sd.addRenderable(&mi, mtx);
    }
Ejemplo n.º 6
0
    OP_INIT()
    {
        eOP_PARAM_ADD_FXYZ("Position", eF32_MIN, eF32_MAX, 10.0f, 10.0f, 10.0f);
        eOP_PARAM_ADD_FLOAT("Range", 0.01f, eF32_MAX, 100.0f);
        eOP_PARAM_ADD_RGB("Diffuse", 1.0f, 1.0f, 1.0f);
        eOP_PARAM_ADD_RGB("Ambient", 0.0f, 0.0f, 0.0f);
        eOP_PARAM_ADD_RGB("Specular", 1.0f, 1.0f, 1.0f);
        eOP_PARAM_ADD_LABEL("Shadows", "Shadows");
        eOP_PARAM_ADD_BOOL("Casts shadows", eFALSE);
        eOP_PARAM_ADD_FLAGS("Shadowed faces", "X+|X-|Y+|Y-|Z+|Z-", 0x3f); // All on = first 6 bits set.
        eOP_PARAM_ADD_FLOAT("Penumbra size", 0.0f, eF32_MAX, 2.0f);
        eOP_PARAM_ADD_FLOAT("Shadow bias", 0.0f, 1.0f, 0.001f);

        // Create light bounding sphere mesh.
        _addCircleToMesh(m_lightMesh, 100, eVector3(   0.0f,    0.0f, eHALFPI));
        _addCircleToMesh(m_lightMesh, 100, eVector3(   0.0f, eHALFPI,    0.0f));
        _addCircleToMesh(m_lightMesh, 100, eVector3(eHALFPI,    0.0f,    0.0f));

        m_lightMesh.finishLoading(eMesh::TYPE_DYNAMIC);
    }
Ejemplo n.º 7
0
void eMesh::createWireCube(eMesh &mesh, const eVector3 &size, const eMaterial *mat)
{
    eASSERT(mat != eNULL);

    const eVector3 vertices[8] =
    {
        eVector3(-0.5f, -0.5f, -0.5f), // ulh
        eVector3(-0.5f, -0.5f,  0.5f), // ulv
        eVector3( 0.5f, -0.5f,  0.5f), // urv
        eVector3( 0.5f, -0.5f, -0.5f), // urh
        eVector3(-0.5f,  0.5f, -0.5f), // olh
        eVector3(-0.5f,  0.5f,  0.5f), // olv
        eVector3( 0.5f,  0.5f,  0.5f), // orv
        eVector3( 0.5f,  0.5f, -0.5f), // orh
    };

    mesh.clear();

    for (eU32 i=0; i<8; i++)
    {
        eVector3 pos = vertices[i];
        pos.scale(size);

        mesh.addVertex(pos);
    }

    // bottom quad
    mesh.addLine(0, 1, mat);
    mesh.addLine(1, 2, mat);
    mesh.addLine(2, 3, mat);
    mesh.addLine(3, 0, mat);

    // top quad
    mesh.addLine(4, 5, mat);
    mesh.addLine(5, 6, mat);
    mesh.addLine(6, 7, mat);
    mesh.addLine(7, 4, mat);

    // four lines
    mesh.addLine(0, 4, mat);
    mesh.addLine(1, 5, mat);
    mesh.addLine(2, 6, mat);
    mesh.addLine(3, 7, mat);

    mesh.finishLoading(TYPE_DYNAMIC);
}
Ejemplo n.º 8
0
    OP_EXEC(eGraphicsApiDx9 *gfx, eF32 radius, eU32 count, const eVector3 &rot)
    {
        eSceneData &sd = ((eIModelOp *)getInputOperator(0))->getResult().sceneData;

        const eVector3 exRot = rot*eTWOPI;
        const eVector3 trans(0.0f, 0.0f, radius);

        eVector3 curRot = exRot;
        eF32 step = eTWOPI/(count+1);

        for (eU32 i=0; i<=count; i++)
        {
            curRot += exRot;
            curRot.y += step;

            m_sceneData.merge(sd, eMatrix4x4(curRot, trans, eVector3(1.0f), eTRUE));
        }
    }
Ejemplo n.º 9
0
void eDeferredRenderer::renderQuad(const eRect &r, const eSize &size, const eVector2 &tileUv, const eVector2 &scrollUv) const
{
    const eCamera cam(0.0f, (eF32)size.width, 0.0f, (eF32)size.height, -1.0f, 1.0f);
    cam.activate(m_gfx);

    eGeometry geo(4, 0, 2, eVTXTYPE_DEFAULT, eGeometry::TYPE_DYNAMIC, ePRIMTYPE_TRIANGLESTRIPS);
    eVertex *vertices = eNULL;

    geo.startFilling((ePtr *)&vertices, eNULL);
    {
        // +0.5 and -0.5 are required for offsetting screen-space
        // coordinates of quad a bit in order to compensate
        // for correct texel to pixel mapping in Direct3D9.
        vertices[0].set(eVector3((eF32)r.left-0.5f,  (eF32)r.bottom+0.5f, 0.0f), eVector3(), eVector2(scrollUv.u,          scrollUv.v),          eColor::WHITE);
        vertices[1].set(eVector3((eF32)r.left-0.5f,  (eF32)r.top+0.5f,    0.0f), eVector3(), eVector2(scrollUv.u,          tileUv.v+scrollUv.v), eColor::WHITE);
        vertices[2].set(eVector3((eF32)r.right-0.5f, (eF32)r.bottom+0.5f, 0.0f), eVector3(), eVector2(tileUv.u+scrollUv.u, scrollUv.v),          eColor::WHITE);
        vertices[3].set(eVector3((eF32)r.right-0.5f, (eF32)r.top+0.5f,    0.0f), eVector3(), eVector2(tileUv.u+scrollUv.u, tileUv.v+scrollUv.v), eColor::WHITE);
    }
    geo.stopFilling();
    geo.render();
}
Ejemplo n.º 10
0
void eCamera::_extractFrustumPlanes()
{
    eASSERT(m_type == eCAM_PERSPECTIVE);

    // frustum corners after perspective projection
    eVector3 corners[8] =
    {
        eVector3(-1.0f, -1.0f,  0.0f), 
        eVector3( 1.0f, -1.0f,  0.0f), 
        eVector3(-1.0f,  1.0f,  0.0f), 
        eVector3( 1.0f,  1.0f,  0.0f), 
        eVector3(-1.0f, -1.0f,  1.0f), 
        eVector3( 1.0f, -1.0f,  1.0f), 
        eVector3(-1.0f,  1.0f,  1.0f), 
        eVector3( 1.0f,  1.0f,  1.0f), 
    };

    // get corners before perspective projection by
    // multiplying with inverse projection matrix
    const eMatrix4x4 invViewProjMtx = (m_viewMtx*m_projMtx).inverse();

    for (eInt i=0; i<8; i++)
    {
        eVector4 v(corners[i], 1.0f);
        v *= invViewProjMtx;
        v /= v.w;
        corners[i].set(v.x, v.y, v.z);
    }

    // setup frustum planes
    m_frustumPlanes[0] = ePlane(corners[0], corners[1], corners[2]);
    m_frustumPlanes[1] = ePlane(corners[6], corners[7], corners[5]);
    m_frustumPlanes[2] = ePlane(corners[2], corners[6], corners[4]);
    m_frustumPlanes[3] = ePlane(corners[7], corners[3], corners[5]);
    m_frustumPlanes[4] = ePlane(corners[2], corners[3], corners[6]);
    m_frustumPlanes[5] = ePlane(corners[1], corners[0], corners[4]);
}
Ejemplo n.º 11
0
    OP_EXEC(eGraphicsApiDx9 *gfx, const eVector3 &trans, const eVector3 &rot, const eVector3 &scale,
            eU32 count, const eVector3 &randTrans, const eVector3 &randRot, const eVector3 &randScale, eU32 seed)
    {
        eSceneData &sd = ((eIModelOp *)getInputOperator(0))->getResult().sceneData;

        eMatrix4x4 tf;
        tf.transformation(rot*eTWOPI, trans, scale);
        eMatrix4x4 mtx;

		seed++;

        for (eU32 i=0; i<count+1; i++)
        {
			const eVector3 vec_s = eVector3(1.0f)+randScale.random(seed);
			const eVector3 vec_t = randTrans.random(seed);
			const eVector3 vec_r = (randRot*eTWOPI).random(seed);

            const eMatrix4x4 randMtx(vec_r, vec_t, vec_s, eTRUE);

            m_sceneData.merge(sd, randMtx*mtx);
            mtx *= tf;
        }
    }
Ejemplo n.º 12
0
eVector3 eMatrix3x3::getColumn(eU32 col) const
{
    eASSERT(col <= 2);
    return eVector3(m[col], m[col+3], m[col+6]);
}
Ejemplo n.º 13
0
eU32 eMesh::addVertex(const eVector3 &pos, const eColor &color)
{
    return addVertex(pos, eVector3(), eVector2(), color);
}
Ejemplo n.º 14
0
Approximation::Approximation(eU32 gridCnt, eU32 sampleCnt, eF32* samples, eF32* normals)
{
//	this->m_gridCnt = gridCnt;

//	m_boundBox.clear();
	eKD_Tree* kdTree = new eKD_Tree();
	KD_Item* sampleItems = new KD_Item[sampleCnt];
	for(eU32 i = 0; i < sampleCnt; i++)
	{
		sampleItems[i].pos = eVector3(samples[i * 3 + 0], samples[i * 3 + 1], samples[i * 3 + 2]);
		sampleItems[i].objectData = &normals[i * 3];
//		m_boundBox.updateExtentsFast(sampleItems[i].pos);
	}
//	m_boundBox.updateExtentsFinalize();
	kdTree->InsertPoints(sampleItems, sampleCnt);
	this->root = new ApproxNode(kdTree->root);

/*
	KD_Lookup_Entry*	queryBuffer = new KD_Lookup_Entry[sampleCnt];
	eF32*				pointBuffer = new eF32[(3 + 1) * (sampleCnt * 3 + 1)];
	eF32*				valueBuffer = new eF32[sampleCnt * 3 + 1];

	this->m_spaces = new TensorProductSpace[gridCnt*gridCnt*gridCnt]; 
	m_step = m_boundBox.getSizeVector() / (eF32)(gridCnt);
	int t = 0;
	for(eU32 z = 0; z < gridCnt; z++)
		for(eU32 y = 0; y < gridCnt; y++)
			for(eU32 x = 0; x < gridCnt; x++)
			{
				eVector3 pos0((eF32)x * m_step.x, (eF32)y * m_step.y, (eF32)z * m_step.z);
				pos0 += m_boundBox.getMinimum();
				eVector3 pos1 = pos0 + m_step;
				
				eU32 p = 0;
				eU32 v = 0;

				eU32 minSamples = 10;
				eU32 cnt = 0;
				eVector3 pivot = (pos0 + pos1) * 0.5;
				eF32 radiusSquared = (m_step * 0.5).sqrLength();
				kdTree->CollectInRadius(&pivot, radiusSquared, queryBuffer, cnt);
				if(cnt < minSamples)
				{
					kdTree->findKNearest(&pivot, minSamples, queryBuffer, cnt);
					radiusSquared = queryBuffer[cnt-1].distanceSquared;

					pointBuffer[p++] = 1;
					pointBuffer[p++] = pivot.x;
					pointBuffer[p++] = pivot.y;
					pointBuffer[p++] = pivot.z;
					eVector3 normal(*(((eF32*)queryBuffer[0].element->objectData) + 0),
									*(((eF32*)queryBuffer[0].element->objectData) + 1),
									*(((eF32*)queryBuffer[0].element->objectData) + 2));
//					valueBuffer[v++] = ((pivot - queryBuffer[0].element->pos).normalized() * normal.normalized()) * eSqrt(queryBuffer[0].distanceSquared);
					valueBuffer[v++] = ((pivot - queryBuffer[0].element->pos) * normal);

				}

				for(eU32 i = 0; i < cnt; i++)
				{
					for(eS32 d = -1; d <= 1; d++)
					{
						eF32 epsilon = (eF32)d * 0.001;
//						pointBuffer[p++] = Wendland(eSqrt(queryBuffer[i].distanceSquared), eSqrt(radiusSquared));
						pointBuffer[p++] = 1.0f;
						pointBuffer[p++] = queryBuffer[i].element->pos.x + *(((eF32*)queryBuffer[i].element->objectData) + 0) * epsilon;
						pointBuffer[p++] = queryBuffer[i].element->pos.y + *(((eF32*)queryBuffer[i].element->objectData) + 1) * epsilon;
						pointBuffer[p++] = queryBuffer[i].element->pos.z + *(((eF32*)queryBuffer[i].element->objectData) + 2) * epsilon;
						valueBuffer[v++] = epsilon;
					}
				}

				this->m_spaces[t].Calculate(v, pointBuffer, valueBuffer);
				t++;
			}
//	this->m_spaces = new TensorProductSpace(grade, dimensionality, sampleC
	this->m_step.x = 1.0 / this->m_step.x;
	this->m_step.y = 1.0 / this->m_step.y;
	this->m_step.z = 1.0 / this->m_step.z;
*/
}
Ejemplo n.º 15
0
eVector3 eMatrix3x3::operator * (const eVector3 &v) const
{
    return eVector3(m11*v.x+m12*v.y+m13*v.z,
                    m21*v.x+m22*v.y+m23*v.z,
                    m31*v.x+m32*v.y+m33*v.z);
}
Ejemplo n.º 16
0
 eVector3 toVec3()
 {
     return eVector3(x, y, z);
 }
Ejemplo n.º 17
0
void eCALLBACK eTriangulator::_combineCallback(eF64 newVert[3], eU32 neighbourVert[4], eF32 neighborWeight[4], eU32 *index, eTriangulator *trg)
{
    trg->m_vertices.append(eVector3((eF32)newVert[0], (eF32)newVert[1], (eF32)newVert[2]));
    *index = trg->m_vertices.size()-1;
}
Ejemplo n.º 18
0
eVector3 eMatrix4x4::operator * (const eVector3 &v) const
{
    return eVector3(m11*v.x+m12*v.y+m13*v.z+m14,
                    m21*v.x+m22*v.y+m23*v.z+m24,
                    m31*v.x+m32*v.y+m33*v.z+m34);
}
Ejemplo n.º 19
0
void eLSystem::drawInternal(eSceneData& destsg, eMesh& destMesh, tState* state) {
	ePROFILER_ZONE("L-System - Draw Internal Pre");

    this->m_gen_materials_dsIdx.clear();
    for(eU32 i = 0 ; i < this->m_gen_materials.size(); i++)
        this->m_gen_materials_dsIdx.append(destMesh.addDrawSection(this->m_gen_materials[i], eMesh::DrawSection::TYPE_TRIANGLES));

	eQuat originRot = state->curBaseRotation;
	{
		eArray<tProdSymbol>& curProd = m_prodBuffer[0];
		curProd.clear();

		eArray<tSymbol>& production = productions[0];
		for(eU32 s = 0; s < production.size(); s++) {
			tSymbol& curSymbol = production[s];
			tProdSymbol& ps = curProd.push();
			ps.correctRot = originRot;
		}
	}

	eF32 accumulatedStepLen = 0.0f;
	eU32 accumulatedStepCount = 0;
	drawStackPos = 0;
	tDrawState* drawState = getDefaultDrawState();
	drawState->lastTurtle = state->turtle;

    for(eU32 p = 1; p < numProductions; p++) {
		this->pushState(&state);
	
		eBool isLastProduction = p == numProductions - 1;

		state->curBaseRotation = eQuat();

        eU32 polyScopeCnt = 0;
		eArray<tSymbol>& prevProduction = productions[p - 1];
		eArray<tSymbol>& production = productions[p];

		eArray<tProdSymbol>& prevProd = m_prodBuffer[(1-p % 2)];
		eArray<tProdSymbol>& curProd = m_prodBuffer[p % 2];

		curProd.clear();
		curProd.reserve(production.size());

		for(eU32 s = 0; s < production.size(); s++) {
			tSymbol& curSymbol = production[s];
			const tSymbol& parentSymbol = prevProduction[curSymbol.parentIdx];
				
			tProdSymbol& curProdSym = curProd.push();
			const tProdSymbol& parentProdSym = prevProd[curSymbol.parentIdx];

			const eS32 symbolRaw = curSymbol.symbol;
				
			switch(curSymbol.symbol) {
				case '^':	state->turtle.width *= 2.0f; break;
				case '&':	state->turtle.width *= 0.5f; break;
//                case '!':	state->turtle.width = curSymbol.params[0] * this->m_baseWidth; break;
				case '\'':	if(state->turtle.polyMatIdx < this->m_gen_materials.size() - 1) state->turtle.polyMatIdx++; break;
				case '[':	pushState(&state); break;
				case ']':	popState(&state); break;
				case '{':	polyScopeCnt++; break;
				case '}':	polyScopeCnt--; break;
				case 'F':
				case 'G': {
						eQuat currentRot = parentProdSym.correctRot * curSymbol.rotation;
						eQuat currentGlobalRot = state->curBaseRotation * currentRot;
						this->applyForce(curSymbol, currentGlobalRot, state->curBaseRotation, state->turtle.position);

						state->turtle.rotation = (state->curBaseRotation * currentRot);
						eF32 amount = (state->turtle.size * state->turtle.height * curSymbol.params[0]);
						state->turtle.texPos += curSymbol.texVec * (this->m_gen_texScale * amount);
						state->turtle.position += state->turtle.rotation.getVector(2) * amount;
					}
				default:
					state->turtle.size *= m_sizeDecayPar;
					curProdSym.correctRot = state->curBaseRotation * parentProdSym.correctRot;
//                    {
//	                ePROFILER_ZONE("L-System - Draw Internal Calc");
					state->turtle.rotation = curProdSym.correctRot * curSymbol.rotation;
//                    }
			}

			// only draw last production
			if(!isLastProduction)
				continue;
				
			ePROFILER_ZONE("L-System - DrawInterpret");

			switch(curSymbol.symbol) {

			case '%': { // skip remaining
					eU32 scopeCnt = 1;
					while(((++s) < (eS32)production.size()) && (scopeCnt > 0))
						if(production[s].symbol == '[')			scopeCnt++;
						else if(production[s].symbol == ']')	scopeCnt--;
					s -= 2;
				}
				continue;
			case '[': this->pushDrawState(&drawState); break;
			case ']': this->popDrawState(&drawState); break;
			case '{': 
						if(polyStackPos >= polygonStack.size())
							polygonStack.append(eArray<eInt>()); 
						polygon = &polygonStack[polyStackPos++];
						polygon->clear(); 
					break;
			case '}': {
					if((state->turtle.polyMatIdx >= 0) && (state->turtle.polyMatIdx < m_gen_materials.size())) {
						for(eU32 p = 0; (eS32)p < (eS32)polygon->size() - 2; p++) {
							// draw polys
							destMesh.addTriangleFast((*polygon)[p], 
								                 (*polygon)[p+1], 
												 (*polygon)[polygon->size() - 1],
												 m_gen_materials_dsIdx[state->turtle.polyMatIdx]);
						}
					}

					// pop stack
                    polyStackPos--;
                    if(polyStackPos > 0)
					    polygon = &polygonStack[polyStackPos - 1];
				}
				break;
			case 'F':
			case '.': if(polyStackPos > 0) {
							polygon->append(destMesh.addVertex(state->turtle.position, state->turtle.rotation.getVector(2), state->turtle.texPos)); 
                      }
				// no break
			default:
				if((symbolRaw >= LSYS_VAR_MIN) && (symbolRaw <= LSYS_VAR_MAX)) {
					if(this->m_subSystem[symbolRaw] != eNULL) {
//						ePROFILER_ZONE("L-System - Draw Sub LSys");
						this->m_subSystem[symbolRaw]->processSub(destsg, destMesh, state->turtle);
					} else if(this->m_subMesh[symbolRaw] != eNULL) {
						ePROFILER_ZONE("L-System - Draw Sub Model");

						eMatrix4x4 mtx;
						mtx.scale(state->turtle.size);
						eQuat con = state->turtle.rotation;
						con.conjugate();
                        eMatrix4x4 rotMtx((eQuat(eVector3(1,0,0), -ePI * 0.5f) * (con)));
						mtx = mtx * rotMtx;
						mtx.translate(eVector3(state->turtle.position.x, state->turtle.position.y, state->turtle.position.z));

                        if(m_subMeshInstancing[symbolRaw])
                            destsg.merge(*this->m_subMesh[symbolRaw], mtx);
                        else
                            for(eU32 i = 0; i < m_subMesh[symbolRaw]->getEntryCount(); i++) 
                                _mergeIntoMesh(destMesh, mtx, rotMtx, m_subMesh[symbolRaw]->getEntry(i));
//                                _mergeIntoMesh(destMesh, mtx, mtx, m_subMesh[symbolRaw]->getEntry(i));
					} else {
						bool skipDraw = false;
						if((polyStackPos == 0) || (polygon->size() == 0)) {
							// draw aggregated shapes
							if((symbolRaw != 'F') || (state->turtle.polyMatIdx < 0) || (state->turtle.polyMatIdx >= m_gen_materials.size()))
							{
							} else {

								eBool forceDraw = (s >= production.size() - 1) ||
									(production[s + 1].symbol != curSymbol.symbol);
								eF32 stepLen = state->turtle.size * state->turtle.height;
								skipDraw = !this->drawShapes(destMesh, *drawState, drawState->lastTurtle, state->turtle, accumulatedStepLen + stepLen, drawState->texYOffset, drawState->texYOffset + m_gen_texScale, forceDraw, accumulatedStepCount + 1);
								if(skipDraw) {
									accumulatedStepCount++;
									accumulatedStepLen += stepLen;
								} else {
									accumulatedStepCount = 0;
									accumulatedStepLen = 0.0f;
								}
							}
						}

						drawState->texYOffset += m_gen_texScale;
						if(!skipDraw)
							drawState->lastTurtle = state->turtle;
					}
				}
			}
		}
		this->popState(&state);
	} 

}