예제 #1
0
void FrameGraphRenderable::fillHardwareBuffers()
{
    Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
    Ogre::Real *vertices = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));

    Ogre::HardwareVertexBufferSharedPtr vcbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(1);
    Ogre::RGBA* pColours = static_cast<Ogre::RGBA*>(vcbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    uint16_t index = 0;
    for (uint16_t i = 0; i < mNumFrames; i++) {
        float x = i * mLineSpace - 1.0f;

        // OgreTime line
        vertices[index +  0] = x;
        vertices[index +  1] = -1;
        vertices[index +  2] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 0.0f, 0.0f), pColours++);		// Color
        vertices[index +  3] = x;
        vertices[index +  4] = -1;
        vertices[index +  5] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 0.0f, 0.0f), pColours++);		// Color

        // BulletTime line
        vertices[index +  6] = x;
        vertices[index +  7] = -1;
        vertices[index +  8] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 1.0f, 0.0f), pColours++);		// Color
        vertices[index +  9] = x;
        vertices[index + 10] = -1;
        vertices[index + 11] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 1.0f, 0.0f), pColours++);		// Color

        // WorldTime line
        vertices[index + 12] = x;
        vertices[index + 13] = -1;
        vertices[index + 14] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 0.0f, 1.0f), pColours++);		// Color
        vertices[index + 15] = x;
        vertices[index + 16] = -1;
        vertices[index + 17] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 0.0f, 1.0f), pColours++);		// Color

        // UnknownTime line
        vertices[index + 18] = x;
        vertices[index + 19] = -1;
        vertices[index + 20] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 1.0f, 1.0f), pColours++);		// Color
        vertices[index + 21] = x;
        vertices[index + 22] = -1;
        vertices[index + 23] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 1.0f, 1.0f), pColours++);		// Color

        index += ValuesPerGraphLine;
    }
    vcbuf->unlock();
    vbuf->unlock();

    mBox.setInfinite();
}
예제 #2
0
void CDynamicLineDrawer::FillHardwareBuffers()
{
	int Size = int(Points.size());

	PrepareHardwareBuffers(Size);

	if (!Size) {
		mBox.setExtents( Ogre::Vector3::ZERO, Ogre::Vector3::ZERO );
		Dirty = false;
		return;
	}

	Ogre::Vector3 AABMin = Points[0];
	Ogre::Vector3 AABMax = Points[0];

	Ogre::HardwareVertexBufferSharedPtr VBuf =
		mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);

	Ogre::HardwareVertexBufferSharedPtr CBuf =
		mRenderOp.vertexData->vertexBufferBinding->getBuffer(1);

	// get rendersystem to pack colours
	Ogre::RenderSystem* RS = Ogre::Root::getSingleton().getRenderSystem();

	Ogre::Real* VPrPos = static_cast<Ogre::Real*>(VBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::RGBA* CPrPos = static_cast<Ogre::RGBA*>(CBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	for(int i = 0; i < Size; i++)
	{
		*VPrPos++ = Points[i].x;
		*VPrPos++ = Points[i].y;
		*VPrPos++ = Points[i].z;

		Ogre::RGBA color;
		RS->convertColourValue(Colours[i], &color);
		*CPrPos++ = color;
		//*CPrPos++ = unsigned int(Colours[i].g);
		//*CPrPos++ = unsigned int(Colours[i].b);

		if(Points[i].x < AABMin.x)
			AABMin.x = Points[i].x;
		if(Points[i].y < AABMin.y)
			AABMin.y = Points[i].y;
		if(Points[i].z < AABMin.z)
			AABMin.z = Points[i].z;

		if(Points[i].x > AABMax.x)
			AABMax.x = Points[i].x;
		if(Points[i].y > AABMax.y)
			AABMax.y = Points[i].y;
		if(Points[i].z > AABMax.z)
			AABMax.z = Points[i].z;
	}
	VBuf->unlock();
	CBuf->unlock();

	mBox.setExtents(AABMin, AABMax);

	Dirty = false;
}
예제 #3
0
void GrassPatch::Update(const Ogre::Vector3 &sphere_center, float sphere_radius, Ogre::Real t)
{
	int			i;
	static  bool inited = false;
	Ogre::Vector3 delta;
	float length;
	int end=0;
	Ogre::Vector3 a, b;
	float radius=sphere_radius*sphere_radius*2.2;

	// Update the particle field
	m_Particles->Step(0.001f); // use of t ?
    Ogre::HardwareVertexBufferSharedPtr vVertices = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);

	Ogre::Real *pVertices = static_cast<Ogre::Real*>( vVertices->lock( 
                                        //Ogre::HardwareBuffer::HBL_DISCARD
                                        Ogre::HardwareBuffer::HBL_NORMAL 
                                            ) );    
  
	// Upload new blade positions
	if(!inited)
	{
		for (i = 0; i < m_NbBlades; i++)
		{
			m_Blades[i]->Constrain(sphere_center, sphere_radius);
			m_Particles->GetGrassParticle(i).ClearForce();
			m_Blades[i]->UpdateVertexBuffer(i, pVertices);
		}
		inited=true;
		vVertices->unlock();
	}
	else
	{	
		for (i = 0; i < m_NbBlades; i++)
		{		
			m_Blades[i]-> GetPosition(a);
			delta = a - sphere_center;
			length = delta.x * delta.x + delta.y * delta.y+ delta.z*delta.z;
			
			if ((m_Blades[i]->moving)||(length-radius<0))
			{
				m_Blades[i]->Constrain(sphere_center, sphere_radius);
				m_Particles->GetGrassParticle(i).ClearForce();
				m_Blades[i]->UpdateVertexBuffer(i, pVertices);
				end++;
			}
		}
		vVertices->unlock();

	}
	int ttt = sprintf(iterations, "Iterations: %d ", end);
	end=0;
}
예제 #4
0
void FrameGraphRenderable::drawGraphLine(TimeGraphLine& line, uint16_t graphLine)
{
    Ogre::Real ogreTop, bulletTop, worldTop, unknownTop;

    ogreTop = (line.ogre / mCurrentScaling);
    bulletTop = ogreTop + (line.bullet / mCurrentScaling);
    worldTop = bulletTop + (line.world / mCurrentScaling);
    unknownTop = worldTop + (line.unknown / mCurrentScaling);

    ogreTop = ogreTop * 2 - 1.0f;
    bulletTop = bulletTop * 2 - 1.0f;
    worldTop = worldTop * 2 - 1.0f;
    unknownTop = unknownTop * 2 - 1.0f;

    Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
    Ogre::Real *vertices = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));

    vertices += graphLine * ValuesPerGraphLine;

    // Set the ogre line top vertex
    vertices[ 4] = ogreTop;
    // Set the bullet line vertices
    vertices[ 7] = ogreTop;
    vertices[10] = bulletTop;
    // Set the world line vertices
    vertices[13] = bulletTop;
    vertices[16] = worldTop;
    // Set the unknown line vertices
    vertices[19] = worldTop;
    vertices[22] = unknownTop;

    vbuf->unlock();
}
예제 #5
0
void processPositionElement( VertexData* vertexData, const VertexElement* vertexElem )
{
	int nMaxVert= vertexData->vertexCount ;
	//const Ogre::VertexElement* VertexEle_POS = vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION );
 
	// get vertex buffer info via the input element
	Ogre::HardwareVertexBufferSharedPtr VertexBufPOS = vertexData->vertexBufferBinding->getBuffer( vertexElem->getSource() );
 
	//LOCK BUFFER
	unsigned char* VertexPtrPOS = static_cast<unsigned char*>( VertexBufPOS->lock( Ogre::HardwareBuffer::HBL_NORMAL)   );
	int VertSizePOS=VertexBufPOS->getVertexSize();

	float * pElementPOS=NULL;
   
	//A vector of every vertices position
	std::vector<Ogre::Vector3> positions(nMaxVert);
	//Copy each position into position vector
	for(int nVert=0 ; nVert<nMaxVert ; nVert++)
	{
		vertexElem->baseVertexPointerToElement( VertexPtrPOS, &pElementPOS );
		Ogre::Vector3 vertex(pElementPOS);
		vertex = mTransform * vertex;
		pElementPOS[0] = vertex.x;
		pElementPOS[1] = vertex.y;
		pElementPOS[2] = vertex.z;
		mBoundingBox.merge(vertex);
		VertexPtrPOS+=VertSizePOS ;
	}
	//UNLOCK BUFFER
	if(VertexBufPOS->isLocked()){VertexBufPOS->unlock();}
}
예제 #6
0
void FrameGraphRenderable::redrawGraph()
{
    Ogre::Real ogreTop, bulletTop, worldTop, unknownTop;

    Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
    Ogre::Real *vertices = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));

    for (size_t i = 0; i < mNumFrames; i++) {
        ogreTop = (mlastTimes[i].ogre / mCurrentScaling);
        bulletTop = ogreTop + (mlastTimes[i].bullet / mCurrentScaling);
        worldTop = bulletTop + (mlastTimes[i].world / mCurrentScaling);
        unknownTop = worldTop + (mlastTimes[i].unknown / mCurrentScaling);

        ogreTop = ogreTop * 2 - 1.0f;
        bulletTop = bulletTop * 2 - 1.0f;
        worldTop = worldTop * 2 - 1.0f;
        unknownTop = unknownTop * 2 - 1.0f;

        // Set the ogre line top vertex
        vertices[ 4] = ogreTop;
        // Set the bullet line vertices
        vertices[ 7] = ogreTop;
        vertices[10] = bulletTop;
        // Set the world line vertices
        vertices[13] = bulletTop;
        vertices[16] = worldTop;
        // Set the unknown line vertices
        vertices[19] = worldTop;
        vertices[22] = unknownTop;

        vertices += ValuesPerGraphLine;
    }

    vbuf->unlock();
}
예제 #7
0
    void Selection2D::setCorners(Ogre::Real left, Ogre::Real top, Ogre::Real right, Ogre::Real bottom, bool updateAABB) 
    {
        Ogre::HardwareVertexBufferSharedPtr vbuf = 
            mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
        float* pFloat = static_cast<float*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));

        *pFloat++ = left;
        *pFloat++ = top;
        *pFloat++ = -1;

        *pFloat++ = left;
        *pFloat++ = bottom;
        *pFloat++ = -1;

        *pFloat++ = right;
        *pFloat++ = bottom;
        *pFloat++ = -1;

        *pFloat++ = right;
        *pFloat++ = top;
        *pFloat++ = -1;

        *pFloat++ = left;
        *pFloat++ = top;
        *pFloat++ = -1;

        vbuf->unlock();

        if(updateAABB)
        {
            mBox.setExtents(
                std::min(left, right), std::min(top, bottom), 0,
                std::max(left, right), std::max(top, bottom), 0);
        }
    }
