World: r3wp
[Core] Discuss core issues
older newer | first last |
shadwolf 14-Jan-2005 [159x3] | so MD2 format encapsulate many Frame as array and all those frames encapsulate many Vert that discribe for this frame each location of every point of my 3d Model |
the we have the posibility to take a bunch of frame for example from 0 to 10 to say that's animation set correspond to run | |
animation | |
eFishAnt 14-Jan-2005 [162x3] | aha, you give me so many ideas for my editor... |
it is sometimes too mind expanding to write code while chatting. Sometimes I think I need a few more heads, and a couple more arms to type and click...maybe I should draw a new model of myself. | |
but I think I would use REBOL blocks rather than some silly C structs. blocks are such flexible containers. | |
shadwolf 14-Jan-2005 [165] | in my 3D engine I will make a switch to change the animation that are into my model that supose for me to have all my 3D model to get the identical set of animation or to make animation switch that could be adapted to every 3D Model Type (that's why 3D engeneers not even more use this format and prefert bone animation based file format like MDL or MD3/MD5) |
eFishAnt 14-Jan-2005 [166] | aha...a datatype-sensitive editor...see, I should close down the right side of my brain so the left side can type code easier. |
shadwolf 14-Jan-2005 [167x11] | for example if I say walk is frame 0 10 for human but for aliens in my game I nead to have only frames 0 to 5 for the walk I need to make 2 animation list and 2 animation switches to handle human (main caracter of my game for example) and alien |
If i have alien type 1 alien type 2 alien type 3 etc... and all of them with different set of animation it could be very heavy task to handle all of them using MD2 but that's not our purpose in fact :) | |
data-type sensitive editor but normally rebol is datatype unsensive :) | |
so or we allways ue struct! to typify our variables (wich can't be reuse). In C if I make SDM2Header *a, *b; a content and b content (physical memory localtion) will not be the same | |
in rebol a: SMD2Header and b: SMD2Header will point to the same memory chunk ... | |
>> a: SMD2Header >> b: SMD2Header >> a/m_iMagicNum: 1234234 == 1234234 >> probe b/m_iMagicNum 1234234 == 1234234 >> | |
and that normal becaus in C to initialise data I will use a malloc call witch will attrubute to a and b on the same based type different memory location | |
in my example program that exploite the SMD2Header strucure we can see: | |
//------------------------------------------------------------- //- Load //- Loads an MD2 model from file //------------------------------------------------------------- bool CMd2::Load(const char * szFilename) { unsigned char * ucpBuffer = 0; unsigned char * ucpPtr = 0; unsigned char * ucpTmpPtr = 0; int iFileSize = 0; FILE * f; if(!(f = fopen(szFilename, "rb"))) { APP->Log(COLOR_RED, "Could not open MD2 file %s", szFilename); return false; } //check file size and read it all into the buffer int iStart = ftell(f); fseek(f, 0, SEEK_END); int iEnd = ftell(f); fseek(f, 0, SEEK_SET); iFileSize = iEnd - iStart; //Allocate memory for whole file ucpBuffer = new unsigned char[iFileSize]; ucpPtr = ucpBuffer; if(!ucpBuffer) { APP->Log(COLOR_RED, "Could not allocate memory for %s", szFilename); return false; } //Load file into buffer if(fread(ucpBuffer, 1, iFileSize, f) != (unsigned)iFileSize) { APP->Log(COLOR_RED, "Could not read from %s", szFilename); delete [] ucpBuffer; return false; } //close the file, we don't need it anymore fclose(f); //get the header memcpy(&m_Head, ucpPtr, sizeof(SMD2Header)); //make sure it is a valid MD2 file before we get going if(m_Head.m_iMagicNum != 844121161 || m_Head.m_iVersion != 8) { APP->Log(COLOR_RED, "%s is not a valid MD2 file", szFilename); delete [] ucpBuffer; return false; } ucpTmpPtr = ucpPtr; ucpTmpPtr += m_Head.m_iOffsetFrames; //read the frames m_pFrames = new SMD2Frame[m_Head.m_iNumFrames]; for(int i = 0; i < m_Head.m_iNumFrames; i++) { float fScale[3]; float fTrans[3]; m_pFrames[i].m_pVerts = new SMD2Vert[m_Head.m_iNumVertices]; //expand the verices memcpy(fScale, ucpTmpPtr, 12); memcpy(fTrans, ucpTmpPtr + 12, 12); memcpy(m_pFrames[i].m_caName, ucpTmpPtr + 24, 16); ucpTmpPtr += 40; for(int j = 0; j < m_Head.m_iNumVertices; j++) { //swap y and z coords to convert to the proper orientation on screen m_pFrames[i].m_pVerts[j].m_fVert[0] = ucpTmpPtr[0] * fScale[0] + fTrans[0]; m_pFrames[i].m_pVerts[j].m_fVert[1] = ucpTmpPtr[2] * fScale[2] + fTrans[2]; m_pFrames[i].m_pVerts[j].m_fVert[2] = ucpTmpPtr[1] * fScale[1] + fTrans[1]; m_pFrames[i].m_pVerts[j].m_ucReserved = ucpTmpPtr[3]; ucpTmpPtr += 4; } } //Read in the triangles ucpTmpPtr = ucpPtr; ucpTmpPtr += m_Head.m_iOffsetTriangles; m_pTriangles = new SMD2Tri[m_Head.m_iNumTriangles]; memcpy(m_pTriangles, ucpTmpPtr, 12 * m_Head.m_iNumTriangles); //Read the U/V texture coords ucpTmpPtr = ucpPtr; ucpTmpPtr += m_Head.m_iOffsetTexCoords; m_pTexCoords = new SMD2TexCoord[m_Head.m_iNumTexCoords]; short * sTexCoords = new short[m_Head.m_iNumTexCoords * 2]; memcpy(sTexCoords, ucpTmpPtr, 4 * m_Head.m_iNumTexCoords); for(i = 0; i < m_Head.m_iNumTexCoords; i++) { m_pTexCoords[i].m_fTex[0] = (float)sTexCoords[2*i] / m_Head.m_iSkinWidthPx; m_pTexCoords[i].m_fTex[1] = (float)sTexCoords[2*i+1] / m_Head.m_iSkinHeightPx; } delete [] sTexCoords; //Read the skin filenames ucpTmpPtr = ucpPtr; ucpTmpPtr += m_Head.m_iOffsetSkins; m_pSkins = new SMD2Skin[m_Head.m_iNumSkins]; //Load textures for(i = 0; i < m_Head.m_iNumSkins; i++) { memcpy(m_pSkins[i].m_caSkin, ucpTmpPtr, 64); //hack off the leading parts and just get the filename char * szEnd = strrchr(m_pSkins[i].m_caSkin, '/'); if(szEnd) { szEnd++; strcpy(m_pSkins[i].m_caSkin, szEnd); } m_pSkins[i].m_Image.Load(m_pSkins[i].m_caSkin); ucpTmpPtr += 64; } delete [] ucpBuffer; return true; } | |
countainer class : | |
class CMd2 : public CModel { public: //Set skin to one of the files specified in the md2 files itself void SetSkin(unsigned int uiSkin); //Set skin to a different image void SetSkin(CImage& skin); //Load the file bool Load(const char * szFilename); //Render file at the initial position void Render(); //Render the file at a certain frame void Render(unsigned int uiFrame); //Animate the md2 model (start and end frames of 0 and 0 will loop through the WHOLE model void Animate(float fSpeed = 30.0f, unsigned int uiStartFrame = 0, unsigned int uiEndFrame = 0, bool bLoop = true); //constructors/destructo CMd2(); CMd2(const char * szFile); ~CMd2(); private: CTimer m_Timer; //file header information SMD2Header m_Head; //Frame information SMD2Frame * m_pFrames; //Triangles SMD2Tri * m_pTriangles; //Texure coords SMD2TexCoord * m_pTexCoords; //Skin files SMD2Skin * m_pSkins; //Interpolated vertices SMD2Vert * m_pVerts; //Current skin unsigned int m_uiSkin; //Using a custom skin? bool m_bIsCustomSkin; //The custom skin CImage * m_pCustSkin; }; | |
eFishAnt 14-Jan-2005 [178] | you go too fast for me...;-) I have to find some time this weekend to play with the first toys... |
shadwolf 14-Jan-2005 [179x2] | so you make a SDM2Header *m_Header; to declare your header type from structure SMD3Header, then you read the correct emont of data in the file storing it to ucpPtr then you init m_Header it using memcpy(&m_Head, ucpPtr, sizeof(SMD2Header)); |
if you want to load 3 MD2 files you need only to make other main pointer to the information you retrieve from the file | |
Ladislav 14-Jan-2005 [181] | Shadwolf: "in rebol a: SMD2Header and b: SMD2Header will point to the same memory chunk ..." yes, but you should do it as follows: a: make struct! SMD2Header b: make struct! SMD2Header |
shadwolf 14-Jan-2005 [182x4] | in rebol you will need to load 3 files to declare SDM2Header_f1 SMD2Header_f3 and SMD2Header_f3 with for both the stricly identical content tso your recoding 3 times or X times the same thing ... |
I'm not an expert on struct! far of that (wel in C yes but in REBOL no and I think it's because I'm not using load/library capability until now) but that's a good discution to point to difficulties on this kind of task and I hope help rebol Core to have a bettre handling of that | |
ladyslav on declaration statement REBOL need me to give him the datas I ust tryed what you just propose: | |
>> a: make struct! SMD2Header ** Script Error: Invalid argument: (missing value) ** Near: a: make struct! SMD2Header | |
Ladislav 14-Jan-2005 [186x2] | a: make struct! SMD2Header none ; or [some values here] |
if you supply none, you generate an "empty" struct | |
Cyphre 14-Jan-2005 [188] | shadwolf: have you read this? http://www.rebol.com/docs/library.html |
shadwolf 14-Jan-2005 [189] | yes so I had to read the file first then make my variable content basing me on a precut of the rode datas from file to be allowed to fill my variable content on inititialisation |
Ladislav 14-Jan-2005 [190] | you can create an empty struct using NONE and fill it using the read data |
shadwolf 14-Jan-2005 [191x2] | yes I read it cyphre long time ago when it was recently published but one thing that's apear to me dangerous is for example use: |
a-struct: make struct! [ in-string [string!] "Input string" in-int [integer!] "Input integer" ] ["This is input" 42] | |
Cyphre 14-Jan-2005 [193] | what is dangerous on that? |
shadwolf 14-Jan-2005 [194x4] | while in C my struct is struct a-struct { char in-string[25]; int in-int; } |
how can I be certain using string! unlimited REBOL countainer to correctly feet with the char 25 strictly sized contained in C | |
no contained but countainer | |
the dangerous thing is that with rebal I can over pass easly the 25 limitation and write every where in the countigous memeryy area ;) | |
Cyphre 14-Jan-2005 [198] | If I understand you well you have tu create string! of length 25 in rebol for your purpose. |
shadwolf 14-Jan-2005 [199x2] | that's not a direct use for me I intent thru thi discution to enlight some problems that every one can infront using rebol external library capability |
or reusing C/C++/VB binary struct based data type (like MD2 file format) | |
Cyphre 14-Jan-2005 [201] | It is on you to not override the length of the string IMO You have to deal with this as you are working with static memory so it is not a problem of Rebol itself. I think you ca easily write 'dangerous' code when dealing with DLL interfaces ;) Making error in this are usually ends up with crash (memory acces violation). |
shadwolf 14-Jan-2005 [202] | yes I know that ;) |
eFishAnt 14-Jan-2005 [203] | maybe that IS a good point to make it harder to crash at the interface. The toughest code to write is always the in-between stuff. |
shadwolf 14-Jan-2005 [204x2] | the main purpose I purchase is to enhance and simplify the rebol interaction with external lib and C/C++/VB structure binary file based |
and that's why I can here to expose the difficulties I see on that issue and try with you to get infos or solutions to propose to Carl | |
Cyphre 14-Jan-2005 [206] | so what is your solution? Do you know how to improve the interface? |
eFishAnt 14-Jan-2005 [207] | It takes a guru level REBOLer who is also profishant in C to write an interface to a DLL, although there are becoming more and simple examples...but maybe shadwolf wants to make it a graphical process? |
shadwolf 14-Jan-2005 [208] | not that far .... lol |
older newer | first last |