Beispiel #1
0
void GrassPatch::createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16)
{
	MeshPtr pSphere = MeshManager::getSingleton().createManual(strName,		ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	SubMesh *pSphereVertex = pSphere->createSubMesh();

	pSphere->sharedVertexData = new VertexData();
	VertexData* vertexData = pSphere->sharedVertexData;

	// define the vertex format
	VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
	size_t currOffset = 0;
	// positions
	vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
	currOffset += VertexElement::getTypeSize(VET_FLOAT3);
	// normals
	vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
	currOffset += VertexElement::getTypeSize(VET_FLOAT3);
	// two dimensional texture coordinates
	vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
	currOffset += VertexElement::getTypeSize(VET_FLOAT2);

	// allocate the vertex buffer
	vertexData->vertexCount = (nRings + 1) * (nSegments+1);
	HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	VertexBufferBinding* binding = vertexData->vertexBufferBinding;
	binding->setBinding(0, vBuf);
	float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

	// allocate index buffer
	pSphereVertex->indexData->indexCount = 6 * nRings * (nSegments + 1);
	pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
	unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

	float fDeltaRingAngle = (Math::PI / nRings);
	float fDeltaSegAngle = (2 * Math::PI / nSegments);
	unsigned short wVerticeIndex = 0 ;

	// Generate the group of rings for the sphere
	for( int ring = 0; ring <= nRings; ring++ ) {
		float r0 = r * sinf (ring * fDeltaRingAngle);
		float y0 = r * cosf (ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(int seg = 0; seg <= nSegments; seg++) {
			float x0 = r0 * sinf(seg * fDeltaSegAngle);
			float z0 = r0 * cosf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			*pVertex++ = x0;
			*pVertex++ = y0;
			*pVertex++ = z0;

			Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
			*pVertex++ = vNormal.x;
			*pVertex++ = vNormal.y;
			*pVertex++ = vNormal.z;

			*pVertex++ = (float) seg / (float) nSegments;
			*pVertex++ = (float) ring / (float) nRings;

			if (ring != nRings) {
                               // each vertex (except the last) has six indices pointing to it
				*pIndices++ = wVerticeIndex + nSegments + 1;
				*pIndices++ = wVerticeIndex;               
				*pIndices++ = wVerticeIndex + nSegments;
				*pIndices++ = wVerticeIndex + nSegments + 1;
				*pIndices++ = wVerticeIndex + 1;
				*pIndices++ = wVerticeIndex;
				wVerticeIndex ++;
			}
		}; // end for seg
	} // end for ring

	// Unlock
	vBuf->unlock();
	iBuf->unlock();
	// Generate face list
	pSphereVertex->useSharedVertices = true;

	// the original code was missing this line:
	pSphere->_setBounds( AxisAlignedBox( Vector3(-r, -r, -r), Vector3(r, r, r) ), false );
	pSphere->_setBoundingSphereRadius(r);
        // this line makes clear the mesh is loaded (avoids memory leaks)
        pSphere->load();
 }
void SurfacePatchRenderable::createHardwareBuffers()
{
	VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

	HardwareVertexBufferSharedPtr vbuf =
		HardwareBufferManager::getSingleton().createVertexBuffer(
		mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
		mRenderOp.vertexData->vertexCount,
  		HardwareBuffer::HBU_STATIC_WRITE_ONLY,
		false);

	bind->setBinding(0, vbuf);

	HardwareIndexBufferSharedPtr ibuf =
		HardwareBufferManager::getSingleton().createIndexBuffer(
		HardwareIndexBuffer::IT_32BIT, // type of index
		mRenderOp.indexData->indexCount, // number of indexes
  		HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage
		false); // no shadow buffer	

	mRenderOp.indexData->indexBuffer = ibuf;	

	Vector3 vaabMin(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max());
	Vector3 vaabMax(0.0, 0.0, 0.0);
	
	Real* prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));

	const float textureWeights[3][3] = {{1, 0, 0},
										{0, 1, 0},
  										{0, 0, 1}};
										
	/*const int textureNumberOffsets[3][3] = {{0, 1, 2},
											{-1, 0, 1},
		   									{-2, -1, 0}};*/
	
	for (int v = 0; v < patch->numVertices * 2; v += 2)
	{
		// Position
		*prPos++ = patch->vertices[v].x;
		*prPos++ = patch->vertices[v].y;
		*prPos++ = patch->vertices[v].z;

		// Normal
		*prPos++ = patch->vertices[v+1].x;
		*prPos++ = patch->vertices[v+1].y;
		*prPos++ = patch->vertices[v+1].z;

		// texture weights
		const int curIndex = patch->vertNumbers[v/2];
		const int posInTriangle = curIndex % 3;
		*prPos++ = textureWeights[posInTriangle][0];
		*prPos++ = textureWeights[posInTriangle][1];
		*prPos++ = textureWeights[posInTriangle][2];

		// texture numbers
		for (int i = 0; i < posInTriangle; i++)
			*prPos++ = patch->textures[patch->indices[curIndex - (posInTriangle - i)]];
		*prPos++ = patch->textures[patch->indices[curIndex]];
		for (int i = posInTriangle + 1; i < 3; i++)
			*prPos++ = patch->textures[patch->indices[curIndex + (i - posInTriangle)]];

		// texture numbers
		//*prPos++ = patch->textures[(v/2)/3*3 + 0] + 0.5f;	// 0.5f: number between 0 and 1 as offset because in the shader,
		//*prPos++ = patch->textures[(v/2)/3*3 + 1] + 0.5f;	// floor() is used to determine the texture number as integer and this is
		//*prPos++ = patch->textures[(v/2)/3*3 + 2] + 0.5f;	// much too imprecise if the real texture numbers are passed in!

		// Adjust bounding box ...
		if (patch->vertices[v].x < vaabMin.x)
			vaabMin.x = patch->vertices[v].x;
		if (patch->vertices[v].y < vaabMin.y)
			vaabMin.y = patch->vertices[v].y;
		if (patch->vertices[v].z < vaabMin.z)
			vaabMin.z = patch->vertices[v].z;

		if (patch->vertices[v].x > vaabMax.x)
			vaabMax.x = patch->vertices[v].x;
		if (patch->vertices[v].y > vaabMax.y)
			vaabMax.y = patch->vertices[v].y;
		if (patch->vertices[v].z > vaabMax.z)
			vaabMax.z = patch->vertices[v].z;
	}		

	vbuf->unlock();

	mBox.setExtents(vaabMin, vaabMax);
	
	Ogre::uint* pIdx = static_cast<Ogre::uint*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
	for (int i = 0; i < patch->numIndices; i++)
	{
		*pIdx++ = patch->indices[i];
	}	

	ibuf->unlock();

	// Clean up the surface patch as much as possible
	delete[] patch->textures;
	delete[] patch->vertNumbers;
}
Beispiel #3
0
FlexMesh::FlexMesh(
	Ogre::String const & name, 
	node_t *nds, 
	int n1, 
	int n2, 
	int nstart, 
	int nrays,
	Ogre::String const & face_material_name, 
	Ogre::String const & band_material_name, 
	bool rimmed, 
	float rimratio
) :
	  is_rimmed(rimmed)
	, nbrays(nrays)
	, nodes(nds)
	, rim_ratio(rimratio)
{
	/// Create the mesh via the MeshManager
	msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	/// Create submeshes
	subface = msh->createSubMesh();
	subband = msh->createSubMesh();

	//materials
	subface->setMaterialName(face_material_name);
	subband->setMaterialName(band_material_name);

	/// Define the vertices
	nVertices = 4*nrays+2;
	if (is_rimmed) nVertices+=2*nrays;
	vbufCount = (2*3+2)*nVertices;
	vertices=(float*)malloc(vbufCount*sizeof(float));
	//shadow
	shadownorvertices=(float*)malloc(nVertices*(3+2)*sizeof(float));
	shadowposvertices=(float*)malloc(nVertices*3*2*sizeof(float));
	nodeIDs=(int*)malloc(nVertices*sizeof(int));

	//define node ids
	nodeIDs[0]=n1;
	nodeIDs[1]=n2;
	int i;
	for (i=0; i<nrays; i++)
	{
		//face
		nodeIDs[2+i*2]=nstart+i*2;
		nodeIDs[2+i*2+1]=nstart+i*2+1;
		if (is_rimmed)
		{
			//band
			nodeIDs[2+2*nrays+i*2]=nstart+2*nrays+i*2;
			nodeIDs[2+2*nrays+i*2+1]=nstart+2*nrays+i*2+1;
			//face2 (outer)
			nodeIDs[2+4*nrays+i*2]=nstart+2*nrays+i*2;
			nodeIDs[2+4*nrays+i*2+1]=nstart+2*nrays+i*2+1;
		} else
		{
			//band
			nodeIDs[2+2*nrays+i*2]=nstart+i*2;
			nodeIDs[2+2*nrays+i*2+1]=nstart+i*2+1;
		}
	}
	//color fix to remove
//		for (i=0; i<(int)nVertices; i++)
//		{
//			covertices[i].color=Vector3(0.0, 0.0, 0.0);
//		};
	//textures coordinates
	covertices[0].texcoord=Vector2(0.5, 0.5);
	covertices[1].texcoord=Vector2(0.5, 0.5);
	for (i=0; i<nrays; i++)
	{
		//band
		covertices[2+2*nrays+(i/2)*4].texcoord=Vector2(0.0, 0.0);
		covertices[2+2*nrays+(i/2)*4+1].texcoord=Vector2(0.0, 1.0);
		covertices[2+2*nrays+(i/2)*4+2].texcoord=Vector2(1.0, 0.0);
		covertices[2+2*nrays+(i/2)*4+3].texcoord=Vector2(1.0, 1.0);
		//face
		if (is_rimmed)
		{
			covertices[2+i*2].texcoord=Vector2(0.5+0.5*rim_ratio*sin((float)i*2.0*3.14159/nrays), 0.5+0.5*rim_ratio*cos((float)i*2.0*3.14159/nrays));
			covertices[2+i*2+1].texcoord=covertices[2+i*2].texcoord;
			covertices[2+4*nrays+i*2].texcoord=Vector2(0.5+0.5*sin(((float)i+0.5)*2.0*3.14159/nrays), 0.5+0.5*cos(((float)i+0.5)*2.0*3.14159/nrays));
			covertices[2+4*nrays+i*2+1].texcoord=covertices[2+4*nrays+i*2].texcoord;
		} else
		{
			covertices[2+i*2].texcoord=Vector2(0.5+0.5*sin(i*2.0*3.14159/nrays), 0.5+0.5*cos(i*2.0*3.14159/nrays));
			covertices[2+i*2+1].texcoord=covertices[2+i*2].texcoord;
		}
	}

	/// Define triangles
	/// The values in this table refer to vertices in the above table
	bandibufCount = 3*2*nrays;
	faceibufCount = 3*2*nrays;
	if (is_rimmed) faceibufCount=faceibufCount*3;
	facefaces=(unsigned short*)malloc(faceibufCount*sizeof(unsigned short));
	bandfaces=(unsigned short*)malloc(bandibufCount*sizeof(unsigned short));
	for (i=0; i<nrays; i++)
	{
		//wheel sides
		facefaces[3*(i*2)]=0;   facefaces[3*(i*2)+1]=2+i*2;     facefaces[3*(i*2)+2]=2+((i+1)%nrays)*2;
		facefaces[3*(i*2+1)]=1; facefaces[3*(i*2+1)+2]=2+i*2+1; facefaces[3*(i*2+1)+1]=2+((i+1)%nrays)*2+1;
		if (is_rimmed)
		{
			facefaces[3*(i*4+0+2*nrays)]=2+i*2; facefaces[3*(i*4+0+2*nrays)+1]=2+4*nrays+i*2;             facefaces[3*(i*4+0+2*nrays)+2]=2+((i+1)%nrays)*2;
			facefaces[3*(i*4+1+2*nrays)]=2+4*nrays+i*2; facefaces[3*(i*4+1+2*nrays)+1]=2+4*nrays+((i+1)%nrays)*2; facefaces[3*(i*4+1+2*nrays)+2]=2+((i+1)%nrays)*2;
			facefaces[3*(i*4+2+2*nrays)]=2+i*2+1; facefaces[3*(i*4+2+2*nrays)+2]=2+4*nrays+i*2+1;             facefaces[3*(i*4+2+2*nrays)+1]=2+((i+1)%nrays)*2+1;
			facefaces[3*(i*4+3+2*nrays)]=2+4*nrays+i*2+1; facefaces[3*(i*4+3+2*nrays)+2]=2+4*nrays+((i+1)%nrays)*2+1; facefaces[3*(i*4+3+2*nrays)+1]=2+((i+1)%nrays)*2+1;
		}
		//wheel band
//			bandfaces[3*(i*2)]=2+2*nrays+i*2; bandfaces[3*(i*2)+1]=2+2*nrays+i*2+1; bandfaces[3*(i*2)+2]=2+2*nrays+((i+1)%nrays)*2+1;
//			bandfaces[3*(i*2+1)]=2+2*nrays+((i+1)%nrays)*2+1; bandfaces[3*(i*2+1)+2]=2+2*nrays+i*2; bandfaces[3*(i*2+1)+1]=2+2*nrays+((i+1)%nrays)*2;
		bandfaces[3*(i*2)]=2+2*nrays+i*2; bandfaces[3*(i*2)+1]=2+2*nrays+i*2+1; bandfaces[3*(i*2)+2]=2+2*nrays+((i+1)%nrays)*2;
		bandfaces[3*(i*2+1)]=2+2*nrays+((i+1)%nrays)*2; bandfaces[3*(i*2+1)+2]=2+2*nrays+((i+1)%nrays)*2+1; bandfaces[3*(i*2+1)+1]=2+2*nrays+i*2+1;
	}

	//update coords
	updateVertices();

	/// Create vertex data structure for 8 vertices shared between submeshes
	msh->sharedVertexData = new VertexData();
	msh->sharedVertexData->vertexCount = nVertices;

	/// Create declaration (memory format) of vertex data
	decl = msh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;
	decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
//        decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE);
//        offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
	offset += VertexElement::getTypeSize(VET_FLOAT2);

	/// Allocate vertex buffer of the requested number of vertices (vertexCount)
	/// and bytes per vertex (offset)
	vbuf =
		HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

	/// Upload the vertex data to the card
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

	/// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
	VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
	bind->setBinding(0, vbuf);

	//for the face
	/// Allocate index buffer of the requested number of vertices (ibufCount)
	HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton().
		createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			faceibufCount,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	/// Upload the index data to the card
	faceibuf->writeData(0, faceibuf->getSizeInBytes(), facefaces, true);

	/// Set parameters of the submesh
	subface->useSharedVertices = true;
	subface->indexData->indexBuffer = faceibuf;
	subface->indexData->indexCount = faceibufCount;
	subface->indexData->indexStart = 0;

	//for the band
	/// Allocate index buffer of the requested number of vertices (ibufCount)
	HardwareIndexBufferSharedPtr bandibuf = HardwareBufferManager::getSingleton().
		createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			bandibufCount,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	/// Upload the index data to the card
	bandibuf->writeData(0, bandibuf->getSizeInBytes(), bandfaces, true);

	/// Set parameters of the submesh
	subband->useSharedVertices = true;
	subband->indexData->indexBuffer = bandibuf;
	subband->indexData->indexCount = bandibufCount;
	subband->indexData->indexStart = 0;

	/// Set bounding information (for culling)
	msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true);
	//msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1));

		/// Notify Mesh object that it has been loaded
	//msh->buildTangentVectors();
	/*unsigned short src, dest;
	if (!msh->suggestTangentVectorBuildParams(src, dest))
	{
		msh->buildTangentVectors(src, dest);
	}
	*/

	msh->load();
	//msh->touch();
	//        msh->load();

	//msh->buildEdgeList();
}
//---------------------------------------------------------------------
void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits)
{
    if (!vertexSplits.empty())
    {
        // ok, need to increase the vertex buffer size, and alter some indexes

        // vertex buffers first
        VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding();
        const VertexBufferBinding::VertexBufferBindingMap& bindmap =
            mVData->vertexBufferBinding->getBindings();
        for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i =
                    bindmap.begin(); i != bindmap.end(); ++i)
        {
            HardwareVertexBufferSharedPtr srcbuf = i->second;
            // Derive vertex count from buffer not vertex data, in case using
            // the vertexStart option in vertex data
            size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size();
            // Create new buffer & bind
            HardwareVertexBufferSharedPtr newBuf =
                HardwareBufferManager::getSingleton().createVertexBuffer(
                    srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(),
                    srcbuf->hasShadowBuffer());
            newBindings->setBinding(i->first, newBuf);

            // Copy existing contents (again, entire buffer, not just elements referenced)
            newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true);

            // Split vertices, read / write from new buffer
            char* pBase = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));
            for (VertexSplits::iterator spliti = vertexSplits.begin();
                    spliti != vertexSplits.end(); ++spliti)
            {
                const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize();
                char* pDstBase = pBase + spliti->second * newBuf->getVertexSize();
                memcpy(pDstBase, pSrcBase, newBuf->getVertexSize());
            }
            newBuf->unlock();

        }

        // Update vertex data
        // Increase vertex count according to num splits
        mVData->vertexCount += vertexSplits.size();
        // Flip bindings over to new buffers (old buffers released)
        HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding);
        mVData->vertexBufferBinding = newBindings;

        // If vertex size requires 32bit index buffer
        if (mVData->vertexCount > 65536)
        {
            for (size_t i = 0; i < mIDataList.size(); ++i)
            {
                // check index size
                IndexData* idata = mIDataList[i];
                HardwareIndexBufferSharedPtr srcbuf = idata->indexBuffer;
                if (srcbuf->getType() == HardwareIndexBuffer::IT_16BIT)
                {
                    size_t indexCount = srcbuf->getNumIndexes();

                    // convert index buffer to 32bit.
                    HardwareIndexBufferSharedPtr newBuf =
                        HardwareBufferManager::getSingleton().createIndexBuffer(
                            HardwareIndexBuffer::IT_32BIT, indexCount,
                            srcbuf->getUsage(), srcbuf->hasShadowBuffer());

                    uint16* pSrcBase = static_cast<uint16*>(srcbuf->lock(HardwareBuffer::HBL_NORMAL));
                    uint32* pBase = static_cast<uint32*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));

                    size_t j = 0;
                    while (j < indexCount)
                    {
                        *pBase++ = *pSrcBase++;
                        ++j;
                    }

                    srcbuf->unlock();
                    newBuf->unlock();

                    // assign new index buffer.
                    idata->indexBuffer = newBuf;
                }
            }
        }
    }

}
Beispiel #5
0
void Road2::createMesh()
{
    AxisAlignedBox aab;
    union
    {
        float* vertices;
        CoVertice_t* covertices;
    };
    /// Create the mesh via the MeshManager
    Ogre::String mesh_name = Ogre::String("RoadSystem-").append(Ogre::StringConverter::toString(mid));
    msh = MeshManager::getSingleton().createManual(mesh_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    mainsub = msh->createSubMesh();
    mainsub->setMaterialName("road2");

    /// Define the vertices
    size_t vbufCount = (2 * 3 + 2) * vertexcount;
    vertices = (float*)malloc(vbufCount * sizeof(float));
    int i;
    //fill values
    for (i = 0; i < vertexcount; i++)
    {
        covertices[i].texcoord = tex[i];
        covertices[i].vertex = vertex[i];
        //normals are computed later
        covertices[i].normal = Vector3::ZERO;
        aab.merge(vertex[i]);
    }

    /// Define triangles
    size_t ibufCount = 3 * tricount;

    //compute normals
    for (i = 0; i < tricount && i * 3 + 2 < MAX_TRIS * 3; i++)
    {
        Vector3 v1, v2;
        v1 = covertices[tris[i * 3 + 1]].vertex - covertices[tris[i * 3]].vertex;
        v2 = covertices[tris[i * 3 + 2]].vertex - covertices[tris[i * 3]].vertex;
        v1 = v1.crossProduct(v2);
        v1.normalise();
        covertices[tris[i * 3]].normal += v1;
        covertices[tris[i * 3 + 1]].normal += v1;
        covertices[tris[i * 3 + 2]].normal += v1;
    }
    //normalize
    for (i = 0; i < vertexcount; i++)
    {
        covertices[i].normal.normalise();
    }

    /// Create vertex data structure for vertices shared between sub meshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = vertexcount;

    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    /// Allocate vertex buffer of the requested number of vertices (vertexCount)
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, vbuf);

    //for the face
    /// Allocate index buffer of the requested number of vertices (ibufCount)
    HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
        createIndexBuffer(
            HardwareIndexBuffer::IT_16BIT,
            ibufCount,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    ibuf->writeData(0, ibuf->getSizeInBytes(), tris, true);

    /// Set parameters of the submesh
    mainsub->useSharedVertices = true;
    mainsub->indexData->indexBuffer = ibuf;
    mainsub->indexData->indexCount = ibufCount;
    mainsub->indexData->indexStart = 0;

    msh->_setBounds(aab, true);

    /// Notify Mesh object that it has been loaded
    msh->load();

    free(vertices);
};
    //-----------------------------------------------------------------------
    void MeshManager::loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params)
    {
		if (params.ySegmentsToKeep == -1) params.ySegmentsToKeep = params.ysegments;

		if ((params.xsegments + 1) * (params.ySegmentsToKeep + 1) > 65536)
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
				"Plane tessellation is too high, must generate max 65536 vertices", 
				__FUNCTION__);
        SubMesh *pSub = pMesh->createSubMesh();


        // Set up vertex data
        // Use a single shared buffer
        pMesh->sharedVertexData = OGRE_NEW VertexData();
        VertexData* vertexData = pMesh->sharedVertexData;
        // Set up Vertex Declaration
        VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
        size_t currOffset = 0;
        // We always need positions
        vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
        currOffset += VertexElement::getTypeSize(VET_FLOAT3);
        // Optional normals
        if(params.normals)
        {
            vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
            currOffset += VertexElement::getTypeSize(VET_FLOAT3);
        }

        for (unsigned short i = 0; i < params.numTexCoordSets; ++i)
        {
            // Assumes 2D texture coords
            vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
            currOffset += VertexElement::getTypeSize(VET_FLOAT2);
        }

        vertexData->vertexCount = (params.xsegments + 1) * (params.ySegmentsToKeep + 1);

        // Allocate vertex buffer
        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().
            createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
            params.vertexBufferUsage, params.vertexShadowBuffer);

        // Set up the binding (one source only)
        VertexBufferBinding* binding = vertexData->vertexBufferBinding;
        binding->setBinding(0, vbuf);

        // Work out the transform required
        // Default orientation of plane is normal along +z, distance 0
        Matrix4 xlate, xform, rot;
        Matrix3 rot3;
        xlate = rot = Matrix4::IDENTITY;
        // Determine axes
        Vector3 zAxis, yAxis, xAxis;
        zAxis = params.plane.normal;
        zAxis.normalise();
        yAxis = params.upVector;
        yAxis.normalise();
        xAxis = yAxis.crossProduct(zAxis);
        if (xAxis.length() == 0)
        {
            //upVector must be wrong
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
                "MeshManager::createPlane");
        }

        rot3.FromAxes(xAxis, yAxis, zAxis);
        rot = rot3;

        // Set up standard transform from origin
        xlate.setTrans(params.plane.normal * -params.plane.d);

        // concatenate
        xform = xlate * rot;

        // Generate vertex data
        // Imagine a large sphere with the camera located near the top
        // The lower the curvature, the larger the sphere
        // Use the angle from viewer to the points on the plane
        // Credit to Aftershock for the general approach
        Real camPos;      // Camera position relative to sphere center

        // Derive sphere radius
        Vector3 vertPos;  // position relative to camera
        Real sphDist;      // Distance from camera to sphere along box vertex vector
        // Vector3 camToSph; // camera position to sphere
        Real sphereRadius;// Sphere radius
        // Actual values irrelevant, it's the relation between sphere radius and camera position that's important
        const Real SPHERE_RAD = 100.0;
        const Real CAM_DIST = 5.0;

        sphereRadius = SPHERE_RAD - params.curvature;
        camPos = sphereRadius - CAM_DIST;

        // Lock the whole buffer
        float* pFloat = static_cast<float*>(
            vbuf->lock(HardwareBuffer::HBL_DISCARD) );
        Real xSpace = params.width / params.xsegments;
        Real ySpace = params.height / params.ysegments;
        Real halfWidth = params.width / 2;
        Real halfHeight = params.height / 2;
        Vector3 vec, norm;
        Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE;
        Real maxSquaredLength = 0;
        bool firstTime = true;

        for (int y = params.ysegments - params.ySegmentsToKeep; y < params.ysegments + 1; ++y)
        {
            for (int x = 0; x < params.xsegments + 1; ++x)
            {
                // Work out centered on origin
                vec.x = (x * xSpace) - halfWidth;
                vec.y = (y * ySpace) - halfHeight;
                vec.z = 0.0f;
                // Transform by orientation and distance
                vec = xform.transformAffine(vec);
                // Assign to geometry
                *pFloat++ = vec.x;
                *pFloat++ = vec.y;
                *pFloat++ = vec.z;

                // Build bounds as we go
                if (firstTime)
                {
                    min = vec;
                    max = vec;
                    maxSquaredLength = vec.squaredLength();
                    firstTime = false;
                }
                else
                {
                    min.makeFloor(vec);
                    max.makeCeil(vec);
                    maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
                }

                if (params.normals)
                {
                    // Default normal is along unit Z
                    norm = Vector3::UNIT_Z;
                    // Rotate
                    norm = params.orientation * norm;

                    *pFloat++ = norm.x;
                    *pFloat++ = norm.y;
                    *pFloat++ = norm.z;
                }

                // Generate texture coords
                // Normalise position
                // modify by orientation to return +y up
                vec = params.orientation.Inverse() * vec;
                vec.normalise();
                // Find distance to sphere
                sphDist = Math::Sqrt(camPos*camPos * (vec.y*vec.y-1.0f) + sphereRadius*sphereRadius) - camPos*vec.y;

                vec.x *= sphDist;
                vec.z *= sphDist;

                // Use x and y on sphere as texture coordinates, tiled
                Real s = vec.x * (0.01f * params.xTile);
                Real t = 1.0f - (vec.z * (0.01f * params.yTile));
                for (unsigned short i = 0; i < params.numTexCoordSets; ++i)
                {
                    *pFloat++ = s;
                    *pFloat++ = t;
                }


            } // x
        } // y

        // Unlock
        vbuf->unlock();
        // Generate face list
        pSub->useSharedVertices = true;
        tesselate2DMesh(pSub, params.xsegments + 1, params.ySegmentsToKeep + 1, false, 
            params.indexBufferUsage, params.indexShadowBuffer);

        pMesh->_setBounds(AxisAlignedBox(min, max), true);
        pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
    }