예제 #8
0
파일: DynamicLines.cpp 프로젝트: onze/Steel
    void DynamicLines::fillHardwareBuffers()
    {
        unsigned int size = (unsigned int)mPoints.size();

        prepareHardwareBuffers(size, 0);

        if(!size)
        {
            mBox.setExtents(Ogre::Vector3::ZERO, Ogre::Vector3::ZERO);
            mDirty = false;
            return;
        }

        Ogre::Vector3 vaabMin = mPoints[0];
        Ogre::Vector3 vaabMax = mPoints[0];

        Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);

        Ogre::Real *prPos = static_cast<Ogre::Real *>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        {
            for(unsigned int i = 0; i < size; i++)
            {
                *prPos++ = mPoints[i].x;
                *prPos++ = mPoints[i].y;
                *prPos++ = mPoints[i].z;

                if(!mUse2D)
                {
                    if(mPoints[i].x < vaabMin.x)
                        vaabMin.x = mPoints[i].x;

                    if(mPoints[i].y < vaabMin.y)
                        vaabMin.y = mPoints[i].y;

                    if(mPoints[i].z < vaabMin.z)
                        vaabMin.z = mPoints[i].z;

                    if(mPoints[i].x > vaabMax.x)
                        vaabMax.x = mPoints[i].x;

                    if(mPoints[i].y > vaabMax.y)
                        vaabMax.y = mPoints[i].y;

                    if(mPoints[i].z > vaabMax.z)
                        vaabMax.z = mPoints[i].z;
                }
            }
        }

        vbuf->unlock();

        if(mUse2D)
            mBox.setInfinite();
        else
            mBox.setExtents(vaabMin, vaabMax);

        mDirty = false;
    }
