Jump to content
  • Advertisement
Sign in to follow this  
muimui1911

Load multiple objects in space

This topic is 4669 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Merry X'mas and Happy new year everyone, I have a question to ask you guys, I am building a program that needed to load 3D objects into space, the objects are in .3ds format, I have the loader done and it works fine, however, what i needed now is that in program when i click load from file->menu->open, i suppose to load the selected object out, and my problem now is how can i load objects after objects where the previous will stay in the space, for example, if i have load a table in my space, then if i load another object again, the new object will appear as well as the old object. I am working in WIN32 API, I have my 3ds Loader in class, C3DS is the class of my loader Load3ds(filepath); //use this to load the object in Render3ds(); //this is where it will draw the object out in main.cpp i have C3DS obj3d; obj3d.Load3ds(filepath); //this is how i use to load an object obj3d.Render3ds(); //this is how u call to draw the object out Thanks very much for helping, if my question is unclear please ask me to explain it again in another way. Millions of thanks [Edited by - muimui1911 on December 31, 2005 10:51:29 AM]

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure if I understand you correctly, but since you bumped the thread I'll give it a shot.


C3DS obj3d;

obj3d.Load3ds(filepath); //this is how i use to load an object
obj3d.Render3ds(); //this is how u call to draw the object out

It seems from this code snippet you have only one instance of an object, so if you load another one, it will unload the first one, right?

The trick would then be to have multiple object instances. This would require some adjustments elsewhere in your program, because you will now have a collection of objects to render, update, etc. instead of one.

You will need some structure for this collection. I will assume a STL vector for this.

std::vector<C3DS> vObjects;

// When loading...
C3DS object;
object.Load3ds( ... );
vObjects.push_back( object );

// When rendering...
std::vector<C3DS>::iterator iObject;
for ( iObject = vObjects.begin(); iObject != vObjects.end() )
iObject->Render3ds();


You will also have to include transformation info in the object class to prevent all objects from showing up at the same spot (the origin or other).

Illco

Share this post


Link to post
Share on other sites
Quote:
Original post by TFS_Waldo
Well, what API are you using (Win32 API, or MFC maybe)?


I am using WIN32 API as i said above, thanks

[Edited by - muimui1911 on December 31, 2005 10:45:12 PM]

Share this post


Link to post
Share on other sites
Hi muimui,

It seems there are two issues here, both of which Illco addressed:

1. Loading and storing multiple objects in memory
2. Drawing them at different places in the world

The first can be handled just as Illco described. It does look like his example assumes the 3DS class has deep copy implemented, so if that isn't the case you may need to adjust the example a bit to fit your needs. It's hard to say exactly how it should be handled without being familiar with your 3DS class.

The other problem is that presumably the models are loaded centered at the origin, and therefore will all be drawn on top of each other. This can be addressed by enclosing each draw call in a glPushMatrix()/glPopMatrix() block, and performing the necessary transformations after the glPushMatrix() and before the draw call.

If you still need help with this, I'd say the next step would be to, first of all, tell us which of the aforementioned problems (1, 2, or both 1 and 2) you're having trouble with. Then, describe in as much detail as you can how and why the suggestions given so far aren't working.

Share this post


Link to post
Share on other sites
Thank you very much for all the helps here, I think I will give a try on the suggestion you alll have given and if i have any other problems, i will Post reply on this post again, thanks again.

Share this post


Link to post
Share on other sites
Thanks jyk and Illco,
I have given a seriou try on this for about half a day and I still couldn't get it right, so here i will give a more detailed information for you guys to look at.

GetFilename(szPath);
// this function makes the open file dialog popout,where the "szPath" is the
// actual path

There are two classes to load and store the .3ds file, and they are C3ds and Cload3ds,

" C3ds " this class is to draw the objects and attach the textures onto is, and in this class there is a function called
"void C3ds::Init_3ds(char* filename)" when this function runs, it will call the functions in the "Cload3ds" and starts loading geometries.
In "C3ds" there are also a function called "void C3dsLoader::Render3ds()"
when this function is been call, it starts drawing objects.

" Cload3ds " is to load the .3ds file's information in, and here i will show some declarations of the important parameters.


struct tMaterial
{
char strName[255];
char strFile[255];
BYTE color[3];
int texureId;
float uTile;
float vTile;
float uOffset;
float vOffset;
};