Beispiel #7
0
    //---------------------------------------------------------------------
    void PrefabFactory::createCube(Mesh* mesh)
    {
        SubMesh* sub = mesh->createSubMesh();

        const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides
        const int NUM_ENTRIES_PER_VERTEX = 8;
        const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX;
        const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides

        const Real CUBE_SIZE = 100.0f;
        const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f;

        // Create 4 vertices per side instead of 6 that are shared for the whole cube.
        // The reason for this is with only 6 vertices the normals will look bad
        // since each vertex can "point" in a different direction depending on the face it is included in.
        float vertices[NUM_VERTEX_ENTRIES] = {
            // front side
            -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,   // pos
            0,0,1,  // normal
            0,1,    // texcoord
            CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            0,0,1,
            1,1,
            CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            0,0,1,
            1,0,
            -CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE ,
            0,0,1,
            0,0,

            // back side
            CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,0,-1,
            0,1,
            -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,0,-1,
            1,1,
            -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,0,-1,
            1,0,
            CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,0,-1,
            0,0,

            // left side
            -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            -1,0,0,
            0,1,
            -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            -1,0,0,
            1,1,
            -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            -1,0,0,
            1,0,
            -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            -1,0,0,
            0,0,

            // right side
            CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            1,0,0,
            0,1,
            CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            1,0,0,
            1,1,
            CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            1,0,0,
            1,0,
            CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            1,0,0,
            0,0,

            // up side
            -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            0,1,0,
            0,1,
            CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            0,1,0,
            1,1,
            CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,1,0,
            1,0,
            -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,1,0,
            0,0,

            // down side
            -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,-1,0,
            0,1,
            CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            0,-1,0,
            1,1,
            CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            0,-1,0,
            1,0,
            -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
            0,-1,0,
            0,0
        };

        mesh->sharedVertexData = OGRE_NEW VertexData();
        mesh->sharedVertexData->vertexCount = NUM_VERTICES;
        VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
        VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

        size_t offset = 0;
        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
        offset += VertexElement::getTypeSize(VET_FLOAT3);
        decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
        offset += VertexElement::getTypeSize(VET_FLOAT3);
        decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
        offset += VertexElement::getTypeSize(VET_FLOAT2);

        HardwareVertexBufferSharedPtr vbuf =
            HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        bind->setBinding(0, vbuf);

        vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

        sub->useSharedVertices = true;
        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
            createIndexBuffer(
            HardwareIndexBuffer::IT_16BIT,
            NUM_INDICES,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

        unsigned short faces[NUM_INDICES] = {
            // front
            0,1,2,
            0,2,3,

            // back
            4,5,6,
            4,6,7,

            // left
            8,9,10,
            8,10,11,

            // right
            12,13,14,
            12,14,15,

            // up
            16,17,18,
            16,18,19,

            // down
            20,21,22,
            20,22,23
        };

        sub->indexData->indexBuffer = ibuf;
        sub->indexData->indexCount = NUM_INDICES;
        sub->indexData->indexStart = 0;
        ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

        mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
            CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true);

        mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE);
    }
Beispiel #8
0
    //-----------------------------------------------------------------------------------
    void Rectangle2D::initRectangle2D(void)
    {
        // use identity projection and view matrices
        mUseIdentityProjection  = true;
        mUseIdentityView        = true;

        mRenderOp.vertexData = OGRE_NEW VertexData();

        mRenderOp.indexData                 = 0;
        mRenderOp.vertexData->vertexCount   = mQuad ? 4 : 3;
        mRenderOp.vertexData->vertexStart   = 0;
        //Strip or list is fine for triangle, but using lists avoids tiny unnecessary state
        //switches (assuming most of normal render is indexed list).
        mRenderOp.operationType             = mQuad ? RenderOperation::OT_TRIANGLE_STRIP :
                                                        RenderOperation::OT_TRIANGLE_LIST;
        mRenderOp.useIndexes                                    = false; 
        mRenderOp.useGlobalInstancingVertexBufferIsAvailable    = false;

        VertexDeclaration* decl     = mRenderOp.vertexData->vertexDeclaration;
        VertexBufferBinding* bind   = mRenderOp.vertexData->vertexBufferBinding;

        size_t offset = 0;
        decl->addElement( 0, 0, VET_FLOAT3, VES_POSITION );
        offset += VertexElement::getTypeSize( VET_FLOAT3 );
        decl->addElement( 0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES );

        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize( 0 ), mRenderOp.vertexData->vertexCount,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY );

        // Bind buffer
        bind->setBinding( 0, vbuf );

        float *pVerts = static_cast<float*>( vbuf->lock(HardwareBuffer::HBL_DISCARD) );
        if( mQuad )
        {
            //1st Top-left
            *pVerts++ = -1.0f;
            *pVerts++ =  1.0f;
            *pVerts++ = -1.0f;

            *pVerts++ =  0.0f;
            *pVerts++ =  0.0f;

            //2nd Bottom-left
            *pVerts++ = -1.0f;
            *pVerts++ = -1.0f;
            *pVerts++ = -1.0f;

            *pVerts++ =  0.0f;
            *pVerts++ =  1.0f;

            //3rd Top-right
            *pVerts++ =  1.0f;
            *pVerts++ =  1.0f;
            *pVerts++ = -1.0f;

            *pVerts++ =  1.0f;
            *pVerts++ =  0.0f;

            //4th Bottom-right
            *pVerts++ =  1.0f;
            *pVerts++ = -1.0f;
            *pVerts++ = -1.0f;

            *pVerts++ =  1.0f;
            *pVerts++ =  1.0f;
        }
        else
        {
            //1st Top-left
            *pVerts++ = -1.0f;
            *pVerts++ =  1.0f;
            *pVerts++ = -1.0f;

            *pVerts++ =  0.0f;
            *pVerts++ =  0.0f;

            //2nd Bottom-left
            *pVerts++ = -1.0f;
            *pVerts++ = -3.0f; //3 = lerp( -1, 1, 2 );
            *pVerts++ = -1.0f;

            *pVerts++ =  0.0f;
            *pVerts++ =  2.0f;

            //3rd Top-right
            *pVerts++ =  3.0f;
            *pVerts++ =  1.0f;
            *pVerts++ = -1.0f;

            *pVerts++ =  2.0f;
            *pVerts++ =  0.0f;
        }

        vbuf->unlock();

        //Add the normals.
        decl->addElement( 1, 0, VET_FLOAT3, VES_NORMAL );

        vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                decl->getVertexSize( 1 ), mRenderOp.vertexData->vertexCount,
                HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE );

        bind->setBinding( 1, vbuf );

        float *pNorm = static_cast<float*>( vbuf->lock(HardwareBuffer::HBL_DISCARD) );
        *pNorm++ = 0.0f;
        *pNorm++ = 0.0f;
        *pNorm++ = 1.0f;

        *pNorm++ = 0.0f;
        *pNorm++ = 0.0f;
        *pNorm++ = 1.0f;

        *pNorm++ = 0.0f;
        *pNorm++ = 0.0f;
        *pNorm++ = 1.0f;

        if( mQuad )
        {
            *pNorm++ = 0.0f;
            *pNorm++ = 0.0f;
            *pNorm++ = 1.0f;
        }

        vbuf->unlock();

        // set basic white material
        this->setMaterial( "BaseWhiteNoLighting" );
    }
