3D Rad - Free 3D game maker - Forum

This forum is now archived!

This forum is locked, and is a read-only version. A new community-ran forum can be found at classdev.net

News:

The 3DRad community can be found at classdev.net.

Pages: [1] 2

Author Topic: Imposter object meshMap to a vertex array  (Read 3462 times)

« on: June 25, 2010, 03:25:17 PM »
Is it possible to have this read by a script as a function in RAD, bool iMapMeshArrayGet(string, Vector3, int)
Returns false when there is no more vertexes to read from the .x
This would save me processing power by skipping scanning of a terrain for imposter placement.

..Edit : When I think about it, the .x file could be read by a script.
  Or even an external dll could do this job aswell.
« Last Edit: June 25, 2010, 03:30:56 PM by shadmar »

jestermon

« Reply #1 on: June 25, 2010, 05:46:41 PM »
I have a little utility I wrote for Rad 3D Pucman, that reads a .x file and after cleaning out all duplicate vertices (there can be many), it loads them into a database... If I made a small mod by removing the database and dumping it into a dll; It can have a single function, where you pass the x name as a parameter and return a fully loaded Vertex3 array to hold the vertex list..

It can look something like this..

Code: [Select]
//globals .. for use anywhere

Vector3 [] xList();
int xListLength = 0;

void GetVectorList(string xName)
{
   ... blah blah
   //xList gets loaded
   //xListLength gets set
}


you could then access the individual elements like this ...

Code: [Select]
   for(int i=0; i<xListLength;i++){
      iObjectImposterSet(OBJ_XX, i, whateverOrientation, xList[i]);
   }

Will this help?
« Last Edit: June 25, 2010, 05:49:49 PM by jestermon »
« Reply #2 on: June 25, 2010, 11:46:45 PM »
I suppose it depends on the size of your xListLength as to the degree of script slowdown you get (as per my lengthy FOR-NEXT loop problem) ?!
AKA: The 3D Raddict http://www.3draddict.com/
« Reply #3 on: June 26, 2010, 02:32:16 AM »
Yes sometjing like that would work.
You would only need to populate this array in init() section once, or on every iObjectRefresh()

My idea here was placing trees.

Edit:
 **lightbulb pop**

Even if you scan the terrain and place'm I can still save the vectors to a file, and just read after. this feels like looking at the trees and not seeing the forrest.
Thanks guys, scan once, write to file and read ever after will actually solve my problem here. It really helps thinking out loud :)
« Last Edit: June 26, 2010, 02:34:26 AM by shadmar »

jestermon

« Reply #4 on: June 26, 2010, 07:14:30 AM »
Yes sometjing like that would work.
You would only need to populate this array in init() section once, or on every iObjectRefresh()

My idea here was placing trees.

Edit:
 **lightbulb pop**

Even if you scan the terrain and place'm I can still save the vectors to a file, and just read after. this feels like looking at the trees and not seeing the forrest.
Thanks guys, scan once, write to file and read ever after will actually solve my problem here. It really helps thinking out loud :)
After all the light-bulbs have popped, and you are speaking of files... Will you still need the x file Reader utility... Before I do it for no reason?
« Reply #5 on: June 26, 2010, 09:00:30 AM »
It would still be useful, placing imposters at meshmap verteces is nice, but we still don't have access to them to manipulate, show/hide/move etc.
So in my opinion it would be great to have a x-reader yes.

jestermon

« Reply #6 on: June 26, 2010, 09:06:49 AM »
I suppose it depends on the size of your xListLength as to the degree of script slowdown you get (as per my lengthy FOR-NEXT loop problem) ?!
Very lengthy for loops can be a great problem. but that's if there are 1000's of them. In 3D pucman I scan 700+ pucs per frame for collision detection, and there is no hitch even with iVectorLength calcs. I got as many as 4000 working without effecting frame rate. Anything over 5000 imposters with added calcs starts having some serious impact though. This is about the limit I play at anyway.
« Reply #7 on: June 26, 2010, 09:20:02 AM »
In my Grid frustrum example I use 50000 imposters
It's a 16x16 (256 grid nodes which holds on average 195 imposters)
It searches (256 num nodes)+(nodes in view frustrum*imposters registered in each), typically :
256+16*195 = 3376 checks instead of 50000 in a FOR .. NEXT loop.
This is a good way of indexing the imposters so you don't need to check all 50000