void
TerrainTileEditable::_notifyHeightModified(int xstart, int zstart, int xend, int zend)
{
	assert(0 <= xstart && xstart < xend && xend <= mXSize+1);
	assert(0 <= zstart && zstart < zend && zend <= mZSize+1);

    if (mVertexDatas.empty())
    {
        // Nothing todo when buffer never initialised
        return;
    }

	// TODO: (optimization) some grid may be need to recompute normal only

	TerrainData* data = mOwner->getData();
	Ogre::HardwareVertexBufferSharedPtr posNormBuffer = mVertexDatas.front()->vertexBufferBinding->getBuffer(0);
	float* pPosNormBuffer = static_cast<float*>(posNormBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL));
    float buffer[6];
	int xsize = mXSize;
    int zsize = mZSize;
	int xbase = mXBase;
	int zbase = mZBase;
	for (int z = zstart; z < zend; ++z)
	{
		for (int x = xstart; x < xend; ++x)
		{
			Ogre::Vector3 v;
            v = data->_getPosition(x+xbase, z+zbase);
            buffer[0] = v.x; buffer[1] = v.y; buffer[2] = v.z;
			v = data->_getNormal(x+xbase, z+zbase);
            buffer[3] = v.x; buffer[4] = v.y; buffer[5] = v.z;
            if (0 < z)
            {
                if (0 < x)
                    memcpy(pPosNormBuffer + (((z-1) * xsize + (x-1)) * 4 + 3) * 6, buffer, 6*sizeof(float));
                if (x < xsize)
                    memcpy(pPosNormBuffer + (((z-1) * xsize + (x-0)) * 4 + 2) * 6, buffer, 6*sizeof(float));
            }
            if (z < zsize)
            {
                if (0 < x)
                    memcpy(pPosNormBuffer + (((z-0) * xsize + (x-1)) * 4 + 1) * 6, buffer, 6*sizeof(float));
                if (x < xsize)
                    memcpy(pPosNormBuffer + (((z-0) * xsize + (x-0)) * 4 + 0) * 6, buffer, 6*sizeof(float));
            }
		}
	}
	posNormBuffer->unlock();

	// re-compue bounding box
	data->_computeTileBoundingBox(mBounds, xbase, zbase, xsize, zsize);

    // trigger update of bounding box
    getParentNode()->needUpdate();
}
예제 #10
0
void ImGuiInterface::RenderDrawLists(ImDrawList** const cmdLists, int cmdListsCount)
{
    // Assume render system is configured according to InterfaceManager::_configureRenderSystem
    mRenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
    
    // For each command list
    for (int i = 0; i < cmdListsCount; i++)
    {
        ImVector<ImDrawCmd>& commands = cmdLists[i]->commands;

        // Allocate more space if needed
        if (mSize < cmdLists[i]->vtx_buffer.size())
        {
            mSize = cmdLists[i]->vtx_buffer.size();
            AllocateVertexBuffer(mSize);
        }

        // Copy vertices into VB
        Ogre::HardwareVertexBufferSharedPtr vb =
            mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
        ImDrawVert* vertices = static_cast<ImDrawVert*>(
            vb->lock(0, vb->getSizeInBytes(), Ogre::HardwareBuffer::HBL_DISCARD));
        memcpy(vertices, &cmdLists[i]->vtx_buffer[0], cmdLists[i]->vtx_buffer.size() * sizeof(ImDrawVert));
        vb->unlock();

        // Execute draw calls
        int offset = 0;
        for (auto c : commands)
        {
            mRenderSystem->setScissorTest(true, c.clip_rect.x, c.clip_rect.y, c.clip_rect.z, c.clip_rect.w);

            // Set texture
            if (c.texture_id)
            {
                ImguiTextureHandle* handle = reinterpret_cast<ImguiTextureHandle*>(c.texture_id);
                mRenderSystem->_setTexture(0, true, handle->texturePtr);
                mRenderSystem->_setTextureBlendMode(0, mAlphaBlendMode);
            }
            else
            {
                mRenderSystem->_disableTextureUnit(0);
            }

            // Draw vertices
            mRenderOp.vertexData->vertexStart = offset;
            mRenderOp.vertexData->vertexCount = c.vtx_count;
            mRenderSystem->_render(mRenderOp);
            offset += c.vtx_count;
        }
    }
    mRenderSystem->setScissorTest(false);
}
예제 #11
0
//------------------------------------------------------------------------------------------------
void DynamicLines::fillHardwareBuffers()
{
	int size = m_Points.size();

	prepareHardwareBuffers(size,0);

	if (!size) {
		mBox.setExtents(Vec3::ZERO,Vec3::ZERO);
		m_bDirty=false;
		return;
	}

	Vec3 vaabMin = m_Points[0];
	Vec3 vaabMax = m_Points[0];

	Ogre::HardwareVertexBufferSharedPtr vbuf =
		mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);

	real *prPos = static_cast<real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	{
		for(int i = 0; i < size; i++)
		{
			*prPos++ = m_Points[i].x;
			*prPos++ = m_Points[i].y;
			*prPos++ = m_Points[i].z;

			if(m_Points[i].x < vaabMin.x)
				vaabMin.x = m_Points[i].x;
			if(m_Points[i].y < vaabMin.y)
				vaabMin.y = m_Points[i].y;
			if(m_Points[i].z < vaabMin.z)
				vaabMin.z = m_Points[i].z;

			if(m_Points[i].x > vaabMax.x)
				vaabMax.x = m_Points[i].x;
			if(m_Points[i].y > vaabMax.y)
				vaabMax.y = m_Points[i].y;
			if(m_Points[i].z > vaabMax.z)
				vaabMax.z = m_Points[i].z;
		}
	}
	vbuf->unlock();

	mBox.setExtents(vaabMin, vaabMax);

	m_bDirty = false;
}
//------------------------------------------------------------------------------------------------
void VertexIndexToShape::addStaticVertexData(const Ogre::VertexData *vertex_data)
{
    if (!vertex_data)
    {
        return;
    }

    const Ogre::VertexData *data = vertex_data;

    const unsigned int prev_size = mVertexCount;
    mVertexCount += (unsigned int)data->vertexCount;

    Ogre::Vector3 *tmp_vert = new Ogre::Vector3[mVertexCount];
    if (mVertexBuffer)
    {
        memcpy(tmp_vert, mVertexBuffer, sizeof(Ogre::Vector3) * prev_size);
        delete[] mVertexBuffer;
    }
    mVertexBuffer = tmp_vert;

    // Get the positional buffer element
    {	
        const Ogre::VertexElement *posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
        Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
        const unsigned int vSize = (unsigned int)vbuf->getVertexSize();

        unsigned char *vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        float *pReal = NULL;
        Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size];
        const unsigned int vertexCount = (unsigned int)data->vertexCount;
        for (unsigned int j = 0; j < vertexCount; ++j)
        {
            posElem->baseVertexPointerToElement(vertex, &pReal);
            vertex += vSize;

            curVertices->x = (*pReal++);
            curVertices->y = (*pReal++);
            curVertices->z = (*pReal++);

            *curVertices = mTransform * (*curVertices);
            
            curVertices++;
        }
        vbuf->unlock();
    }
}
예제 #13
0
//-------------------------------------------------------
// http://www.ogre3d.org/tikiwiki/Raycasting+to+the+polygon+level
std::pair<bool, float> Ground::GetVertexIntersection(const Ogre::Ray & ray, const Ogre::SubMesh* subMesh)
{
    OgreAssert(false == subMesh->useSharedVertices, "Mesh with shared data is not supported");

    const Ogre::VertexElement* posElem = subMesh->vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
    
    Ogre::HardwareVertexBufferSharedPtr vbuffer = subMesh->vertexData->vertexBufferBinding->getBuffer(posElem->getSource());

    unsigned char* vertexes = reinterpret_cast<unsigned char*>(vbuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

    size_t count = subMesh->vertexData->vertexCount;

    float intersection = -1.0f;

    OgreAssert(count == REGION_SIZE * REGION_SIZE * 4, "Wrong buffer size");
    float* pReal;
    for (size_t i = 0; i < REGION_SIZE * REGION_SIZE; ++i)
    {
        Ogre::Vector3 v0, v1, v2, v3;
        for (auto vp : { &v0, &v1, &v2, &v3 })
        {
            posElem->baseVertexPointerToElement(vertexes, &pReal);
            *vp = Ogre::Vector3(pReal[0], pReal[1], pReal[2]);
            vertexes += vbuffer->getVertexSize();
        }

        auto hit1 = Ogre::Math::intersects(ray, v1, v2, v0, true, false);
        if (hit1.first && (intersection < 0.0f || hit1.second < intersection))
        {
            intersection = hit1.second;
        }
        auto hit2 = Ogre::Math::intersects(ray, v3, v2, v1, true, false);
        if (hit2.first && (intersection < 0.0f || hit2.second < intersection))
        {
            intersection = hit2.second;
        }
    }
    vbuffer->unlock();
    if (intersection >= 0.0f)
    {
        return std::make_pair(true, intersection);
    }
    return std::make_pair(false, -1.0f);
}
예제 #14
0
std::vector<Ogre::Vector3> OgreRecast::getManualObjectVertices(Ogre::ManualObject *manual)
{
    std::vector<Ogre::Vector3> returnVertices;
    unsigned long thisSectionStart = 0;
    for (size_t i=0; i < manual->getNumSections(); i++)
    {
        Ogre::ManualObject::ManualObjectSection * section = manual->getSection(i);
        Ogre::RenderOperation * renderOp = section->getRenderOperation();

        //Collect the vertices
        {
            const Ogre::VertexElement * vertexElement = renderOp->vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
            Ogre::HardwareVertexBufferSharedPtr vertexBuffer = renderOp->vertexData->vertexBufferBinding->getBuffer(vertexElement->getSource());

            char * verticesBuffer = (char*)vertexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
            float * positionArrayHolder;

            thisSectionStart = returnVertices.size();

            returnVertices.reserve(returnVertices.size() + renderOp->vertexData->vertexCount);

            for (unsigned int j=0; j<renderOp->vertexData->vertexCount; j++)
            {
                vertexElement->baseVertexPointerToElement(verticesBuffer + j * vertexBuffer->getVertexSize(), &positionArrayHolder);
                Ogre::Vector3 vertexPos = Ogre::Vector3(positionArrayHolder[0],
                                                        positionArrayHolder[1],
                                                        positionArrayHolder[2]);

                //vertexPos = (orient * (vertexPos * scale)) + position;

                returnVertices.push_back(vertexPos);
            }

            vertexBuffer->unlock();
        }
    }

    return returnVertices;
}
void
TerrainTileEditable::fillLayerBuffer(size_t layer, const Ogre::HardwareVertexBufferSharedPtr& buffer)
{
    float* pFloat = static_cast<float*>(buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));

    const TerrainData* data = mOwner->getData();
    int xbase = mXBase;
    int zbase = mZBase;
    int xsize = mXSize;
    int zsize = mZSize;

    for (int z = 0; z < zsize; ++z)
    {
        for (int x = 0; x < xsize; ++x)
        {
            size_t grid = (zbase + z) * data->mXSize + (xbase + x);
            const TerrainData::GridInfo& gridInfo = data->mGridInfos[grid];
            const TerrainData::LayerInfo& layerInfo = gridInfo.layers[layer];
            if (layerInfo.pixmapId)
            {
                std::pair<Real, Real> t;
                t = mOwner->_getPixmapCorner(layerInfo, TerrainData::LEFT_TOP, gridInfo.flags);
                *pFloat++ = t.first; *pFloat++ = t.second;
                t = mOwner->_getPixmapCorner(layerInfo, TerrainData::RIGHT_TOP, gridInfo.flags);
                *pFloat++ = t.first; *pFloat++ = t.second;
                t = mOwner->_getPixmapCorner(layerInfo, TerrainData::LEFT_BOTTOM, gridInfo.flags);
                *pFloat++ = t.first; *pFloat++ = t.second;
                t = mOwner->_getPixmapCorner(layerInfo, TerrainData::RIGHT_BOTTOM, gridInfo.flags);
                *pFloat++ = t.first; *pFloat++ = t.second;
            }
            else
            {
                pFloat += 2 * 4;
            }
        }
    }

    buffer->unlock();
}
예제 #16
0
	void VertexBuffer::AddFromVertexData(Ogre::VertexData* vertexData)
	{
		// Get vertex count
		const unsigned int addedCount = vertexData->vertexCount;

		if(_reserved < _size + addedCount)
		{
			Reserve(_size + addedCount);
		}

		// Get VertexElement with info on used vertex semantics
		const Ogre::VertexElement* vertexElement = 
			vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
		// Get actual vertex buffer and its size
		Ogre::HardwareVertexBufferSharedPtr hardwareBuffer = 
			vertexData->vertexBufferBinding->getBuffer(vertexElement->getSource());
		const unsigned int vertexSize = (unsigned int)hardwareBuffer->getVertexSize();
		// Lock buffer with read-only to retrieve vertex data
		unsigned char* buffer = static_cast<unsigned char*>(
			hardwareBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
		// Pointer to one component of vertex vector
		float *curVertexData = NULL;

		for (unsigned int j = 0; j < addedCount; ++j)
		{
			vertexElement->baseVertexPointerToElement(buffer, &curVertexData);
			buffer += vertexSize;

			_buffer.push_back(Ogre::Vector3(
				*curVertexData,
				*(curVertexData+1) ,
				*(curVertexData+2)));

			curVertexData += 3;
		}

		_size = _buffer.size();
		hardwareBuffer->unlock();
	}
void GPUBillboardSet::createVertexDataForVertexShaderOnly(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size() * 4; 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = true; 
	mRenderOp.indexData = OGRE_NEW Ogre::IndexData();
	mRenderOp.indexData->indexCount = vertices.size() * 6;
	mRenderOp.indexData->indexStart = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
	Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

	// Create vertex buffer
    Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
        mRenderOp.vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;

	const Ogre::Vector2 uvs[4] = {	Ogre::Vector2( -1.f, 1.f ),
									Ogre::Vector2( -1.f, -1.f ),
									Ogre::Vector2( 1.f, -1.f ),
									Ogre::Vector2( 1.f, 1.f ) };
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for ( unsigned int j=0; j<4; j++ )
		{
			for (itr=elems.begin(); itr!=elems.end(); ++itr)
			{
				Ogre::VertexElement& elem = *itr;
				if (elem.getSemantic() == Ogre::VES_POSITION)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = vertex.position.x; *pReal++;
					*pReal = vertex.position.y; *pReal++;
					*pReal = vertex.position.z; *pReal++;
				}
				else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
				{
					elem.baseVertexPointerToElement(pVert, &pRGBA);
					renderSystem->convertColourValue(vertex.color, pRGBA);
				}
				else if (elem.getSemantic() == Ogre::VES_TEXTURE_COORDINATES && elem.getIndex() == 0)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = uvs[j].x; *pReal++;
					*pReal = uvs[j].y; *pReal++;
				}
			}
			// Go to next vertex 
			pVert += vbuf->getVertexSize();
		}
	}
	vbuf->unlock();

	// Create index buffer
	if (mRenderOp.indexData->indexCount>=65536)
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( 
			Ogre::HardwareIndexBuffer::IT_32BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint32* indices = static_cast<Ogre::uint32*>(ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD));

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint32 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for (unsigned int i=0; i<vertices.size(); ++i)
		{
			for (unsigned int j=0; j<6; ++j)
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}
	else
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
			Ogre::HardwareIndexBuffer::IT_16BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint16* indices = static_cast<Ogre::uint16*>( ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint16 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for ( unsigned int i=0; i<vertices.size(); ++i )
		{
			for ( unsigned int j=0; j<6; ++j )
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}

    // Set material
    this->setMaterial("GPUBillboard");
}
예제 #18
0
// Get the mesh information for the given mesh.
// Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData
void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh,
                                size_t &vertex_count,
                                Ogre::Vector3* &vertices,
                                size_t &index_count,
                                Ogre::uint32* &indices,
                                const Ogre::Vector3 &position,
                                const Ogre::Quaternion &orient,
                                const Ogre::Vector3 &scale)
{
    bool added_shared = false;
    size_t current_offset = 0;
    size_t shared_offset = 0;
    size_t next_offset = 0;
    size_t index_offset = 0;

    vertex_count = index_count = 0;

    // Calculate how many vertices and indices we're going to need
    for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* submesh = mesh->getSubMesh( i );

        // We only need to add the shared vertices once
        if(submesh->useSharedVertices)
        {
            if( !added_shared )
            {
                vertex_count += mesh->sharedVertexData->vertexCount;
                added_shared = true;
            }
        }
        else
        {
            vertex_count += submesh->vertexData->vertexCount;
        }

        // Add the indices
        index_count += submesh->indexData->indexCount;
    }


    // Allocate space for the vertices and indices
    vertices = new Ogre::Vector3[vertex_count];
    indices = new Ogre::uint32[index_count];

    added_shared = false;

    // Run through the submeshes again, adding the data into the arrays
    for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* submesh = mesh->getSubMesh(i);

        Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

        if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
        {
            if(submesh->useSharedVertices)
            {
                added_shared = true;
                shared_offset = current_offset;
            }

            const Ogre::VertexElement* posElem =
                vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

            Ogre::HardwareVertexBufferSharedPtr vbuf =
                vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

            unsigned char* vertex =
                static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

            // There is _no_ baseVertexPointerToElement() which takes an Ogre::Ogre::Real or a double
            //  as second argument. So make it float, to avoid trouble when Ogre::Ogre::Real will
            //  be comiled/typedefed as double:
            //      Ogre::Ogre::Real* pOgre::Real;
            float* pReal;

            for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
            {
                posElem->baseVertexPointerToElement(vertex, &pReal);

                Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);

                vertices[current_offset + j] = (orient * (pt * scale)) + position;
            }

            vbuf->unlock();
            next_offset += vertex_data->vertexCount;
        }


        Ogre::IndexData* index_data = submesh->indexData;
        size_t numTris = index_data->indexCount / 3;
        Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

        bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

        Ogre::uint32*  pLong = static_cast<Ogre::uint32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);


        size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;

        if ( use32bitindexes )
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = pLong[k] + static_cast<Ogre::uint32>(offset);
            }
        }
        else
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = static_cast<Ogre::uint32>(pShort[k]) +
                    static_cast<Ogre::uint32>(offset);
            }
        }

        ibuf->unlock();
        current_offset = next_offset;
    }
}
예제 #19
0
void OgreMeshRay::GetMeshInformation(const Ogre::ManualObject* manual,
		size_t& vertex_count, Ogre::Vector3*& vertices, size_t& index_count,
		unsigned long*& indices, const Ogre::Vector3& position,
		const Ogre::Quaternion& orient, const Ogre::Vector3& scale) {
	std::vector<Ogre::Vector3> returnVertices;
	std::vector<unsigned long> returnIndices;
	unsigned long thisSectionStart = 0;
	for (unsigned int i = 0, size = manual->getNumSections(); i < size; ++i) {
		Ogre::ManualObject::ManualObjectSection* section = manual->getSection(
				i);
		Ogre::RenderOperation* renderOp = section->getRenderOperation();

		std::vector<Ogre::Vector3> pushVertices;
		//Collect the vertices
		{
			const Ogre::VertexElement* vertexElement =
					renderOp->vertexData->vertexDeclaration->findElementBySemantic(
							Ogre::VES_POSITION);
			Ogre::HardwareVertexBufferSharedPtr vertexBuffer =
					renderOp->vertexData->vertexBufferBinding->getBuffer(
							vertexElement->getSource());

			char* verticesBuffer = static_cast<char*>(vertexBuffer->lock(
					Ogre::HardwareBuffer::HBL_READ_ONLY));
			float* positionArrayHolder;

			thisSectionStart = returnVertices.size() + pushVertices.size();

			pushVertices.reserve(renderOp->vertexData->vertexCount);

			for (unsigned int j = 0; j < renderOp->vertexData->vertexCount;
					++j) {
				vertexElement->baseVertexPointerToElement(
						verticesBuffer + j * vertexBuffer->getVertexSize(),
						&positionArrayHolder);
				Ogre::Vector3 vertexPos = Ogre::Vector3(positionArrayHolder[0],
						positionArrayHolder[1], positionArrayHolder[2]);
				vertexPos = (orient * (vertexPos * scale)) + position;
				pushVertices.push_back(vertexPos);
			}

			vertexBuffer->unlock();
		}
		//Collect the indices
		{
			if (renderOp->useIndexes) {
				Ogre::HardwareIndexBufferSharedPtr indexBuffer =
						renderOp->indexData->indexBuffer;

				if (indexBuffer.isNull()
						|| renderOp->operationType
								!= Ogre::RenderOperation::OT_TRIANGLE_LIST) {
					//No triangles here, so we just drop the collected vertices and move along to the next section.
					continue;
				} else {
					returnVertices.reserve(
							returnVertices.size() + pushVertices.size());
					returnVertices.insert(returnVertices.end(),
							pushVertices.begin(), pushVertices.end());
				}

				unsigned int* pLong =
						static_cast<unsigned int*>(indexBuffer->lock(
								Ogre::HardwareBuffer::HBL_READ_ONLY));
				unsigned short* pShort =
						reinterpret_cast<unsigned short*>(pLong);

				returnIndices.reserve(
						returnIndices.size() + renderOp->indexData->indexCount);

				for (size_t j = 0; j < renderOp->indexData->indexCount; ++j) {
					unsigned long index;
					//We also have got to remember that for a multi section object, each section has
					//different vertices, so the indices will not be correct. To correct this, we
					//have to add the position of the first vertex in this section to the index

					//(At least I think so...)
					if (indexBuffer->getType()
							== Ogre::HardwareIndexBuffer::IT_32BIT)
						index = static_cast<unsigned long>(pLong[j])
								+ thisSectionStart;
					else
						index = static_cast<unsigned long>(pShort[j])
								+ thisSectionStart;

					returnIndices.push_back(index);
				}

				indexBuffer->unlock();
			}
		}
	}

	//Now we simply return the data.
	index_count = returnIndices.size();
	vertex_count = returnVertices.size();
	vertices = new Ogre::Vector3[vertex_count];
	for (unsigned long i = 0; i < vertex_count; ++i)
		vertices[i] = returnVertices[i];
	indices = new unsigned long[index_count];
	for (unsigned long i = 0; i < index_count; ++i)
		indices[i] = returnIndices[i];

	//All done.
	return;
}
예제 #20
0
   void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
        shapeNumber = 0;

        if (allshapes == NULL || creaturemodel == NULL || skel == NULL)
        {
            return;
        }

        std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
	    for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)

                {
                    //std::map<unsigned short, PosAndRot> vecPosRot;

			Nif::NiTriShapeCopy& copy = *allshapesiter;
			std::vector<Ogre::Vector3>* allvertices = &copy.vertices;



			//std::set<unsigned int> vertices;
			//std::set<unsigned int> normals;
			//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector =  copy.boneinfo;
            std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >* verticesToChange = &copy.vertsToWeights;

			//std::cout << "Name " << copy.sname << "\n";
			Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
		            Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));


				std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
				//Each shape has multiple indices
				if(initialVertices.size() )
				{

					if(copy.vertices.size() == initialVertices.size())
					{
						//Create if it doesn't already exist
						if(shapeIndexI.size() == static_cast<std::size_t> (shapeNumber))
						{
							std::vector<int> vec;
							shapeIndexI.push_back(vec);
						}
                        if(time >= copy.morph.getStartTime() && time <= copy.morph.getStopTime()){
						float x;
						for (unsigned int i = 0; i < copy.morph.getAdditionalVertices().size(); i++){
							int j = 0;
							if(shapeIndexI[shapeNumber].size() <= i)
								shapeIndexI[shapeNumber].push_back(0);


							if(timeIndex(time,copy.morph.getRelevantTimes()[i],(shapeIndexI[shapeNumber])[i], j, x)){
							int indexI = (shapeIndexI[shapeNumber])[i];
							std::vector<Ogre::Vector3> relevantData = (copy.morph.getRelevantData()[i]);
							float v1 = relevantData[indexI].x;
							float v2 = relevantData[j].x;
							float t = v1 + (v2 - v1) * x;
							if ( t < 0 ) t = 0;
							if ( t > 1 ) t = 1;
						    if( t != 0 && initialVertices.size() == copy.morph.getAdditionalVertices()[i].size())
							{
								for (unsigned int v = 0; v < initialVertices.size(); v++){
									initialVertices[v] += ((copy.morph.getAdditionalVertices()[i])[v]) * t;
								}
							}

							}



						}

						allvertices = &initialVertices;
                        }
						shapeNumber++;
					}
				}


			    if(verticesToChange->size() > 0){

                for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >::iterator iter = verticesToChange->begin();
                    iter != verticesToChange->end(); iter++)
                {
                    std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
                    int verIndex = iter->first;
                    Ogre::Vector3 currentVertex = (*allvertices)[verIndex];
                    Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
                    Ogre::Bone *bonePtr = 0;



                    Ogre::Vector3 vecPos;
                    Ogre::Quaternion vecRot;
					std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = vecRotPos.find(boneinfocopy);

                    if(result == vecRotPos.end()){
                        bonePtr = skel->getBone(boneinfocopy->bonename);

                        vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
                        vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;


                             PosAndRot both;
                            both.vecPos = vecPos;
                            both.vecRot = vecRot;
                            vecRotPos[boneinfocopy] = both;

                    }
                    else{
                        PosAndRot both = result->second;
                        vecPos = both.vecPos;
                        vecRot = both.vecRot;
                    }

                    Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;



                    for(std::size_t i = 1; i < inds.size(); i++){
                        boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
                        result = vecRotPos.find(boneinfocopy);


                        if(result == vecRotPos.end()){
                            bonePtr = skel->getBone(boneinfocopy->bonename);
                            vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
                            vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;

                                PosAndRot both;
                                both.vecPos = vecPos;
                                both.vecRot = vecRot;
                                vecRotPos[boneinfocopy] = both;

                        }
                         else{
                                PosAndRot both = result->second;
                                vecPos = both.vecPos;
                                vecRot = both.vecRot;
                        }


                        absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;


                    }
                     Ogre::Real* addr = (pReal + 3 * verIndex);
							  *addr = absVertPos.x;
							  *(addr+1) = absVertPos.y;
				              *(addr+2) = absVertPos.z;

                }




				}
				else
				{
					//Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename);
					Ogre::Quaternion shaperot = copy.trafo.rotation;
					Ogre::Vector3 shapetrans = copy.trafo.trans;
					float shapescale = copy.trafo.scale;
					std::vector<std::string> boneSequence = copy.boneSequence;

					Ogre::Vector3 transmult;
						Ogre::Quaternion rotmult;
						float scale;
					if(boneSequence.size() > 0){
                        std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
                        if(skel->hasBone(*boneSequenceIter)){
					Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);




						transmult = bonePtr->getPosition();
						rotmult = bonePtr->getOrientation();
						scale = bonePtr->getScale().x;
						boneSequenceIter++;

					    for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++)
					    {
							if(skel->hasBone(*boneSequenceIter)){
							Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
								// Computes C = B + AxC*scale
								transmult = transmult + rotmult * bonePtr->getPosition();
								rotmult = rotmult * bonePtr->getOrientation();
								scale = scale * bonePtr->getScale().x;
							}
						    //std::cout << "Bone:" << *boneSequenceIter << "   ";
					    }
						transmult = transmult + rotmult * shapetrans;
						rotmult = rotmult * shaperot;
						scale = shapescale * scale;

						//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
					}
                    }
					else
					{
						transmult = shapetrans;
						rotmult = shaperot;
						scale = shapescale;
					}




					// Computes C = B + AxC*scale
					 // final_vector = old_vector + old_rotation*new_vector*old_scale/

					for(unsigned int i = 0; i < allvertices->size(); i++){
						Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i];
						Ogre::Real* addr = pReal + i * 3;
					    *addr = current.x;
						*(addr+1) = current.y;
						*(addr + 2) = current.z;

					}/*
					for(int i = 0; i < allnormals.size(); i++){
						Ogre::Vector3 current =rotmult * allnormals[i];
						Ogre::Real* addr = pRealNormal + i * 3;
					    *addr = current.x;
						*(addr+1) = current.y;
						*(addr + 2) = current.z;

					}*/

				}
				vbuf->unlock();

		}

    }
