Beispiel #1
0
bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	// write STL MESH header

	file->write("solid ",6);
	const core::stringc name(SceneManager->getMeshCache()->getMeshFilename(mesh));
	file->write(name.c_str(),name.size());
	file->write("\n\n",2);

	// write mesh buffers
	
	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer)
		{
			const u16 indexCount = buffer->getIndexCount();

			switch(buffer->getVertexType())
			{
			case video::EVT_STANDARD:
				{
					video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
					for (u32 j=0; j<indexCount; j+=3)
						writeFace(file,
							vtx[buffer->getIndices()[j]].Pos,
							vtx[buffer->getIndices()[j+1]].Pos,
							vtx[buffer->getIndices()[j+2]].Pos);
				}
				break;
			case video::EVT_2TCOORDS:
				{
					video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
					for (u32 j=0; j<indexCount; j+=3)
						writeFace(file,
							vtx[buffer->getIndices()[j]].Pos,
							vtx[buffer->getIndices()[j+1]].Pos,
							vtx[buffer->getIndices()[j+2]].Pos);
				}
				break;
			case video::EVT_TANGENTS:
				{
					video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
					for (u32 j=0; j<indexCount; j+=3)
						writeFace(file,
							vtx[buffer->getIndices()[j]].Pos,
							vtx[buffer->getIndices()[j+1]].Pos,
							vtx[buffer->getIndices()[j+2]].Pos);
				}
				break;
			}
			file->write("\n",1);
		}
	}

	file->write("endsolid ",9);
	file->write(name.c_str(),name.size());

	return true;
}
void CTriangleSelector::updateFromMesh(const IMesh* mesh) const
{
	if (!mesh)
		return;

	u32 meshBuffers = mesh->getMeshBufferCount();
	u32 triangleCount = 0;

	for (u32 i = 0; i < meshBuffers; ++i)
	{
		IMeshBuffer* buf = mesh->getMeshBuffer(i);
		u32 idxCnt = buf->getIndexCount();
		const u16* indices = buf->getIndices();

		switch (buf->getVertexType())
		{
		case video::EVT_STANDARD:
			{
				video::S3DVertex* vtx = (video::S3DVertex*)buf->getVertices();
				for (u32 index = 0; index < idxCnt; index += 3)
				{
					core::triangle3df & tri = Triangles[triangleCount++];
					tri.pointA = vtx[indices[index + 0]].Pos;
					tri.pointB = vtx[indices[index + 1]].Pos;
					tri.pointC = vtx[indices[index + 2]].Pos;
				}
			}
			break;
		case video::EVT_2TCOORDS:
			{
				video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buf->getVertices();
				for (u32 index = 0; index < idxCnt; index += 3)
				{
					core::triangle3df & tri = Triangles[triangleCount++];
					tri.pointA = vtx[indices[index + 0]].Pos;
					tri.pointB = vtx[indices[index + 1]].Pos;
					tri.pointC = vtx[indices[index + 2]].Pos;
				}
			}
			break;
		case video::EVT_TANGENTS:
			{
				video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buf->getVertices();
				for (u32 index = 0; index < idxCnt; index += 3)
				{
					core::triangle3df & tri = Triangles[triangleCount++];
					tri.pointA = vtx[indices[index + 0]].Pos;
					tri.pointB = vtx[indices[index + 1]].Pos;
					tri.pointC = vtx[indices[index + 2]].Pos;
				}
			}
			break;
		}
	}
}
Beispiel #3
0
f32 TerrainTile::getVerticeHeight(vector3df pos)
{
	f32 radius = 100;
	f32 returnvalue = 0;
	f32 smallest = radius;
	IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);

	S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices();

	u16* mb_indices  = meshBuffer->getIndices();

	//Check all indices in the mesh to find the one that is nearest the position
	for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
	{
	    vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
        pos.Y = realPos.Y; //Put the height at the same height

		//Check if its the smallest distance
	    if((realPos.getDistanceFrom(pos) < smallest))
	    {
			smallest = realPos.getDistanceFrom(pos);
			returnvalue = realPos.Y;
	    }

	}
	return returnvalue;

}
Beispiel #4
0
float CGWIC_Cell::GetTerrainHeightUnderPointMetric(irr::core::vector3df pnt)
{
	u32 x = floor(pnt.X);
	u32 z = floor(pnt.Z);
	if (x > 255) x = 255;
	if (z > 255) z = 255;
	u32 index = x * 256 + z;
	IMesh* pMesh = terrain->getMesh();
	float res = 0.f;
//	float max = 0;
	const float scy = terrain->getScale().Y;
	//FIXME: get the true position in meters
	for (u32 n=0; n<pMesh->getMeshBufferCount(); n++) {
		IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(n);
		if (pMeshBuffer->getVertexType() != EVT_2TCOORDS) continue;
		S3DVertex2TCoords* pVertices = (S3DVertex2TCoords*)pMeshBuffer->getVertices();
		res = pVertices[index].Pos.Y / scy;
//		res = (pVertices[index].Pos.Y + terrain->getPosition().Y) / scy;
//		res += terrain->getPosition().Y / GWIC_IRRUNITS_PER_METER;
//		std::cerr << "POSIT  " << res << std::endl;
//		for (u32 k=0; k<(256*256); k++) if (pVertices[k].Pos.Y > max) max = pVertices[k].Pos.Y;
//		std::cerr << "MAXX  " << max << std::endl;
		break;
	}
	return res;
}
ConvexHull::ConvexHull(ISceneNode *irrobject, double mass)
	   :PhysicalObject(irrobject, mass)
{
	IMeshBuffer* mbuffer = ((IAnimatedMeshSceneNode*)irrobject)->getMesh()->getMeshBuffer(0);

	int numVertices = mbuffer->getVertexCount();

	btVector3 vertexBase[numVertices];

	S3DVertex* vertices = (S3DVertex*)(mbuffer->getVertices());
	vector3df scale = irrobject->getScale();

	btConvexHullShape* chshape = new btConvexHullShape();

	for(int i = 0; i < numVertices; i++)
	{
		vertexBase[i].setX((float)(vertices[i].Pos.X * scale.X));
		vertexBase[i].setY((float)(vertices[i].Pos.Y * scale.Y));
		vertexBase[i].setZ((float)(vertices[i].Pos.Z * scale.Z));
		chshape->addPoint(vertexBase[i]);
	}

	initialize(chshape);

}
Beispiel #6
0
void CGWIC_Cell::RandomizeTerrain(float subdelta)
{
	IMesh* pMesh = terrain->getMesh();
	s32 Q = static_cast<s32> (subdelta);
	for (u32 n=0; n<pMesh->getMeshBufferCount(); n++) {
		IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(n);
		if (pMeshBuffer->getVertexType() != EVT_2TCOORDS) continue;
		S3DVertex2TCoords* pVertices = (S3DVertex2TCoords*)pMeshBuffer->getVertices();
		//1. find the current max & min, since we don't want to escalate landscape
		float max = 0;
		float min = 256;
		u32 i;
		for (i=0; i<(256*256); i++) {
			if (pVertices[i].Pos.Y < min) min = pVertices[i].Pos.Y;
			if (pVertices[i].Pos.Y > max) max = pVertices[i].Pos.Y;
		}
		std::cout << "RandTerr: min=" << min << ";  max=" << max << std::endl;
		//2. create temp array & randomize it
		std::vector<float> tmparr;
		float cy;
		for (i=0; i<(256*256); i++) {
			if (Q) {
				cy = Random_FLOAT(max-min);
				cy += min;
			} else cy = 0;
			tmparr.push_back(cy);
		}
		std::cout << std::endl;
		//3. interpolate vertices inside big quads
		s32 A = 0;
		if (Q) A = 256 / Q + 1;
		for (int qx=0; qx<A; qx++)
			for (int qy=0; qy<A; qy++) {
				//TODO: remove unnecessary vars
				int x0 = qx * Q;
				int y0 = qy * Q;
				int xe = x0 + Q;
				if (xe > 255) xe = 255;
				int ye = y0 + Q;
				if (ye > 255) ye = 255;
				float hx0 = tmparr[x0*256+y0];
				float hy0 = (qx%2)? tmparr[xe*256+ye]:hx0;
				float hxe = tmparr[xe*256+y0];
				float hye = tmparr[x0*256+ye];
				float lhy = hye - hy0;
				float lhx = hxe - hx0;
				for (int cx=x0; cx<xe; cx++)
					for (int cy=y0; cy<ye; cy++) {
						float ch = (((qx%2)?(x0-cx):(cx-x0))/lhx)*lhx+hx0;
						ch += (((qy%2)?(y0-cy):(cy-y0))/lhy)*lhy+hy0;
						tmparr[cx*256+cy] = ch / 2;
					}
			}
		//4. get result back
		for (i=0; i<(256*256); i++)
			pVertices[i].Pos.Y = tmparr[i];
		break;
	}
	TerrainChanged();
}
Beispiel #7
0
    //-----------------------------------------------------------------------
    //                     e x t r a c t T r i a n g l e s
    //-----------------------------------------------------------------------
    btTriangleMesh* TMeshShape::extractTriangles(IMesh* mesh,   
        bool removeDupVertices)
    {
        vector3df p1, p2, p3;

        // 32 bit indices, 3 component vertices - allows for use in decomposition.
        btTriangleMesh* triMesh = new btTriangleMesh(true, false);
        u32 bufCount = mesh->getMeshBufferCount();

        for(u32 i=0;i<bufCount;i++)
        {
            IMeshBuffer* mbuf = mesh->getMeshBuffer(i);
            void* vp = mbuf->getVertices();
            E_VERTEX_TYPE vtype = mbuf->getVertexType();
            S3DVertex           *vstd = (S3DVertex*) vp;
            S3DVertex2TCoords   *v2t = (S3DVertex2TCoords*) vp;
            S3DVertexTangents   *vtan = (S3DVertexTangents*)vp;
            const u16* ip = mbuf->getIndices();
            u32 ic = mbuf->getIndexCount();
            u32 fi = 0;
            while(fi < ic)
            {
                S3DVertex *v1,*v2,*v3;
                switch(vtype)
                {
                case EVT_2TCOORDS:
                    v1 = &v2t[ip[fi++]];
                    v2 = &v2t[ip[fi++]];
                    v3 = &v2t[ip[fi++]];
                    break;
                case EVT_TANGENTS:
                    v1 = &vtan[ip[fi++]];
                    v2 = &vtan[ip[fi++]];
                    v3 = &vtan[ip[fi++]];
                    break;
                default:
                    v1 = &vstd[ip[fi++]];
                    v2 = &vstd[ip[fi++]];
                    v3 = &vstd[ip[fi++]];
                    break;
                }

                p1 = v1->Pos;
                p2 = v2->Pos;
                p3 = v3->Pos;

                btVector3 b1(p1.X, p1.Y, p1.Z);
                btVector3 b2(p2.X, p2.Y, p2.Z);
                btVector3 b3(p3.X, p3.Y, p3.Z);

                triMesh->addTriangle(b1,b2,b3,removeDupVertices);
            }
        }
        return triMesh;
    }