A quadtree would possible be better, but I have been unsuccessfull in writing one in angelcode.
When I get some time do work on dll's I will have a re-look.
Spatial indexing instead of brute force is the way to go.
« Last Edit: June 26, 2010, 09:22:17 AM by shadmar »

jestermon

« Reply #8 on: June 26, 2010, 11:48:23 AM »
I like the idea of using a quadtree, maybe a dll could do something there. I'll take a peek.
Back to business..
Here's the latest Xreader, a vast improvement on the previous releases, since it removes all duplicate vertices from the list, and uses a single neatly wrapped function with ASCII generated as needed. Cleaner and faster.
You will have to convert your compressed X files to text.. Sometimes if an xfile can't load, I import and then re-export it with Fragmation, which solves this problem.
Hope this is helps.

This project is a simple example of placing a fish at all vertex points.
« Reply #9 on: June 26, 2010, 01:24:52 PM »

Thanks J for the dll, but I didn't manage to get it running.
I tested it default on the platform100m file as in the demo provided (re-exported the .x from frag as text too).
Placed the DLL in the Script folder.

Maybe I'm missing something ?

jestermon

« Reply #10 on: June 26, 2010, 02:10:09 PM »
Strange.. Let me make up a project of what I used.. Will post soon.

Edit:
Ok here it is. It has the project, the dll and the platform100m rigidbody_mesh.x in their appropriate directories. I imported and then re-exported the x file with the settings as shown in the image
Try replacing the xfile in your rigidbody folder with the model I used.. You can always put a backup back again.. It did not work the first time round, so I did the Fragmotion thing on it.. For models that I build myself, I never have problems.


« Last Edit: June 26, 2010, 02:29:28 PM by jestermon »

jestermon

« Reply #11 on: June 26, 2010, 02:42:33 PM »
While thinking about random tree placements, an idea occurred to me.. I'll try an experiment on it.. If one uses a scanner, one should be able to determine a "surface-point" anywhere on a mesh, and then one could use this for object placement

1.. point scanner down
2.. make scanner a reasonable length
3.. randomly generate x/z coordinates using simple dispersal pattens
4.. scan for y coordinate where scanner intersects "ground" surface
5.. store in vector list
6.. place objects

should work nicely without having to use a mesh for pinpoint locations.
« Last Edit: June 26, 2010, 02:44:49 PM by jestermon »
« Reply #12 on: June 26, 2010, 04:18:27 PM »
Hmm still nothing.
I checked the handle from iDLLLoad and that returns 0
In your code I replaced the xreader3.dll with MyDLL.dll and handle returned a number.
It could be your dll has some dependants I don't have installed ?, I don't know.
The sqllite.dll works ok too, but I can't get this one past iDLLLoad

Quote
1.. point scanner down
2.. make scanner a reasonable length
3.. randomly generate x/z coordinates using simple dispersal pattens
4.. scan for y coordinate where scanner intersects "ground" surface
5.. store in vector list
6.. place objects

Yes the Grid frustrum does this, and also my current tree seeder does it this way.
Main problem with scanning is that it misses quite often, and returns no vector so you ned several repetitions to get a good cover, and that takes some time.

jestermon