예제 #21
0
    void Utils::GetMeshInformation(
        const Ogre::MeshPtr mesh,
        size_t &vertexCount,
        Ogre::Vector3* &vertices,
        size_t &indexCount,
        unsigned* &indices) 
    {
        bool addShared = false;
        size_t currentOffset = 0;
        size_t shared_offset = 0;
        size_t nextOffset = 0;
        size_t indexOffset = 0;


        vertexCount = indexCount = 0;

        for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) {
            Ogre::SubMesh* submesh = mesh->getSubMesh(i);
            if(submesh->useSharedVertices) {
                if( !addShared ) {
                    vertexCount += mesh->sharedVertexData->vertexCount;
                    addShared = true;
                }
            }
            else {
                vertexCount += submesh->vertexData->vertexCount;
            }
            indexCount += submesh->indexData->indexCount;
        }


        vertices = new Ogre::Vector3[vertexCount];
        indices = new unsigned[indexCount];

        addShared = false;

        for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) {
            Ogre::SubMesh* submesh = mesh->getSubMesh(i);

            Ogre::VertexData* vertexData = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

            if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !addShared)) {
                if(submesh->useSharedVertices) {
                    addShared = true;
                    shared_offset = currentOffset;
                }

                const Ogre::VertexElement* posElem =
                    vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

                Ogre::HardwareVertexBufferSharedPtr vbuf =
                    vertexData->vertexBufferBinding->getBuffer(posElem->getSource());

                unsigned char* vertex =
                    static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

                float* pReal;

                for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) {
                    posElem->baseVertexPointerToElement(vertex, &pReal);
                    Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
                    vertices[currentOffset + j] = pt;
                }
                
                vbuf->unlock();
                nextOffset += vertexData->vertexCount;
            }


            Ogre::IndexData* indexData = submesh->indexData;
            size_t numTris = indexData->indexCount / 3;
            Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;
            
            bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

            unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
            unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);

            size_t offset = (submesh->useSharedVertices)? shared_offset : currentOffset;

            if ( use32bitindexes ) {
                for ( size_t k = 0; k < numTris*3; ++k) {
                    indices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset);
                }
            }
            else {
                for ( size_t k = 0; k < numTris*3; ++k) {
                    indices[indexOffset++] = static_cast<unsigned long>(pShort[k]) +
                                              static_cast<unsigned long>(offset);
                }
            }

            ibuf->unlock();
            currentOffset = nextOffset;
        }
    }
