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;
}
Beispiel #2
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 #3
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;
}
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 #5
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 #6
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 #7
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;
}
	//! 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();
	}
//! 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);
        }
    }
}