示例#1
0
void ESKOgre::createFakeEntity(Ogre::SceneManager *mSceneMgr) {
	Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual(name + "_skeleton", XENOVIEWER_RESOURCE_GROUP);
	msh->setSkeletonName(name);

	Ogre::SubMesh* sub = msh->createSubMesh();
	const size_t nVertices = 3;
	const size_t nVertCount = 3;
	const size_t vbufCount = nVertCount*nVertices;
	float *vertices = (float *)malloc(sizeof(float)*vbufCount);

	for (size_t i = 0; i < nVertices; i++) {
		vertices[i*nVertCount] = 0.0;
		vertices[i*nVertCount + 1] = 0.0;
		vertices[i*nVertCount + 2] = 0.0;
	}

	const size_t ibufCount = 3;
	unsigned short *faces = (unsigned short *)malloc(sizeof(unsigned short) * ibufCount);

	for (size_t i = 0; i < ibufCount; i++) {
		faces[i] = i;
	}

	msh->sharedVertexData = new Ogre::VertexData();
	msh->sharedVertexData->vertexCount = nVertices;

	Ogre::VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;

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

	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
	Ogre::VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
	bind->setBinding(0, vbuf);
	Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ibufCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
	sub->useSharedVertices = true;
	sub->indexData->indexBuffer = ibuf;
	sub->indexData->indexCount = ibufCount;
	sub->indexData->indexStart = 0;

	msh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100));
	msh->_setBoundingSphereRadius(100);
	msh->load();

	free(faces);
	free(vertices);

	skeleton_entity = mSceneMgr->createEntity(name + "_skeleton");
	skeleton_node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	skeleton_node->attachObject(skeleton_entity);
	skeleton_node->setVisible(false);
}
示例#2
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh, const Ogre::String& name, int bone_id )
{
    int offset_to_vertex     = offset_to_data;
    int offset_to_triangle_t = offset_to_vertex + 0x04 + file->GetU32LE( offset_to_vertex );
    int number_of_triangle_t = file->GetU16LE( offset_to_triangle_t );
    u16 tpage  = file->GetU16LE( offset_to_triangle_t + 0x02 );
    int offset_to_quad_t     = offset_to_triangle_t + 0x04 + number_of_triangle_t * 0x10;
    int number_of_quad_t     = file->GetU16LE( offset_to_quad_t );
    int offset_to_triangle   = offset_to_quad_t + 0x4 + number_of_quad_t * 0x14;
    int number_of_triangle   = file->GetU16LE( offset_to_triangle );
    int offset_to_quad       = offset_to_triangle + 0x4 + number_of_triangle * 0x14;
    int number_of_quad       = file->GetU16LE( offset_to_quad );

    Ogre::SubMesh* sub_mesh = mesh->createSubMesh( name );
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_triangle_t * 3 + number_of_quad_t * 6 + number_of_triangle * 3 + number_of_quad * 6 );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

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

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    Ogre::RGBA colours[ sub_mesh->vertexData->vertexCount ];



    // add textured triangle
    for (int j = 0; j < number_of_triangle_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        u16 clut = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        int x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add textured quad
    for (int j = 0; j < number_of_quad_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        u16 clut = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        int x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x10) + texture.start_x;
        dt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x11) + texture.start_y;
        dt.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);
        rs->convertColourValue(colour, colours + cur_index + 3);
        rs->convertColourValue(colour, colours + cur_index + 4);
        rs->convertColourValue(colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }



    // add color triangle
    for (int j = 0; j < number_of_triangle; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        at.x = bt.x = ct.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x13) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add color quad
    for (int j = 0; j < number_of_quad; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        at.x = bt.x = ct.x = dt.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = dt.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x13) / 256.0f);
        Ogre::ColourValue d_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x14) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x15) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x16) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x17) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);
        rs->convertColourValue(b_colour, colours + cur_index + 3);
        rs->convertColourValue(c_colour, colours + cur_index + 4);
        rs->convertColourValue(d_colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }

    vbuf0->unlock();
    vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours, true);
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();

    if (bone_id != -1)
    {
        LOGGER->Log("Assign bones to vertexes\n");

        int vertex_number = sub_mesh->vertexData->vertexCount;
        for( int i = 0; i < vertex_number; ++i )
        {
            Ogre::VertexBoneAssignment vba;
            vba.vertexIndex = i;
            vba.boneIndex = bone_id;
            vba.weight = 1.0f;
            sub_mesh->addBoneAssignment( vba );
        }
    }
}
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);
	}
}
示例#4
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh )
{
    File* file12 = new File( "./data/field/5/1b/1/12/1" );
    u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff;
    LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" );
    u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4;
    LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" );



    int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 );
    int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 );
    int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 );
    int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 );
    int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a );
    int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c );
    int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e );
    int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 );

    u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 );
    u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 );
    u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c );
    u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 );



    Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */);
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >(
        number_of_monochrome_textured_quads * 6 +
        number_of_monochrome_textured_triangles * 3/* +
        number_of_shaded_textured_quads * 6 +
        number_of_shaded_textured_triangles * 3 +
        number_of_gradated_quads * 6 +
        number_of_gradated_triangles * 3 +
        number_of_monochrome_quads * 6 +
        number_of_monochrome_triangles * 3*/ );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

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

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    
    std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount);

    Ogre::RGBA* colours = coloursVec.data();



    for( int i = 0; i < number_of_monochrome_textured_quads; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );
        int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;




        int image_id = file->GetU8( pointer_to_mesh_data + 0x13 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/
        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );
        Ogre::Vector2 dt( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );
        rs->convertColourValue( colour, colours + cur_index + 3 );
        rs->convertColourValue( colour, colours + cur_index + 4 );
        rs->convertColourValue( colour, colours + cur_index + 5 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;
        idata[ cur_index + 3 ] = cur_index + 3;
        idata[ cur_index + 4 ] = cur_index + 4;
        idata[ cur_index + 5 ] = cur_index + 5;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 3;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 4;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 5;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );



        cur_index += 6;
        pointer_to_mesh_data += 0x18;
    }



    for( int i = 0; i < number_of_monochrome_textured_triangles; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;

        int image_id = file->GetU8( pointer_to_mesh_data + 0x6 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/

        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );

        cur_index += 3;
        pointer_to_mesh_data += 0x14;
    }



    vbuf0->unlock();
    vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true );
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();



    delete file12;
}
示例#5
0
 // Write submesh data to an Ogre compatible mesh
 bool Submesh::createOgreSubmesh(Ogre::MeshPtr pMesh,const ParamList& params)
 {
     size_t i,j;
     bool stat;
     // Create a new submesh
     Ogre::SubMesh* pSubmesh;
     if (m_name != "")
         pSubmesh = pMesh->createSubMesh(m_name.c_str());
     else
         pSubmesh = pMesh->createSubMesh();
     // Set material
     pSubmesh->setMaterialName(m_pMaterial->name().c_str());
     // Set use shared geometry flag
     pSubmesh->useSharedVertices = params.useSharedGeom;
     // Create vertex data for current submesh
     pSubmesh->vertexData = new Ogre::VertexData();
     // Set number of indexes
     pSubmesh->indexData->indexCount = 3*m_faces.size();
     pSubmesh->vertexData->vertexCount = m_vertices.size();
     // Check if we need to use 32 bit indexes
     bool use32BitIndexes = false;
     if (m_vertices.size() > 65536 || params.useSharedGeom)
     {
         use32BitIndexes = true;
     }
     // Create a new index buffer
     pSubmesh->indexData->indexBuffer = 
         Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
             use32BitIndexes ? Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT,
             pSubmesh->indexData->indexCount,
             Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
     // Fill the index buffer with faces data
     if (use32BitIndexes)
     {
         Ogre::uint32* pIdx = static_cast<Ogre::uint32*>(
             pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
         for (i=0; i<m_faces.size(); i++)
         {
             *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[0]);
             *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[1]);
             *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[2]);
         }
         pSubmesh->indexData->indexBuffer->unlock();
     }
     else
     {
         Ogre::uint16* pIdx = static_cast<Ogre::uint16*>(
             pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
         for (i=0; i<m_faces.size(); i++)
         {
             *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[0]);
             *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[1]);
             *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[2]);
         }
         pSubmesh->indexData->indexBuffer->unlock();
     }
     // Define vertex declaration (only if we're not using shared geometry)
     if(!params.useSharedGeom)
     {
         Ogre::VertexDeclaration* pDecl = pSubmesh->vertexData->vertexDeclaration;
         unsigned buf = 0;
         size_t offset = 0;
         // Add vertex position
         pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
         offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
         // Add vertex normal
         if (params.exportVertNorm)
         {
             pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
             offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
         }
         // Add vertex colour
         if(params.exportVertCol)
         {
             pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
             offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
         }
         // Add texture coordinates
         for (i=0; i<m_vertices[0].texcoords.size(); i++)
         {
             Ogre::VertexElementType uvType = Ogre::VertexElement::multiplyTypeCount(Ogre::VET_FLOAT1, 2);
             pDecl->addElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, static_cast<unsigned short>(i));
             offset += Ogre::VertexElement::getTypeSize(uvType);
         }
         Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration(
             params.exportVBA, params.exportBlendShapes || params.exportVertAnims, false);
         // Fill the vertex buffer using the newly created vertex declaration
         stat = createOgreVertexBuffer(pSubmesh,pDecl,m_vertices);
         // Write vertex bone assignements list
         if (params.exportVBA)
         {
             // Create a new vertex bone assignements list
             Ogre::SubMesh::VertexBoneAssignmentList vbas;
             // Scan list of shared geometry vertices
             for (i=0; i<m_vertices.size(); i++)
             {
                 vertex v = m_vertices[i];
                 // Add all bone assignemnts for every vertex to the bone assignements list
                 for (j=0; j<v.vbas.size(); j++)
                 {
                     Ogre::VertexBoneAssignment vba;
                     vba.vertexIndex = static_cast<unsigned int>(i);
                     vba.boneIndex = v.vbas[j].jointIdx;
                     vba.weight = v.vbas[j].weight;
                     vbas.insert(Ogre::SubMesh::VertexBoneAssignmentList::value_type(i, vba));
                 }
             }
             // Rationalise the bone assignements list
             pSubmesh->parent->_rationaliseBoneAssignments(pSubmesh->vertexData->vertexCount,vbas);
             // Add bone assignements to the submesh
             for (Ogre::SubMesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++)
             {
                 pSubmesh->addBoneAssignment(bi->second);
             }
             pSubmesh->_compileBoneAssignments();
         }
         pSubmesh->vertexData->reorganiseBuffers(pOptimalDecl);
     }
     return true;
 }