Beispiel #8
0
void TerrainTile::mergeToTile(TerrainTile* tile)
{
    if(!tile || custom)
    {
        #ifdef DEBUG
        cout << "DEBUG : TERRAIN TILE : MERGE FAILED, TILE IS NULL: " << endl;
        #endif
        return;
    }
    else
    {
        IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);
        IMeshBuffer* neighborBuffer = tile->getMeshBuffer();

        S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices();
        S3DVertex* n_mb_vertices = (S3DVertex*) neighborBuffer->getVertices();

        u16* mb_indices  = meshBuffer->getIndices();
        u16* n_mb_indices  = neighborBuffer->getIndices();

        for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
        {
            for (unsigned int i = 0; i < neighborBuffer->getVertexCount(); i += 1)
            {
                vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
                vector3df nRealPos = n_mb_vertices[i].Pos*(scale/nodescale) + tile->getNode()->getPosition();

                if((realPos.X == nRealPos.X) && (realPos.Z == nRealPos.Z))
                {
                    mb_vertices[j].Pos.Y = n_mb_vertices[i].Pos.Y;
					mb_vertices[j].Normal = n_mb_vertices[i].Normal; //New Copy the normal information
					needrecalc=true;
                }
            }
        }

        //smgr->getMeshManipulator()->recalculateNormals(((IMeshSceneNode*)node)->getMesh(),true);
		((IMeshSceneNode*)node)->getMesh()->setDirty();
		needrecalc = true;

    }
}
Beispiel #9
0
void TerrainTile::restoreUndo()
{
	if (undohistory.size()>0)
	{
		IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);

		S3DVertex* mb_vertices = (S3DVertex*)meshBuffer->getVertices();

		u16* mb_indices = meshBuffer->getIndices();
		printf("Here is the undo history size: %i\n", undohistory.size());
		undobuffer = undohistory.back();
		printf("Here is the undo buffer size: %i\n", undobuffer.size());

		for (unsigned int j = 0; j < undohistory[undohistory.size()-1].size(); j += 1)
		{
			mb_vertices[j].Pos.Y = undohistory[undohistory.size() - 1][j];
		}

		meshBuffer = ((IMeshSceneNode*)ocean)->getMesh()->getMeshBuffer(0);

		mb_vertices = (S3DVertex*)meshBuffer->getVertices();

		mb_indices = meshBuffer->getIndices();

		for (unsigned int j = 0; j < undohistory[undohistory.size() - 1].size(); j += 1)
		{
			mb_vertices[j].Pos.Y = undohistory[undohistory.size() - 1][j];
		}
		


		
		needrecalc = true;
		recalculate();
		undohistory.pop_back(); //Remove the last element of the vector by 1;
		
		undobuffer.clear(); //Clear the buffer;
		
	}
	
}
Beispiel #10
0
void TerrainTile::transformMeshToValue(vector3df clickPos, f32 radius, f32 radius2, f32 strength, f32 value, bool norecalc)
{

	if (custom)
		return;

    if(strength<0) strength = -strength;

    IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);

	S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices();

	u16* mb_indices  = meshBuffer->getIndices();

	for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
	{
	    vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
        clickPos.Y = realPos.Y;
	    if(realPos.getDistanceFrom(clickPos) < radius)
	    {
			needrecalc=true;
            //f32 ratio = sin(radius - realPos.getDistanceFrom(clickPos));
			f32 ratio = radius;

			if (radius2-realPos.getDistanceFrom(clickPos)<0)
				ratio = (radius+radius2)-realPos.getDistanceFrom(clickPos);

            if(mb_vertices[j].Pos.Y > value)
            {
				//mb_vertices[j].Pos.Y -= strength * ratio / (scale/nodescale);
                mb_vertices[j].Pos.Y -= strength * ratio / (scale/nodescale);
                if(mb_vertices[j].Pos.Y <= value) mb_vertices[j].Pos.Y = value;

            }
            if(mb_vertices[j].Pos.Y < value)
            {
		        //mb_vertices[j].Pos.Y += strength * ratio / (scale / nodescale);
				mb_vertices[j].Pos.Y += strength *ratio / (scale / nodescale);
                if(mb_vertices[j].Pos.Y >= value) mb_vertices[j].Pos.Y = value;
            }
	    }
	}

	if (norecalc)
	{
		recalculate(true);
	}
	else
		recalculate();
}
Beispiel #11
0
void TerrainTile::storeUndo()
{
	IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);

	S3DVertex* mb_vertices = (S3DVertex*)meshBuffer->getVertices();

	u16* mb_indices = meshBuffer->getIndices();
	
	for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
	{
		undobuffer.push_back(mb_vertices[j].Pos.Y);
	}
	undohistory.push_back(undobuffer);
	undobuffer.clear();
}
Beispiel #12
0
void TerrainTile::transformMesh(vector3df clickPos, f32 radius, f32 radius2, f32 strength, bool norecalc)
{

	if (custom)
		return;

    IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);

	S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices();

	u16* mb_indices  = meshBuffer->getIndices();

	for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
	{
	    vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
        clickPos.Y = realPos.Y;

	    if(realPos.getDistanceFrom(clickPos) < radius)
	    {
			needrecalc=true; // This will flag the tile since it's in the radius and will modify the tile vertices.

            //f32 ratio = sin(radius - realPos.getDistanceFrom(clickPos));
			//- (realPos.getDistanceFrom(clickPos)-radius2)
			f32 ratio = radius;

			if (radius2-realPos.getDistanceFrom(clickPos)<0)
				ratio = (radius+radius2)-realPos.getDistanceFrom(clickPos);

	        mb_vertices[j].Pos.Y += (strength * (ratio)/(scale/nodescale));
			//printf("found something here: vertice %i, vertice Y: %f\n",j, mb_vertices[j].Pos.Y);
	    }

		//if(mb_vertices[j].Pos.Y > nodescale/4) mb_vertices[j].Pos.Y = nodescale/4;
		// Fix up/down limits
		if(mb_vertices[j].Pos.Y > nodescale*0.75f) mb_vertices[j].Pos.Y = nodescale*0.75f;
	    if(mb_vertices[j].Pos.Y < -(nodescale*0.25f)) mb_vertices[j].Pos.Y = -(nodescale*0.25f);
	}

	if (norecalc)
	{
		recalculate(true);
	}
	else
		recalculate();

}
Beispiel #13
0
bool CGWIC_Cell::SetTerrainHeightUnderPointMetric(irr::core::vector3df pnt, float height, bool update)
{
	u32 x = floor(pnt.X);
	u32 z = floor(pnt.Z);
	if (x > 255) x = 255;
	if (z > 255) z = 255;
	u32 index = x * 256 + z;
	IMesh* pMesh = terrain->getMesh();
	const float scy = terrain->getScale().Y;
	for (u32 n=0; n<pMesh->getMeshBufferCount(); n++) {
		IMeshBuffer* pMeshBuffer = pMesh->getMeshBuffer(n);
		if (pMeshBuffer->getVertexType() != EVT_2TCOORDS) continue;
		S3DVertex2TCoords* pVertices = (S3DVertex2TCoords*)pMeshBuffer->getVertices();
		pVertices[index].Pos.Y = height * scy;
		break;
	}
	if (update) TerrainChanged();
	return true;
}
Beispiel #14
0
// Test the tile if it was being modified
bool TerrainTile::checkModified()
{
	bool modified = false;

    IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);
	S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices();

    for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
	{
	    vector3df realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
	    if(realPos.Y != 0.0f )
        {
           modified = true;
		   j=meshBuffer->getVertexCount();
		   break;
        }
	}

	return modified;

}
void CPlanarShadow::buildMesh(IMesh*mesh)
{

	s32 i;
	s32 totalVertices = 0;
	s32 totalIndices = 0;
	s32 bufcnt = mesh->getMeshBufferCount();
	IMeshBuffer* b;

	int vtxNow = 0;

	for (i=0; i<bufcnt; ++i)
	{
		IMeshBuffer* b;
		b = mesh->getMeshBuffer(i);

		video::S3DVertex* vtxbuff = (video::S3DVertex*)b->getVertices();

		for(int o = 0; o < b->getVertexCount(); o++)
			Vertices[vtxNow++] = vtxbuff[o].Pos;
	}

}
//! sets the mesh from which the shadow volume should be generated.
void CShadowVolumeSceneNode::setMeshToRenderFrom(IMesh* mesh)
{
    ShadowVolumesUsed = 0;

    s32 oldIndexCount = IndexCount;
    s32 oldVertexCount = VertexCount;

    VertexCount = 0;
    IndexCount = 0;

    if (!mesh)
        return;

    // calculate total amount of vertices and indices

    u32 i;
    s32 totalVertices = 0;
    s32 totalIndices = 0;
    u32 bufcnt = mesh->getMeshBufferCount();
    IMeshBuffer* b;

    for (i=0; i<bufcnt; ++i)
    {
        b = mesh->getMeshBuffer(i);
        totalIndices += b->getIndexCount();
        totalVertices += b->getVertexCount();
    }

    // allocate memory if nececcary

    if (totalVertices > VertexCountAllocated)
    {
        delete [] Vertices;
        Vertices = new core::vector3df[totalVertices];
        VertexCountAllocated = totalVertices;
    }

    if (totalIndices > IndexCountAllocated)
    {
        delete [] Indices;
        Indices = new u16[totalIndices];
        IndexCountAllocated = totalIndices;

        if (UseZFailMethod)
        {
            delete [] FaceData;
            FaceData = new bool[totalIndices / 3];
        }
    }

    // copy mesh

    for (i=0; i<bufcnt; ++i)
    {
        b = mesh->getMeshBuffer(i);

        s32 idxcnt = b->getIndexCount();
        s32 vtxnow = VertexCount;

        const u16* idxp = b->getIndices();
        const u16* idxpend = idxp + idxcnt;

        for (; idxp!=idxpend; ++idxp)
            Indices[IndexCount++] = *idxp + vtxnow;

        s32 vtxcnt = b->getVertexCount();

        switch(b->getVertexType())
        {
        case video::EVT_STANDARD:
        {
            const video::S3DVertex* vp = (video::S3DVertex*)b->getVertices();
            const video::S3DVertex* vpend = vp + vtxcnt;

            for (; vp!=vpend; ++vp)
                Vertices[VertexCount++] = (*vp).Pos;
        }
        break;
        case video::EVT_2TCOORDS:
        {
            const video::S3DVertex2TCoords* vp = (video::S3DVertex2TCoords*)b->getVertices();
            const video::S3DVertex2TCoords* vpend = vp + vtxcnt;

            for (; vp!=vpend; ++vp)
                Vertices[VertexCount++] = (*vp).Pos;
        }
        break;
        case video::EVT_TANGENTS:
        {
            const video::S3DVertexTangents* vp = (video::S3DVertexTangents*)b->getVertices();
            const video::S3DVertexTangents* vpend = vp + vtxcnt;

            for (; vp!=vpend; ++vp)
                Vertices[VertexCount++] = (*vp).Pos;
        }
        break;
        }
    }

    // recalculate adjacency if neccessarry
    if (oldVertexCount != VertexCount &&
            oldIndexCount != IndexCount && UseZFailMethod)
        calculateAdjacency();

    // create as much shadow volumes as there are lights but
    // do not ignore the max light settings.

    u32 lights = SceneManager->getVideoDriver()->getDynamicLightCount();
    core::matrix4 mat = Parent->getAbsoluteTransformation();
    core::vector3df parentpos = Parent->getAbsolutePosition();
    core::vector3df lpos;
    mat.makeInverse();

    for (i=0; i<lights; ++i)
    {
        const video::SLight& dl = SceneManager->getVideoDriver()->getDynamicLight(i);
        lpos = dl.Position;
        if (dl.CastShadows &&
                fabs((lpos - parentpos).getLengthSQ()) <= (dl.Radius*dl.Radius*4.0f))
        {
            mat.transformVect(lpos);
            createShadowVolume(lpos);
        }
    }
}
	//! draws the element and its children
	void CGUIMeshViewer::draw()
	{
		if (!IsVisible)
			return;

		IGUISkin* skin = Environment->getSkin();
		IVideoDriver* driver = Environment->getVideoDriver();
		rect<SINT32> viewPort = AbsoluteRect;
		viewPort.LowerRightCorner.x -= 1;
		viewPort.LowerRightCorner.y -= 1;
		viewPort.UpperLeftCorner.x += 1;
		viewPort.UpperLeftCorner.y += 1;

		viewPort.clipAgainst(AbsoluteClippingRect);

		// draw the frame

		rect<SINT32> frameRect(AbsoluteRect);
		frameRect.LowerRightCorner.y = frameRect.UpperLeftCorner.y + 1;
		skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect);

		frameRect.LowerRightCorner.y = AbsoluteRect.LowerRightCorner.y;
		frameRect.LowerRightCorner.x = frameRect.UpperLeftCorner.x + 1;
		skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect);

		frameRect = AbsoluteRect;
		frameRect.UpperLeftCorner.x = frameRect.LowerRightCorner.x - 1;
		skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);

		frameRect = AbsoluteRect;
		frameRect.UpperLeftCorner.y = AbsoluteRect.LowerRightCorner.y - 1;
		skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect);

		// draw the mesh

		if (Mesh)
		{
			//TODO: if outside of screen, dont draw.
			// - why is the absolute clipping rect not already the screen?

			rect<SINT32> oldViewPort = driver->getViewPort();

			driver->setViewPort(viewPort);

			Matrix4 mat;

			//CameraControl->calculateProjectionMatrix(mat);
			//driver->setTransform(TS_PROJECTION, mat);

			mat = Matrix4::IDENTITY;
			mat.setTrans(Vector3(0, 0, 0));
			//mat.setTranslation(Vector3(0, 0, 0));
			driver->setTransform(ETS_WORLD, mat);

			//CameraControl->calculateViewMatrix(mat);
			//driver->setTransform(TS_VIEW, mat);

			driver->setMaterial(Material);

			UINT32 frame = 0;
			if (Mesh->getFrameCount())
				frame = (Timer::getTime() / 20) % Mesh->getFrameCount();
			const IMesh* const m = Mesh->getMesh(frame);
			for (UINT32 i = 0; i<m->getMeshBufferCount(); ++i)
			{
				IMeshBuffer* mb = m->getMeshBuffer(i);
				driver->drawVertexPrimitiveList(mb->getVertices(),
					mb->getVertexCount(), mb->getIndices(),
					mb->getIndexCount() / 3, mb->getVertexType(),
					EPT_TRIANGLES, mb->getIndexType());
			}

			driver->setViewPort(oldViewPort);
		}

		IGUIElement::draw();
	}