Beispiel #9
0
void Tile::_generateSubMesh(MeshPtr& mesh)
{
	// Create a submesh to the given mesh.
	SubMesh* tileMesh = mesh->createSubMesh();

	// Define the vertices.
	size_t index = 0;
	size_t vertCount = this->mCorners.size() + 1; // corner count + center corner

	Real* vertices = new Real[vertCount*3*2];    // (number of verts)*(x, y, z)*(coord, normal) -or- vertCount*3*2

	// Manually add center vertex.
	// -- Position (ord: x, y, z)
	vertices[index++] = this->mPosition.x;
	vertices[index++] = (Ogre::Real)(this->elevation);
	vertices[index++] = this->mPosition.y;

	// -- Normal (ord: x, y, z)
	Vector3 norm = Vector3::UNIT_Y;

	vertices[index++] = norm.x;
	vertices[index++] = norm.y;
	vertices[index++] = norm.z;

	// Add the rest of the vertices to data buffer.
    for(std::vector<Corner*>::iterator it = this->mCorners.begin(); it != this->mCorners.end(); ++it) {
		// Add to the next point to the array.
		// -- Position
		Vector3 vector = (*it)->vec3();

		vertices[index++] = vector.x;
		vertices[index++] = vector.y;
		vertices[index++] = vector.z;

		// -- Normal
		Vector3 normal = Vector3::UNIT_Y;

		vertices[index++] = normal.x;
		vertices[index++] = normal.y;
		vertices[index++] = normal.z;
	}

	// Define vertices color.
	RenderSystem* rs = Root::getSingleton().getRenderSystem();
	RGBA* colors = new RGBA[vertCount];

	for(size_t i = 0; i < vertCount; ++i)
		rs->convertColourValue(ColourValue(0.0f + 0.175f*i, 0.2f, 1.0f - 0.175f*i), colors + i);

	// Define the triangles.
	size_t faceCount = vertCount - 1; // Face count = vertCount - cent

	size_t center = 0;
	size_t last   = 1; //collin was here
	size_t curr   = 2;

	unsigned short* faces = new unsigned short[faceCount*3];

	index = 0;

	for(size_t i = 0; i < faceCount; ++i) {
		assert(last < vertCount && curr < vertCount); // Panic check

		faces[index++] = center;
		faces[index++] = curr;
		faces[index++] = last;

		last = curr++;

		if(curr >= vertCount) curr = 1;
	}

	// All information has been generated, move into mesh structures.
	//   Note: Currently does not implement or used any sort of shared
	//     vertices. This is intentional and should be changed at the 
	//     soonest conveienence. IE -- Never. ;P
	tileMesh->useSharedVertices = false;
	tileMesh->vertexData = new VertexData();
	tileMesh->vertexData->vertexCount = vertCount;

	// Create memory footprint for vertex data.
	size_t offset = 0;
	VertexDeclaration* decl = tileMesh->vertexData->vertexDeclaration;

	// Position and normal buffer.
	// -- Position
	decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
	offset += VertexElement::getTypeSize(VET_FLOAT3);

	// -- Normal
	decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
	offset += VertexElement::getTypeSize(VET_FLOAT3);

	// Allocate a vertex buffer for a number of vertices and vertex size.
	HardwareVertexBufferSharedPtr vertBuff = 
		HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, // Size of a vertex, in bytes.
			tileMesh->vertexData->vertexCount,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Write our data to vertex buffer.
	vertBuff->writeData(0, vertBuff->getSizeInBytes(), vertices, true);

	// Set the buffer's bind location.
	VertexBufferBinding* vertBind = tileMesh->vertexData->vertexBufferBinding;
	vertBind->setBinding(0, vertBuff);

	// Color buffer for vertices
	offset = 0;
	decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE);
	offset += VertexElement::getTypeSize(VET_COLOUR);

	// Allocate a new buffer for colors.
	vertBuff = HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, // Size of a vertex, in bytes.
			tileMesh->vertexData->vertexCount,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Write color data to buffer.
	vertBuff->writeData(0, vertBuff->getSizeInBytes(), colors, true);

	// Set the color buffer's bind location
	vertBind->setBinding(1, vertBuff);

	// Allocate a buffer for the index information
	HardwareIndexBufferSharedPtr indexBuff = HardwareBufferManager::getSingleton().createIndexBuffer(
		HardwareIndexBuffer::IT_16BIT,
		faceCount*3,
		HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Write data to the buffer.
	indexBuff->writeData(0, indexBuff->getSizeInBytes(), faces, true);

	// Finalize submesh.
	tileMesh->indexData->indexBuffer = indexBuff;
	tileMesh->indexData->indexCount = faceCount*3;
	tileMesh->indexData->indexStart = 0;

	// Deallocate the vertex and face arrays.
	if(vertices) delete[] vertices;
	if(faces) delete[] faces;
}
	Rectangle2D::Rectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) 
    {
        // use identity projection and view matrices
        mUseIdentityProjection = true;
        mUseIdentityView = true;

        mRenderOp.vertexData = OGRE_NEW VertexData();

        mRenderOp.indexData = 0;
        mRenderOp.vertexData->vertexCount = 4; 
        mRenderOp.vertexData->vertexStart = 0; 
        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; 
        mRenderOp.useIndexes = false; 

        VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
        VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;

        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);


        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(POSITION_BINDING),
            mRenderOp.vertexData->vertexCount,
            vBufUsage);

        // Bind buffer
        bind->setBinding(POSITION_BINDING, vbuf);

		decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);

		vbuf = 
			HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(NORMAL_BINDING),
            mRenderOp.vertexData->vertexCount,
            vBufUsage);

		bind->setBinding(NORMAL_BINDING, vbuf);

		float *pNorm = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		*pNorm++ = 0.0f;
		*pNorm++ = 0.0f;
		*pNorm++ = 1.0f;

		vbuf->unlock();

        if (includeTextureCoords)
        {
            decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);


            HardwareVertexBufferSharedPtr tvbuf = 
                HardwareBufferManager::getSingleton().createVertexBuffer(
                decl->getVertexSize(TEXCOORD_BINDING),
                mRenderOp.vertexData->vertexCount,
                vBufUsage);

            // Bind buffer
            bind->setBinding(TEXCOORD_BINDING, tvbuf);

            // Set up basic tex coordinates
            float* pTex = static_cast<float*>(
                tvbuf->lock(HardwareBuffer::HBL_DISCARD));
            *pTex++ = 0.0f;
            *pTex++ = 0.0f;
            *pTex++ = 0.0f;
            *pTex++ = 1.0f;
            *pTex++ = 1.0f;
            *pTex++ = 0.0f;
            *pTex++ = 1.0f;
            *pTex++ = 1.0f;
            tvbuf->unlock();
        }

        // set basic white material
        this->setMaterial("BaseWhiteNoLighting");
    }
Beispiel #11
0
FlexMeshWheel::FlexMeshWheel(SceneManager *manager, char* name, node_t *nds, int n1, int n2, int nstart, int nrays, char* meshname, char* texband, float rimradius, bool rimreverse, MaterialFunctionMapper *mfm, Skin *usedSkin, MaterialReplacer *mr) : mr(mr)
{
	rim_radius=rimradius;
	revrim=rimreverse;
	smanager=manager;
	nbrays=nrays;
	nodes=nds;
	id0=n1;
	id1=n2;
	idstart=nstart;

	//the rim object
	char rimname[256];
	sprintf(rimname, "rim-%s", name);
	rimEnt = manager->createEntity(rimname, meshname);
	MaterialFunctionMapper::replaceSimpleMeshMaterials(rimEnt, ColourValue(0, 0.5, 0.8));
	if(mfm) mfm->replaceMeshMaterials(rimEnt);
	if(mr) mr->replaceMeshMaterials(rimEnt);
	if(usedSkin) usedSkin->replaceMeshMaterials(rimEnt);
	rnode=manager->getRootSceneNode()->createChildSceneNode();
	rnode->attachObject(rimEnt);

	/// Create the mesh via the MeshManager
	msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,new ResourceBuffer());

	/// Create submeshes
	sub = msh->createSubMesh();

	//materials
	sub->setMaterialName(texband);

	/// Define the vertices 
	nVertices = 6*(nrays+1);
	vbufCount = (2*3+2)*nVertices;
	vertices=(float*)malloc(vbufCount*sizeof(float));
	//shadow
	shadownorvertices=(float*)malloc(nVertices*(3+2)*sizeof(float));
	shadowposvertices=(float*)malloc(nVertices*3*2*sizeof(float));

	int i;
	//textures coordinates
	for (i=0; i<nrays+1; i++)
	{
		covertices[i*6   ].texcoord=Vector2((float)i/(float)nrays, 0.00);
		covertices[i*6+1 ].texcoord=Vector2((float)i/(float)nrays, 0.23);
		covertices[i*6+2 ].texcoord=Vector2((float)i/(float)nrays, 0.27);
		covertices[i*6+3 ].texcoord=Vector2((float)i/(float)nrays, 0.73);
		covertices[i*6+4 ].texcoord=Vector2((float)i/(float)nrays, 0.77);
		covertices[i*6+5 ].texcoord=Vector2((float)i/(float)nrays, 1.00);
	}

	/// Define triangles
	/// The values in this table refer to vertices in the above table
	ibufCount = 3*10*nrays;
	faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short));
	for (i=0; i<nrays; i++)
	{
		faces[3*(i*10  )]=i*6;   faces[3*(i*10  )+1]=i*6+1;     faces[3*(i*10  )+2]=(i+1)*6;
		faces[3*(i*10+1)]=i*6+1; faces[3*(i*10+1)+1]=(i+1)*6+1; faces[3*(i*10+1)+2]=(i+1)*6;

		faces[3*(i*10+2)]=i*6+1; faces[3*(i*10+2)+1]=i*6+2;     faces[3*(i*10+2)+2]=(i+1)*6+1;
		faces[3*(i*10+3)]=i*6+2; faces[3*(i*10+3)+1]=(i+1)*6+2; faces[3*(i*10+3)+2]=(i+1)*6+1;

		faces[3*(i*10+4)]=i*6+2; faces[3*(i*10+4)+1]=i*6+3;     faces[3*(i*10+4)+2]=(i+1)*6+2;
		faces[3*(i*10+5)]=i*6+3; faces[3*(i*10+5)+1]=(i+1)*6+3; faces[3*(i*10+5)+2]=(i+1)*6+2;

		faces[3*(i*10+6)]=i*6+3; faces[3*(i*10+6)+1]=i*6+4;     faces[3*(i*10+6)+2]=(i+1)*6+3;
		faces[3*(i*10+7)]=i*6+4; faces[3*(i*10+7)+1]=(i+1)*6+4; faces[3*(i*10+7)+2]=(i+1)*6+3;

		faces[3*(i*10+8)]=i*6+4; faces[3*(i*10+8)+1]=i*6+5;     faces[3*(i*10+8)+2]=(i+1)*6+4;
		faces[3*(i*10+9)]=i*6+5; faces[3*(i*10+9)+1]=(i+1)*6+5; faces[3*(i*10+9)+2]=(i+1)*6+4;
	}

	normy=1.0;
	//update coords
	updateVertices();
	//compute normy;
	normy=((covertices[0].vertex-covertices[1].vertex).crossProduct(covertices[1].vertex-covertices[6+1].vertex)).length();
	//recompute for normals
	updateVertices();

	/// Create vertex data structure for 8 vertices shared between submeshes
	msh->sharedVertexData = new VertexData();
	msh->sharedVertexData->vertexCount = nVertices;

	/// Create declaration (memory format) of vertex data
	decl = msh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;
	decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