Ogre::SceneNode *TutorialApplication::loadBSP(std::shared_ptr<l2p::UModel> m, bool ignoreNonVisible) {
  l2p::Name name = m->package->name;
  std::vector<float> vertex_data;
  std::vector<uint32_t> index_buf;
  l2p::Box bounds;

  // Build vertex and index buffer.
  for (auto ni = m->nodes.begin(), ne = m->nodes.end(); ni != ne; ++ni) {
    l2p::BSPNode &n = *ni;
    l2p::BSPSurface &s = m->surfaces[n.surface];

    if (ignoreNonVisible && ignoreNode(m.get(), n, s))
      continue;

    uint32_t vert_start = vertex_data.size() / 8;

    const Ogre::Vector3 uvec = ogre_cast(m->vectors[s.U]);
    const Ogre::Vector3 vvec = ogre_cast(m->vectors[s.V]);
    const Ogre::Vector3 base = ogre_cast(m->points[s.base]);
    int usize = 0;
    int vsize = 0;
    std::shared_ptr<l2p::UTexture> mat = s.material;
    if (mat) {
      usize = mat->USize;
      vsize = mat->VSize;
    }

    if (usize == 0 || vsize == 0)
      usize = vsize = 64;

    // Vertex buffer.
    if (n.num_verticies > 0) {
      l2p::Vector Normal = m->vectors[s.normal];

      for (uint32_t vert_index = 0; vert_index < n.num_verticies; ++vert_index) {
        const l2p::Vector &pos = m->points[m->vertexes[n.vert_pool + vert_index].vertex];
        const Ogre::Vector3 dist(ogre_cast(pos) - base);
        const Ogre::Vector2 tcoord((dist | uvec) / float(usize), (dist | vvec) / float(vsize));
        bounds += pos;
        vertex_data.push_back(pos.X);
        vertex_data.push_back(pos.Y);
        vertex_data.push_back(pos.Z);
        vertex_data.push_back(Normal.X);
        vertex_data.push_back(Normal.Y);
        vertex_data.push_back(Normal.Z);
        vertex_data.push_back(tcoord.x);
        vertex_data.push_back(tcoord.y);
      }

      if (s.flags & l2p::PF_TwoSided) {
        for (uint32_t vert_index = 0; vert_index < n.num_verticies; ++vert_index) {
          const l2p::Vector &pos = m->points[m->vertexes[n.vert_pool + vert_index].vertex];
          const Ogre::Vector3 dist(ogre_cast(pos) - base);
          const Ogre::Vector2 tcoord((dist | uvec) / float(usize), (dist | vvec) / float(vsize));
          vertex_data.push_back(pos.X);
          vertex_data.push_back(pos.Y);
          vertex_data.push_back(pos.Z);
          vertex_data.push_back(Normal.X);
          vertex_data.push_back(Normal.Y);
          vertex_data.push_back(-Normal.Z);
          vertex_data.push_back(tcoord.x);
          vertex_data.push_back(tcoord.y);
        }
      }
    }

    // Index buffer.
    for (int verti = 2; verti < n.num_verticies; ++verti) {
      index_buf.push_back(vert_start);
      index_buf.push_back(vert_start + verti - 1);
      index_buf.push_back(vert_start + verti);
    }
    if (s.flags & l2p::PF_TwoSided) {
      for (int verti = 2; verti < n.num_verticies; ++verti) {
        index_buf.push_back(vert_start);
        index_buf.push_back(vert_start + verti);
        index_buf.push_back(vert_start + verti - 1);
      }
    }
  }

  if (vertex_data.size() == 0 || index_buf.size() == 0)
    return nullptr;

  Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(Ogre::String(name) + Ogre::String(m->name), "General");
  Ogre::VertexData  *data = new Ogre::VertexData();
  mesh->sharedVertexData = data;
  data->vertexCount = vertex_data.size() / 8;

  Ogre::VertexDeclaration *decl = data->vertexDeclaration;
  uint32_t offset = 0;
  decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
  decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
  decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

  Ogre::HardwareVertexBufferSharedPtr vbuf =
    Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
      offset,
      data->vertexCount,
      Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  vbuf->writeData(0, vbuf->getSizeInBytes(), &vertex_data.front(), true);
  data->vertexBufferBinding->setBinding(0, vbuf);

  // Setup index buffer.
  Ogre::HardwareIndexBufferSharedPtr ibuf =
    Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
      Ogre::HardwareIndexBuffer::IT_32BIT,
      index_buf.size(),
      Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

  ibuf->writeData(0, ibuf->getSizeInBytes(), &index_buf.front(), true);
  Ogre::SubMesh *subMesh = mesh->createSubMesh();
  subMesh->useSharedVertices = true;
  subMesh->indexData->indexBuffer = ibuf;
  subMesh->indexData->indexCount  = index_buf.size();
  subMesh->indexData->indexStart  = 0;

  mesh->_setBounds(Ogre::AxisAlignedBox(bounds.min.X, bounds.min.Y, bounds.min.Z, bounds.max.X, bounds.max.Y, bounds.max.Z));
  mesh->_setBoundingSphereRadius((std::max(bounds.max.X - bounds.min.X, std::max(bounds.max.Y - bounds.min.Y, bounds.max.Z - bounds.min.Z))) / 2.0);

  mesh->load();

  Ogre::Entity *ent = mSceneMgr->createEntity(Ogre::String(name) + Ogre::String(m->name) + "E", Ogre::String(name) + Ogre::String(m->name));
  ent->setUserAny(Ogre::Any(static_cast<l2p::UObject*>(m.get())));
  ent->setMaterialName("StaticMesh/Default");
  Ogre::SceneNode *node = mUnrealCordNode->createChildSceneNode();
  node->attachObject(ent);

  return node;
}
示例#7
0
void RoR::GfxEnvmap::SetupEnvMap()
{
    m_rtt_texture = Ogre::TextureManager::getSingleton().getByName("EnvironmentTexture");

    for (int face = 0; face < NUM_FACES; face++)
    {
        m_render_targets[face] = m_rtt_texture->getBuffer(face)->getRenderTarget();
        m_cameras[face] = gEnv->sceneManager->createCamera("EnvironmentCamera-" + TOSTRING(face));
        m_cameras[face]->setAspectRatio(1.0);
        m_cameras[face]->setProjectionType(Ogre::PT_PERSPECTIVE);
        m_cameras[face]->setFixedYawAxis(false);
        m_cameras[face]->setFOVy(Ogre::Degree(90));
        m_cameras[face]->setNearClipDistance(0.1f);
        m_cameras[face]->setFarClipDistance(gEnv->mainCamera->getFarClipDistance());

        Ogre::Viewport* v = m_render_targets[face]->addViewport(m_cameras[face]);
        v->setOverlaysEnabled(false);
        v->setClearEveryFrame(true);
        v->setBackgroundColour(gEnv->mainCamera->getViewport()->getBackgroundColour());
        m_render_targets[face]->setAutoUpdated(false);
    }

    m_cameras[0]->setDirection(+Ogre::Vector3::UNIT_X);
    m_cameras[1]->setDirection(-Ogre::Vector3::UNIT_X);
    m_cameras[2]->setDirection(+Ogre::Vector3::UNIT_Y);
    m_cameras[3]->setDirection(-Ogre::Vector3::UNIT_Y);
    m_cameras[4]->setDirection(-Ogre::Vector3::UNIT_Z);
    m_cameras[5]->setDirection(+Ogre::Vector3::UNIT_Z);

    if (App::diag_envmap.GetActive())
    {
        // create fancy mesh for debugging the envmap
        Ogre::Overlay* overlay = Ogre::OverlayManager::getSingleton().create("EnvMapDebugOverlay");
        if (overlay)
        {
            Ogre::Vector3 position = Ogre::Vector3::ZERO;
            float scale = 1.0f;

            Ogre::MeshPtr mesh = Ogre::MeshManager::getSingletonPtr()->createManual("cubeMapDebug", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
            // create sub mesh
            Ogre::SubMesh* sub = mesh->createSubMesh();

            // Initialize render operation
            sub->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
            //
            sub->useSharedVertices = true;
            mesh->sharedVertexData = new Ogre::VertexData;
            sub->indexData = new Ogre::IndexData;

            // Create vertex declaration
            size_t offset = 0;
            mesh->sharedVertexData->vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
            offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
            mesh->sharedVertexData->vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES);

            // Create and bind vertex buffer
            mesh->sharedVertexData->vertexCount = 14;
            Ogre::HardwareVertexBufferSharedPtr vertexBuffer =
                Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
                    mesh->sharedVertexData->vertexDeclaration->getVertexSize(0),
                    mesh->sharedVertexData->vertexCount,
                    Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
            mesh->sharedVertexData->vertexBufferBinding->setBinding(0, vertexBuffer);

            // Vertex data
            static const float vertexData[] = {
                // Position      Texture coordinates    // Index
                0.0, 2.0, -1.0, 1.0, 1.0, //  0
                0.0, 1.0, -1.0, -1.0, 1.0, //  1
                1.0, 2.0, -1.0, 1.0, -1.0, //  2
                1.0, 1.0, -1.0, -1.0, -1.0, //  3
                2.0, 2.0, 1.0, 1.0, -1.0, //  4
                2.0, 1.0, 1.0, -1.0, -1.0, //  5
                3.0, 2.0, 1.0, 1.0, 1.0, //  6
                3.0, 1.0, 1.0, -1.0, 1.0, //  7
                4.0, 2.0, -1.0, 1.0, 1.0, //  8
                4.0, 1.0, -1.0, -1.0, 1.0, //  9
                1.0, 3.0, -1.0, 1.0, 1.0, // 10
                2.0, 3.0, 1.0, 1.0, 1.0, // 11
                1.0, 0.0, -1.0, -1.0, 1.0, // 12
                2.0, 0.0, 1.0, -1.0, 1.0, // 13
            };

            // Fill vertex buffer
            float* pData = static_cast<float*>(vertexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
            for (size_t vertex = 0, i = 0; vertex < mesh->sharedVertexData->vertexCount; vertex++)
            {
                // Position
                *pData++ = position.x + scale * vertexData[i++];
                *pData++ = position.y + scale * vertexData[i++];
                *pData++ = 0.0;

                // Texture coordinates
                *pData++ = vertexData[i++];
                *pData++ = vertexData[i++];
                *pData++ = vertexData[i++];
            }
            vertexBuffer->unlock();

            // Create index buffer
            sub->indexData->indexCount = 36;
            Ogre::HardwareIndexBufferSharedPtr indexBuffer =
                Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
                    Ogre::HardwareIndexBuffer::IT_16BIT,
                    sub->indexData->indexCount,
                    Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
            sub->indexData->indexBuffer = indexBuffer;

            // Index data
            static const Ogre::uint16 indexData[] = {
                // Indices         // Face
                 0,  1,  2,        //  0
                 2,  1,  3,        //  1
                 2,  3,  4,        //  2
                 4,  3,  5,        //  3
                 4,  5,  6,        //  4
                 6,  5,  7,        //  5
                 6,  7,  8,        //  6
                 8,  7,  9,        //  7
                10,  2, 11,        //  8
                11,  2,  4,        //  9
                 3, 12,  5,        // 10
                 5, 12, 13,        // 11
            };

            // Fill index buffer
            indexBuffer->writeData(0, indexBuffer->getSizeInBytes(), indexData, true);

            mesh->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE);
            mesh->_setBoundingSphereRadius(10);
            mesh->load();

            Ogre::Entity* e = gEnv->sceneManager->createEntity(mesh->getName());
            e->setCastShadows(false);
            e->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY - 1);
            e->setVisible(true);

            e->setMaterialName("tracks/EnvMapDebug");
            Ogre::SceneNode* mDebugSceneNode = new Ogre::SceneNode(gEnv->sceneManager);
            mDebugSceneNode->attachObject(e);
            mDebugSceneNode->setPosition(Ogre::Vector3(0, 0, -5));
            mDebugSceneNode->setFixedYawAxis(true, Ogre::Vector3::UNIT_Y);
            mDebugSceneNode->setVisible(true);
            mDebugSceneNode->_update(true, true);
            mDebugSceneNode->_updateBounds();
            overlay->add3D(mDebugSceneNode);
            overlay->show();
        }
    }
}
示例#8
0
void GeometryFactory::generateSphericDome (const Ogre::String &name, int segments, DomeType type) {
    // Return now if already exists
    if (Ogre::MeshManager::getSingleton ().resourceExists (name)) {
        return;
    }

    Ogre::LogManager::getSingleton ().logMessage (
        "Caelum: Creating " + name + " sphere mesh resource...");

    // Use the mesh manager to create the mesh
    Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton ().createManual (name, RESOURCE_GROUP_NAME);
    // Create a submesh
    Ogre::SubMesh *sub = msh->createSubMesh ();

    // Create the shared vertex data
    Ogre::VertexData *vertexData = new Ogre::VertexData ();
    msh->sharedVertexData = vertexData;

    // Define the vertices' format
    Ogre::VertexDeclaration *vertexDecl = vertexData->vertexDeclaration;
    size_t currOffset = 0;
    // Position
    vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
    currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
    // Normal
    vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
    currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT3);
    // Texture coordinates
    vertexDecl->addElement (0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
    currOffset += Ogre::VertexElement::getTypeSize (Ogre::VET_FLOAT2);

    // Allocate the vertex buffer
    switch (type) {
    case DT_GRADIENTS:
        vertexData->vertexCount = segments * (segments - 1) + 2;
        break;
    case DT_STARFIELD:
        vertexData->vertexCount = (segments + 1) * (segments + 1);
        break;
    };
    Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton ().createVertexBuffer (vertexDecl->getVertexSize (0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
    Ogre::VertexBufferBinding *binding = vertexData->vertexBufferBinding;
    binding->setBinding (0, vBuf);

    float *pVertex = static_cast<float *>(vBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD));

    // Allocate the index buffer
    switch (type) {
    case DT_GRADIENTS:
        sub->indexData->indexCount = 2 * segments * (segments - 1) * 3;
        break;
    case DT_STARFIELD:
        sub->indexData->indexCount = 2 * (segments - 1) * segments * 3;
        break;
    };
    sub->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton ().createIndexBuffer (Ogre::HardwareIndexBuffer::IT_16BIT, sub->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
    Ogre::HardwareIndexBufferSharedPtr iBuf = sub->indexData->indexBuffer;
    unsigned short *pIndices = static_cast<unsigned short *>(iBuf->lock (Ogre::HardwareBuffer::HBL_DISCARD));

    // Fill the buffers
    switch (type) {
    case DT_GRADIENTS:
        fillGradientsDomeBuffers (pVertex, pIndices, segments);
        break;
    case DT_STARFIELD:
        fillStarfieldDomeBuffers (pVertex, pIndices, segments);
        break;
    };

    // Close the vertex buffer
    vBuf->unlock ();

    // Close the index buffer
    iBuf->unlock ();

    // Finishing it...
    sub->useSharedVertices = true;
    msh->_setBounds (Ogre::AxisAlignedBox (-1, -1, -1, 1, 1, 1), false);
    msh->_setBoundingSphereRadius (1);
    msh->load ();

    Ogre::LogManager::getSingleton ().logMessage (
        "Caelum: generateSphericDome DONE");
}
示例#9
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();
}
void TutorialApplication::createSphere(const std::string& strName, const float r, const int nRings, const int nSegments) {
	Ogre::MeshPtr pSphere = Ogre::MeshManager::getSingleton().createManual(Ogre::String(strName), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	Ogre::SubMesh *pSphereVertex = pSphere->createSubMesh();
 
	pSphere->sharedVertexData = new Ogre::VertexData();
	Ogre::VertexData* vertexData = pSphere->sharedVertexData;
 
	// define the vertex format
	Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
	size_t currOffset = 0;
	// positions
	vertexDecl->addElement(0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	// normals
	vertexDecl->addElement(0, currOffset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	// two dimensional texture coordinates
	vertexDecl->addElement(0, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);
 
	// allocate the vertex buffer
	vertexData->vertexCount = (nRings + 1) * (nSegments+1);
	Ogre::HardwareVertexBufferSharedPtr vBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
	binding->setBinding(0, vBuf);
	float* pVertex = static_cast<float*>(vBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
 
	// allocate index buffer
	pSphereVertex->indexData->indexCount = 6 * nRings * (nSegments + 1);
	pSphereVertex->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
	Ogre::HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
	unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
 
	float fDeltaRingAngle = (Ogre::Math::PI / nRings);
	float fDeltaSegAngle = (2 * Ogre::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;
 
            Ogre::Vector3 vNormal = Ogre::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( Ogre::AxisAlignedBox( Ogre::Vector3(-r, -r, -r), Ogre::Vector3(r, r, r) ), false );
    pSphere->_setBoundingSphereRadius(r);
    // this line makes clear the mesh is loaded (avoids memory leaks)
    pSphere->load();
}
示例#11
0
bool Terrain::createTerrain()
{

	if(mMainViewport == NULL) 
		mMainViewport = Core::getSingleton().mCamera->getViewport();
	Ogre::CompositorManager::getSingleton().addCompositor(mMainViewport, "DemoCompositor");
	Ogre::CompositorManager::getSingleton().setCompositorEnabled(mMainViewport, "DemoCompositor", true);

	mMapData = MapDataManager::getSingletonPtr();
	DataLibrary* datalib = DataLibrary::getSingletonPtr();
	int terrainszie = mMapData->getMapSize() + 2 * MAPBOLDER + 1;

	Core::getSingleton().mSceneMgr->setSkyBox(true, "SkyBox",200);

	Ogre::GpuSharedParametersPtr sharedparams = Ogre::GpuProgramManager::getSingleton().getSharedParameters("TestSharedParamsName");
	float border = mMapData->getMapSize() * 12.0f;
	sharedparams->setNamedConstant("border", border);

	//创建灯光
	Core::getSingleton().mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
	mLight = Core::getSingleton().mSceneMgr->createLight("TerrainLight");
	mLight->setType(Ogre::Light::LT_DIRECTIONAL);
	mLight->setPosition(-500.0f,500.0f, 500.0f);
	mLight->setDirection(1.0f, -1.0f, -1.0f);
	mLight->setDiffuseColour(Ogre::ColourValue(0.5f, 0.5f,0.5f));
	mLight->setSpecularColour(Ogre::ColourValue(0.8f, 0.8f,0.8f));

	//设置深度图投影
	Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName("shadowdepthmap");
	if(tex.isNull())
		tex = Ogre::TextureManager::getSingleton().createManual("shadowdepthmap",
			Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 2048, 2048, 0, Ogre::PF_FLOAT16_R, Ogre::TU_RENDERTARGET);
	mShadowDepthMapTarget = tex->getBuffer()->getRenderTarget();
	Ogre::Viewport* vp = mShadowDepthMapTarget->addViewport(CameraContral::getSingleton().getShadowMapCamera());
	vp->setSkiesEnabled(false);
	vp->setOverlaysEnabled(false);
	vp->setVisibilityMask(VISMASK_OPAQUE);
	vp->setMaterialScheme("WriteDepthMap");
	vp->setBackgroundColour(Ogre::ColourValue(1.0f,1.0f,1.0f));
	mShadowDepthMapTarget->addListener(this);
	//弱爆了……
	Ogre::MaterialPtr mat;
	mat = Ogre::MaterialManager::getSingleton().getByName("TerrainTile");
	Ogre::AliasTextureNamePairList texAliasList;
	std::string texname;
	datalib->getData("GameData/BattleData/MapData/Ground/G0Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	datalib->getData("GameData/BattleData/MapData/Ground/G1Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse1",texname));
	datalib->getData("GameData/BattleData/MapData/Ground/G2Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse2",texname));
	datalib->getData("GameData/BattleData/MapData/Ground/G3Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse3",texname));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat1");
	datalib->getData("GameData/BattleData/MapData/Ground/G0Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat2");
	datalib->getData("GameData/BattleData/MapData/Ground/G1Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat3");
	datalib->getData("GameData/BattleData/MapData/Ground/G2Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat4");
	datalib->getData("GameData/BattleData/MapData/Ground/G3Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat1");
	datalib->getData("GameData/BattleData/MapData/Ground/G0Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat2");
	datalib->getData("GameData/BattleData/MapData/Ground/G1Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat3");
	datalib->getData("GameData/BattleData/MapData/Ground/G2Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat4");
	datalib->getData("GameData/BattleData/MapData/Ground/G3Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	//创建地面Mesh
	mTerrainNode = Core::getSingleton().mSceneMgr->getRootSceneNode()->createChildSceneNode("TerrainNode");

	int numVertices = terrainszie * terrainszie * VERTEX_QUAD;
	int numIndex = terrainszie * terrainszie * VERTEX_PREQUAD;
	Ogre::MeshPtr mTerrainMesh = Ogre::MeshManager::getSingleton().createManual("TerrianMesh",
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	Ogre::SubMesh* subMesh  = mTerrainMesh->createSubMesh();
	subMesh->useSharedVertices=false;
	subMesh->setMaterialName("TerrainTile");

	// 创建顶点数据结构
	subMesh->vertexData = new Ogre::VertexData();
	subMesh->vertexData->vertexStart = 0;
	subMesh->vertexData->vertexCount = numVertices;

	//顶点声明与缓冲区绑定
	Ogre::VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration;
	Ogre::VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding;

	//设置顶点数据结构
	size_t offsetUV = 0;
	vdecl->addElement(VERTEX_POS_BINDING, 0, Ogre::VET_FLOAT3,Ogre::VES_POSITION);//向顶点添加一个位置元素
	vdecl->addElement(VERTEX_NOM_BINDING, 0, Ogre::VET_FLOAT3,Ogre::VES_NORMAL);
	for(int i = 0 ; i < TEXTURE_COUNT ; i ++)
	{
		offsetUV += vdecl->addElement (VERTEX_UV_BINDING, offsetUV, Ogre::VET_FLOAT2,  Ogre::VES_TEXTURE_COORDINATES , i).getSize();
	}

	// 创建世界坐标顶点缓冲区
	Ogre::HardwareVertexBufferSharedPtr vbufPos =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		vdecl->getVertexSize(VERTEX_POS_BINDING),
		numVertices,
		Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
	vbind->setBinding(VERTEX_POS_BINDING, vbufPos);

	Ogre::HardwareVertexBufferSharedPtr vbufNOM =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		vdecl->getVertexSize(VERTEX_NOM_BINDING),
		numVertices,
		Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
	vbind->setBinding(VERTEX_NOM_BINDING, vbufNOM);

	// 创建纹理坐标顶点缓冲区
	Ogre::HardwareVertexBufferSharedPtr vbufUV =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		vdecl->getVertexSize(VERTEX_UV_BINDING),
		numVertices,
		Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
	vbind->setBinding(VERTEX_UV_BINDING, vbufUV);

	// 创建索引缓冲区
	Ogre::HardwareIndexBufferSharedPtr indexBuffer =
		Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
		Ogre::HardwareIndexBuffer::IT_16BIT ,
		numIndex,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	//创建地形
	float* pBufferPos = (float*)vbufPos->lock(Ogre::HardwareBuffer::HBL_DISCARD);
	float* pBufferUV = (float*)vbufUV->lock(Ogre::HardwareBuffer::HBL_DISCARD);
	float* pBufferNom = (float*)vbufNOM->lock(Ogre::HardwareBuffer::HBL_DISCARD);

	float startpos = - terrainszie * TILESIZE / 2;
	for(int y = 0 ; y < terrainszie; y ++)
	{
		for(int x = 0 ; x < terrainszie; x ++)
		{
			createTile(x, y, startpos + x * TILESIZE, startpos + y * TILESIZE, pBufferPos, pBufferUV, pBufferNom);
			pBufferPos += 3 * VERTEX_QUAD ;
			pBufferNom += 3 * VERTEX_QUAD ;
			pBufferUV += 2 * VERTEX_QUAD * 4;
		}
	}

	vbufNOM->unlock();
	vbufUV->unlock();
	vbufPos->unlock();

	//写入索引信息
	// 锁定索引缓冲区
	Ogre::ushort* pIdx = (Ogre::ushort*)indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
	for(int y = 0 ; y < terrainszie ; y ++)
	{
		for(int x = 0 ; x < terrainszie ; x ++)
		{
			Ogre::ushort iIndexTopLeft = (x + y * terrainszie) * VERTEX_QUAD;
			Ogre::ushort iIndexTopRight = iIndexTopLeft + 1;
			Ogre::ushort iIndexBottomLeft = iIndexTopLeft + 2;
			Ogre::ushort iIndexBottomRight = iIndexTopLeft + 3;
			*pIdx++ = iIndexBottomLeft;
			*pIdx++ = iIndexBottomRight;
			*pIdx++ = iIndexTopLeft;

			*pIdx++ = iIndexBottomRight;
			*pIdx++ = iIndexTopRight;
			*pIdx++ = iIndexTopLeft;
		}
	}
	indexBuffer->unlock();
	//设置模型的的索引数据
	subMesh->indexData->indexBuffer = indexBuffer;
	subMesh->indexData->indexStart = 0;
	subMesh->indexData->indexCount =numIndex;

	Ogre::AxisAlignedBox meshBounds(startpos,0,startpos,
		-startpos,5,-startpos);
	mTerrainMesh->_setBounds(meshBounds);

	mTerrainEntity = Core::getSingleton().mSceneMgr->createEntity("TerrianMesh");
	mTerrainNode->attachObject(mTerrainEntity);
	mTerrainEntity->setQueryFlags(QUERYMASK_TERRAIN);
	mTerrainNode->setPosition(0,0,0);

	//创建水面
	tex = Ogre::TextureManager::getSingleton().getByName("reflection");
	if(tex.isNull())
		tex = Ogre::TextureManager::getSingleton().createManual("reflection",
			Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
	mReflectionTarget = tex->getBuffer()->getRenderTarget();
	mReflectionTarget->addViewport(Core::getSingleton().mCamera)->setOverlaysEnabled(false);
	mReflectionTarget->addListener(this);
// 	mat = Ogre::MaterialManager::getSingleton().getByName("ReflectionWater");
// 	tech = mat->getTechnique(0);
// 	pass = tech->getPass(0);
// 	tu =  pass->getTextureUnitState(1);
// 	tu->setTextureName(tex->getName());

	mWaterPlane = Ogre::Plane(Ogre::Vector3::UNIT_Y, WATERHEIGHT);

	mWaterNode = Core::getSingleton().mSceneMgr->getRootSceneNode()->createChildSceneNode("WaterNode");
	mWaterObject = Core::getSingleton().mSceneMgr->createManualObject("WaterObject");

	mWaterObject->begin("DemoWater",Ogre::RenderOperation::OT_TRIANGLE_LIST);
	startpos += TILESIZE/2;
	for(int y = 0; y < terrainszie; y++)
		for(int x = 0; x < terrainszie; x++)
		{
			if(mMapData->getTerrainType(x -MAPBOLDER, y -MAPBOLDER ) == Water)
			{
				mWaterObject->position(startpos + x * TILESIZE, 0.0f, startpos + y * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(0.0f,0.0f);
				mWaterObject->position(startpos + (x+1) * TILESIZE, 0.0f, startpos + (y+1) * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(1.0f,1.0f);
				mWaterObject->position(startpos + (x+1) * TILESIZE, 0.0f, startpos + y * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(1.0f,0.0f);
				mWaterObject->position(startpos + (x+1) * TILESIZE, 0.0f, startpos + (y+1) * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(1.0f,1.0f);
				mWaterObject->position(startpos + x * TILESIZE, 0.0f, startpos + y * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(0.0f,0.0f);
				mWaterObject->position(startpos + x * TILESIZE, 0.0f, startpos + (y+1) * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(0.0f,1.0f);
			}
		}
	mWaterObject->end();

	mWaterNode->attachObject(mWaterObject);
	mWaterNode->setPosition(0,WATERHEIGHT,0);


	//设置摄像机移动范围
	
	float minx = 0.0f;// = ( - (float)(terrainszie - 2 * MAPBOLDER) / 2.0f - 1.0f) * TILESIZE ;
	getWorldCoords(0,0,minx,minx);
	minx -= TILESIZE/2;
	CameraContral::getSingleton().setMoveRect(minx, minx);
	CameraContral::getSingleton().resetCamera();

	//深度投影测试
// 	Ogre::MeshManager::getSingleton().createPlane("testplane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
// 		mWaterPlane, 64, 64, 1, 1, true, 1, 1, 1, Ogre::Vector3::UNIT_Z);
// 	Ogre::Entity* testent = Core::getSingleton().mSceneMgr->createEntity("testplaneent", "testplane");
// 	testent->setMaterialName("DepthTest");
// 	Ogre::SceneNode* testnode = Core::getSingleton().mSceneMgr->getRootSceneNode()->createChildSceneNode();
// 	testnode->attachObject(testent);
// 	testnode->setPosition(0.0f,10.0f,0.0f);
	return true;
}