source: OGRE/trunk/ogrenew/Samples/VolumeTex/src/VolumeRenderable.cpp @ 657

Revision 657, 7.1 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14#include "VolumeRenderable.h"
15#include <OgreCamera.h>
16#include <OgreSceneNode.h>
17#include <OgreHardwareVertexBuffer.h>
18#include <OgreHardwareIndexBuffer.h>
19#include <OgreHardwareBufferManager.h>
20#include <OgreMaterial.h>
21#include <OgreTechnique.h>
22#include <OgrePass.h>
23#include <OgreTextureUnitState.h>
24#include <OgreTextureManager.h>
25#include <OgreMaterialManager.h>
26using namespace Ogre;
27
28VolumeRenderable::VolumeRenderable(size_t nSlices, float size, const String &texture):
29        mSlices(nSlices),
30        mSize(size),
31        mTexture(texture)
32{
33        mRadius = sqrtf(size*size+size*size+size*size)/2.0f;
34        mBox = Ogre::AxisAlignedBox(-size, -size, -size, size, size, size);
35       
36        // No shadows
37        setCastShadows(false);
38       
39        initialise();
40}
41VolumeRenderable::~VolumeRenderable()
42{
43        // Remove private material
44        MaterialManager::getSingleton().remove(mTexture);
45    // need to release IndexData and vertexData created for renderable
46    delete mRenderOp.indexData;
47    delete mRenderOp.vertexData;
48
49}
50
51void VolumeRenderable::_notifyCurrentCamera( Camera* cam )
52{
53        // Fake orientation toward camera
54        Vector3 zVec = getParentNode()->_getDerivedPosition() - cam->getDerivedPosition();
55        zVec.normalise();
56        Vector3 fixedAxis = cam->getDerivedOrientation() * Vector3::UNIT_Y ;
57       
58        Vector3 xVec = fixedAxis.crossProduct( zVec );
59        xVec.normalise();
60
61        Vector3 yVec = zVec.crossProduct( xVec );
62        yVec.normalise();
63       
64        Quaternion oriQuat;
65        oriQuat.FromAxes( xVec, yVec, zVec );
66       
67        oriQuat.ToRotationMatrix(mFakeOrientation);
68       
69        Matrix3 tempMat;
70        Quaternion q = getParentNode()->_getDerivedOrientation().UnitInverse() * oriQuat ;
71        q.ToRotationMatrix(tempMat);
72       
73        Matrix4 rotMat = Matrix4::IDENTITY;
74        rotMat = tempMat;
75        rotMat.setTrans(Vector3(0.5f, 0.5f, 0.5f));
76        mUnit->setTextureTransform(rotMat);
77}
78
79
80//const Ogre::Quaternion& VolumeRenderable::getWorldOrientation(void) const
81//{
82//      return Ogre::Quaternion::IDENTITY;
83//}
84
85void VolumeRenderable::getWorldTransforms( Matrix4* xform ) const
86{
87        Matrix4 destMatrix(Matrix4::IDENTITY); // this initialisation is needed
88       
89        const Vector3 &position = getParentNode()->_getDerivedPosition();
90        const Vector3 &scale = getParentNode()->_getDerivedScale();
91        Matrix3 scale3x3(Matrix3::ZERO);
92        scale3x3[0][0] = scale.x;
93        scale3x3[1][1] = scale.y;
94        scale3x3[2][2] = scale.z;
95
96        destMatrix = mFakeOrientation * scale3x3;
97        destMatrix.setTrans(position);
98               
99        *xform = destMatrix;
100}
101
102void VolumeRenderable::initialise()
103{
104        // Create geometry
105        size_t nvertices = mSlices*4; // n+1 planes
106        size_t elemsize = 3*3;
107        size_t dsize = elemsize*nvertices;
108        size_t x;
109       
110        Ogre::IndexData *idata = new Ogre::IndexData();
111        Ogre::VertexData *vdata = new Ogre::VertexData();
112       
113        // Create  structures
114        float *vertices = new float[dsize];
115       
116        float coords[4][2] = {
117                {0.0f, 0.0f},
118                {0.0f, 1.0f},
119                {1.0f, 0.0f},
120                {1.0f, 1.0f}
121        };
122        for(x=0; x<mSlices; x++)
123        {
124                for(size_t y=0; y<4; y++)
125                {
126                        float xcoord = coords[y][0]-0.5;
127                        float ycoord = coords[y][1]-0.5;
128                        float zcoord = -((float)x/(float)(mSlices-1)  - 0.5f);
129                        // 1.0f .. a/(a+1)
130                        // coordinate
131                        vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f);
132                        vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f);
133                        vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f);
134                        // normal
135                        vertices[x*4*elemsize+y*elemsize+3] = 0.0f;
136                        vertices[x*4*elemsize+y*elemsize+4] = 0.0f;
137                        vertices[x*4*elemsize+y*elemsize+5] = 1.0f;
138                        // tex
139                        vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f);
140                        vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f);
141                        vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f);
142                }
143        }
144        unsigned short *faces = new unsigned short[mSlices*6];
145        for(x=0; x<mSlices; x++)
146        {
147                faces[x*6+0] = x*4+0;
148                faces[x*6+1] = x*4+1;
149                faces[x*6+2] = x*4+2;
150                faces[x*6+3] = x*4+1;
151                faces[x*6+4] = x*4+2;
152                faces[x*6+5] = x*4+3;
153        }
154        // Setup buffers
155        vdata->vertexStart = 0;
156        vdata->vertexCount = nvertices;
157       
158        VertexDeclaration* decl = vdata->vertexDeclaration;
159        VertexBufferBinding* bind = vdata->vertexBufferBinding;
160
161        size_t offset = 0;
162        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
163        offset += VertexElement::getTypeSize(VET_FLOAT3);
164        decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
165        offset += VertexElement::getTypeSize(VET_FLOAT3);
166        decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES);
167        offset += VertexElement::getTypeSize(VET_FLOAT3);
168
169        HardwareVertexBufferSharedPtr vbuf =
170        HardwareBufferManager::getSingleton().createVertexBuffer(
171                offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
172
173        bind->setBinding(0, vbuf);
174
175        vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
176       
177        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
178                createIndexBuffer(
179                        HardwareIndexBuffer::IT_16BIT,
180                        mSlices*6,
181                        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
182
183        idata->indexBuffer = ibuf;
184        idata->indexCount = mSlices*6;
185        idata->indexStart = 0;
186        ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
187
188        // Delete temporary buffers
189        delete [] vertices;
190        delete [] faces;
191       
192        // Now make the render operation
193        mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
194        mRenderOp.indexData = idata;
195        mRenderOp.vertexData = vdata;
196        mRenderOp.useIndexes = true;
197       
198         // Create a brand new private material
199        MaterialPtr material =
200                MaterialManager::getSingleton().create(mTexture, "VolumeRenderable",
201                        false, 0); // Manual, loader
202
203        // Remove pre-created technique from defaults
204        material->removeAllTechniques();
205       
206        // Create a techinique and a pass and a texture unit
207        Technique * technique = material->createTechnique();
208        Pass * pass = technique->createPass();
209        TextureUnitState * textureUnit = pass->createTextureUnitState();
210       
211        // Set pass parameters
212        pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
213        pass->setDepthWriteEnabled(false);
214        pass->setCullingMode(CULL_NONE);
215        pass->setLightingEnabled(false);
216       
217        // Set texture unit parameters
218        textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
219        textureUnit->setTextureName(mTexture, TEX_TYPE_3D);
220        textureUnit->setTextureFiltering(TFO_TRILINEAR);
221       
222        mUnit = textureUnit;
223        m_pMaterial = material;
224}
225
226Ogre::Real VolumeRenderable::getBoundingRadius() const
227{
228        return mRadius;
229}
230Ogre::Real VolumeRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const
231{
232        Ogre::Vector3 min, max, mid, dist;
233
234        min = mBox.getMinimum();
235        max = mBox.getMaximum();
236        mid = ((min - max) * 0.5) + min;
237        dist = cam->getDerivedPosition() - mid;
238                                                                       
239        return dist.squaredLength();
240}
241
Note: See TracBrowser for help on using the repository browser.