//        decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE);
//        offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
	offset += VertexElement::getTypeSize(VET_FLOAT2);

	/// Allocate vertex buffer of the requested number of vertices (vertexCount) 
	/// and bytes per vertex (offset)
	vbuf = 
	  HardwareBufferManager::getSingleton().createVertexBuffer(
		  offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

	/// Upload the vertex data to the card
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

	/// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
	VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; 
	bind->setBinding(0, vbuf);

	//for the face
	/// Allocate index buffer of the requested number of vertices (ibufCount) 
	HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
	 createIndexBuffer(
		 HardwareIndexBuffer::IT_16BIT, 
			ibufCount, 
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	/// Upload the index data to the card
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

	/// Set parameters of the submesh
	sub->useSharedVertices = true;
	sub->indexData->indexBuffer = ibuf;
	sub->indexData->indexCount = ibufCount;
	sub->indexData->indexStart = 0;

    
	/// Set bounding information (for culling)
	msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true);
	//msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1));

	/// Notify Mesh object that it has been loaded
	msh->buildEdgeList();
	//msh->buildTangentVectors();
	/*unsigned short src, dest;
	if (!msh->suggestTangentVectorBuildParams(src, dest))
	{
		msh->buildTangentVectors(src, dest);
	}
	*/

	msh->load();
	//msh->touch(); 
	//        msh->load();

			//msh->buildEdgeList();
}
Ogre::MeshPtr LodOutsideMarker::createConvexHullMesh(const String& meshName, const String& resourceGroupName)
{
    // Based on the wiki sample: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Generating+A+Mesh

    // Resource with given name should not exist!
    assert(MeshManager::getSingleton().getByName(meshName).isNull());

    generateHull(); // calculate mHull triangles.

    // Convex hull can't be empty!
    assert(!mHull.empty());

    MeshPtr mesh = MeshManager::getSingleton().createManual(meshName, resourceGroupName, NULL);
    SubMesh* subMesh = mesh->createSubMesh();

    vector<Real>::type vertexBuffer;
    vector<unsigned short>::type indexBuffer;
    // 3 position/triangle * 3 Real/position
    vertexBuffer.reserve(mHull.size() * 9);
    // 3 index / triangle
    indexBuffer.reserve(mHull.size() * 3);
    int id=0;
    // min & max position
    Vector3 minBounds(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max());
    Vector3 maxBounds(std::numeric_limits<Real>::min(), std::numeric_limits<Real>::min(), std::numeric_limits<Real>::min());

    for (size_t i = 0; i < mHull.size(); i++) {
        assert(!mHull[i].removed);
        for(size_t n = 0; n < 3; n++){
            indexBuffer.push_back(id++);
            vertexBuffer.push_back(mHull[i].vertex[n]->position.x);
            vertexBuffer.push_back(mHull[i].vertex[n]->position.y);
            vertexBuffer.push_back(mHull[i].vertex[n]->position.z);
            minBounds.x = std::min<Real>(minBounds.x, mHull[i].vertex[n]->position.x);
            minBounds.y = std::min<Real>(minBounds.y, mHull[i].vertex[n]->position.y);
            minBounds.z = std::min<Real>(minBounds.z, mHull[i].vertex[n]->position.z);
            maxBounds.x = std::max<Real>(maxBounds.x, mHull[i].vertex[n]->position.x);
            maxBounds.y = std::max<Real>(maxBounds.y, mHull[i].vertex[n]->position.y);
            maxBounds.z = std::max<Real>(maxBounds.z, mHull[i].vertex[n]->position.z);
        }
    }

    /// Create vertex data structure for 8 vertices shared between submeshes
    mesh->sharedVertexData = new VertexData();
    mesh->sharedVertexData->vertexCount = mHull.size() * 3;

    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    // 1st buffer
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);

    /// Allocate vertex buffer of the requested number of vertices (vertexCount) 
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf = 
        HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), &vertexBuffer[0], true);

    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; 
    bind->setBinding(0, vbuf);

    /// Allocate index buffer of the requested number of vertices (ibufCount) 
    HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
        createIndexBuffer(
        HardwareIndexBuffer::IT_16BIT, 
        indexBuffer.size(), 
        HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    ibuf->writeData(0, ibuf->getSizeInBytes(), &indexBuffer[0], true);

    /// Set parameters of the submesh
    subMesh->useSharedVertices = true;
    subMesh->indexData->indexBuffer = ibuf;
    subMesh->indexData->indexCount = indexBuffer.size();
    subMesh->indexData->indexStart = 0;

    /// Set bounding information (for culling)
    mesh->_setBounds(AxisAlignedBox(minBounds, maxBounds));
    mesh->_setBoundingSphereRadius(maxBounds.distance(minBounds) / 2.0f);

    /// Set material to transparent blue
    subMesh->setMaterialName("Examples/TransparentBlue50");

    /// Notify -Mesh object that it has been loaded
    mesh->load();

    return mesh;
}
Beispiel #13
0
void BasicTutorial2::createColourCube()
{
    /// Create the mesh via the MeshManager
    Ogre::MeshPtr msh = MeshManager::getSingleton().createManual("ColourCube", "General");
 
    /// Create one submesh
    SubMesh* sub = msh->createSubMesh();
 
    const float sqrt13 = 0.577350269f; /* sqrt(1/3) */
 
    /// Define the vertices (8 vertices, each have 3 floats for position and 3 for normal)
    const size_t nVertices = 8;
    const size_t vbufCount = 3*2*nVertices;
    float vertices[vbufCount] = {
            -100.0,100.0,-100.0,        //0 position
            -sqrt13,sqrt13,-sqrt13,     //0 normal
            100.0,100.0,-100.0,         //1 position
            sqrt13,sqrt13,-sqrt13,      //1 normal
            100.0,-100.0,-100.0,        //2 position
            sqrt13,-sqrt13,-sqrt13,     //2 normal
            -100.0,-100.0,-100.0,       //3 position
            -sqrt13,-sqrt13,-sqrt13,    //3 normal
            -100.0,100.0,100.0,         //4 position
            -sqrt13,sqrt13,sqrt13,      //4 normal
            100.0,100.0,100.0,          //5 position
            sqrt13,sqrt13,sqrt13,       //5 normal
            100.0,-100.0,100.0,         //6 position
            sqrt13,-sqrt13,sqrt13,      //6 normal
            -100.0,-100.0,100.0,        //7 position
            -sqrt13,-sqrt13,sqrt13,     //7 normal
    };
 
    RenderSystem* rs = Root::getSingleton().getRenderSystem();
    RGBA colours[nVertices];
    RGBA *pColour = colours;
    // Use render system to convert colour value since colour packing varies
    rs->convertColourValue(ColourValue(1.0,0.0,0.0), pColour++); //0 colour
    rs->convertColourValue(ColourValue(1.0,1.0,0.0), pColour++); //1 colour
    rs->convertColourValue(ColourValue(0.0,1.0,0.0), pColour++); //2 colour
    rs->convertColourValue(ColourValue(0.0,0.0,0.0), pColour++); //3 colour
    rs->convertColourValue(ColourValue(1.0,0.0,1.0), pColour++); //4 colour
    rs->convertColourValue(ColourValue(1.0,1.0,1.0), pColour++); //5 colour
    rs->convertColourValue(ColourValue(0.0,1.0,1.0), pColour++); //6 colour
    rs->convertColourValue(ColourValue(0.0,0.0,1.0), pColour++); //7 colour
 
    /// Define 12 triangles (two triangles per cube face)
    /// The values in this table refer to vertices in the above table
    const size_t ibufCount = 36;
    unsigned short faces[ibufCount] = {
            0,2,3,
            0,1,2,
            1,6,2,
            1,5,6,
            4,6,5,
            4,7,6,
            0,7,4,
            0,3,7,
            0,5,1,
            0,4,5,
            2,7,3,
            2,6,7
    };
 
    /// Create vertex data structure for 8 vertices shared between submeshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = nVertices;
 
    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    // 1st buffer
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    /// Allocate vertex buffer of the requested number of vertices (vertexCount) 
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf = 
        HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
 
    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; 
    bind->setBinding(0, vbuf);
 
    // 2nd buffer
    offset = 0;
    decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE);
    offset += VertexElement::getTypeSize(VET_COLOUR);
    /// Allocate vertex buffer of the requested number of vertices (vertexCount) 
    /// and bytes per vertex (offset)
    vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), colours, true);
 
    /// Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding(1, vbuf);
 
    /// Allocate index buffer of the requested number of vertices (ibufCount) 
    HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
        createIndexBuffer(
        HardwareIndexBuffer::IT_16BIT, 
        ibufCount, 
        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
 
    /// Upload the index data to the card
    ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
 
    /// Set parameters of the submesh
    sub->useSharedVertices = true;
    sub->indexData->indexBuffer = ibuf;
    sub->indexData->indexCount = ibufCount;
    sub->indexData->indexStart = 0;
 
    /// Set bounding information (for culling)
    msh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100));
    msh->_setBoundingSphereRadius(Math::Sqrt(3*100*100));
 
    /// Notify -Mesh object that it has been loaded
    msh->load();
}
Beispiel #14
0
	//---------------------------------------------------------------------
	void OptimiseTool::rebuildVertexBuffers()
	{
		// We need to build new vertex buffers of the new, reduced size
		VertexBufferBinding* newBind =
			HardwareBufferManager::getSingleton().createVertexBufferBinding();

		// Lock source buffers
		typedef std::vector<char*> BufferLocks;
		BufferLocks srcbufferLocks;
		BufferLocks destbufferLocks;
		const VertexBufferBinding::VertexBufferBindingMap& srcBindings =
			mTargetVertexData->vertexBufferBinding->getBindings();
		VertexBufferBinding::VertexBufferBindingMap::const_iterator bindi;
		srcbufferLocks.resize(mTargetVertexData->vertexBufferBinding->getLastBoundIndex()+1);
		destbufferLocks.resize(mTargetVertexData->vertexBufferBinding->getLastBoundIndex()+1);
		for (bindi = srcBindings.begin(); bindi != srcBindings.end(); ++bindi)
		{
			char* lock = static_cast<char*>(bindi->second->lock(HardwareBuffer::HBL_READ_ONLY));
			srcbufferLocks[bindi->first] = lock;

			// Add a new vertex buffer and binding
			HardwareVertexBufferSharedPtr newBuf =
				HardwareBufferManager::getSingleton().createVertexBuffer(
					bindi->second->getVertexSize(),
					mUniqueVertexList.size(),
					bindi->second->getUsage(),
					bindi->second->hasShadowBuffer());
			newBind->setBinding(bindi->first, newBuf);
			lock = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_DISCARD));
			destbufferLocks[bindi->first] = lock;
		}
		const VertexBufferBinding::VertexBufferBindingMap& destBindings =
			newBind->getBindings();


		// Iterate over the new vertices
		for (UniqueVertexList::iterator ui = mUniqueVertexList.begin();
			ui != mUniqueVertexList.end(); ++ui)
		{
			uint32 origVertexIndex = ui->oldIndex;
			// copy vertex from each buffer in turn
			VertexBufferBinding::VertexBufferBindingMap::const_iterator srci =
				srcBindings.begin();
			VertexBufferBinding::VertexBufferBindingMap::const_iterator desti =
				destBindings.begin();
			for (; srci != srcBindings.end(); ++srci, ++desti)
			{
				// determine source pointer
				char* pSrc = srcbufferLocks[srci->first] +
					(srci->second->getVertexSize() * origVertexIndex);
				char* pDest = destbufferLocks[desti->first];

				// Copy vertex from source index
				memcpy(pDest, pSrc, desti->second->getVertexSize());

				// increment destination lock pointer
				destbufferLocks[desti->first] += desti->second->getVertexSize();
			}
		}

		// unlock the buffers now
		for (bindi = srcBindings.begin(); bindi != srcBindings.end(); ++bindi)
		{
			bindi->second->unlock();
		}
		for (bindi = destBindings.begin(); bindi != destBindings.end(); ++bindi)
		{
			bindi->second->unlock();
		}

		// now switch over the bindings, and thus the buffers
		VertexBufferBinding* oldBind = mTargetVertexData->vertexBufferBinding;
		mTargetVertexData->vertexBufferBinding = newBind;
		HardwareBufferManager::getSingleton().destroyVertexBufferBinding(oldBind);

		// Update vertex count in data
		mTargetVertexData->vertexCount = mUniqueVertexList.size();


	}
    //-----------------------------------------------------------------------
    void MeshManager::loadManualPlane(Mesh* pMesh, MeshBuildParams& params)
    {
		if ((params.xsegments + 1) * (params.ysegments + 1) > 65536)
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
				"Plane tessellation is too high, must generate max 65536 vertices", 
				__FUNCTION__);
        SubMesh *pSub = pMesh->createSubMesh();

        // Set up vertex data
        // Use a single shared buffer
        pMesh->sharedVertexData = OGRE_NEW VertexData();
        VertexData* vertexData = pMesh->sharedVertexData;
        // Set up Vertex Declaration
        VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
        size_t currOffset = 0;
        // We always need positions
        vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
        currOffset += VertexElement::getTypeSize(VET_FLOAT3);
        // Optional normals
        if(params.normals)
        {
            vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
            currOffset += VertexElement::getTypeSize(VET_FLOAT3);
        }

        for (unsigned short i = 0; i < params.numTexCoordSets; ++i)
        {
            // Assumes 2D texture coords
            vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
            currOffset += VertexElement::getTypeSize(VET_FLOAT2);
        }

        vertexData->vertexCount = (params.xsegments + 1) * (params.ysegments + 1);

        // Allocate vertex buffer
        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().
            createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount,
            params.vertexBufferUsage, params.vertexShadowBuffer);

        // Set up the binding (one source only)
        VertexBufferBinding* binding = vertexData->vertexBufferBinding;
        binding->setBinding(0, vbuf);

        // Work out the transform required
        // Default orientation of plane is normal along +z, distance 0
        Matrix4 xlate, xform, rot;
        Matrix3 rot3;
        xlate = rot = Matrix4::IDENTITY;
        // Determine axes
        Vector3 zAxis, yAxis, xAxis;
        zAxis = params.plane.normal;
        zAxis.normalise();
        yAxis = params.upVector;
        yAxis.normalise();
        xAxis = yAxis.crossProduct(zAxis);
        if (xAxis.length() == 0)
        {
            //upVector must be wrong
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
                "MeshManager::createPlane");
        }

        rot3.FromAxes(xAxis, yAxis, zAxis);
        rot = rot3;

        // Set up standard transform from origin
        xlate.setTrans(params.plane.normal * -params.plane.d);

        // concatenate
        xform = xlate * rot;

        // Generate vertex data
        // Lock the whole buffer
        float* pReal = static_cast<float*>(
            vbuf->lock(HardwareBuffer::HBL_DISCARD) );
        Real xSpace = params.width / params.xsegments;
        Real ySpace = params.height / params.ysegments;
        Real halfWidth = params.width / 2;
        Real halfHeight = params.height / 2;
        Real xTex = (1.0f * params.xTile) / params.xsegments;
        Real yTex = (1.0f * params.yTile) / params.ysegments;
        Vector3 vec;
        Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE;
        Real maxSquaredLength = 0;
        bool firstTime = true;

        for (int y = 0; y < params.ysegments + 1; ++y)
        {
            for (int x = 0; x < params.xsegments + 1; ++x)
            {
                // Work out centered on origin
                vec.x = (x * xSpace) - halfWidth;
                vec.y = (y * ySpace) - halfHeight;
                vec.z = 0.0f;
                // Transform by orientation and distance
                vec = xform.transformAffine(vec);
                // Assign to geometry
                *pReal++ = vec.x;
                *pReal++ = vec.y;
                *pReal++ = vec.z;

                // Build bounds as we go
                if (firstTime)
                {
                    min = vec;
                    max = vec;
                    maxSquaredLength = vec.squaredLength();
                    firstTime = false;
                }
                else
                {
                    min.makeFloor(vec);
                    max.makeCeil(vec);
                    maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength());
                }

                if (params.normals)
                {
                    // Default normal is along unit Z
                    vec = Vector3::UNIT_Z;
                    // Rotate
                    vec = rot.transformAffine(vec);

                    *pReal++ = vec.x;
                    *pReal++ = vec.y;
                    *pReal++ = vec.z;
                }

                for (unsigned short i = 0; i < params.numTexCoordSets; ++i)
                {
                    *pReal++ = x * xTex;
                    *pReal++ = 1 - (y * yTex);
                }


            } // x
        } // y

        // Unlock
        vbuf->unlock();
        // Generate face list
        pSub->useSharedVertices = true;
        tesselate2DMesh(pSub, params.xsegments + 1, params.ysegments + 1, false, 
            params.indexBufferUsage, params.indexShadowBuffer);

        pMesh->_setBounds(AxisAlignedBox(min, max), true);
        pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength));
    }
Beispiel #16
0
void GeomUtils::createSphere(VertexData*& vertexData, IndexData*& indexData
						 , float radius
						 , int nRings, int nSegments
						 , bool bNormals
						 , bool bTexCoords)
{
	assert(vertexData && indexData);

	// define the vertex format
	VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
	size_t currOffset = 0;
	// positions
	vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
	currOffset += VertexElement::getTypeSize(VET_FLOAT3);

	if (bNormals)
	{
		// normals
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);

	}
	// two dimensional texture coordinates
	if (bTexCoords)
	{
		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
	}

	// allocate the vertex buffer
	vertexData->vertexCount = (nRings + 1) * (nSegments+1);
	HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	VertexBufferBinding* binding = vertexData->vertexBufferBinding;
	binding->setBinding(0, vBuf);
	float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

	// allocate index buffer
	indexData->indexCount = 6 * nRings * (nSegments + 1);
	indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
	unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

	float fDeltaRingAngle = (Math::PI / nRings);
	float fDeltaSegAngle = (2 * Math::PI / nSegments);
	unsigned short wVerticeIndex = 0 ;

	// Generate the group of rings for the sphere
	for( int ring = 0; ring <= nRings; ring++ ) {
		float r0 = radius * sinf (ring * fDeltaRingAngle);
		float y0 = radius * cosf (ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(int seg = 0; seg <= nSegments; seg++) {
			float x0 = r0 * sinf(seg * fDeltaSegAngle);
			float z0 = r0 * cosf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			*pVertex++ = x0;
			*pVertex++ = y0;
			*pVertex++ = z0;

			if (bNormals)
			{
				Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
				*pVertex++ = vNormal.x;
				*pVertex++ = vNormal.y;
				*pVertex++ = vNormal.z;
			}
			if (bTexCoords)
			{
				*pVertex++ = (float) seg / (float) nSegments;
				*pVertex++ = (float) ring / (float) nRings;			
			}

			if (ring != nRings) 
			{
				// each vertex (except the last) has six indices pointing to it
				*pIndices++ = wVerticeIndex + nSegments + 1;
				*pIndices++ = wVerticeIndex;               
				*pIndices++ = wVerticeIndex + nSegments;
				*pIndices++ = wVerticeIndex + nSegments + 1;
				*pIndices++ = wVerticeIndex + 1;
				*pIndices++ = wVerticeIndex;
				wVerticeIndex ++;
			}
		}; // end for seg
	} // end for ring

	// Unlock
	vBuf->unlock();
	iBuf->unlock();
}
    //-----------------------------------------------------------------------
    void MeshManager::loadManualCurvedPlane(Mesh* pMesh, MeshBuildParams& params)
    {
		if ((params.xsegments + 1) * (params.ysegments + 1) > 65536)
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
				"Plane tessellation is too high, must generate max 65536 vertices", 
				__FUNCTION__);
        SubMesh *pSub = pMesh->createSubMesh();

        // Set options
        pMesh->sharedVertexData = OGRE_NEW VertexData();
        pMesh->sharedVertexData->vertexStart = 0;
        VertexBufferBinding* bind = pMesh->sharedVertexData->vertexBufferBinding;
        VertexDeclaration* decl = pMesh->sharedVertexData->vertexDeclaration;

        pMesh->sharedVertexData->vertexCount = (params.xsegments + 1) * (params.ysegments + 1);

        size_t offset = 0;
        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
        offset += VertexElement::getTypeSize(VET_FLOAT3);
        if (params.normals)
        {
            decl->addElement(0, 0, VET_FLOAT3, VES_NORMAL);
            offset += VertexElement::getTypeSize(VET_FLOAT3);
        }

        for (unsigned short i = 0; i < params.numTexCoordSets; ++i)
        {
            decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
            offset += VertexElement::getTypeSize(VET_FLOAT2);
        }


        // Allocate memory
        HardwareVertexBufferSharedPtr vbuf = 
            HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, 
            pMesh->sharedVertexData->vertexCount, 
            params.vertexBufferUsage, 
            params.vertexShadowBuffer);
        bind->setBinding(0, vbuf);

        // Work out the transform required
        // Default orientation of plane is normal along +z, distance 0
        Matrix4 xlate, xform, rot;
        Matrix3 rot3;
        xlate = rot = Matrix4::IDENTITY;
        // Determine axes
        Vector3 zAxis, yAxis, xAxis;
        zAxis = params.plane.normal;
        zAxis.normalise();
        yAxis = params.upVector;
        yAxis.normalise();
        xAxis = yAxis.crossProduct(zAxis);
        if (xAxis.length() == 0)
        {
            //upVector must be wrong
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.",
                "MeshManager::createPlane");
        }

        rot3.FromAxes(xAxis, yAxis, zAxis);
        rot = rot3;

        // Set up standard transform from origin
        xlate.setTrans(params.plane.normal * -params.plane.d);

        // concatenate
        xform = xlate * rot;

        // Generate vertex data
        float* pFloat = static_cast<float*>(
            vbuf->lock(HardwareBuffer::HBL_DISCARD)); 
        Real xSpace = params.width / params.xsegments;
        Real ySpace = params.height / params.ysegments;
        Real halfWidth = params.width / 2;
        Real halfHeight = params.height / 2;
        Real xTex = (1.0f * params.xTile) / params.xsegments;
        Real yTex = (1.0f * params.yTile) / params.ysegments;
        Vector3 vec;

        Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE;
        Real maxSqLen = 0;
        bool first = true;

        Real diff_x, diff_y, dist;

        for (int y = 0; y < params.ysegments + 1; ++y)
        {
            for (int x = 0; x < params.xsegments + 1; ++x)
            {
                // Work out centered on origin
                vec.x = (x * xSpace) - halfWidth;
                vec.y = (y * ySpace) - halfHeight;

                // Here's where curved plane is different from standard plane.  Amazing, I know.
                diff_x = (x - ((params.xsegments) / 2)) / static_cast<Real>((params.xsegments));
                diff_y = (y - ((params.ysegments) / 2)) / static_cast<Real>((params.ysegments));
                dist = sqrt(diff_x*diff_x + diff_y * diff_y );
				vec.z = (-sin((1-dist) * (Math::PI/2)) * params.curvature) + params.curvature;

                // Transform by orientation and distance
                Vector3 pos = xform.transformAffine(vec);
                // Assign to geometry
                *pFloat++ = pos.x;
                *pFloat++ = pos.y;
                *pFloat++ = pos.z;

                // Record bounds
                if (first)
                {
                    min = max = vec;
                    maxSqLen = vec.squaredLength();
                    first = false;
                }
                else
                {
                    min.makeFloor(vec);
                    max.makeCeil(vec);
                    maxSqLen = std::max(maxSqLen, vec.squaredLength());
                }

                if (params.normals)
                {
                    // This part is kinda 'wrong' for curved planes... but curved planes are
                    //   very valuable outside sky planes, which don't typically need normals
                    //   so I'm not going to mess with it for now. 

                    // Default normal is along unit Z
                    //vec = Vector3::UNIT_Z;
                    // Rotate
                    vec = rot.transformAffine(vec);
					vec.normalise();

                    *pFloat++ = vec.x;
                    *pFloat++ = vec.y;
                    *pFloat++ = vec.z;
                }

                for (unsigned short i = 0; i < params.numTexCoordSets; ++i)
                {
                    *pFloat++ = x * xTex;
                    *pFloat++ = 1 - (y * yTex);
                }

            } // x
        } // y
        vbuf->unlock();

        // Generate face list
        tesselate2DMesh(pSub, params.xsegments + 1, params.ysegments + 1, 
            false, params.indexBufferUsage, params.indexShadowBuffer);

        pMesh->_setBounds(AxisAlignedBox(min, max), true);
        pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSqLen));

    }