« Reply #13 on: June 26, 2010, 06:10:30 PM »
Very strange indeed... sqlite and the xReader are both compiled with Devc++...
Only thing I can think of is that you may need the mingwm dll. But that the sqlite one works, and the Xreader not; makes little sense. Here's the mingwm10.dll that comes with Devc++ 4.9.9.2
You probably have DevC++ on your machine, and the ming dll versions could conflict (just a passing thought, not necessarily the problem).. Place this dll in the script directory together with the Xreader3.dll, pehaps this solves the problem, which now really has me confused.

Here's the source for both dll's and they are not that different in design, the sqlite one just has some extra database stuff in it.

RadSqLite.c
Code: [Select]
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <sqlite3.h>

__declspec(dllexport) void doSql(float *param);
__declspec(dllexport) void setDatabase(float *param);
__declspec(dllexport) void getRecord(float *param);
__declspec(dllexport) void getRecordcount(float *param);
__declspec(dllexport) void debugOn(float *param);
__declspec(dllexport) void debugOff(float *param);
__declspec(dllexport) void setRecord(float *param);

void float2str();

sqlite3 *db;
char *zErrMsg = 0;
char sql[1024]="";
int db_open=0;
char dbStr[1024][1024];
int dbC = 0;
char ss[1024];
float ff[1024];
char dbname[100];
char dbgstr[100];

int dbg = 0;

//--------------------------------------------------
void debug()
{
   FILE *fp;
   if(!dbg) return;
   fp = fopen("RadSqLite.debug","a");
   if(!fp)
      fp = (FILE*)open("RadSqLite.debug","w");
   fprintf(fp,"%s\n",dbgstr);
   fclose(fp);
}


//--------------------------------------------------
void cleanup()
{
   int i;
   char c;
   for(i=0;i<strlen(ss);i++){
      if(ss[i] == '!')
         ss[i]=' ';
   }
}

//--------------------------------------------------
void setRecord(float *param)
{
   int i;
   float f;
   f = param[0];
   if(f<0) f = 0;       //clip the
   if(f>1023) f = 1023; //limts
   for(i=0;i<1024;i++){
      ff[i]=param[i+1];
      if(param[i+1]=0)
         break;
   }
   float2str();
   cleanup();
   dbStr[(int)f][0] = 0;
   strcpy(dbStr[(int)f],ss);
   sprintf(dbgstr,"setRecord: %d = %s",(int)f,ss);
   debug();
}

//--------------------------------------------------
static int dbCallback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   char dta[1024]="";
   for(i=0; i<argc; i++){
      if((strlen(argv[i])+strlen(dbStr[dbC])+1) < 1023){
         strcat(dta,(argv[i] ? argv[i] : "NULL"));
         //strcat(dta,argv[i]);
         strcat(dta,";");
      }
   }
   strcpy(dbStr[dbC],dta);
   dbC++;
   if(dbC > 1023) dbC=1023;
   return 0;
}

//--------------------------------------------------
int dbOpen(char* dbName)
{
   int rc=0;
   int dbrc;
   strcpy(dbgstr, "dbOpen: ");
   strcat(dbgstr,dbName);
   strcat(dbgstr,"\n");
   debug();
   db_open=0;
   dbrc = sqlite3_open(dbName, &db);
   if(dbrc){
      db_open=0;
      dbg=1;
      sprintf(dbgstr, "Can't open database: %s\n", sqlite3_errmsg(db));
      debug();
      sqlite3_close(db);
      rc=0;
   }else{
      db_open=1;
      rc=1;
   }
   return rc;
}

//--------------------------------------------------
int dbExec(char *sql)
{
   int rc=0;
   int dbrc;
   strcpy(dbgstr, "dbExec: ");
   strcat(dbgstr,sql);
   debug();
   dbC = 0;
   if(!db_open) return;
   dbrc = sqlite3_exec(db, sql, dbCallback, 0, &zErrMsg);
   if (dbrc!=SQLITE_OK ){
      dbg = 1;
      sprintf(dbgstr, "SQL error: %s\n", zErrMsg);
      debug();
      rc=0;
   }else{
      rc=1;
   }
   strcpy(dbgstr,sql);
   debug();
   sprintf(dbgstr,"Records returned: %d",dbC);
   debug();
   return rc;
}

