Primitive for drawing complex 3D structures ?
-
- Gnoblar
- Posts: 11
- Joined: Tue Apr 19, 2005 3:11 am
- Location: Macaé, BRAZIL
Primitive for drawing complex 3D structures ?
Hi,
I need a primitive for drawing a structure like this one :
I tried using vertex with OT_POINT_LIST , but the points are not scaled when the camera gets near them (I know, they are just points)... should I use cubes ? How to paint them with a color ?
That image is 300x300x300 , so the primitive has to be fast.
I never used 3d engines before and I'm having a hard time here, could anybody give me a hint ?
Thanks !
I need a primitive for drawing a structure like this one :
I tried using vertex with OT_POINT_LIST , but the points are not scaled when the camera gets near them (I know, they are just points)... should I use cubes ? How to paint them with a color ?
That image is 300x300x300 , so the primitive has to be fast.
I never used 3d engines before and I'm having a hard time here, could anybody give me a hint ?
Thanks !
- elmer
- Gnoblar
- Posts: 21
- Joined: Fri Apr 15, 2005 2:12 am
volumetric texture?
http://www.ogre3d.org/phpBB2/viewtopic.php?t=7313
http://www.ogre3d.org/phpBB2/viewtopic.php?t=7313
Elmer is not like the rest of the elephants in the jungle, he's a multi-coloured patchwork elephant!
-
- Gnoblar
- Posts: 11
- Joined: Tue Apr 19, 2005 3:11 am
- Location: Macaé, BRAZIL
Yes, I saw the Volumetric Texture demo, but my app is supposed to run on old machines too...I need another way to do it.
That image is a 3D matrix of 0's and 1's generated on the fly (it's the microstructure of a rock generated from thin section microphotographies)... all I need is to plot voxels on the screen (the 1's in the 3D matrix).
That image is a 3D matrix of 0's and 1's generated on the fly (it's the microstructure of a rock generated from thin section microphotographies)... all I need is to plot voxels on the screen (the 1's in the 3D matrix).
- Kencho
- OGRE Retired Moderator
- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
- Contact:
- DWORD
- OGRE Retired Moderator
- Posts: 1365
- Joined: Tue Sep 07, 2004 12:43 pm
- Location: Aalborg, Denmark
- Contact:
- jacmoe
- OGRE Retired Moderator
- Posts: 20570
- Joined: Thu Jan 22, 2004 10:13 am
- Location: Denmark
- x 179
- Contact:
Or send it to us!
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
- DWORD
- OGRE Retired Moderator
- Posts: 1365
- Joined: Tue Sep 07, 2004 12:43 pm
- Location: Aalborg, Denmark
- Contact:
Well, here it is then.
isosurfaces.zip
I can't remember what state the code is in; I think I was playing around with some shaders in there, too. And for reason I even documented it with Doxygen. Consider this code in the public domain.
BTW, isn't there some patent thingies with the marching cubes algorithm?
isosurfaces.zip
I can't remember what state the code is in; I think I was playing around with some shaders in there, too. And for reason I even documented it with Doxygen. Consider this code in the public domain.
BTW, isn't there some patent thingies with the marching cubes algorithm?
- jacmoe
- OGRE Retired Moderator
- Posts: 20570
- Joined: Thu Jan 22, 2004 10:13 am
- Location: Denmark
- x 179
- Contact:
Taken from hereSubject 5.11: What is the status of the patent on the "marching cubes" algorithm?
United States Patent Number: 4,710,876
Date of Patent: Dec. 1, 1987
Inventors: Harvey E. Cline, William E. Lorensen
Assignee: General Electric Company
Title: "System and Method for the Display of Surface Structures Contained Within the Interior Region of a Solid Body"
Filed: Jun. 5, 1985
United States Patent Number: 4,885,688
Date of Patent: Dec. 5, 1989
Inventor: Carl R. Crawford
Assignee: General Electric Company
Title: "Minimization of Directed Points Generated in Three-Dimensional Dividing Cubes Method"
Filed: Nov. 25, 1987
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
-
- Gnoblar
- Posts: 11
- Joined: Tue Apr 19, 2005 3:11 am
- Location: Macaé, BRAZIL
Hi,
DWORD, this algorithm is exactly what I needed ! I have no words to express my gratitude, man. Thank you !
Here are the changes in Metaball.cpp to my Meta3DMatrix.cpp, I kept the line :
mIsoSurfaces[0]->setIsoValue(0.15);
in CustomFrameListener.cpp setting the threshold value to 0.15.
for (size_t z = z0; z <= z1; ++z) {
for (size_t y = y0; y <= y1; ++y) {
for (size_t x = x0; x <= x1; ++x) {
size_t index = dataGrid->getGridIndex(x, y, z);
// generate a non-correlated(random)
//porous media with porosity=90% for testing
if ((rand() % 100) > 90) {
values[index] = 0.81;
}
}
}
}
Here's the result with a 40x40x40 grid :
I have a million questions, though, so I'm just going to ask the more pressing ones :
1) I need a larger grid (300x300x300 at least) and I'm getting too many vertexes, so I tried changing index buffer allocation with :
HardwareIndexBuffer::IT_32BIT
is it as simple as changing that ? It crashed at runtime because DX7 doesn't support 32 bit indexes, are they supported by opengl and DX9 ?
2) when I set values[index] to a value very close and greather than mIsoValue I get a cardboard looking structure (without volume). Replacing the "if" in the code above with :
if(z=z0) values[index]=0.15;
I get this (the iso surface on the left has a smaller threshold, the one in the right has a threshold equals to 0.15):
I took a look at the marching cubes algorithm and i think this is an unexpected behavior... is it supposed to be happening ?
3) What are the gradients used for ?
Thanks a lot,
Tiago
DWORD, this algorithm is exactly what I needed ! I have no words to express my gratitude, man. Thank you !
Here are the changes in Metaball.cpp to my Meta3DMatrix.cpp, I kept the line :
mIsoSurfaces[0]->setIsoValue(0.15);
in CustomFrameListener.cpp setting the threshold value to 0.15.
for (size_t z = z0; z <= z1; ++z) {
for (size_t y = y0; y <= y1; ++y) {
for (size_t x = x0; x <= x1; ++x) {
size_t index = dataGrid->getGridIndex(x, y, z);
// generate a non-correlated(random)
//porous media with porosity=90% for testing
if ((rand() % 100) > 90) {
values[index] = 0.81;
}
}
}
}
Here's the result with a 40x40x40 grid :
I have a million questions, though, so I'm just going to ask the more pressing ones :
1) I need a larger grid (300x300x300 at least) and I'm getting too many vertexes, so I tried changing index buffer allocation with :
HardwareIndexBuffer::IT_32BIT
is it as simple as changing that ? It crashed at runtime because DX7 doesn't support 32 bit indexes, are they supported by opengl and DX9 ?
2) when I set values[index] to a value very close and greather than mIsoValue I get a cardboard looking structure (without volume). Replacing the "if" in the code above with :
if(z=z0) values[index]=0.15;
I get this (the iso surface on the left has a smaller threshold, the one in the right has a threshold equals to 0.15):
I took a look at the marching cubes algorithm and i think this is an unexpected behavior... is it supposed to be happening ?
3) What are the gradients used for ?
Thanks a lot,
Tiago
- DWORD
- OGRE Retired Moderator
- Posts: 1365
- Joined: Tue Sep 07, 2004 12:43 pm
- Location: Aalborg, Denmark
- Contact:
No problem.Tiago wrote:DWORD, this algorithm is exactly what I needed ! I have no words to express my gratitude, man. Thank you !
OGL and D3D9 support 32 bit indices. But I don't think you'll get very good performance using a grid that big. Maybe another technique would be better for such large datasets.Tiago wrote:1) I need a larger grid (300x300x300 at least) and I'm getting too many vertexes, so I tried changing index buffer allocation with :
HardwareIndexBuffer::IT_32BIT
is it as simple as changing that ? It crashed at runtime because DX7 doesn't support 32 bit indexes, are they supported by opengl and DX9 ?
I don't really know. But there's a limit to how small structures can be polygonized.Tiago wrote:2) when I set values[index] to a value very close and greather than mIsoValue I get a cardboard looking structure (without volume). Replacing the "if" in the code above with :
if(z=z0) values[index]=0.15;
I get this (the iso surface on the left has a smaller threshold, the one in the right has a threshold equals to 0.15):
(...)
I took a look at the marching cubes algorithm and i think this is an unexpected behavior... is it supposed to be happening ?
I used them for calculating normals but it didn't work very well, and I can't remember if they're actually used for anything as it is now. IIRC you can choose to calculate normals using the gradient.Tiago wrote:3) What are the gradients used for ?
-
- Gnoblar
- Posts: 11
- Joined: Tue Apr 19, 2005 3:11 am
- Location: Macaé, BRAZIL
Thanks a bunch, Christian !
Code is working fine now...
But my program slows to a crawl when I use a grid too large, even when the window where the 3d model is displayed is minimized (it's a MDI windowed application using Qt)... maybe the rendering loop is still going when the window looses focus. Anyway, I'll try to solve that another day.
Here's how to change it to 32 bit, should anyone be interested in doing it. Took me a while since I'm new to 3d and Ogre.
1) Create a new member variable
HardwareIndexBuffer::IndexType mNumberBitsIndexBuffer;
2)Initialize in the constructor
mNumberBitsIndexBuffer = HardwareIndexBuffer::IT_32BIT;
3) In DynamicRenderable.cpp, change the assert to :
if (mNumberBitsIndexBuffer == HardwareIndexBuffer::IT_32BIT) {
OgreAssert(indexCount <= std::numeric_limits<unsigned int>::max(), "indexCount exceeds 32 bit");
}
else {
OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit");
}
4) At buffer creation :
mRenderOp.indexData->indexBuffer =
HardwareBufferManager::getSingleton().createIndexBuffer(
///////////////HardwareIndexBuffer::IT_16BIT,
mNumberBitsIndexBuffer,
mIndexBufferCapacity,
HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
5) At isosurface.cpp :
// Fill hardware index buffer
if (mNumberBitsIndexBuffer == HardwareIndexBuffer::IT_32BIT) {
// we are using 32 bit indexes now, so "unsigned int" must be used instead of "unsigned short"
unsigned int* pIndex = static_cast<unsigned int*>(ibuf->lock(0, mRenderOp.indexData->indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD));
for (IsoTriangleVector::iterator x = mIsoTriangles.begin(); x != mIsoTriangles.end(); ++x)
{
*pIndex++ = static_cast<unsigned int>(mIsoVertexIndices[x->vertices[0]]);
*pIndex++ = static_cast<unsigned int>(mIsoVertexIndices[x->vertices[1]]);
*pIndex++ = static_cast<unsigned int>(mIsoVertexIndices[x->vertices[2]]);
}
}
else {
unsigned short* pIndex = static_cast<unsigned short*>(ibuf->lock(0, mRenderOp.indexData->indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD));
for (IsoTriangleVector::iterator x = mIsoTriangles.begin(); x != mIsoTriangles.end(); ++x)
{
*pIndex++ = static_cast<unsigned short>(mIsoVertexIndices[x->vertices[0]]);
*pIndex++ = static_cast<unsigned short>(mIsoVertexIndices[x->vertices[1]]);
*pIndex++ = static_cast<unsigned short>(mIsoVertexIndices[x->vertices[2]]);
}
}
Code is working fine now...
But my program slows to a crawl when I use a grid too large, even when the window where the 3d model is displayed is minimized (it's a MDI windowed application using Qt)... maybe the rendering loop is still going when the window looses focus. Anyway, I'll try to solve that another day.
Here's how to change it to 32 bit, should anyone be interested in doing it. Took me a while since I'm new to 3d and Ogre.
1) Create a new member variable
HardwareIndexBuffer::IndexType mNumberBitsIndexBuffer;
2)Initialize in the constructor
mNumberBitsIndexBuffer = HardwareIndexBuffer::IT_32BIT;
3) In DynamicRenderable.cpp, change the assert to :
if (mNumberBitsIndexBuffer == HardwareIndexBuffer::IT_32BIT) {
OgreAssert(indexCount <= std::numeric_limits<unsigned int>::max(), "indexCount exceeds 32 bit");
}
else {
OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit");
}
4) At buffer creation :
mRenderOp.indexData->indexBuffer =
HardwareBufferManager::getSingleton().createIndexBuffer(
///////////////HardwareIndexBuffer::IT_16BIT,
mNumberBitsIndexBuffer,
mIndexBufferCapacity,
HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
5) At isosurface.cpp :
// Fill hardware index buffer
if (mNumberBitsIndexBuffer == HardwareIndexBuffer::IT_32BIT) {
// we are using 32 bit indexes now, so "unsigned int" must be used instead of "unsigned short"
unsigned int* pIndex = static_cast<unsigned int*>(ibuf->lock(0, mRenderOp.indexData->indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD));
for (IsoTriangleVector::iterator x = mIsoTriangles.begin(); x != mIsoTriangles.end(); ++x)
{
*pIndex++ = static_cast<unsigned int>(mIsoVertexIndices[x->vertices[0]]);
*pIndex++ = static_cast<unsigned int>(mIsoVertexIndices[x->vertices[1]]);
*pIndex++ = static_cast<unsigned int>(mIsoVertexIndices[x->vertices[2]]);
}
}
else {
unsigned short* pIndex = static_cast<unsigned short*>(ibuf->lock(0, mRenderOp.indexData->indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD));
for (IsoTriangleVector::iterator x = mIsoTriangles.begin(); x != mIsoTriangles.end(); ++x)
{
*pIndex++ = static_cast<unsigned short>(mIsoVertexIndices[x->vertices[0]]);
*pIndex++ = static_cast<unsigned short>(mIsoVertexIndices[x->vertices[1]]);
*pIndex++ = static_cast<unsigned short>(mIsoVertexIndices[x->vertices[2]]);
}
}