Beispiel #18
0
FlexObj::FlexObj(node_t *nds, std::vector<CabTexcoord>& texcoords, int numtriangles, 
                 int* triangles, std::vector<CabSubmesh>& submesh_defs, 
                 char* texname, const char* name, char* backtexname, char* transtexname)
{
    m_triangle_count = numtriangles;

    m_all_nodes=nds;
    // Create the mesh via the MeshManager
    m_mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    // Create submeshes
    m_submeshes.reserve(submesh_defs.size());
    for (size_t j=0; j<submesh_defs.size(); j++)
    {
        Ogre::SubMesh* submesh = m_mesh->createSubMesh();
        switch (submesh_defs[j].backmesh_type)
        {
        case CabSubmesh::BACKMESH_OPAQUE:      submesh->setMaterialName(backtexname);  break;
        case CabSubmesh::BACKMESH_TRANSPARENT: submesh->setMaterialName(transtexname); break;
        default:                               submesh->setMaterialName(texname);
        }
        m_submeshes.push_back(submesh);
    };

    // Define the m_vertices_raw (8 vertices, each consisting of 3 groups of 3 floats
    m_vertex_count = texcoords.size();
    m_vertices_raw=(float*)malloc(((2*3+2)*m_vertex_count)*sizeof(float));
    m_vertex_nodes=(int*)malloc(m_vertex_count*sizeof(int));
    
    for (size_t i=0; i<m_vertex_count; i++)
    {
        m_vertex_nodes[i] = texcoords[i].node_id; //define node ids
        m_vertices[i].texcoord=Vector2(texcoords[i].texcoord_u, texcoords[i].texcoord_v); //textures coordinates
    }

    // Define triangles
    // The values in this table refer to vertices in the above table
    m_index_count = 3*numtriangles;
    m_indices=(unsigned short*)malloc(m_index_count*sizeof(unsigned short));
    for (size_t i=0; i<m_index_count; i++)
    {
        m_indices[i]=ComputeVertexPos(i/3, triangles[i], submesh_defs);
    }

    m_s_ref=(float*)malloc(numtriangles*sizeof(float));

    for (size_t i=0; i<(unsigned int)numtriangles;i++)
    {
        Ogre::Vector3 base_pos = m_all_nodes[m_vertex_nodes[m_indices[i*3]]].RelPosition;
        Ogre::Vector3 v1       = m_all_nodes[m_vertex_nodes[m_indices[i*3+1]]].RelPosition - base_pos;
        Ogre::Vector3 v2       = m_all_nodes[m_vertex_nodes[m_indices[i*3+2]]].RelPosition - base_pos;
        m_s_ref[i]=v1.crossProduct(v2).length()*2.0;
    }

    this->UpdateMesh(); // Initialize the dynamic mesh

    // Create vertex data structure for vertices shared between submeshes
    m_mesh->sharedVertexData = new VertexData();
    m_mesh->sharedVertexData->vertexCount = m_vertex_count;

    // Create declaration (memory format) of vertex data
    m_vertex_format = m_mesh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    m_vertex_format->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    // Allocate vertex buffer of the requested number of vertices (vertexCount)
    // and bytes per vertex (offset)
    m_hw_vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, m_mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    // Upload the vertex data to the card
    m_hw_vbuf->writeData(0, m_hw_vbuf->getSizeInBytes(), m_vertices_raw, true);

    // Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = m_mesh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, m_hw_vbuf);

    // Set parameters of the submeshes
    for (size_t j=0; j<m_submeshes.size(); j++)
    {
        size_t index_count;
        if (j == 0)
            index_count = 3*submesh_defs[j].cabs_pos;
        else
            index_count = 3*(submesh_defs[j].cabs_pos-submesh_defs[j-1].cabs_pos); // 3 indices per triangle

        m_submeshes[j]->useSharedVertices = true;
        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().createIndexBuffer(
             HardwareIndexBuffer::IT_16BIT,
             index_count,
             HardwareBuffer::HBU_STATIC_WRITE_ONLY);

        // Upload the index data to the card
        unsigned short* faces_ptr;
        if (j == 0)
            faces_ptr = &m_indices[0];
        else
            faces_ptr = &m_indices[submesh_defs[j-1].cabs_pos * 3];

        ibuf->writeData(0, ibuf->getSizeInBytes(), faces_ptr, true);
        m_submeshes[j]->indexData->indexBuffer = ibuf;
        m_submeshes[j]->indexData->indexCount = index_count;
        m_submeshes[j]->indexData->indexStart = 0;
    }

    // Set bounding information (for culling)
    m_mesh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100), true);

    // Notify Mesh object that it has been loaded
    m_mesh->load();
}
Beispiel #19
0
FlexAirfoil::FlexAirfoil(SceneManager *manager, char* name, node_t *nds, int pnfld, int pnfrd, int pnflu, int pnfru, int pnbld, int pnbrd, int pnblu, int pnbru, char* texband, Vector2 texlf, Vector2 texrf, Vector2 texlb, Vector2 texrb, char mtype, float controlratio, float mind, float maxd, char* afname, float lift_coef, AeroEngine** tps, bool break_able)
{
//		innan=0;
	liftcoef=lift_coef;
	breakable=break_able;
	broken=false;
	debug[0]=0;
	free_wash=0;
    smanager=manager;
	aeroengines=tps;
	nodes=nds;
	useInducedDrag=false;
	nfld=pnfld; nodes[nfld].iIsSkin=true;
	nfrd=pnfrd; nodes[nfrd].iIsSkin=true;
	nflu=pnflu; nodes[nflu].iIsSkin=true;
	nfru=pnfru; nodes[nfru].iIsSkin=true;
	nbld=pnbld; nodes[nbld].iIsSkin=true;
	nbrd=pnbrd; nodes[nbrd].iIsSkin=true;
	nblu=pnblu; nodes[nblu].iIsSkin=true;
	nbru=pnbru; nodes[nbru].iIsSkin=true;
	mindef=mind;
	maxdef=maxd;
	airfoil=new Airfoil(afname);
	//airfoil->getcl(-180.0, 0, 0);
	//airfoil->dumpcl();
	int i;
	for (i=0; i<90; i++) airfoilpos[i]=refairfoilpos[i];
	type=mtype;
	hascontrol=(mtype!='n' && mtype!='S'&& mtype!='T' && mtype!='U'&& mtype!='V');
	isstabilator=(mtype=='S' || mtype=='T' || mtype=='U' || mtype=='V');
	stabilleft=(mtype=='T' || mtype=='V');
	deflection=0.0;
	chordratio=controlratio;

	if (hascontrol)
	{
		//setup control surface
		airfoilpos[56]=controlratio;
		airfoilpos[56+3]=controlratio;
		airfoilpos[56+6]=controlratio;
		airfoilpos[56+9]=controlratio;

		airfoilpos[55]=-controlratio+1.5;
		airfoilpos[55+3]=-controlratio+1.5;
		airfoilpos[55+6]=controlratio-0.5;
		airfoilpos[55+9]=controlratio-0.5;
		for (i=0; i<12; i++) airfoilpos[54+12+i]=airfoilpos[54+i];
	}
	/// Create the mesh via the MeshManager
    msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, new ResourceBuffer());

    /// Create submeshes
    subface = msh->createSubMesh();
    subband = msh->createSubMesh();
	subcup=msh->createSubMesh();
	subcdn=msh->createSubMesh();

	//materials
	subface->setMaterialName(texband);
	subband->setMaterialName(texband);
	subcup->setMaterialName(texband);
	subcdn->setMaterialName(texband);

    /// Define the vertices
    nVertices = 24*2+4+2;
    vbufCount = (2*3+2)*nVertices;
	vertices=(float*)malloc(vbufCount*sizeof(float));
	//shadow
	shadownorvertices=(float*)malloc(nVertices*(3+2)*sizeof(float));
	shadowposvertices=(float*)malloc(nVertices*3*2*sizeof(float));

	//textures coordinates
	covertices[0].texcoord=texlf;
	covertices[1].texcoord=texrf;

	covertices[2].texcoord=texlf+(texlb-texlf)*0.03;
	covertices[3].texcoord=texrf+(texrb-texrf)*0.03;
	covertices[4].texcoord=texlf+(texlb-texlf)*0.03;
	covertices[5].texcoord=texrf+(texrb-texrf)*0.03;

	covertices[6].texcoord=texlf+(texlb-texlf)*0.10;
	covertices[7].texcoord=texrf+(texrb-texrf)*0.10;
	covertices[8].texcoord=texlf+(texlb-texlf)*0.10;
	covertices[9].texcoord=texrf+(texrb-texrf)*0.10;

	covertices[10].texcoord=texlf+(texlb-texlf)*0.25;
	covertices[11].texcoord=texrf+(texrb-texrf)*0.25;
	covertices[12].texcoord=texlf+(texlb-texlf)*0.25;
	covertices[13].texcoord=texrf+(texrb-texrf)*0.25;

	covertices[14].texcoord=texlf+(texlb-texlf)*0.45;
	covertices[15].texcoord=texrf+(texrb-texrf)*0.45;
	covertices[16].texcoord=texlf+(texlb-texlf)*0.45;
	covertices[17].texcoord=texrf+(texrb-texrf)*0.45;

	covertices[18].texcoord=texlf+(texlb-texlf)*airfoilpos[56];
	covertices[19].texcoord=texrf+(texrb-texrf)*airfoilpos[56];
	covertices[20].texcoord=texlf+(texlb-texlf)*airfoilpos[56];
	covertices[21].texcoord=texrf+(texrb-texrf)*airfoilpos[56];

	covertices[22].texcoord=covertices[18].texcoord;
	covertices[23].texcoord=covertices[19].texcoord;
	covertices[24].texcoord=covertices[20].texcoord;
	covertices[25].texcoord=covertices[21].texcoord;

	covertices[26].texcoord=texlb;
	covertices[27].texcoord=texrb;
	covertices[28].texcoord=texlb;
	covertices[29].texcoord=texrb;

	for (i=0; i<24; i++) covertices[i+30].texcoord=covertices[i].texcoord;

	/// Define triangles
    /// The values in this table refer to vertices in the above table
    bandibufCount = 3*20;
    faceibufCount = 3*20;
	cupibufCount=3*2;
	cdnibufCount=3*2;
    facefaces=(unsigned short*)malloc(faceibufCount*sizeof(unsigned short));
    bandfaces=(unsigned short*)malloc(bandibufCount*sizeof(unsigned short));
    cupfaces=(unsigned short*)malloc(cupibufCount*sizeof(unsigned short));
    cdnfaces=(unsigned short*)malloc(cdnibufCount*sizeof(unsigned short));
	
	//attack
	bandfaces[0]=0;
	bandfaces[1]=2;
	bandfaces[2]=1;

	bandfaces[3]=2;
	bandfaces[4]=3;
	bandfaces[5]=1;

	bandfaces[6]=0;
	bandfaces[7]=1;
	bandfaces[8]=4;

	bandfaces[9]=4;
	bandfaces[10]=1;
	bandfaces[11]=5;
	for (i=0; i<5; i++)
	{
		//band
		int v=i*4+2;
		if (i!=4)
		{
			bandfaces[i*12+12]=v;
			bandfaces[i*12+13]=v+4;
			bandfaces[i*12+14]=v+1;

			bandfaces[i*12+15]=v+4;
			bandfaces[i*12+16]=v+5;
			bandfaces[i*12+17]=v+1;

			bandfaces[i*12+18]=v+2;
			bandfaces[i*12+19]=v+3;
			bandfaces[i*12+20]=v+6;

			bandfaces[i*12+21]=v+6;
			bandfaces[i*12+22]=v+3;
			bandfaces[i*12+23]=v+7;
		}
/*			if (i==4)
		{
			bandfaces[i*12+20]=v+4;
			bandfaces[i*12+21]=v+4;
			bandfaces[i*12+23]=v+5;
		}
*/

		//sides
		facefaces[i*12]=30+0;
		facefaces[i*12+1]=30+v+4;
		facefaces[i*12+2]=30+v;

		facefaces[i*12+3]=30+0;
		facefaces[i*12+4]=30+v+2;
		facefaces[i*12+5]=30+v+6;

		facefaces[i*12+6]=30+1;
		facefaces[i*12+7]=30+v+1;
		facefaces[i*12+8]=30+v+5;

		facefaces[i*12+9]=30+1;
		facefaces[i*12+10]=30+v+7;
		facefaces[i*12+11]=30+v+3;
		if (i==4)
		{
//				facefaces[i*12+5]=20+v+4;
//				facefaces[i*12+10]=20+v+5;
			facefaces[i*12]=30+0;
			facefaces[i*12+1]=30+v+2;
			facefaces[i*12+2]=30+v;

			facefaces[i*12+3]=30+v+4;
			facefaces[i*12+4]=30+v;
			facefaces[i*12+5]=30+v+2;

			facefaces[i*12+6]=30+1;
			facefaces[i*12+7]=30+v+1;
			facefaces[i*12+8]=30+v+3;

			facefaces[i*12+9]=30+v+5;
			facefaces[i*12+10]=30+v+3;
			facefaces[i*12+11]=30+v+1;
		}

	}
	cupfaces[0]=22;
	cupfaces[1]=26;
	cupfaces[2]=23;
	cupfaces[3]=26;
	cupfaces[4]=27;
	cupfaces[5]=23;

	cdnfaces[0]=24;
	cdnfaces[1]=25;
	cdnfaces[2]=29;
	cdnfaces[3]=24;
	cdnfaces[4]=29;
	cdnfaces[5]=28;

	float tsref=2.0*(nodes[nfrd].RelPosition-nodes[nfld].RelPosition).crossProduct(nodes[nbld].RelPosition-nodes[nfld].RelPosition).length();
	sref=2.0*(nodes[nfrd].RelPosition-nodes[nfld].RelPosition).crossProduct(nodes[nbrd].RelPosition-nodes[nfrd].RelPosition).length();
	if (tsref>sref) sref=tsref;
	sref=sref*sref;

	lratio=(nodes[nfld].RelPosition-nodes[nflu].RelPosition).length()/(nodes[nfld].RelPosition-nodes[nbld].RelPosition).length();
	rratio=(nodes[nfrd].RelPosition-nodes[nfru].RelPosition).length()/(nodes[nfrd].RelPosition-nodes[nbrd].RelPosition).length();

	thickness=(nodes[nfld].RelPosition-nodes[nflu].RelPosition).length();

	//update coords
	updateVertices();

	/// Create vertex data structure for 8 vertices shared between submeshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = nVertices;

    /// Create declaration (memory format) of vertex data
    decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