예제 #22
0
void OgreMeshAsset::CreateKdTree()
{
    meshData.Clear();
    normals.clear();
    uvs.clear();
    subMeshTriangleCounts.clear();
    for(unsigned short i = 0; i < ogreMesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh *submesh = ogreMesh->getSubMesh(i);
        assert(submesh);
        
        Ogre::VertexData *vertexData = submesh->useSharedVertices ? ogreMesh->sharedVertexData : submesh->vertexData;
        assert(vertexData);
        
        const Ogre::VertexElement *posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
        if (!posElem)
        {
            subMeshTriangleCounts.push_back(0);
            continue; // No position element. Ignore this submesh.
        }
        
        Ogre::HardwareVertexBufferSharedPtr vbufPos = vertexData->vertexBufferBinding->getBuffer(posElem->getSource());

        unsigned char *pos = (unsigned char*)vbufPos->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
        assert(pos);
        size_t posOffset = posElem->getOffset();
        size_t posSize = vbufPos->getVertexSize();
        
        // Texcoord element is not mandatory
        unsigned char *texCoord = 0;
        size_t texOffset = 0;
        size_t texSize = 0;
        Ogre::HardwareVertexBufferSharedPtr vbufTex;
        const Ogre::VertexElement *texElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
        if (texElem)
        {
            vbufTex = vertexData->vertexBufferBinding->getBuffer(texElem->getSource());
            // Check if the texcoord buffer is different than the position buffer, in that case lock it separately
            if (vbufTex != vbufPos)
                texCoord = static_cast<unsigned char*>(vbufTex->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
            else
                texCoord = pos;
            texOffset = texElem->getOffset();
            texSize = vbufTex->getVertexSize();
        }
        
        Ogre::IndexData *indexData = submesh->indexData;
        Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;

        u32 *pLong = (u32*)ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
        u16 *pShort = (u16*)pLong;
        const bool use32BitIndices = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
        
        for(unsigned j = 0; j+2 < indexData->indexCount; j += 3)
        {
            unsigned i0, i1, i2;
            if (use32BitIndices)
            {
                i0 = pLong[j];
                i1 = pLong[j+1];
                i2 = pLong[j+2];
            }
            else
            {
                i0 = pShort[j];
                i1 = pShort[j+1];
                i2 = pShort[j+2];
            }
            
            float3 v0 = *(float3*)(pos + posOffset + i0 * posSize);
            float3 v1 = *(float3*)(pos + posOffset + i1 * posSize);
            float3 v2 = *(float3*)(pos + posOffset + i2 * posSize);
            Triangle t(v0, v1, v2);
            meshData.AddObjects(&t, 1);

            if (texElem)
            {
                uvs.push_back(*((float2*)(texCoord + texOffset + i0 * texSize)));
                uvs.push_back(*((float2*)(texCoord + texOffset + i1 * texSize)));
                uvs.push_back(*((float2*)(texCoord + texOffset + i2 * texSize)));
            }

            float3 edge1 = v1 - v0;
            float3 edge2 = v2 - v0;
            float3 normal = edge1.Cross(edge2);
            normal.Normalize();
            normals.push_back(normal);
        }
        subMeshTriangleCounts.push_back((int)(indexData->indexCount / 3));
        
        vbufPos->unlock();
        if (!vbufTex.isNull() && vbufTex != vbufPos)
            vbufTex->unlock();
        ibuf->unlock();
    }

    {
        PROFILE(OgreMeshAsset_KdTree_Build);
        meshData.Build();
    }
}
예제 #23
0
void PhysicsManager::getMeshInformation(Ogre::MeshPtr mesh,size_t &vertex_count,Vector3* &vertices, size_t &index_count, unsigned* &indices, const Ogre::Vector3 &position,  const Ogre::Quaternion &orient,const Ogre::Vector3 &scale)
{
	vertex_count = index_count = 0;

	bool added_shared = false;
	size_t current_offset = vertex_count;
	size_t shared_offset = vertex_count;
	size_t next_offset = vertex_count;
	size_t index_offset = index_count;
	size_t prev_vert = vertex_count;
	size_t prev_ind = index_count;

	// Calculate how many vertices and indices we're going to need
	for(int i = 0;i < mesh->getNumSubMeshes();i++)
	{
		SubMesh* submesh = mesh->getSubMesh(i);

		// We only need to add the shared vertices once
		if(submesh->useSharedVertices)
		{
			if(!added_shared)
			{
				VertexData* vertex_data = mesh->sharedVertexData;
				vertex_count += vertex_data->vertexCount;
				added_shared = true;
			}
		}
		else
		{
			VertexData* vertex_data = submesh->vertexData;
			vertex_count += vertex_data->vertexCount;
		}

		// Add the indices
		Ogre::IndexData* index_data = submesh->indexData;
		index_count += index_data->indexCount;
	}

	// Allocate space for the vertices and indices
	vertices = new Vector3[vertex_count];
	indices = new unsigned[index_count];

	added_shared = false;

	// Run through the submeshes again, adding the data into the arrays
	for(int i = 0;i < mesh->getNumSubMeshes();i++)
	{
		SubMesh* submesh = mesh->getSubMesh(i);

		Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
		if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
		{
			if(submesh->useSharedVertices)
			{
				added_shared = true;
				shared_offset = current_offset;
			}

			const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
			Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
			unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
			Ogre::Real* pReal;

			for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
			{
				posElem->baseVertexPointerToElement(vertex, &pReal);

				Vector3 pt;

				pt.x = (*pReal++);
				pt.y = (*pReal++);
				pt.z = (*pReal++);

				pt = (orient * (pt * scale)) + position;

				vertices[current_offset + j].x = pt.x;
				vertices[current_offset + j].y = pt.y;
				vertices[current_offset + j].z = pt.z;
			}
			vbuf->unlock();
			next_offset += vertex_data->vertexCount;
		}

		Ogre::IndexData* index_data = submesh->indexData;

		size_t numTris = index_data->indexCount / 3;
		unsigned short* pShort;
		unsigned int* pInt;
		Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
		bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
		if (use32bitindexes) pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
		else pShort = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

		for(size_t k = 0; k < numTris; ++k)
		{
			size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset;

			unsigned int vindex = use32bitindexes? *pInt++ : *pShort++;
			indices[index_offset + 0] = vindex + offset;
			vindex = use32bitindexes? *pInt++ : *pShort++;
			indices[index_offset + 1] = vindex + offset;
			vindex = use32bitindexes? *pInt++ : *pShort++;
			indices[index_offset + 2] = vindex + offset;

			index_offset += 3;
		}
		ibuf->unlock();
		current_offset = next_offset;
	}
}
//------------------------------------------------------------------------------------------------
void VertexIndexToShape::addAnimatedVertexData(const Ogre::VertexData *vertex_data,
                                               const Ogre::VertexData *blend_data,
                                               const Ogre::Mesh::IndexMap *indexMap)
{
    // Get the bone index element
    assert(vertex_data);

    const Ogre::VertexData *data = blend_data;
    const unsigned int prev_size = mVertexCount;
    mVertexCount += (unsigned int)data->vertexCount;
    Ogre::Vector3 *tmp_vert = new Ogre::Vector3[mVertexCount];
    if (mVertexBuffer)
    {
        memcpy(tmp_vert, mVertexBuffer, sizeof(Ogre::Vector3) * prev_size);
        delete[] mVertexBuffer;
    }
    mVertexBuffer = tmp_vert;

    // Get the positional buffer element
    {	
        const Ogre::VertexElement *posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
        assert(posElem);
        Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource());
        const unsigned int vSize = (unsigned int)vbuf->getVertexSize();

        unsigned char *vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        float *pReal;
        Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size];
        const unsigned int vertexCount = (unsigned int)data->vertexCount;
        for (unsigned int j = 0; j < vertexCount; ++j)
        {
            posElem->baseVertexPointerToElement(vertex, &pReal);
            vertex += vSize;

            curVertices->x = (*pReal++);
            curVertices->y = (*pReal++);
            curVertices->z = (*pReal++);

            *curVertices = mTransform * (*curVertices);

            curVertices++;
        }
        vbuf->unlock();
    }

    {
        const Ogre::VertexElement *bneElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_BLEND_INDICES);
        assert(bneElem);
		
        Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(bneElem->getSource());
        const unsigned int vSize = (unsigned int)vbuf->getVertexSize();
        unsigned char *vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

        unsigned char *pBone = NULL;

        if (!mBoneIndex)
        {
            mBoneIndex = new BoneIndex();	
        }

        Ogre::Vector3 *curVertices = &mVertexBuffer[prev_size];

        const unsigned int vertexCount = (unsigned int)vertex_data->vertexCount;
        for (unsigned int j = 0; j < vertexCount; ++j)
        {
            bneElem->baseVertexPointerToElement(vertex, &pBone);
            vertex += vSize;

            const unsigned char currBone = (indexMap) ? (*indexMap)[*pBone] : *pBone;
            const BoneIndex::iterator i = mBoneIndex->find(currBone);
            Vector3Array *l = NULL;
            if (i == mBoneIndex->end())
            {
                l = new Vector3Array;
                mBoneIndex->insert(BoneKeyIndex(currBone, l));
            }
            else 
            {
                  l = i->second;
            }

            l->push_back(*curVertices);

            curVertices++;
        }

        vbuf->unlock();
    }
}
//----------------------------------------------------------------------------------------
void PortalOutlineRenderable::setupVertices(Ogre::Real width, Ogre::Real height)
{

	Ogre::Real maxx = width/2;
	Ogre::Real maxy = height/2;
	Ogre::Real maxz = 0.2f;
	Ogre::Real minx = -(width/2);
	Ogre::Real miny = -(height/2);
	Ogre::Real minz = -0.2f;

	// fill in the Vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
	float* pPos = static_cast<float*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	//outline
	// line 0
	*pPos++ = minx;
	*pPos++ = miny;
	*pPos++ = 0.0;

    *pPos++ = maxx;
	*pPos++ = miny;
	*pPos++ = 0.0;

	// line 1
	*pPos++ = maxx;
	*pPos++ = miny;
	*pPos++ = 0.0;

	*pPos++ = maxx;
	*pPos++ = maxy;
	*pPos++ = 0.0;

	// line 2
	*pPos++ = maxx;
	*pPos++ = maxy;
	*pPos++ = 0.0;

    *pPos++ = minx;
	*pPos++ = maxy;
	*pPos++ = 0.0;

	// line 3
	*pPos++ = minx;
	*pPos++ = maxy;
	*pPos++ = 0.0;

	*pPos++ = minx;
	*pPos++ = miny;
	*pPos++ = 0.0;

	//line 4 (direction pointer)
	*pPos++ = 0.0;
	*pPos++ = 0.0;
	*pPos++ = 0.0;

	*pPos++ = 0.0;
	*pPos++ = 0.0;
	*pPos++ = 0.5;

	vbuf->unlock();
	// setup the bounding box of this SimpleRenderable
	Ogre::AxisAlignedBox aab(Ogre::Vector3(minx,miny,minz),Ogre::Vector3(maxx,maxy,maxz));
	setBoundingBox(aab);
}
예제 #26
0
void MilkshapePlugin::doExportMesh(msModel* pModel)
{


    // Create singletons
    Ogre::SkeletonManager skelMgr;
    Ogre::DefaultHardwareBufferManager defHWBufMgr;
	Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton();
	Ogre::MeshManager meshMgr;


    //
    // choose filename
    //
    OPENFILENAME ofn;
    memset (&ofn, 0, sizeof (OPENFILENAME));

    char szFile[MS_MAX_PATH];
    char szFileTitle[MS_MAX_PATH];
    char szDefExt[32] = "mesh";
    char szFilter[128] = "OGRE .mesh Files (*.mesh)\0*.mesh\0All Files (*.*)\0*.*\0\0";
    szFile[0] = '\0';
    szFileTitle[0] = '\0';

    ofn.lStructSize = sizeof (OPENFILENAME);
    ofn.lpstrDefExt = szDefExt;
    ofn.lpstrFilter = szFilter;
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = MS_MAX_PATH;
    ofn.lpstrFileTitle = szFileTitle;
    ofn.nMaxFileTitle = MS_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
    ofn.lpstrTitle = "Export to OGRE Mesh";

    if (!::GetSaveFileName (&ofn))
        return /*0*/;

    logMgr.logMessage("Creating Mesh object...");
    Ogre::MeshPtr ogreMesh = Ogre::MeshManager::getSingleton().create("export", 
        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    logMgr.logMessage("Mesh object created.");

    bool foundBoneAssignment = false;

    // No shared geometry
    int i;
	int wh, numbones;
	int intweight[3], intbones[3];
    size_t j;
    Ogre::Vector3 min, max, currpos;
    Ogre::Real maxSquaredRadius;
    bool first = true;
    for (i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);

        logMgr.logMessage("Creating SubMesh object...");
        Ogre::SubMesh* ogreSubMesh = ogreMesh->createSubMesh();
        logMgr.logMessage("SubMesh object created.");
        // Set material
        logMgr.logMessage("Getting SubMesh Material...");
        int matIdx = msMesh_GetMaterialIndex(pMesh);

        if (matIdx == -1)
        {
            // No material, use blank
            ogreSubMesh->setMaterialName("BaseWhite");
            logMgr.logMessage("No Material, using default 'BaseWhite'.");
        }
        else
        {

            msMaterial *pMat = msModel_GetMaterialAt(pModel, matIdx);
            ogreSubMesh->setMaterialName(pMat->szName);
            logMgr.logMessage("SubMesh Material Done.");
        }


        logMgr.logMessage("Setting up geometry...");
        // Set up mesh geometry
        ogreSubMesh->vertexData = new Ogre::VertexData();
        ogreSubMesh->vertexData->vertexCount = msMesh_GetVertexCount (pMesh);
        ogreSubMesh->vertexData->vertexStart = 0;
        Ogre::VertexBufferBinding* bind = ogreSubMesh->vertexData->vertexBufferBinding;
        Ogre::VertexDeclaration* decl = ogreSubMesh->vertexData->vertexDeclaration;
        // Always 1 texture layer, 2D coords
        #define POSITION_BINDING 0
        #define NORMAL_BINDING 1
        #define TEXCOORD_BINDING 2
        decl->addElement(POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        decl->addElement(NORMAL_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
        decl->addElement(TEXCOORD_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
        // Create buffers
        Ogre::HardwareVertexBufferSharedPtr pbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(POSITION_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        Ogre::HardwareVertexBufferSharedPtr nbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        Ogre::HardwareVertexBufferSharedPtr tbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        bind->setBinding(POSITION_BINDING, pbuf);
        bind->setBinding(NORMAL_BINDING, nbuf);
        bind->setBinding(TEXCOORD_BINDING, tbuf);

        ogreSubMesh->useSharedVertices = false;

        float* pPos = static_cast<float*>(
            pbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));

        logMgr.logMessage("Doing positions and texture coords...");
        for (j = 0; j < ogreSubMesh->vertexData->vertexCount; ++j)
        {
            logMgr.logMessage("Doing vertex " + Ogre::StringConverter::toString(j));
            msVertex *pVertex = msMesh_GetVertexAt (pMesh, (int)j);
			msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j);
            msVec3 Vertex;
            msVertex_GetVertex (pVertex, Vertex);

            *pPos++ = Vertex[0];
            *pPos++ = Vertex[1];
            *pPos++ = Vertex[2];
            // Deal with bounds
            currpos = Ogre::Vector3(Vertex[0], Vertex[1], Vertex[2]);
            if (first)
            {
                min = max = currpos;
                maxSquaredRadius = currpos.squaredLength();
                first = false;
            }
            else
            {
                min.makeFloor(currpos);
                max.makeCeil(currpos);
                maxSquaredRadius = std::max(maxSquaredRadius, currpos.squaredLength());
            }

            int boneIdx = msVertex_GetBoneIndex(pVertex);
            if (boneIdx != -1)
            {
				foundBoneAssignment = true;
				numbones = 1;
				intbones[0] = intbones[1] = intbones[2] = -1;
				intweight[0] = intweight[1] = intweight[2] = 0;
				for(wh = 0; wh < 3; ++wh) 
				{
					intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh);
					if(intbones[wh] == -1) 
						break;

					++numbones;
					intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh);

				} // for(k)
				Ogre::VertexBoneAssignment vertAssign;
				vertAssign.boneIndex = boneIdx;
				vertAssign.vertexIndex = (unsigned int)j;
				if(numbones == 1) 
				{
					vertAssign.weight = 1.0;
				} // single assignment
				else 
				{
					vertAssign.weight=(Ogre::Real)intweight[0]/100.0;
				}
				ogreSubMesh->addBoneAssignment(vertAssign);
				if(numbones > 1) 
				{
					// this somewhat contorted logic is because the first weight [0] matches to the bone assignment
					// located with pVertex. The next two weights [1][2] match up to the first two bones found
					// with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight
					for(wh = 0; wh < 3; wh++) 
					{
						boneIdx = intbones[wh];
						if(boneIdx == -1) 
							break;
						vertAssign.boneIndex = boneIdx;
						vertAssign.vertexIndex = (unsigned int)j;
						if(wh == 2) 
						{ 
							// fourth weight is 1.0-(sumoffirstthreeweights)
							vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+
								((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0));
						}
						else 
						{
							vertAssign.weight=(Ogre::Real)intweight[wh+1];
						}
						ogreSubMesh->addBoneAssignment(vertAssign);
					} // for(k)
				} // if(numbones)
			}

        }
        pbuf->unlock();

        float* pTex = static_cast<float*>(
            tbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        logMgr.logMessage("Doing uvs, normals and indexes (v2)...");

        // Aargh, Milkshape uses stupid separate normal indexes for the same vertex like 3DS
        // Normals aren't described per vertex but per triangle vertex index
        // Pain in the arse, we have to do vertex duplication again if normals differ at a vertex (non smooth)
        // WHY don't people realise this format is a pain for passing to 3D APIs in vertex buffers?
        float* pNorm = static_cast<float*>(
            nbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        ogreSubMesh->indexData->indexCount = msMesh_GetTriangleCount (pMesh) * 3;
        // Always use 16-bit buffers, Milkshape can't handle more anyway
        Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
            createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT,
            ogreSubMesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        ogreSubMesh->indexData->indexBuffer = ibuf;
        unsigned short *pIdx = static_cast<unsigned short*>(
            ibuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        for (j = 0; j < ogreSubMesh->indexData->indexCount; j+=3)
        {
            msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, (int)j/3);
			msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3);
            word nIndices[3];
            msTriangle_GetVertexIndices (pTriangle, nIndices);
            msVec3 Normal;
            msVec2 uv;
            int k, vertIdx;

            for (k = 0; k < 3; ++k)
            {
                vertIdx = nIndices[k];
                // Face index
                pIdx[j+k] = vertIdx;

                // Vertex normals
                // For the moment, ignore any discrepancies per vertex
				msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]);
				msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]);
				pTex[(vertIdx*2)]=uv[0];
				pTex[(vertIdx*2)+1]=uv[1];
                pNorm[(vertIdx*3)] = Normal[0];
                pNorm[(vertIdx*3)+1] = Normal[1];
                pNorm[(vertIdx*3)+2] = Normal[2];
            }

        } // Faces
        nbuf->unlock();
        ibuf->unlock();
        tbuf->unlock();

        // Now use Ogre's ability to reorganise the vertex buffers the best way
        Ogre::VertexDeclaration* newDecl = 
            ogreSubMesh->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
                foundBoneAssignment, false);
        Ogre::BufferUsageList bufferUsages;
        for (size_t u = 0; u <= newDecl->getMaxSource(); ++u)
            bufferUsages.push_back(Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        ogreSubMesh->vertexData->reorganiseBuffers(newDecl, bufferUsages);


        logMgr.logMessage("Geometry done.");
    } // SubMesh

    // Set bounds
    ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(maxSquaredRadius));
    ogreMesh->_setBounds(Ogre::AxisAlignedBox(min, max), false);


    // Keep hold of a Skeleton pointer for deletion later
    // Mesh uses Skeleton pointer for skeleton name
    Ogre::SkeletonPtr pSkel;

    if (exportSkeleton && foundBoneAssignment)
    {
        // export skeleton, also update mesh to point to it
        pSkel = doExportSkeleton(pModel, ogreMesh);
    }
    else if (!exportSkeleton && foundBoneAssignment)
    {
        // We've found bone assignments, but skeleton is not to be exported
        // Prompt the user to find the skeleton
        if (!locateSkeleton(ogreMesh))
            return;

    }

    // Export
    logMgr.logMessage("Creating MeshSerializer..");
    Ogre::MeshSerializer serializer;
    logMgr.logMessage("MeshSerializer created.");

    // Generate LODs if required
    if (generateLods)
    {
        // Build LOD depth list
        Ogre::Mesh::LodDistanceList distList;
        float depth = 0;
        for (unsigned short depthidx = 0; depthidx < numLods; ++depthidx)
        {
            depth += lodDepthIncrement;
            distList.push_back(depth);
        }

        ogreMesh->generateLodLevels(distList, lodReductionMethod, lodReductionAmount);
    }

    if (generateEdgeLists)
    {
        ogreMesh->buildEdgeList();
    }

    if (generateTangents)
    {
		unsigned short src, dest;
		ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest);
		ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity);
    }

    // Export
    Ogre::String msg;
	msg  = "Exporting mesh data to file '" + Ogre::String(szFile) + "'";
    logMgr.logMessage(msg);
    serializer.exportMesh(ogreMesh.getPointer(), szFile);
    logMgr.logMessage("Export successful");

    Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle());
    if (!pSkel.isNull())
        Ogre::SkeletonManager::getSingleton().remove(pSkel->getHandle());

	if (exportMaterials && msModel_GetMaterialCount(pModel) > 0)
	{
		doExportMaterials(pModel);
	}
}
void GPUBillboardSet::createVertexDataForVertexAndGeometryShaders(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_POINT_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size(); 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = false; 
	mRenderOp.indexData = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
    Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);

	// Create vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
		mRenderOp.vertexData->vertexCount,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for (itr=elems.begin(); itr!=elems.end(); ++itr)
		{
			Ogre::VertexElement& elem = *itr;
			if (elem.getSemantic() == Ogre::VES_POSITION)
			{
				elem.baseVertexPointerToElement(pVert, &pReal);
				*pReal = vertex.position.x; *pReal++;
				*pReal = vertex.position.y; *pReal++;
				*pReal = vertex.position.z; *pReal++;
			}
			else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
			{
				elem.baseVertexPointerToElement(pVert, &pRGBA);
				renderSystem->convertColourValue(vertex.color, pRGBA);
			}
		}
		// Go to next vertex 
		pVert += vbuf->getVertexSize();
	}
	vbuf->unlock();

    // Set material
    this->setMaterial("GPUBillboardWithGS");
}
예제 #28
0
	void BtOgreSoftBody::updateOgreMesh()
	{
		Ogre::Node *ogreNode = mEntity->getParentNode();
		
		//printf("updateOgreMesh %d %s %s\n", internalId, mEntity->getName().c_str(), ogreNode->getName().c_str());
		
		Ogre::MeshPtr mesh = mEntity->getMesh();
		Ogre::Mesh::SubMeshIterator subMeshI = mesh->getSubMeshIterator();
		Ogre::SubMesh* subMesh = NULL;
		
		Ogre::VertexData* vData = NULL;
		Ogre::VertexDeclaration* vDeclaration = NULL;
		const Ogre::VertexElement* vPosElement = NULL;
		
		bool isSharedVerticesAdded = false;
		unsigned short bufferIndex = 0;
		Ogre::HardwareVertexBufferSharedPtr vBuffer;
		
		// Can not do arithmetic operations on void*
		unsigned char* lockedMem = NULL;
		float* vPosition;
		
		btSoftBody::tNodeArray& btNodes = mSoftBody->m_nodes;
		//printf("Bullet nodes size %d\n", btNodes.size());
		
		int ogreVertexIdx = 0;
		
		while (subMeshI.hasMoreElements()) {
			subMesh = subMeshI.getNext();
			
			if (subMesh->useSharedVertices) {
				
				if (isSharedVerticesAdded) {
					continue;
				}
				
				vData = mesh->sharedVertexData;
				
				// We need to add shared vertices only once
				isSharedVerticesAdded = true;
			} else  {
				vData = subMesh->vertexData;
			}
			
			vDeclaration = vData->vertexDeclaration;
			vPosElement = vDeclaration->findElementBySemantic(Ogre::VES_POSITION);
			
			bufferIndex = vPosElement->getSource();
			vBuffer = vData->vertexBufferBinding->getBuffer(bufferIndex);
			
			// Lock the buffer before reading from it
			lockedMem = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
			
			// Read each vertex
			for (unsigned int i = 0; i < vData->vertexCount; ++i) {
				vPosElement->baseVertexPointerToElement(lockedMem, &vPosition);
				
				int idx = getBulletIndex(ogreVertexIdx);
				
				*vPosition++ = btNodes[idx].m_x.x();
				*vPosition++ = btNodes[idx].m_x.y();
				*vPosition = btNodes[idx++].m_x.z();
				
				// Point to the next vertex
				lockedMem += vBuffer->getVertexSize();
				
				ogreVertexIdx++;
			}
			
			vBuffer->unlock();
		}
				
		btTransform transform = mSoftBody->getWorldTransform();
		btQuaternion rot = transform.getRotation();
	    ogreNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
	    btVector3 pos = transform.getOrigin();
	    ogreNode->setPosition(pos.x(), pos.y(), pos.z());
		
	}