struct t3DObject
{
int numVerts;
int numFaces;
int numTexVertex;
int materialID;
bool bHasTexture;
char strName[255];
UINT *pIndices;
Vector3D *pVerts;
Vector3D *pNormals;
tVector2 *pTexVerts;
tFace *pFaces;
};

struct t3DModel
{
int numObjects;
int numMaterials;
vector<tMaterial> pMaterials; // template is used
vector<t3DObject> pObject; // template is used
};



after all these, the following is what i do to try if it actually stores the collections of objects, unfortunately it doesn't work
I know i need to alter the example that Illco is given, but id o have a few problems


//in main.cpp

//delarations
C3ds obj3ds;
vector<C3ds> vObjects;
vector<C3ds>::iterator iObject;
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// in load-file function
ZeroMemory(szPath, 200);
GetWindowsDirectory(szPath, 200);
GetFilename(szPath);
obj3ds.Init_3ds(szPath);
vObjects.push_back(obj3ds);
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// in render scene function

// for ( iObject = vObjects.begin(); iObject != vObjects.end(); )
// iObject->Render_3ds();

// i have quoted this because it can't draw anything, it causes the program
// i have looked at the use of begin(), it Returns an iterator pointing to the
// beginning of the vector. But i still not sure what it exactly means...




The problems now are if I load an object in, the "vObjects" will have the same value as the "obj3ds", however when i tried to load the second objects in, it crashes. the other problem is when i draw it

for ( iObject = vObjects.begin(); iObject != vObjects.end(); )
iObject->Render_3ds();


this function doesn't actually draw the object, the problem may be i didn't understand very well on this memory management and I didn't alter it correctly so it causes this don't work properly.
I will try to put more information about the problem if the above is not sufficent and sorry for being not helpful.

thaks alot

Share this post


Link to post
Share on other sites
Just a couple of quick comments. First of all, in the following line:
for ( iObject = vObjects.begin(); iObject != vObjects.end(); )
You probably also need to increment the iterator, like this:
for ( iObject = vObjects.begin(); iObject != vObjects.end(); ++iObject )
I'm guessing the main problem though is with the lines:
obj3ds.Init_3ds(szPath);
vObjects.push_back(obj3ds);
It's hard to say exactly what's happening here without seeing your whole 3ds class, as it depends on how memory is managed internally in the class. I'm just going to venture a guess though, and propose what might (or might not) be a quick fix, that is, replacing the above two lines with:
vObjects.push_back(obj3ds);
vObjects[vObjects.size()-1].Init_3ds(szPath);
So you might try that. If it still doesn't work, or continues to crash, you might need to post some of your 3ds class code. The main questions to answer will be:

1. Does it manage memory internally using std::vector's, new and delete, malloc and free, etc.
2. If it doesn't use std::vector, does the destructor properly deallocate any allocated memory
3. If it doesn't use std::vector, does it properly implement 'deep copy' in the = operator

Share this post


Link to post
Share on other sites
Hi there, after your suggestion you have given, i have made some changes and the drawing part is fine now, however the "deep copy" part still leaves a problem, and i have tried some ways trying to set the memory of the std::vector
you have mentioned the main questions to answer is the following:
Quote:

1. Does it manage memory internally using std::vector's, new and delete, malloc and free, etc.
2. If it doesn't use std::vector, does the destructor properly deallocate any allocated memory
3. If it doesn't use std::vector, does it properly implement 'deep copy' in the = operator

I don't really get what you meant by if it doesn't use std::vector, so that means there are other possible ways to multiple loading, right? sorry , i am not very familar with memory mangement, but i have try this in the load object line,
Quote:

vObjects.push_back( obj3dsLoader );
vObjects[vObjects.size()-1].Init_3ds(szPath);
memset(&(vObjects[vObjects.size()-1]), 0, sizeof(C3dsLoader));
//new line

it is perfectly alright to load and draw the first loaded object, but when i load another object in, the program crashes. SO i suppose the best way is to post some code from 3ds class to see if the problem appears there.

Here is the main.cpp

//delarations
C3ds obj3ds;
vector<C3ds> vObjects;
vector<C3ds>::iterator iObject;
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// in load-file function
vObjects.push_back( obj3dsLoader );
vObjects[vObjects.size()-1].Init_3ds(szPath);
memset(&(vObjects[vObjects.size()-1]), 0, sizeof(C3dsLoader));
//no matter the memset line is exist or not, the program still crashes.
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//render scene part
for ( iObject = vObjects.begin(); iObject != vObjects.end(); ++iObject )
iObject->Render_3ds();