//        decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE);
//        offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    /// Allocate vertex buffer of the requested number of vertices (vertexCount) 
    /// and bytes per vertex (offset)
    vbuf = 
      HardwareBufferManager::getSingleton().createVertexBuffer(
          offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; 
    bind->setBinding(0, vbuf);

    //for the face
	/// Allocate index buffer of the requested number of vertices (ibufCount) 
    HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton().
     createIndexBuffer(
         HardwareIndexBuffer::IT_16BIT, 
            faceibufCount, 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    faceibuf->writeData(0, faceibuf->getSizeInBytes(), facefaces, true);

    /// Set parameters of the submesh
    subface->useSharedVertices = true;
    subface->indexData->indexBuffer = faceibuf;
    subface->indexData->indexCount = faceibufCount;
    subface->indexData->indexStart = 0;

    //for the band
	/// Allocate index buffer of the requested number of vertices (ibufCount) 
    HardwareIndexBufferSharedPtr bandibuf = HardwareBufferManager::getSingleton().
     createIndexBuffer(
         HardwareIndexBuffer::IT_16BIT, 
            bandibufCount, 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    bandibuf->writeData(0, bandibuf->getSizeInBytes(), bandfaces, true);

    /// Set parameters of the submesh
    subband->useSharedVertices = true;
    subband->indexData->indexBuffer = bandibuf;
    subband->indexData->indexCount = bandibufCount;
    subband->indexData->indexStart = 0;

    //for the aileron up
	/// Allocate index buffer of the requested number of vertices (ibufCount) 
    HardwareIndexBufferSharedPtr cupibuf = HardwareBufferManager::getSingleton().
     createIndexBuffer(
         HardwareIndexBuffer::IT_16BIT, 
            cupibufCount, 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    cupibuf->writeData(0, cupibuf->getSizeInBytes(), cupfaces, true);

    /// Set parameters of the submesh
    subcup->useSharedVertices = true;
    subcup->indexData->indexBuffer = cupibuf;
    subcup->indexData->indexCount = cupibufCount;
    subcup->indexData->indexStart = 0;

    //for the aileron down
	/// Allocate index buffer of the requested number of vertices (ibufCount) 
    HardwareIndexBufferSharedPtr cdnibuf = HardwareBufferManager::getSingleton().
     createIndexBuffer(
         HardwareIndexBuffer::IT_16BIT, 
            cdnibufCount, 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    cdnibuf->writeData(0, cdnibuf->getSizeInBytes(), cdnfaces, true);

    /// Set parameters of the submesh
    subcdn->useSharedVertices = true;
    subcdn->indexData->indexBuffer = cdnibuf;
    subcdn->indexData->indexCount = cdnibufCount;
    subcdn->indexData->indexStart = 0;
    
    /// Set bounding information (for culling)
    msh->_setBounds(AxisAlignedBox(-20,-20,-20,20,20,20), true);
    //msh->_setBoundingSphereRadius(20.0);

    /// Notify Mesh object that it has been loaded
	//MeshManager::getSingleton().setPrepareAllMeshesForShadowVolumes(false);
	msh->buildEdgeList();
	//msh->prepareForShadowVolume();
	msh->load();
	//MeshManager::getSingleton().setPrepareAllMeshesForShadowVolumes()
}
Beispiel #20
0
WaterMesh::WaterMesh(const String& meshName, Real planeSize, int complexity)
{
	int x,y,b; // I prefer to initialize for() variables inside it, but VC doesn't like it ;(

	this->meshName = meshName ;
	this->complexity =  complexity ;
	numFaces = 2 * complexity * complexity;
	numVertices = (complexity + 1) * (complexity + 1) ;
	lastTimeStamp = 0 ;
	lastAnimationTimeStamp = 0;
	lastFrameTime = 0 ;

	// initialize algorithm parameters
	PARAM_C = 0.3f ; // ripple speed
	PARAM_D = 0.4f ; // distance
	PARAM_U = 0.05f ; // viscosity
	PARAM_T = 0.13f ; // time
	useFakeNormals = false ;

	// allocate space for normal calculation
	vNormals = new Vector3[numVertices];

	// create mesh and submesh
	mesh = MeshManager::getSingleton().createManual(meshName,
        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	subMesh = mesh->createSubMesh();
	subMesh->useSharedVertices=false;

	// Vertex buffers
	subMesh->vertexData = new VertexData();
	subMesh->vertexData->vertexStart = 0;
	subMesh->vertexData->vertexCount = numVertices;

	VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration;
	VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding;


	vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
	vdecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL);
	vdecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);

	// Prepare buffer for positions - todo: first attempt, slow
	posVertexBuffer =
         HardwareBufferManager::getSingleton().createVertexBuffer(
            3*sizeof(float),
			numVertices,
			HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
	vbind->setBinding(0, posVertexBuffer);

	// Prepare buffer for normals - write only
	normVertexBuffer =
         HardwareBufferManager::getSingleton().createVertexBuffer(
            3*sizeof(float),
			numVertices,
			HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
	vbind->setBinding(1, normVertexBuffer);

	// Prepare texture coords buffer - static one
	// todo: optimize to write directly into buffer
	float *texcoordsBufData = new float[numVertices*2];
	for(y=0;y<=complexity;y++) {
		for(x=0;x<=complexity;x++) {
			texcoordsBufData[2*(y*(complexity+1)+x)+0] = (float)x / complexity ;
			texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0f - ((float)y / (complexity)) ;
		}
	}
	texcoordsVertexBuffer =
         HardwareBufferManager::getSingleton().createVertexBuffer(
            2*sizeof(float),
			numVertices,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	texcoordsVertexBuffer->writeData(0,
		texcoordsVertexBuffer->getSizeInBytes(),
		texcoordsBufData,
		true); // true?
	delete [] texcoordsBufData;
    vbind->setBinding(2, texcoordsVertexBuffer);

	// Prepare buffer for indices
	indexBuffer =
		HardwareBufferManager::getSingleton().createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			3*numFaces,
			HardwareBuffer::HBU_STATIC, true);
	unsigned short *faceVertexIndices = (unsigned short*)
		indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD);
	for(y=0 ; y<complexity ; y++) {
		for(int x=0 ; x<complexity ; x++) {
			unsigned short *twoface = faceVertexIndices + (y*complexity+x)*2*3;
			int p0 = y*(complexity+1) + x ;
			int p1 = y*(complexity+1) + x + 1 ;
			int p2 = (y+1)*(complexity+1) + x ;
			int p3 = (y+1)*(complexity+1) + x + 1 ;
			twoface[0]=p2; //first tri
			twoface[1]=p1;
			twoface[2]=p0;
			twoface[3]=p2; //second tri
			twoface[4]=p3;
			twoface[5]=p1;
		}
	}
	indexBuffer->unlock();
	// Set index buffer for this submesh
	subMesh->indexData->indexBuffer = indexBuffer;
	subMesh->indexData->indexStart = 0;
	subMesh->indexData->indexCount = 3*numFaces;

	/*	prepare vertex positions
	 *	note - we use 3 vertex buffers, since algorighm uses two last phases
	 *	to calculate the next one
	 */
	for(b=0;b<3;b++) {
		vertexBuffers[b] = new float[numVertices * 3] ;
		for(y=0;y<=complexity;y++) {
			for(x=0;x<=complexity;x++) {
				int numPoint = y*(complexity+1) + x ;
				float* vertex = vertexBuffers[b] + 3*numPoint ;
				vertex[0]=(float)(x) / (float)(complexity) * (float) planeSize ;
				vertex[1]= 0 ; // rand() % 30 ;
				vertex[2]=(float)(y) / (float)(complexity) * (float) planeSize ;
			}
		}
	}

	AxisAlignedBox meshBounds(0,0,0,
		planeSize,0, planeSize);
	mesh->_setBounds(meshBounds);

	currentBuffNumber = 0 ;
	posVertexBuffer->writeData(0,
		posVertexBuffer->getSizeInBytes(), // size
		vertexBuffers[currentBuffNumber], // source
		true); // discard?

    mesh->load();
    mesh->touch();
}
Beispiel #21
0
    //---------------------------------------------------------------------
    void PrefabFactory::createSphere(Mesh* mesh)
    {
        // sphere creation code taken from the DeferredShading sample, originally from the wiki
        SubMesh *pSphereVertex = mesh->createSubMesh();

        const int NUM_SEGMENTS = 16;
        const int NUM_RINGS = 16;
        const Real SPHERE_RADIUS = 50.0;

        mesh->sharedVertexData = OGRE_NEW VertexData();
        VertexData* vertexData = mesh->sharedVertexData;

        // define the vertex format
        VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
        size_t currOffset = 0;
        // positions
        vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
        currOffset += VertexElement::getTypeSize(VET_FLOAT3);
        // normals
        vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
        currOffset += VertexElement::getTypeSize(VET_FLOAT3);
        // two dimensional texture coordinates
        vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

        // allocate the vertex buffer
        vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1);
        HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
        VertexBufferBinding* binding = vertexData->vertexBufferBinding;
        binding->setBinding(0, vBuf);
        float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

        // allocate index buffer
        pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1);
        pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
        HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
        unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

        float fDeltaRingAngle = (Math::PI / NUM_RINGS);
        float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS);
        unsigned short wVerticeIndex = 0 ;

        // Generate the group of rings for the sphere
        for( int ring = 0; ring <= NUM_RINGS; ring++ ) {
            float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle);
            float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle);

            // Generate the group of segments for the current ring
            for(int seg = 0; seg <= NUM_SEGMENTS; seg++) {
                float x0 = r0 * sinf(seg * fDeltaSegAngle);
                float z0 = r0 * cosf(seg * fDeltaSegAngle);

                // Add one vertex to the strip which makes up the sphere
                *pVertex++ = x0;
                *pVertex++ = y0;
                *pVertex++ = z0;

                Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
                *pVertex++ = vNormal.x;
                *pVertex++ = vNormal.y;
                *pVertex++ = vNormal.z;

                *pVertex++ = (float) seg / (float) NUM_SEGMENTS;
                *pVertex++ = (float) ring / (float) NUM_RINGS;

                if (ring != NUM_RINGS) {
                    // each vertex (except the last) has six indicies pointing to it
                    *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
                    *pIndices++ = wVerticeIndex;
                    *pIndices++ = wVerticeIndex + NUM_SEGMENTS;
                    *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
                    *pIndices++ = wVerticeIndex + 1;
                    *pIndices++ = wVerticeIndex;
                    wVerticeIndex ++;
                }
            }; // end for seg
        } // end for ring

        // Unlock
        vBuf->unlock();
        iBuf->unlock();
        // Generate face list
        pSphereVertex->useSharedVertices = true;

        // the original code was missing this line:
        mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS),
            Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false );

        mesh->_setBoundingSphereRadius(SPHERE_RADIUS);
    }
    //---------------------------------------------------------------------
    void BorderPanelOverlayElement::_restoreManualHardwareResources()
    {
        if(!mInitialised)
            return;

        PanelOverlayElement::_restoreManualHardwareResources();

        // Vertex data

        VertexDeclaration* decl = mRenderOp2.vertexData->vertexDeclaration;

        // Vertex buffer #1, position
        HardwareVertexBufferSharedPtr vbuf =
            HardwareBufferManager::getSingleton().createVertexBuffer(
                decl->getVertexSize(POSITION_BINDING), 
                mRenderOp2.vertexData->vertexCount,
                HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        // bind position
        VertexBufferBinding* binding = mRenderOp2.vertexData->vertexBufferBinding;
        binding->setBinding(POSITION_BINDING, vbuf);

        // Vertex buffer #2, texcoords
        vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                decl->getVertexSize(TEXCOORD_BINDING), 
                mRenderOp2.vertexData->vertexCount,
                HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
        // bind texcoord
        binding->setBinding(TEXCOORD_BINDING, vbuf);


        // Index data

        /* Each cell is
            0-----2
            |    /|
            |  /  |
            |/    |
            1-----3
        */
        mRenderOp2.indexData->indexBuffer =
            HardwareBufferManager::getSingleton().createIndexBuffer(
                HardwareIndexBuffer::IT_16BIT, 
                mRenderOp2.indexData->indexCount, 
                HardwareBuffer::HBU_STATIC_WRITE_ONLY);

        ushort* pIdx = static_cast<ushort*>(
            mRenderOp2.indexData->indexBuffer->lock(
                0, 
                mRenderOp2.indexData->indexBuffer->getSizeInBytes(), 
                HardwareBuffer::HBL_DISCARD) );

        for (ushort cell = 0; cell < 8; ++cell)
        {
            ushort base = cell * 4;
            *pIdx++ = base;
            *pIdx++ = base + 1;
            *pIdx++ = base + 2;

            *pIdx++ = base + 2;
            *pIdx++ = base + 1;
            *pIdx++ = base + 3;
        }

        mRenderOp2.indexData->indexBuffer->unlock();
    }
Beispiel #23
0
//---------------------------------------------------------------------
void TangentSpaceCalc::insertTangents(Result& res,
                                      VertexElementSemantic targetSemantic, unsigned short sourceTexCoordSet,
                                      unsigned short index)
{
    // Make a new tangents semantic or find an existing one
    VertexDeclaration *vDecl = mVData->vertexDeclaration ;
    VertexBufferBinding *vBind = mVData->vertexBufferBinding ;

    const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index);
    bool needsToBeCreated = false;
    VertexElementType tangentsType = mStoreParityInW ? VET_FLOAT4 : VET_FLOAT3;

    if (!tangentsElem)
    {   // no tex coords with index 1
        needsToBeCreated = true ;
    }
    else if (tangentsElem->getType() != tangentsType)
    {
        //  buffer exists, but not 3D
        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                    "Target semantic set already exists but is not of the right size, therefore "
                    "cannot contain tangents. You should delete this existing entry first. ",
                    "TangentSpaceCalc::insertTangents");
    }

    HardwareVertexBufferSharedPtr targetBuffer, origBuffer;
    unsigned char* pSrc = NULL;

    if (needsToBeCreated)
    {
        // To be most efficient with our vertex streams,
        // tack the new tangents onto the same buffer as the
        // source texture coord set
        const VertexElement* prevTexCoordElem =
            mVData->vertexDeclaration->findElementBySemantic(
                VES_TEXTURE_COORDINATES, sourceTexCoordSet);
        if (!prevTexCoordElem)
        {
            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
                        "Cannot locate the first texture coordinate element to "
                        "which to append the new tangents.",
                        "Mesh::orgagniseTangentsBuffer");
        }
        // Find the buffer associated with  this element
        origBuffer = mVData->vertexBufferBinding->getBuffer(
                         prevTexCoordElem->getSource());
        // Now create a new buffer, which includes the previous contents
        // plus extra space for the 3D coords
        targetBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
                           origBuffer->getVertexSize() + VertexElement::getTypeSize(tangentsType),
                           origBuffer->getNumVertices(),
                           origBuffer->getUsage(),
                           origBuffer->hasShadowBuffer() );
        // Add the new element
        tangentsElem = &(vDecl->addElement(
                             prevTexCoordElem->getSource(),
                             origBuffer->getVertexSize(),
                             tangentsType,
                             targetSemantic,
                             index));
        // Set up the source pointer
        pSrc = static_cast<unsigned char*>(
                   origBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
        // Rebind the new buffer
        vBind->setBinding(prevTexCoordElem->getSource(), targetBuffer);
    }
    else
    {
        // space already there
        origBuffer = mVData->vertexBufferBinding->getBuffer(
                         tangentsElem->getSource());
        targetBuffer = origBuffer;
    }


    unsigned char* pDest = static_cast<unsigned char*>(
                               targetBuffer->lock(HardwareBuffer::HBL_DISCARD));
    size_t origVertSize = origBuffer->getVertexSize();
    size_t newVertSize = targetBuffer->getVertexSize();
    for (size_t v = 0; v < origBuffer->getNumVertices(); ++v)
    {
        if (needsToBeCreated)
        {
            // Copy original vertex data as well
            memcpy(pDest, pSrc, origVertSize);
            pSrc += origVertSize;
        }
        // Write in the tangent
        float* pTangent;
        tangentsElem->baseVertexPointerToElement(pDest, &pTangent);
        VertexInfo& vertInfo = mVertexArray[v];
        *pTangent++ = vertInfo.tangent.x;
        *pTangent++ = vertInfo.tangent.y;
        *pTangent++ = vertInfo.tangent.z;
        if (mStoreParityInW)
            *pTangent++ = (float)vertInfo.parity;

        // Next target vertex
        pDest += newVertSize;

    }
    targetBuffer->unlock();

    if (needsToBeCreated)
    {
        origBuffer->unlock();
    }
}
Beispiel #24
0
void MovableText::_setupGeometry()
{
    assert(mpFont);
    assert(!mpMaterial.isNull());

    unsigned int vertexCount = 0;

    //count letters to determine how many vertices are needed
    std::string::iterator i = mCaption.begin();
    std::string::iterator iend = mCaption.end();
    for ( ; i != iend; ++i )
    {
        if ((*i != ' ') && (*i != '\n'))
        {
            vertexCount += 6;
        }
    }

    if (mRenderOp.vertexData)
    {
        delete mRenderOp.vertexData;
        mRenderOp.vertexData = NULL;
        mUpdateColors = true;
    }

    if (mCaption.empty())
    {
        return;
    }

    if (!mRenderOp.vertexData)
        mRenderOp.vertexData = new VertexData();

    mRenderOp.indexData = 0;
    mRenderOp.vertexData->vertexStart = 0;
    mRenderOp.vertexData->vertexCount = vertexCount;
    mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
    mRenderOp.useIndexes = false;

    VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
    VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
    size_t offset = 0;

    // create/bind positions/tex.ccord. buffer
    if (!decl->findElementBySemantic(VES_POSITION))
        decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);

    offset += VertexElement::getTypeSize(VET_FLOAT3);

    if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
        decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2,
                         Ogre::VES_TEXTURE_COORDINATES, 0);

    HardwareVertexBufferSharedPtr ptbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(POS_TEX_BINDING),
            mRenderOp.vertexData->vertexCount,
            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    bind->setBinding(POS_TEX_BINDING, ptbuf);

    // Colours - store these in a separate buffer because they change less often
    if (!decl->findElementBySemantic(VES_DIFFUSE))
        decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);

    HardwareVertexBufferSharedPtr cbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(COLOUR_BINDING),
            mRenderOp.vertexData->vertexCount,
            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    bind->setBinding(COLOUR_BINDING, cbuf);

    float *pPCBuff =
        static_cast<float*> (ptbuf->lock(HardwareBuffer::HBL_DISCARD));

    Real spaceWidth = mSpaceWidth;
    // Derive space width from a capital A
    if (spaceWidth == 0)
        spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;

    float total_height = mCharHeight;
    float total_width = 0.0f;
    float current_width = 0.0f;
    i = mCaption.begin();
    iend = mCaption.end();
    for ( ; i != iend; ++i )
    {
        if (*i == '\n')
        {
            total_height += mCharHeight + 0.01;

            if ( current_width > total_width )
            {
                total_width = current_width;
                current_width = 0.0;
            }
        }
        else
        {
            current_width += mpFont->getGlyphAspectRatio(*i) * mCharHeight * 2.0;
        }
    }

    if ( current_width > total_width )
    {
        total_width = current_width;
    }

    float top = 0.0f;
    switch (mVerticalAlignment)
    {
    case MovableText::V_ABOVE:
        top = total_height * 2;
        break;
    case MovableText::V_CENTER:
        top = 0.5 * total_height * 2;
        break;
    case MovableText::V_BELOW:
        top = 0.0f;
        break;
    }

    float starting_left = 0.0f;
    switch (mHorizontalAlignment)
    {
    case MovableText::H_LEFT:
        starting_left = 0.0f;
        break;
    case MovableText::H_CENTER:
        starting_left = -total_width / 2.0f;
        break;
    }

    float left = starting_left;

    bool newLine = true;
    Real len = 0.0f;
    // for calculation of AABB
    Ogre::Vector3 min(9999999.0f), max(-9999999.0f), currPos(0.0f);
    Ogre::Real maxSquaredRadius = -99999999.0f;
    float largestWidth = 0.0f;
    for (i = mCaption.begin(); i != iend; ++i)
    {
        if (newLine)
        {
            len = 0.0f;
            for (String::iterator j = i; j != iend && *j != '\n'; j++)
            {
                if (*j == ' ')
                    len += spaceWidth;
                else
                    len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0;
            }
            newLine = false;
        }

        if (*i == '\n')
        {
            left = starting_left;
            top -= mCharHeight * 2.0;
            newLine = true;
            continue;
        }

        if (*i == ' ')
        {
            // Just leave a gap, no tris
            left += spaceWidth;
            continue;
        }

        Real horiz_height = mpFont->getGlyphAspectRatio(*i);
        Real u1, u2, v1, v2;
        Ogre::Font::UVRect utmp;
        utmp = mpFont->getGlyphTexCoords(*i);
        u1 = utmp.left;
        u2 = utmp.right;
        v1 = utmp.top;
        v2 = utmp.bottom;

        // each vert is (x, y, z, u, v)
        //-------------------------------------------------------------------------------------
        // First tri
        //
        // Upper left
        currPos = Ogre::Vector3(left, top, 0.0);

        *pPCBuff++ = currPos.x;
        *pPCBuff++ = currPos.y;
        *pPCBuff++ = currPos.z;
        *pPCBuff++ = u1;
        *pPCBuff++ = v1;

        // Deal with bounds


        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        top -= mCharHeight * 2.0;

        // Bottom left
        currPos = Ogre::Vector3(left, top, 0.0);
        *pPCBuff++ = currPos.x;
        *pPCBuff++ = currPos.y;
        *pPCBuff++ = currPos.z;
        *pPCBuff++ = u1;
        *pPCBuff++ = v2;

        // Deal with bounds
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        top += mCharHeight * 2.0;
        left += horiz_height * mCharHeight * 2.0;

        // Top right
        currPos = Ogre::Vector3(left, top, 0.0);
        *pPCBuff++ = currPos.x;
        *pPCBuff++ = currPos.y;
        *pPCBuff++ = currPos.z;
        *pPCBuff++ = u2;
        *pPCBuff++ = v1;
        //-------------------------------------------------------------------------------------

        // Deal with bounds
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        //-------------------------------------------------------------------------------------
        // Second tri
        //
        // Top right (again)
        currPos = Ogre::Vector3(left, top, 0.0);
        *pPCBuff++ = currPos.x;
        *pPCBuff++ = currPos.y;
        *pPCBuff++ = currPos.z;
        *pPCBuff++ = u2;
        *pPCBuff++ = v1;

        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        top -= mCharHeight * 2.0;
        left -= horiz_height * mCharHeight * 2.0;

        // Bottom left (again)
        currPos = Ogre::Vector3(left, top, 0.0);
        *pPCBuff++ = currPos.x;
        *pPCBuff++ = currPos.y;
        *pPCBuff++ = currPos.z;
        *pPCBuff++ = u1;
        *pPCBuff++ = v2;

        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        left += horiz_height * mCharHeight * 2.0;

        // Bottom right
        currPos = Ogre::Vector3(left, top, 0.0);
        *pPCBuff++ = currPos.x;
        *pPCBuff++ = currPos.y;
        *pPCBuff++ = currPos.z;
        *pPCBuff++ = u2;
        *pPCBuff++ = v2;
        //-------------------------------------------------------------------------------------
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        // Go back up with top
        top += mCharHeight * 2.0;

        float currentWidth = (left + 1) / 2 - 0;
        if (currentWidth > largestWidth)
            largestWidth = currentWidth;
    }

    // Unlock vertex buffer
    ptbuf->unlock();

    // update AABB/Sphere radius
    mAABB = Ogre::AxisAlignedBox(min, max);
    mRadius = Ogre::Math::Sqrt(maxSquaredRadius);

    if (mUpdateColors)
        this->_updateColors();

    mNeedUpdate = false;
}
    //------------------------------------------------------------------------------------------------
    void DebugContactText::_setupGeometry()
    {
        assert(mpFont);
        assert(!mpMaterial.isNull());

        unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6);

        if (mRenderOp.vertexData)
        {
            // Removed this test as it causes problems when replacing a caption
            // of the same size: replacing "Hello" with "hello"
            // as well as when changing the text alignment
            //if (mRenderOp.vertexData->vertexCount != vertexCount)
            {
                delete mRenderOp.vertexData;
                mRenderOp.vertexData = NULL;
                mUpdateColors = true;
            }
        }

        if (!mRenderOp.vertexData)
            mRenderOp.vertexData = new VertexData();

        mRenderOp.indexData = 0;
        mRenderOp.vertexData->vertexStart = 0;
        mRenderOp.vertexData->vertexCount = vertexCount;
        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 
        mRenderOp.useIndexes = false; 

        VertexDeclaration  *decl = mRenderOp.vertexData->vertexDeclaration;
        VertexBufferBinding   *bind = mRenderOp.vertexData->vertexBufferBinding;
        size_t offset = 0;

        // create/bind positions/tex.ccord. buffer
        if (!decl->findElementBySemantic(VES_POSITION))
            decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);

        offset += VertexElement::getTypeSize(VET_FLOAT3);

        if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
            decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);

        HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
            mRenderOp.vertexData->vertexCount,
            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
        bind->setBinding(POS_TEX_BINDING, ptbuf);

        // Colours - store these in a separate buffer because they change less often
        if (!decl->findElementBySemantic(VES_DIFFUSE))
            decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);

        HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
            mRenderOp.vertexData->vertexCount,
            HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
        bind->setBinding(COLOUR_BINDING, cbuf);

        size_t charlen = mCaption.size();
        Real *pPCBuff = static_cast<Real*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));

        float largestWidth = 0;
        float left = 0 * 2.0 - 1.0;
        float top = -((0 * 2.0) - 1.0);

        // Derive space width from a capital A
        if (mSpaceWidth == 0)
            mSpaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2;

        // for calculation of AABB
        Ogre::Vector3 min, max, currPos;
        Ogre::Real maxSquaredRadius;
        bool first = true;

        // Use iterator
        String::iterator i, iend;
        iend = mCaption.end();
        bool newLine = true;
        Real len = 0.0f;

        if(mVerticalAlignment == DebugContactText::V_ABOVE)
        {
            // Raise the first line of the caption
            top += mCharHeight;
            for (i = mCaption.begin(); i != iend; ++i)
            {
                if (*i == '\n')
                    top += mCharHeight * 2.0f;
            }
        }

        for (i = mCaption.begin(); i != iend; ++i)
        {
            if (newLine)
            {
                len = 0.0f;
                for (String::iterator j = i; j != iend && *j != '\n'; j++)
                {
                    if (*j == ' ')
                        len += mSpaceWidth;
                    else 
                        len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0f;
                }
                newLine = false;
            }

            if (*i == '\n')
            {
                left = 0 * 2.0 - 1.0;
                top -= mCharHeight * 2.0f;
                newLine = true;
                continue;
            }

            if (*i == ' ')
            {
                // Just leave a gap, no tris
                left += mSpaceWidth;
                // Also reduce tri count
                mRenderOp.vertexData->vertexCount -= 6;
                continue;
            }

            Real horiz_height = mpFont->getGlyphAspectRatio(*i);
            
            //mpFont->getGlyphTexCoords(*i, u1, v1, u2, v2);
            const Font::UVRect &uvRect = mpFont->getGlyphTexCoords(*i);
            const Real u1 = uvRect.left; 
            const Real u2 = uvRect.right; 
            const Real v1 = uvRect.top; 
            const Real v2 = uvRect.bottom; 

            // each vert is (x, y, z, u, v)
            //-------------------------------------------------------------------------------------
            // First tri
            //
            // Upper left
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                *pPCBuff++ = left;
            else
                *pPCBuff++ = left - (len / 2);
            *pPCBuff++ = top;
            *pPCBuff++ = -1.0;
            *pPCBuff++ = u1;
            *pPCBuff++ = v1;

            // Deal with bounds
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                currPos = Ogre::Vector3(left, top, -1.0);
            else
                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
            if (first)
            {
                min = max = currPos;
                maxSquaredRadius = currPos.squaredLength();
                first = false;
            }
            else
            {
                min.makeFloor(currPos);
                max.makeCeil(currPos);
                maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
            }

            top -= mCharHeight * 2.0f;

            // Bottom left
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                *pPCBuff++ = left;
            else
                *pPCBuff++ = left - (len / 2);
            *pPCBuff++ = top;
            *pPCBuff++ = -1.0;
            *pPCBuff++ = u1;
            *pPCBuff++ = v2;

            // Deal with bounds
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                currPos = Ogre::Vector3(left, top, -1.0);
            else
                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

            top += mCharHeight * 2.0f;
            left += horiz_height * mCharHeight * 2.0f;

            // Top right
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                *pPCBuff++ = left;
            else
                *pPCBuff++ = left - (len / 2);
            *pPCBuff++ = top;
            *pPCBuff++ = -1.0;
            *pPCBuff++ = u2;
            *pPCBuff++ = v1;
            //-------------------------------------------------------------------------------------

            // Deal with bounds
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                currPos = Ogre::Vector3(left, top, -1.0);
            else
                currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

            //-------------------------------------------------------------------------------------
            // Second tri
            //
            // Top right (again)
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                *pPCBuff++ = left;
            else
                *pPCBuff++ = left - (len / 2);
            *pPCBuff++ = top;
            *pPCBuff++ = -1.0;
            *pPCBuff++ = u2;
            *pPCBuff++ = v1;

            currPos = Ogre::Vector3(left, top, -1.0);
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

            top -= mCharHeight * 2.0f;
            left -= horiz_height  * mCharHeight * 2.0f;

            // Bottom left (again)
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                *pPCBuff++ = left;
            else
                *pPCBuff++ = left - (len / 2);
            *pPCBuff++ = top;
            *pPCBuff++ = -1.0;
            *pPCBuff++ = u1;
            *pPCBuff++ = v2;

            currPos = Ogre::Vector3(left, top, -1.0);
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

            left += horiz_height  * mCharHeight * 2.0f;

            // Bottom right
            if(mHorizontalAlignment == DebugContactText::H_LEFT)
                *pPCBuff++ = left;
            else
                *pPCBuff++ = left - (len / 2);
            *pPCBuff++ = top;
            *pPCBuff++ = -1.0;
            *pPCBuff++ = u2;
            *pPCBuff++ = v2;
            //-------------------------------------------------------------------------------------

            currPos = Ogre::Vector3(left, top, -1.0);
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

            // Go back up with top
            top += mCharHeight * 2.0f;

            float currentWidth = (left + 1)/2 - 0;
            if (currentWidth > largestWidth)
                largestWidth = currentWidth;
        }

        // Unlock vertex buffer
        ptbuf->unlock();

        // update AABB/Sphere radius
        mAABB = Ogre::AxisAlignedBox(min, max);
        mRadius = Ogre::Math::Sqrt(maxSquaredRadius);

        if (mUpdateColors)
            this->_updateColors();

        mNeedUpdate = false;
    }
    //---------------------------------------------------------------------
    void BorderPanelOverlayElement::initialise(void)
    {
		bool init = !mInitialised;

        PanelOverlayElement::initialise();

        // superclass will handle the interior panel area 

        if (init)
		{
			// Setup render op in advance
			mRenderOp2.vertexData = OGRE_NEW VertexData();
			mRenderOp2.vertexData->vertexCount = 4 * 8; // 8 cells, can't necessarily share vertices cos
														// texcoords may differ
			mRenderOp2.vertexData->vertexStart = 0;

			// Vertex declaration
			VertexDeclaration* decl = mRenderOp2.vertexData->vertexDeclaration;
			// Position and texture coords each have their own buffers to allow
			// each to be edited separately with the discard flag
			decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
			decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

			// Vertex buffer #1, position
			HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton()
				.createVertexBuffer(
					decl->getVertexSize(POSITION_BINDING), 
					mRenderOp2.vertexData->vertexCount,
					HardwareBuffer::HBU_STATIC_WRITE_ONLY);
			// bind position
			VertexBufferBinding* binding = mRenderOp2.vertexData->vertexBufferBinding;
			binding->setBinding(POSITION_BINDING, vbuf);

			// Vertex buffer #2, texcoords
			vbuf = HardwareBufferManager::getSingleton()
				.createVertexBuffer(
					decl->getVertexSize(TEXCOORD_BINDING), 
					mRenderOp2.vertexData->vertexCount,
					HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
			// bind texcoord
			binding->setBinding(TEXCOORD_BINDING, vbuf);

			mRenderOp2.operationType = RenderOperation::OT_TRIANGLE_LIST;
			mRenderOp2.useIndexes = true;
			// Index data
			mRenderOp2.indexData = OGRE_NEW IndexData();
			mRenderOp2.indexData->indexCount = 8 * 6;
			mRenderOp2.indexData->indexStart = 0;
            mRenderOp2.useGlobalInstancingVertexBufferIsAvailable = false;

			/* Each cell is
				0-----2
				|    /|
				|  /  |
				|/    |
				1-----3
			*/
			mRenderOp2.indexData->indexBuffer = HardwareBufferManager::getSingleton().
				createIndexBuffer(
					HardwareIndexBuffer::IT_16BIT, 
					mRenderOp2.indexData->indexCount, 
					HardwareBuffer::HBU_STATIC_WRITE_ONLY);

			ushort* pIdx = static_cast<ushort*>(
				mRenderOp2.indexData->indexBuffer->lock(
					0, 
					mRenderOp2.indexData->indexBuffer->getSizeInBytes(), 
					HardwareBuffer::HBL_DISCARD) );

			for (ushort cell = 0; cell < 8; ++cell)
			{
				ushort base = cell * 4;
				*pIdx++ = base;
				*pIdx++ = base + 1;
				*pIdx++ = base + 2;

				*pIdx++ = base + 2;
				*pIdx++ = base + 1;
				*pIdx++ = base + 3;
			}

			mRenderOp2.indexData->indexBuffer->unlock();

			// Create sub-object for rendering border
			mBorderRenderable = OGRE_NEW BorderRenderable(this);

			mInitialised = true;
		}
    }
Beispiel #27
0
Airbrake::Airbrake(char* basename, int num, node_t *ndref, node_t *ndx, node_t *ndy, node_t *nda, Vector3 pos, float width, float length, float maxang, char* texname, float tx1, float ty1, float tx2, float ty2, float lift_coef)
{
	snode=0;
	noderef=ndref;
	nodex=ndx;
	nodey=ndy;
	nodea=nda;
	offset=pos;
	maxangle=maxang;
	area=width*length*lift_coef;
	char meshname[256];
	sprintf(meshname, "airbrakemesh-%s-%i", basename, num);
	/// Create the mesh via the MeshManager
    msh = MeshManager::getSingleton().createManual(meshname, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

	union
	{
		float *vertices;
		CoVertice_t *covertices;
	};

    /// Create submesh
    SubMesh* sub = msh->createSubMesh();

	//materials
	sub->setMaterialName(texname);

    /// Define the vertices
    size_t nVertices = 4;
    size_t vbufCount = (2*3+2)*nVertices;
	vertices=(float*)malloc(vbufCount*sizeof(float));

	//textures coordinates
	covertices[0].texcoord=Vector2(tx1, ty1);
	covertices[1].texcoord=Vector2(tx2, ty1);
	covertices[2].texcoord=Vector2(tx2, ty2);
	covertices[3].texcoord=Vector2(tx1, ty2);

    /// Define triangles
    /// The values in this table refer to vertices in the above table
    size_t ibufCount = 3*4;
    unsigned short *faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short));
	faces[0]=0; faces[1]=1; faces[2]=2;
	faces[3]=0; faces[4]=2; faces[5]=3;
	faces[6]=0; faces[7]=2; faces[8]=1;
	faces[9]=0; faces[10]=3; faces[11]=2;

	//set coords
	covertices[0].vertex=Vector3(0,0,0);
	covertices[1].vertex=Vector3(width,0,0);
	covertices[2].vertex=Vector3(width,0,length);
	covertices[3].vertex=Vector3(0,0,length);

	covertices[0].normal=Vector3(0,1,0);
	covertices[1].normal=Vector3(0,1,0);
	covertices[2].normal=Vector3(0,1,0);
	covertices[3].normal=Vector3(0,1,0);

    /// Create vertex data structure for vertices shared between submeshes
    msh->sharedVertexData = new VertexData();
    msh->sharedVertexData->vertexCount = nVertices;

    /// Create declaration (memory format) of vertex data
    VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
//        decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE);
//        offset += VertexElement::getTypeSize(VET_FLOAT3);
    decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    /// Allocate vertex buffer of the requested number of vertices (vertexCount)
    /// and bytes per vertex (offset)
    HardwareVertexBufferSharedPtr vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    /// Upload the vertex data to the card
    vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

    /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, vbuf);

	/// Allocate index buffer of the requested number of vertices (ibufCount)
    HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton().
        createIndexBuffer(
            HardwareIndexBuffer::IT_16BIT,
            ibufCount,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    /// Upload the index data to the card
    faceibuf->writeData(0, faceibuf->getSizeInBytes(), faces, true);

    /// Set parameters of the submesh
    sub->useSharedVertices = true;
    sub->indexData->indexBuffer = faceibuf;
    sub->indexData->indexCount = ibufCount;
    sub->indexData->indexStart = 0;

    /// Set bounding information (for culling)
    msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true);
    //msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1));

    /// Notify Mesh object that it has been loaded
	msh->load();

	// create the entity and scene node
	char entname[256];
	sprintf(entname, "airbrakenode-%s-%i", basename, num);
	ec = gEnv->sceneManager->createEntity(entname, meshname);
	snode = gEnv->sceneManager->getRootSceneNode()->createChildSceneNode();
	snode->attachObject(ec);

	updatePosition(0.0);

	free (vertices);
	free (faces);
}
void VolumeRenderable::initialise()
{
	// Create geometry
	size_t nvertices = mSlices*4; // n+1 planes
	size_t elemsize = 3*3;
	size_t dsize = elemsize*nvertices;
	size_t x;
	
	Ogre::IndexData *idata = new Ogre::IndexData();
	Ogre::VertexData *vdata = new Ogre::VertexData();
	
	// Create  structures
	float *vertices = new float[dsize];
	
	float coords[4][2] = {
		{0.0f, 0.0f},
		{0.0f, 1.0f},
		{1.0f, 0.0f},
		{1.0f, 1.0f}
	};
	for(x=0; x<mSlices; x++) 
	{
		for(size_t y=0; y<4; y++)
		{
			float xcoord = coords[y][0]-0.5f;
			float ycoord = coords[y][1]-0.5f;
			float zcoord = -((float)x/(float)(mSlices-1)  - 0.5f);
			// 1.0f .. a/(a+1)
			// coordinate
			vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f);
			vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f);
			vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f);
			// normal
			vertices[x*4*elemsize+y*elemsize+3] = 0.0f;
			vertices[x*4*elemsize+y*elemsize+4] = 0.0f;
			vertices[x*4*elemsize+y*elemsize+5] = 1.0f;
			// tex
			vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f);
			vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f);
			vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f);
		} 
	}
	unsigned short *faces = new unsigned short[mSlices*6];
	for(x=0; x<mSlices; x++) 
	{
		faces[x*6+0] = x*4+0;
		faces[x*6+1] = x*4+1;
		faces[x*6+2] = x*4+2;
		faces[x*6+3] = x*4+1;
		faces[x*6+4] = x*4+2;
		faces[x*6+5] = x*4+3;
	}
	// Setup buffers
	vdata->vertexStart = 0;
	vdata->vertexCount = nvertices;
	
	VertexDeclaration* decl = vdata->vertexDeclaration;
	VertexBufferBinding* bind = vdata->vertexBufferBinding;

	size_t offset = 0;
	decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
	offset += VertexElement::getTypeSize(VET_FLOAT3);
	decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES);
	offset += VertexElement::getTypeSize(VET_FLOAT3);

	HardwareVertexBufferSharedPtr vbuf = 
	HardwareBufferManager::getSingleton().createVertexBuffer(
		offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	bind->setBinding(0, vbuf);

	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
	
	HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
		createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT, 
			mSlices*6, 
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	idata->indexBuffer = ibuf;
	idata->indexCount = mSlices*6;
	idata->indexStart = 0;
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

	// Delete temporary buffers
	delete [] vertices;
	delete [] faces;
	
	// Now make the render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
	mRenderOp.indexData = idata;
	mRenderOp.vertexData = vdata;
	mRenderOp.useIndexes = true;
	
	 // Create a brand new private material
	if (!ResourceGroupManager::getSingleton().resourceGroupExists("VolumeRenderable"))
	{
		ResourceGroupManager::getSingleton().createResourceGroup("VolumeRenderable");
	}
	MaterialPtr material = 
		MaterialManager::getSingleton().create(mTexture, "VolumeRenderable",
			false, 0); // Manual, loader

	// Remove pre-created technique from defaults
	material->removeAllTechniques();
	
	// Create a techinique and a pass and a texture unit
 	Technique * technique = material->createTechnique();
	Pass * pass = technique->createPass();
	TextureUnitState * textureUnit = pass->createTextureUnitState();
	
	// Set pass parameters
	pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	pass->setDepthWriteEnabled(false);
	pass->setCullingMode(CULL_NONE);
	pass->setLightingEnabled(false);
	
	// Set texture unit parameters
	textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
	textureUnit->setTextureName(mTexture, TEX_TYPE_3D);
	textureUnit->setTextureFiltering(TFO_TRILINEAR);
	
	mUnit = textureUnit;
	mMaterial = material;
}
    size_t MeshBuilder::generateBuffers(RenderOperation &operation)
    {
        // Early out if nothing to do.
        if (mIndices.size() == 0)
        {
            return 0;
        }

        // Prepare vertex buffer
        operation.operationType = RenderOperation::OT_TRIANGLE_LIST;

        operation.vertexData = OGRE_NEW VertexData();
        operation.vertexData->vertexCount = mVertices.size();
        operation.vertexData->vertexStart = 0;
    
        VertexDeclaration *decl = operation.vertexData->vertexDeclaration;
        VertexBufferBinding *bind = operation.vertexData->vertexBufferBinding;
    
        size_t offset = 0;

        // Add vertex-positions to the buffer
        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
        offset += VertexElement::getTypeSize(VET_FLOAT3);
    
        // Add vertex-normals to the buffer
        decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    
        HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
            decl->getVertexSize(MAIN_BINDING),
            operation.vertexData->vertexCount,
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);
    
        bind->setBinding(0, vbuf);

        float* vertices = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
    
        VecVertex::const_iterator endVertices = mVertices.end();
        for (VecVertex::const_iterator iter = mVertices.begin(); iter != endVertices; ++iter)
        {
            *vertices++ = (float)iter->x;
            *vertices++ = (float)iter->y;
            *vertices++ = (float)iter->z;
            *vertices++ = (float)iter->nX;
            *vertices++ = (float)iter->nY;
            *vertices++ = (float)iter->nZ;
        }

        vbuf->unlock();
    
        // Get Indexarray
        operation.indexData = OGRE_NEW IndexData();
        operation.indexData->indexCount = mIndices.size();
        operation.indexData->indexStart = 0;
    
        VecIndices::const_iterator endIndices = mIndices.end();
        if (operation.indexData->indexCount > USHRT_MAX)
        {
            operation.indexData->indexBuffer =
                HardwareBufferManager::getSingleton().createIndexBuffer(
                HardwareIndexBuffer::IT_32BIT,
                operation.indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

            unsigned int* indices = static_cast<unsigned int*>(
                operation.indexData->indexBuffer->lock(0,
                    operation.indexData->indexBuffer->getSizeInBytes(),
                    HardwareBuffer::HBL_DISCARD));
    
            for (VecIndices::const_iterator iter = mIndices.begin(); iter != endIndices; ++iter)
            {
                *indices++ = *iter;
            }
        }
        else
        {
            operation.indexData->indexBuffer =
                HardwareBufferManager::getSingleton().createIndexBuffer(
                HardwareIndexBuffer::IT_16BIT,
                operation.indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);

            unsigned short* indices = static_cast<unsigned short*>(
                operation.indexData->indexBuffer->lock(0,
                    operation.indexData->indexBuffer->getSizeInBytes(),
                    HardwareBuffer::HBL_DISCARD));
    
            for (VecIndices::const_iterator iter = mIndices.begin(); iter != endIndices; ++iter)
            {
                *indices++ = (unsigned short)*iter;
            }
        }

        operation.indexData->indexBuffer->unlock();
        return mIndices.size() / 3;
    }