//--------------------------------------------------
void dbClose()
{
   strcpy(dbgstr, "dbClose");
   debug();
   if(db_open) sqlite3_close(db);
}

//--------------------------------------------------
int dbSql(char *database,char *sql)
{
   int rc=0;
   char statement[1024]="";
   strcpy(dbgstr,sql);
   debug();
   sprintf(statement,sql);
   if(!dbOpen(database)) return(0);
   if(!dbExec(sql)) return(0);
   dbClose();
   return (1);
}

//----------------------------------------
void str2float()
{
   int i,L,c;
   L = strlen(ss);
   for(i=0;i<L;i++){
      c = ss[i];
      ff[i] = (float)c;
   }
   ff[L]=0;
}

//----------------------------------------
void float2str()
{
   int i;
   char c[2];
   ss[0]=0;
   for(i=0;i<1024;i++){
      c[0] = ff[i];
      c[1] = 0;
      if(c[0]){
         strcat(ss,c);
      }else{
         break;
      }
   }
}

//----------------------------------------
void getRecordcount(float *param)
{
   float f = (float)dbC;
   param[0] = f;
   sprintf(dbgstr,"getRecordCount: %d",dbC);
   debug();
}

//----------------------------------------
void getRecord(float *param)
{
   float f;
   int n,i;
   f = param[0];
   n = (int)f;
   strcpy(ss,dbStr[n]);
   str2float();
   for(i=0;i<1024;i++){
      param[i] = ff[i];
      if(ff[i]==0)
         break;
   }
}

//----------------------------------------
void setDatabase(float *param)
{
   int i;
   for(i=0;i<1024;i++){
      ff[i]=param[i];
      if(param[i]=0)
         break;
   }
   float2str();
   cleanup();
   strcpy(dbname,ss);
}

//----------------------------------------
void doSql(float *param)
{
   int i;
   if(strlen(dbname) < 1) return;
   for(i=0;i<1024;i++){
      ff[i]=param[i];
      if(param[i]=0)
         break;
   }
   float2str();
   cleanup();
   strcpy(sql,ss);
   dbSql(dbname,sql);
}

//----------------------------------------
void debugOn(float *param)
{
   dbg = 1;
}

//----------------------------------------
void debugOff(float *param)
{
   dbg = 0;
}

xreader3.c   -- LoadFile() has the X-file reader parser, if you are interested

Code: [Select]
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define READY 0
#define VERTS 1
#define DONE  2

char xfile[400];
float list[10000];
float floatfilename[400];
int c1 = -1;

__declspec(dllexport) void GetCount(float* myData);
__declspec(dllexport) void GetData(float* myData);
__declspec(dllexport) void SetName(float* myData);
__declspec(dllexport) void LoadXFile(float *myData);

void LoadFile(char* filename);
void ParseVerts(char* data);
void NameToFloat(char *name);
void floatToName(float* fname);
int checkList(char *s1, char *s2, char *s3);


//----------------------------------------
void debug(char *s)
{
   FILE *fp;
   fp = fopen("c:\\temp\\dump.txt","a");
   if(!fp)
      fp = fopen("c:\\temp\\dump.txt","w");
   fprintf(fp,"%s\n",s);
   fclose(fp);
}



//----------------------------------------
void NameToFloat(char *name)
{
   int i;
   char c;
   for(i=0;i<200;i++){ //clear list
      floatfilename[i] = 0;
   }
   for(i=0; i<strlen(name);i++){
      c = name[i];
     floatfilename[i] = c;
   }
}

//----------------------------------------
void floatToName(float* fname)
{
   int i;
   char c;
   for(i=0;i<200;i++){
      xfile[i]=0;
   }
   for(i=0;i<200;i++){
      c = fname[i];
      if(c == '/') c = '\\';
      xfile[i]=c;
   }
}