//! creates the tree
bool COctTreeSceneNode::createTree(IMesh* mesh)
{
	if (!mesh)
		return false;

	MeshName = SceneManager->getMeshCache()->getMeshFilename( mesh );

	deleteTree();

	u32 beginTime = os::Timer::getRealTime();

	u32 nodeCount = 0;
	u32 polyCount = 0;

	Box = mesh->getBoundingBox();

	if (mesh->getMeshBufferCount())
	{
		vertexType = mesh->getMeshBuffer(0)->getVertexType();

		switch(vertexType)
		{
		case video::EVT_STANDARD:
			{
				for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
				{
					IMeshBuffer* b = mesh->getMeshBuffer(i);
					if (b->getVertexCount() && b->getIndexCount()) 
					{
						Materials.push_back(b->getMaterial());

						StdMeshes.push_back(OctTree<video::S3DVertex>::SMeshChunk());
						OctTree<video::S3DVertex>::SMeshChunk &nchunk = StdMeshes.getLast();
						nchunk.MaterialId = Materials.size() - 1;

						u32 v;
						nchunk.Vertices.reallocate(b->getVertexCount());
						for (v=0; v<b->getVertexCount(); ++v)
							nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]);

						polyCount += b->getIndexCount();

						nchunk.Indices.reallocate(b->getIndexCount());
						for (v=0; v<b->getIndexCount(); ++v)
							nchunk.Indices.push_back(b->getIndices()[v]);
					}
				}

				StdOctTree = new OctTree<video::S3DVertex>(StdMeshes, MinimalPolysPerNode);
				nodeCount = StdOctTree->getNodeCount();
			}
			break;
		case video::EVT_2TCOORDS:
			{
				for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
				{
					IMeshBuffer* b = mesh->getMeshBuffer(i);

					if (b->getVertexCount() && b->getIndexCount()) 
					{
						Materials.push_back(b->getMaterial());
						LightMapMeshes.push_back(OctTree<video::S3DVertex2TCoords>::SMeshChunk());
						OctTree<video::S3DVertex2TCoords>::SMeshChunk& nchunk = LightMapMeshes.getLast();
						nchunk.MaterialId = Materials.size() - 1;

						u32 v;
						nchunk.Vertices.reallocate(b->getVertexCount());
						for (v=0; v<b->getVertexCount(); ++v)
							nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]);

						polyCount += b->getIndexCount();
						nchunk.Indices.reallocate(b->getIndexCount());
						for (v=0; v<b->getIndexCount(); ++v)
							nchunk.Indices.push_back(b->getIndices()[v]);
					}
				}

				LightMapOctTree = new OctTree<video::S3DVertex2TCoords>(LightMapMeshes, MinimalPolysPerNode);
				nodeCount = LightMapOctTree->getNodeCount();
			}
			break;
		case video::EVT_TANGENTS:
			{
				for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
				{
					IMeshBuffer* b = mesh->getMeshBuffer(i);

					if (b->getVertexCount() && b->getIndexCount()) 
					{
						Materials.push_back(b->getMaterial());
						TangentsMeshes.push_back(OctTree<video::S3DVertexTangents>::SMeshChunk());
						OctTree<video::S3DVertexTangents>::SMeshChunk& nchunk = TangentsMeshes.getLast();
						nchunk.MaterialId = Materials.size() - 1;

						u32 v;
						nchunk.Vertices.reallocate(b->getVertexCount());
						for (v=0; v<b->getVertexCount(); ++v)
							nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);

						polyCount += b->getIndexCount();
						nchunk.Indices.reallocate(b->getIndexCount());
						for (v=0; v<b->getIndexCount(); ++v)
							nchunk.Indices.push_back(b->getIndices()[v]);
					}
				}

				TangentsOctTree = new OctTree<video::S3DVertexTangents>(TangentsMeshes, MinimalPolysPerNode);
				nodeCount = TangentsOctTree->getNodeCount();
			}
			break;
		}
	}

	u32 endTime = os::Timer::getRealTime();
	c8 tmp[255];
	sprintf(tmp, "Needed %ums to create OctTree SceneNode.(%u nodes, %u polys)",
		endTime - beginTime, nodeCount, polyCount/3);
	os::Printer::log(tmp, ELL_INFORMATION);

	return true;
}
Beispiel #19
0
bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags)
{
	// write STL MESH header

	file->write("binary ",7);
	const core::stringc name(SceneManager->getMeshCache()->getMeshFilename(mesh));
	const s32 sizeleft = 73-name.size(); // 80 byte header
	if (sizeleft<0)
		file->write(name.c_str(),73);
	else
	{
		char* buf = new char[80];
		memset(buf, 0, 80);
		file->write(name.c_str(),name.size());
		file->write(buf,sizeleft);
		delete [] buf;
	}
	u32 facenum = 0;
	for (u32 j=0; j<mesh->getMeshBufferCount(); ++j)
		facenum += mesh->getMeshBuffer(j)->getIndexCount()/3;
	file->write(&facenum,4);

	// write mesh buffers

	for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
	{
		IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		if (buffer)
		{
			const u16 indexCount = buffer->getIndexCount();

			switch(buffer->getVertexType())
			{
			case video::EVT_STANDARD:
				{
					video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices();
					const u16 attributes = 0;
					for (u32 j=0; j<indexCount; j+=3)
					{
						file->write(&core::plane3df(vtx[buffer->getIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos).Normal, 12);
						file->write(&vtx[buffer->getIndices()[j]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12);
						file->write(&attributes, 2);
					}
				}
				break;
			case video::EVT_2TCOORDS:
				{
					video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices();
					const u16 attributes = 0;
					for (u32 j=0; j<indexCount; j+=3)
					{
						file->write(&core::plane3df(vtx[buffer->getIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos).Normal, 12);
						file->write(&vtx[buffer->getIndices()[j]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12);
						file->write(&attributes, 2);
					}
				}
				break;
			case video::EVT_TANGENTS:
				{
					video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices();
					const u16 attributes = 0;
					for (u32 j=0; j<indexCount; j+=3)
					{
						file->write(&core::plane3df(vtx[buffer->getIndices()[j]].Pos,vtx[buffer->getIndices()[j+1]].Pos,vtx[buffer->getIndices()[j+2]].Pos).Normal, 12);
						file->write(&vtx[buffer->getIndices()[j]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+1]].Pos, 12);
						file->write(&vtx[buffer->getIndices()[j+2]].Pos, 12);
						file->write(&attributes, 2);
					}
				}
				break;
			}
		}
	}
	return true;
}
Beispiel #20
0
Vegetation* TerrainTile::paintVegetation(vector3df clickPos, bool erase)
{
	//Do a prior check to see if there is a least one tree active in the list of active objects
	vector<bool> enabled=VegetationSeed::getInstance()->getEnabled();
	vector<int> newlist;
	for(int i = 0; i<(int)enabled.size(); i++)
	{
		if (enabled[i]==true)
			newlist.push_back(i); //New list will contain the list of the enabled items
	}
	if (newlist.size()==0) return NULL;

    IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0);

	S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices();

	u16* mb_indices  = meshBuffer->getIndices();

	Vegetation* returnvalue = NULL;

	for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1)
	{
	    if(erase)
        {
			vector3df realPos = vector3df (0.0f,0.0f,0.0f);
			//Should be able to place a tree anywhere on a custom model
			if (!custom)
				realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
			else
				realPos = clickPos;

            clickPos.Y = realPos.Y;
            if(realPos.getDistanceFrom(clickPos) < vegetationRange/2 && getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z)))
            {
                Vegetation* toRemove = getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z));
				returnvalue = toRemove;
				return returnvalue;
				// Done outside the function (caller will do the removal)
            }
        }
        else
        {
            vector3df realPos = vector3df (0.0f,0.0f,0.0f);
			//Should be able to place a tree anywhere on a custom model
			if (!custom)
				realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition();
			else
				realPos = clickPos;

            clickPos.Y = realPos.Y; 
            if(realPos.getDistanceFrom(clickPos) < (vegetationRange/2) && !getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z)))
            {
                Vegetation* v = new Vegetation();

                //v->setPosition(vector3df(realPos.X + (rand()%5)*0.1f - 0.25f,realPos.Y/(scale/nodescale),realPos.Z + (rand()%5)*0.1f - 0.25f));
				//v->setPosition(vector3df(realPos.X + (rand()%5)*scale/100,realPos.Y,realPos.Z + (rand()%5)*scale/100));
				v->setPosition(vector3df(realPos.X,realPos.Y,realPos.Z));
                f32 treesize = (f32)(rand() % 50 + 25);
				f32 treerot = (f32)(rand() % 1 + 359);

				v->setScale(vector3df(treesize,treesize,treesize));
				v->setRotation(vector3df(0,treerot,0));

#ifdef DEBUG
				printf("Attempting to place a tree with this size: %f\n",treesize);
#endif
                vegetationVector.push_back(v);
				returnvalue = v;

				return returnvalue;

                #ifdef APP_DEBUG
                cout << "DEBUG : TERRAIN TILE : VEGETATION CREATED: " << realPos.X << "," << realPos.Y << "," << realPos.Z << "   TOTAL:" << vegetationVector.size() << endl;
                #endif
	        }
	    }
	}

	return returnvalue;

}
Beispiel #21
0
// ISoftBody::createShape() is taken from code found on the Irrlicht forum
void ISoftBody::createShape(IMesh* const collMesh)
{
    int cMeshBuffer, j;
    IMeshBuffer *mb;
    video::S3DVertex* mb_vertices;
    u16* mb_indices;


    std::map<int, int> index_map;
    std::map<int, int> bullet_map;
    std::map<int, S3DVertex> vertex_map;
    int count = 0;
    indexCount = 0;

    vertexCount = 0;

    for(cMeshBuffer=0; cMeshBuffer < 1; cMeshBuffer++)
    {
        //printf("Loading new mesh buffer for softbody.\n");
        mb = collMesh->getMeshBuffer(cMeshBuffer);
        mb_vertices = (irr::video::S3DVertex*)mb->getVertices();
        mb_indices = mb->getIndices();

        indexCount += mb->getIndexCount();
        vertexCount += mb->getVertexCount();


        for(u32 i=0; i<mb->getIndexCount(); i++)
        {
            int iIndex = mb_indices[i];
            vector3df iVertex = mb_vertices[iIndex].Pos;
            bool isFirst = true;
            for(u32 j=0; j<i; j++)
            {
                int jIndex = mb_indices[j];
                vector3df jVertex = mb_vertices[jIndex].Pos;
                if (iVertex == jVertex)
                {
                    index_map.insert(std::make_pair(i, j));
                    isFirst = false;
                    break;
                }
            }
            // ???????Bullet??Index??????
            if(isFirst)
            {
                // Irrlicht?Index??????Index
                index_map.insert(std::make_pair(i, i));
                // ?????Index????Index
                bullet_map.insert(std::make_pair(i, count));
                // ??Index?????????
                vertex_map.insert(std::make_pair(count, mb_vertices[iIndex]));
                count++;
            }
        }
    }

    indices = new int[indexCount];
    vertexCount = vertex_map.size();
    vertices = new btScalar[vertexCount*3];

    for(j=0; j<indexCount; j++)
    {
        int index1 = index_map.find(j)->second;
        int index2 = bullet_map.find(index1)->second;
        indices[j]   = index2;
    }

    for(j=0; j<vertexCount; j++)
    {
        vertices[3*j] =   vertex_map[j].Pos.X;
        vertices[3*j+1] = vertex_map[j].Pos.Y;
        vertices[3*j+2] = -vertex_map[j].Pos.Z;
    }

    //std::cout << "create softbody" << std::endl;
    object = btSoftBodyHelpers::CreateFromTriMesh(
        dynamicsWorld->getSoftBodyWorldInfo(), vertices,indices, indexCount/3);

    //std::cout << "create map" << std::endl;
    for(int i=0; i<getPointer()->m_faces.size(); i++)
    {
        btSoftBody::Face face = getPointer()->m_faces[i];

        for(int j=0; j<3; j++)
        {
            if(node_map.find(face.m_n[j]) == node_map.end())
            {
                node_map.insert(std::make_pair(face.m_n[j], node_map.size()));
            }
        }

        for(int j=0; j<3; j++)
        {
            m_indices.push_back(node_map.find(face.m_n[j])->second);
        }
    }

    // Reverse node->index to index->node (should be unique on both sides)
    std::map<btSoftBody::Node*, int>::const_iterator node_iter;
    for(node_iter = node_map.begin(); node_iter != node_map.end(); ++node_iter)
    {
        m_vertices.insert(std::make_pair(node_iter->second, node_iter->first));
    }

    //std::cout << "update Irrlicht vertices" << std::endl;
    std::map<int, btSoftBody::Node*>::const_iterator it;


    for(u32 i=0; i<mb->getVertexCount(); i++)
    {
        for(it=m_vertices.begin(); it != m_vertices.end(); ++it)
        {
            int v_index = it->first;
            btSoftBody::Node* node = it->second;
            if(node->m_x.x() == mb_vertices[i].Pos.X &&
                node->m_x.y() == mb_vertices[i].Pos.Y &&
                node->m_x.z() == mb_vertices[i].Pos.Z)
            {
                MeshMap.insert(std::make_pair(i, v_index));
                break;
            }
        }
    }
}