Load multiple objects in space

Started by
10 comments, last by muimui1911 18 years, 3 months ago
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]
Advertisement
is it because my question is unclear, i stuck on this for a while already.

are there any hint of ways to do this?
Well, what API are you using (Win32 API, or MFC maybe)?
:==-_ Why don't the voices just leave me alone?! _-==:
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 objectobj3d.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
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]
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.
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.
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   //delarationsC3ds obj3ds;vector<C3ds> vObjects;vector<C3ds>::iterator iObject;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// in load-file functionZeroMemory(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
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
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
//delarationsC3ds obj3ds;vector<C3ds> vObjects;vector<C3ds>::iterator iObject;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// in load-file functionvObjects.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 partfor ( iObject = vObjects.begin(); iObject != vObjects.end(); ++iObject )	 iObject->Render_3ds();



in class C3ds
//C3ds.cppCLoad3ds 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

This topic is closed to new replies.

Advertisement