//----------------------------------------
void ParseVerts(char* data)
{
   char s[100];
   char s1[30];
   char s2[30];
   char s3[30];
   char *p, *q;
   strcpy(s,data);
   q = s;
   p = strstr(q,";");
   if(p) *p = 0;  //null terminate on ;
   strcpy(s1,q);
   q = p+1;
   p = strstr(q,";");
   if(p) *p = 0;  //null terminate on ;
   strcpy(s2,q);
   q = p+1;
   p = strstr(q,";");
   if(p) *p = 0;  //null terminate on ;
   strcpy(s3,q);
   if(!checkList(s1,s2,s3)){
      list[++c1] = atof(s1);
      list[++c1] = atof(s2);
      list[++c1] = atof(s3);
   }
}

//----------------------------------------
int checkList(char *s1, char *s2, char *s3)
{
   int res = 0;
   float f1,f2,f3;
   int i;
   f1 = atof(s1);
   f2 = atof(s2);
   f3 = atof(s3);
   for(i=0;i<c1; i+=3){
      if(f1==list[i] && f2==list[i+1] && f3==list[i+2]){
         res = 1;
         break;
      }
   }
   return res;
}

//----------------------------------------
void LoadFile(char* filename)
{
   FILE *fp;
   char fdata[200];
   int lines = 0;
   int state = READY;
   c1 = -1;                              //<--- Bug fix: Added this to reset counter on each new load
   fp = fopen(filename,"r");
   if(fp){
      while(!feof(fp)){
         lines++;
         if(lines > 3333) break;
         fgets(fdata,200,fp);
         if(strstr(fdata,"Mesh "))
            state = VERTS;
         if(state == VERTS){
            if(strstr(fdata,";;"))
               state = DONE;
            if(strstr(fdata,";,"))
               ParseVerts(fdata);
            if(strstr(fdata,";;"))
               ParseVerts(fdata);
            if(state == DONE) //all done
               break;
         }
         if(feof(fp)) break;
      }
      fclose(fp);
   }
}

//----------------------------------------
void GetCount(float* myData)
{
   char txt[10];
   myData[0] = c1;
}


//----------------------------------------
void GetData(float* myData)
{
   int i;
   for(i=0;i<c1;i++)
      myData[i] = list[i];
}


//----------------------------------------
void SetName(float* myData)
{
   int i;
   float n;
   for(i=0;i<200;i++)
      floatfilename[i] = 0;
   for(i=0;i<200;i++){
      n = myData[i];
      if(n>0)
         floatfilename[i] = n;
      else
         break;
   }
   floatToName(floatfilename);
}


//----------------------------------------
void LoadXFile(float *myData)
{
   int i;
   for(i=0;i<10000;i++)
      list[i] = 0;
   LoadFile(xfile);
}


Let's hope the problem was the lack of mingwm10.dll but that sqlite works makes this an interesting mystery.

Edit: After some thought, mingwm10.dll should not really make a difference, because the dll uses nothing specific to *Win* except the external declarations and the format of the DLL-load-header of the file.. Also nothing that requires Ming->Win translation, since there the code is pure ANSI-C.. Only windows.h is required for the dll, but there is no external links except for sqlite.lib in the sqlite dll (perhaps it has some win specific code in its Lib... no idea).... But surprise me and tell me mingwm10.dll makes a difference

Edit2: Aha I found a small bug.(though this did not effect 1st time load). fixed and uploaded latest xreader3.dll (See source above for details)

Edit3: uploaded the compiled project.. Maybe this may not run on your machine.. It runs perfectly on mine.. Should narrow down the problem
« Last Edit: June 26, 2010, 07:21:40 PM by jestermon »
« Reply #14 on: June 27, 2010, 01:09:53 AM »
Cheers J, the last xreader3.dll loads here :)
I guess it was the bug?

The compiled one works aswell

Thanks for the dll solution :)
Pages: [1] 2