예제 #29
0
void MeshUtils::meshBuffersToArrays(const Ogre::MeshPtr& mesh, Ogre::Vector3* vertices, unsigned long* indices)
{
	bool added_shared = false;
	size_t current_offset = 0;
	size_t shared_offset = 0;
	size_t next_offset = 0;
	size_t index_offset = 0;

	//const Ogre::Vector3 &position = ent->getParentNode()->_getDerivedPosition();
	//const Ogre::Quaternion &orient = ent->getParentNode()->_getDerivedOrientation();
	//const Ogre::Vector3 &scale = ent->getParentNode()->_getDerivedScale();

	const Ogre::Vector3 &position = Ogre::Vector3::ZERO;
	const Ogre::Quaternion &orient = Ogre::Quaternion::IDENTITY;
	const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE;

	Ogre::Mesh::SubMeshIterator itr = mesh->getSubMeshIterator();
	while (itr.hasMoreElements()) {
			Ogre::SubMesh* submesh = itr.getNext();

			Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

			if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared)) {
					if (submesh->useSharedVertices) {
							added_shared = true;
							shared_offset = current_offset;
						}

					const Ogre::VertexElement* posElem =
					    vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

					Ogre::HardwareVertexBufferSharedPtr vbuf =
					    vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

					unsigned char* vertex =
					    static_cast<unsigned char*> (vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

					// There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
					//  as second argument. So make it float, to avoid trouble when Ogre::Real will
					//  be comiled/typedefed as double:
					//      Ogre::Real* pReal;
					float* pReal;

					for (size_t k = 0; k < vertex_data->vertexCount; ++k, vertex += vbuf->getVertexSize()) {
							posElem->baseVertexPointerToElement(vertex, &pReal);

							Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);

							vertices[current_offset + k] = (orient * (pt * scale)) + position;
							//vertices[current_offset + k] = pt;
						}

					vbuf->unlock();
					next_offset += vertex_data->vertexCount;
				}


			Ogre::IndexData* index_data = submesh->indexData;
			size_t numTris = index_data->indexCount / 3;
			Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

			bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

			unsigned long* pLong = static_cast<unsigned long*> (ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
			unsigned short* pShort = reinterpret_cast<unsigned short*> (pLong);


			size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset;

			if (use32bitindexes) {
					for (size_t k = 0; k < numTris * 3; ++k) {
							indices[index_offset++] = pLong[k] + static_cast<unsigned long> (offset);
						}
				} else {
					for (size_t k = 0; k < numTris * 3; ++k) {
							indices[index_offset++] = static_cast<unsigned long> (pShort[k]) +
							                          static_cast<unsigned long> (offset);
						}
				}

			ibuf->unlock();
			current_offset = next_offset;
		}
}
예제 #30
0
void Renderer::FindClosestPolygon(Ogre::Entity* entity, float& closestDistance,
                                       Ogre::Vector3& position, Ogre::Vector3& normal)
{
    closestDistance = std::numeric_limits<float>::max();    // default value (means
                                                            // nothing detected)

    // Get transformation
    Ogre::SceneNode* parentNode = entity->getParentSceneNode();
    Ogre::Vector3 parentPos;
    Ogre::Quaternion parentOrientation;
    Ogre::Vector3 parentScale;
    if (parentNode)
    {
        parentPos = parentNode->_getDerivedPosition();
        parentOrientation = parentNode->_getDerivedOrientation();
        parentScale = parentNode->_getDerivedScale();
    }
    else
    {
        parentPos = Ogre::Vector3::ZERO;
        parentOrientation = Ogre::Quaternion::IDENTITY;
        parentScale = Ogre::Vector3::UNIT_SCALE;
    }

    // Handle animated entities
    bool isAnimated = entity->hasSkeleton();
    if (isAnimated)
    {
        entity->addSoftwareAnimationRequest(false);
        entity->_updateAnimation();
    }

    // Loop through each submesh
    Ogre::MeshPtr mesh = entity->getMesh();
    for (uint i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* subMesh = mesh->getSubMesh(i);

        // Ignore anything that isn't a triangle List
        if (subMesh->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST)
            continue;

        // Get the vertex data
        Ogre::VertexData* vertexData;
        if (subMesh->useSharedVertices)
        {
            if (isAnimated)
                vertexData = entity->_getSkelAnimVertexData();
            else
                vertexData = mesh->sharedVertexData;
        }
        else
        {
            if (isAnimated)
                vertexData = entity->getSubEntity(i)->_getSkelAnimVertexData();
            else
                vertexData = subMesh->vertexData;
        }

        // Get the size of one vertex
        const Ogre::VertexElement* posEl =
            vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
        Ogre::HardwareVertexBufferSharedPtr vBuff =
            vertexData->vertexBufferBinding->getBuffer(posEl->getSource());
        uint vertexSize = vBuff->getVertexSize();

        // Save pointer to first vertex
        short* pVertex = (short*)vBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
        short* pStartVertex = pVertex;

        // Get the index buffer
        // If it is null then skip as it must be a point cloud
        Ogre::HardwareIndexBufferSharedPtr iBuff = subMesh->indexData->indexBuffer;

        if (iBuff.isNull())
            continue;

        uint* pLong = (uint*)iBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
        uint16_t* pShort = (uint16_t*)pLong;

        // Look through each vertex and check each triangle with the ray
        Ogre::Vector3 vertexPos;
        Ogre::Vector3 vertex1;
        Ogre::Vector3 vertex2;
        float* pReal;
        uint index;
        for (uint k = 0; k < subMesh->indexData->indexCount; k++)
        {
            // Read index value
            if (iBuff->getType() == Ogre::HardwareIndexBuffer::IT_32BIT)    // if 32bit indexes
            {
                index = (uint)pLong[k];
            }
            else
            {
                index = (uint)pShort[k];
            }

            // Read referenced vertex
            pVertex = pStartVertex + (vertexSize * index);              // calculate pointer
            posEl->baseVertexPointerToElement(pVertex, &pReal);         // read vertex
            vertexPos = Ogre::Vector3(pReal[0], pReal[1], pReal[2]);    // read position values

            // Apply world transformations
            if (parentNode)
                vertexPos = (parentOrientation * (vertexPos * parentScale)) + parentPos;

            // Figure out triangle and calculate the distance if it's the closest
            switch (k % 3)
            {
            case 0:
                vertex1 = vertexPos;
                break;

            case 1:
                vertex2 = vertexPos;
                break;

            case 2:
                RayToTriangleCheck(vertex1, vertex2, vertexPos, closestDistance, position, normal);
                break;

            default:
                break;
            }
        }

        iBuff->unlock();
        vBuff->unlock();
    }

    if (isAnimated)
    {
        entity->removeSoftwareAnimationRequest(false);
    }
}