static MeshPtr importObject(QDataStream &stream)
{
    using namespace Ogre;

    QVector4D bbMin, bbMax;
    stream >> bbMin >> bbMax;

    float distance, distanceSquared; // Here's a bug for you: writes "double"'s instead of floats
    stream >> distanceSquared >> distance;

    MeshPtr ogreMesh = MeshManager::getSingleton().createManual("conversion",
                                                               ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    int vertexCount, indexCount;
    stream >> vertexCount >> indexCount;

    VertexData *vertexData = new VertexData();
    ogreMesh->sharedVertexData = vertexData;

    LogManager::getSingleton().logMessage("Reading geometry...");
    VertexDeclaration* decl = vertexData->vertexDeclaration;
    VertexBufferBinding* bind = vertexData->vertexBufferBinding;
    unsigned short bufferId = 0;

    // Information for calculating bounds
    Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE, pos = Vector3::ZERO;
    Real maxSquaredRadius = -1;
    bool firstVertex = true;

    /*
      Create a vertex definition for our buffer
      */
    size_t offset = 0;

    const VertexElement &positionElement = decl->addElement(bufferId, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);

    const VertexElement &normalElement = decl->addElement(bufferId, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);

    // calculate how many vertexes there actually are
    vertexData->vertexCount = vertexCount;

    // Now create the vertex buffer
    HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().
            createVertexBuffer(offset, vertexData->vertexCount,
                               HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

    // Bind it
    bind->setBinding(bufferId, vbuf);

    // Lock it
    unsigned char *pVert = static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
    unsigned char *pVertStart = pVert;

    QVector<float> positions;
    positions.reserve(vertexCount * 3);

    // Iterate over all children (vertexbuffer entries)
    for (int i = 0; i < vertexCount; ++i) {
        float *pFloat;

        QVector4D vertex;
        stream >> vertex;
		vertex.setZ(vertex.z() * -1);

        /* Copy over the position */
        positionElement.baseVertexPointerToElement(pVert, &pFloat);
        *(pFloat++) = (float)vertex.x();
        *(pFloat++) = (float)vertex.y();
        *(pFloat++) = (float)vertex.z();

        positions.append(vertex.x());
        positions.append(vertex.y());
        positions.append(vertex.z());

        /* While we're at it, calculate the bounding sphere */
        pos.x = vertex.x();
        pos.y = vertex.y();
        pos.z = vertex.z();

        if (firstVertex) {
            min = max = pos;
            maxSquaredRadius = pos.squaredLength();
            firstVertex = false;
        } else {
            min.makeFloor(pos);
            max.makeCeil(pos);
            maxSquaredRadius = qMax(pos.squaredLength(), maxSquaredRadius);
        }

        pVert += vbuf->getVertexSize();
    }

    // Set bounds
    const AxisAlignedBox& currBox = ogreMesh->getBounds();
    Real currRadius = ogreMesh->getBoundingSphereRadius();
    if (currBox.isNull())
    {
        //do not pad the bounding box
        ogreMesh->_setBounds(AxisAlignedBox(min, max), false);
        ogreMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredRadius));
    }
    else
    {
        AxisAlignedBox newBox(min, max);
        newBox.merge(currBox);
        //do not pad the bounding box
        ogreMesh->_setBounds(newBox, false);
        ogreMesh->_setBoundingSphereRadius(qMax(Math::Sqrt(maxSquaredRadius), currRadius));
    }

    /*
       Create faces
     */
    // All children should be submeshes
    SubMesh* sm = ogreMesh->createSubMesh();
    sm->setMaterialName("clippingMaterial");
    sm->operationType = RenderOperation::OT_TRIANGLE_LIST;
    sm->useSharedVertices = true;

    // tri list
    sm->indexData->indexCount = indexCount;

    // Allocate space
    HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
            createIndexBuffer(
                HardwareIndexBuffer::IT_16BIT,
                sm->indexData->indexCount,
                HardwareBuffer::HBU_DYNAMIC,
                false);
    sm->indexData->indexBuffer = ibuf;

    unsigned short *pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));

    QVector<EdgeData::Triangle> triangles(indexCount / 3);

    for (int i = 0; i < indexCount / 3; ++i) {
        quint16 i1, i2, i3;

        stream >> i1 >> i2 >> i3;
        *pShort++ = i1;
        *pShort++ = i2;
        *pShort++ = i3;

        triangles[i].vertIndex[0] = i1;
        triangles[i].vertIndex[1] = i2;
        triangles[i].vertIndex[2] = i3;

    }

    /* Recalculate the vertex normals */
    Vector4 *faceNormals = (Vector4*)_aligned_malloc(sizeof(Vector4) * triangles.size(), 16);

    OptimisedUtil *util = OptimisedUtil::getImplementation();
    util->calculateFaceNormals(positions.constData(),
                               triangles.data(),
                               faceNormals,
                               indexCount / 3);

	 // Iterate over all children (vertexbuffer entries)
	pVert = pVertStart;
    for (int i = 0; i < vertexCount; ++i) {
        float *pFloat;

		Vector3 normal = Vector3::ZERO;
		
		int count = 0;

		/* Search for all faces that use this vertex */
		for (int j = 0; j < triangles.size(); ++j) {
			if (triangles[j].vertIndex[0] == i 
				|| triangles[j].vertIndex[1] == i 
				|| triangles[j].vertIndex[2] == i) {
				normal.x += faceNormals[j].x / faceNormals[j].w;
				normal.y += faceNormals[j].y / faceNormals[j].w;
				normal.z += faceNormals[j].z / faceNormals[j].w;
				count++;
			}
		}

		normal.normalise();

        /* Copy over the position */
		normalElement.baseVertexPointerToElement(pVert, &pFloat);
        *(pFloat++) = normal.x;
        *(pFloat++) = normal.y;
        *(pFloat++) = normal.z;
		
        pVert += vbuf->getVertexSize();
    }

    _aligned_free(faceNormals);

    vbuf->unlock();
    ibuf->unlock();

    return ogreMesh;
}