in class C3ds

//C3ds.cpp
CLoad3ds mLoad3ds;
void C3ds::Init_3ds(char* filename)
{
mLoad3ds.Import3DS(&m3DModel, filename);
//Import3DS function is from class CLoad3ds
...
...
}



in CLoad3ds

/////////////////////////////////////////
//CLoad3ds.h
/////////////////////////////////////////
struct tFace
{
int vertIndex[3];
int coordIndex[3];
};

struct tMaterialInfo
{
char strName[255];
char strFile[255];
BYTE color[3];
int texureId;
float uTile;
float vTile;
float uOffset;
float vOffset;
};

struct t3DObject
{
int numOfVerts;
int numOfFaces;
int numTexVertex;
int materialID;
bool bHasTexture;
char strName[255];
UINT *pIndices;
Vector3D *pVerts;
Vector3D *pNormals;
tVector2 *pTexVerts;
tFace *pFaces;
};


struct t3DModel
{
int numOfObjects;
int numOfMaterials;
vector<tMaterialInfo> pMaterials;
vector<t3DObject> pObject;
};



struct tIndices {

unsigned short a, b, c, bVisible;
};

struct tChunk
{
unsigned short int ID;
unsigned int length;
unsigned int bytesRead;
};

class CLoad3DS
{
public:
CLoad3ds();
bool Import3DS(t3DModel *pModel, char *strFileName);

private:
...//and other function declaration
void CleanUp();
FILE *m_FilePointer;
tChunk *m_CurrentChunk;
tChunk *m_TempChunk;
};
///////////////////////////////////////////////
//CLoad3ds.cpp
//////////////////////////////////////////////
bool CLoad3ds::Import3DS(t3DModel *pModel, char *strFileName)
{
char strMessage[255] = {0};

m_FilePointer = fopen(strFileName, "rb");
if(!m_FilePointer)
{
sprintf(strMessage, "Unable to find the file: %s!", strFileName);
MessageBox(NULL, strMessage, "Error", MB_OK);
return false;
}
ReadChunk(m_CurrentChunk);
if (m_CurrentChunk->ID != PRIMARY)
{
sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);
MessageBox(NULL, strMessage, "Error", MB_OK);
return false;
}
ProcessNextChunk(pModel, m_CurrentChunk);

ComputeNormals(pModel);

CleanUp();

return 0;
}
/////////////////////////////////////////
//here template is used to store infomation,
//look at the case MATERIAL: case OBJECT:, it may help.
/////////////////////////////////////////
void CLoad3DS::ProcessNextChunk(t3DModel *pModel, tChunk *pPreviousChunk)
{
t3DObject newObject = {0};
tMaterialInfo newTexture = {0};
unsigned short version = 0;
int buffer[50000] = {0};

m_CurrentChunk = new tChunk;

while (pPreviousChunk->bytesRead < pPreviousChunk->length)
{
ReadChunk(m_CurrentChunk);

switch (m_CurrentChunk->ID)
{
case VERSION:

m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);

if (version > 0x03)
MessageBox(NULL, "This 3DS file is over version 3 so it may load incorrectly", "Warning", MB_OK);
break;

case OBJECTINFO:
ReadChunk(m_TempChunk);

m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);

m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;

ProcessNextChunk(pModel, m_CurrentChunk);
break;

case MATERIAL:
pModel->numOfMaterials++;

pModel->pMaterials.push_back(newTexture);

ProcessNextMaterialChunk(pModel, m_CurrentChunk);
break;

case OBJECT:
pModel->numOfObjects++;

pModel->pObject.push_back(newObject);

memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));

m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);

ProcessNextObjectChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);
break;
default:

m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
break;
}

pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;
}

delete m_CurrentChunk;
m_CurrentChunk = pPreviousChunk;
}





i hope the above code helps.
Furthermore, i have check the debug and run to the line just after loaded the object, i have found that there is no values, hence, empty in the "obj3ds", instead the vObjects have all the values, i don't know if that helps, but here is my problems, if more code is needed for knowing the problem, i will repost more..

thanks alot and Happy New Year

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!