Skip to main content
gamedev.net
🔒 Locked

More problems with pointers

Started by Rocket05 5 replies 400+ views
Original Post
Rocket05
Rocket05
Alright i am _very_ irritated by this problem. I am using DJGPP and working on a simple 3d engine of my own. i have a stuct for a model (which i dont mean external model, i mean like anything in the game, including objects, levels, and so on). it is defined as follows: (first you need VERTEX): typedef struct _VERTEX { float x,y,z; }VERTEX; (then triangle): typedef struct _TRIANGLE { VERTEX verticies[3]; VERTEX normal; }TRIANGLE; (then face): typedef struct _FACE { VERTEX normal; TRIANGLE *triangles; int num_triangles; }FACE; (then model): typedef struct _MODEL { VERTEX pos; float rx,ry,rz; FACE *faces; int num_faces; }MODEL; go back and look at the code, so you can look at what of the members are pointers. all right, and here is my function, which is really giving me a headache: int FindNormal(FACE* face) { VERTEX v1,v2; VERTEX out; v1.x = face->triangles[0]->v[0].x - face->triangles[0].v[1].x; v1.y = face->triangles[0]->v[0].y - face->triangles[0].v[1].y; v1.z = face->triangles[0]->v[0].z - face->triangles[0].v[1].z; v2.x = face->triangles[0]->v[1].x - face->triangles[0]->v[2].x; v2.y = face->triangles[0]->v[1].y - face->triangles[0]->v[2].y; v2.z = face->triangles[0]->v[1].z - face->triangles[0]->v[2].z; out.x = v1.y*v2.z - v1.z*v2.y; out.y = v1.z*v2.x - v1.x*v2.z; out.z = v1.x*v2.y - v1.y*v2.x; if(out.x > 0) { out.x/=out.x; } if(out.y > 0) { out.y/=out.y; } if(out.z > 0) { out.z/=out.z; } face.normal.x = out.x; face.normal.y = out.y; face.normal.z = out.z; return(0); } and my compiler makes an error saying for almost each line of code complaining about the face->triangles part: "invalid argument type ''->''" so i tried making all of the ''->'' for the face->triangles part, and then it says: "request for member ''triangles'' in something not a struct or union" i am really stumped
"I never let schooling interfere with my education" - Mark Twain
spock
spock
   This code compiles on my machine:

typedef struct _VERTEX {
   float x,y,z;
}VERTEX;

typedef struct _TRIANGLE {
   VERTEX v[3]; // was VERTEX verticies[3];
   VERTEX normal;
}TRIANGLE;

typedef struct _FACE {
   VERTEX normal;
   TRIANGLE *triangles;
   int num_triangles;
}FACE;

typedef struct _MODEL {
   VERTEX pos;
   float rx,ry,rz;
   FACE *faces;
   int num_faces;
}MODEL;

int FindNormal(FACE* face)
{
   VERTEX v1,v2;
   VERTEX out;

   v1.x = face->triangles[0].v[0].x - face->triangles[0].v[1].x;
   v1.y = face->triangles[0].v[0].y - face->triangles[0].v[1].y;
   v1.z = face->triangles[0].v[0].z - face->triangles[0].v[1].z;

   v2.x = face->triangles[0].v[1].x - face->triangles[0].v[2].x;
   v2.y = face->triangles[0].v[1].y - face->triangles[0].v[2].y;
   v2.z = face->triangles[0].v[1].z - face->triangles[0].v[2].z;

   out.x = v1.y*v2.z - v1.z*v2.y;
   out.y = v1.z*v2.x - v1.x*v2.z;
   out.z = v1.x*v2.y - v1.y*v2.x;

   if(out.x > 0)
   {
      out.x/=out.x;
   }
   if(out.y > 0)
   {
      out.y/=out.y;
   }
   if(out.z > 0)
   {
      out.z/=out.z;
   }
   face->normal.x = out.x;
   face->normal.y = out.y;
   face->normal.z = out.z;

   return(0);
}


Edited by - spock on December 9, 2000 12:41:19 AM
the Dealy Lama
the Dealy Lama
-> is shorthand for dereferencing a pointer to a struct
[] also dereferences pointers, but possible offsets.

face->triangles[0]->etc is invalid. dissect it: triangles is a pointer to a triangle struct. I''m assuming you use it for a dynamically allocated array. so, face->triangles[0] is not a pointer, but a TRIANGLE struct, which cannot be dereferenced.

spock''s solution should work.
live long and prosper.

Gruad the Dealy Lama

"What sounds to you like a big bloat of trashy old noise
is in fact the brilliant music of a genius--myself" ~ Iggy Pop
=======================================Matt Welch"What sounds to you like a big bloat of trashy old noiseis in fact the brilliant music of a genius--myself" ~ Iggy Pop
Snyper
Snyper
Ya you are tying to access a member that does not exist. In the line: v1.x = face->triangles[0]->v[0].x - face->triangles[0].v[1].x;
v is not a member of anything, you should be using vertices. Which IS a member of TRIANGLE.

-Snyper
=============================Where's the 'any' key?=============================
Rocket05
Rocket05
its always those stupid little things that make me go berserk when they dont work...

this just shows my extreme stupidity....

but just for future reference, so i dont make another stupid mistake that drives me crazy...

so even if something is a pointer, if it is an array, it is accessed with a '.'?
ex-(triangle[v]->v) dont do that...
ex-(triangle[v].v) do this?





Edited by - rocket05 on December 10, 2000 9:50:59 AM
"I never let schooling interfere with my education" - Mark Twain
Kylotan
Kylotan
No. If it is a pointer, you use ''->'', if it is an actual object, you use ''.'' There are no exceptions. You are misunderstanding the advice given above.

At no point should you use:
face->triangles[0]->v[1].x;

Why? Let''s break this down, left to right.
''face'' is a pointer to a FACE struct, right?
''face->triangles'' is the dynamic array of TRIANGLES within FACE.
''face->triangles[0]'' is therefore the first TRIANGLE in there.
It is not a pointer to a triangle. It is a whole triangle structure. Therefore, your next symbol should be ''.'', not ''->''. Or maybe you actually meant for FACE to contain a dynamic array of pointers to triangles, which would be ''TRIANGLE** triangles;'' ... note, 2 asterisks.

Continuing on, assuming you fixed that error:
''face->triangles[0].v'' would be the ''v'' data member of the TRIANGLE in question. But, TRIANGLES do not have a ''v'' data member! So that''s an error too. I assume you really meant:
''face->triangles[0].vertices'' (note corrected spelling, too.)
Then, you can progress on towards:
''face->triangles[0].vertices[1].x;'' as you originally intended.
ddarius
ddarius
Well, this doesn''t pertain to your problem, but I think it should be said anyways.

The way you have your structures setup isn''t very efficient. Actually the inefficiency is the way you handle vertices.

Most every 3D engine does what I''m about to describe in some fashion (maybe not mine).

First, here''s the problem. Imagine a square made up of two triangles. Well, in that square the triangles share two vertices. So, you rotate the square. To do that, you rotate the three vertices in one triangle and the three vertices in the other, for a total of 6 rotations. However, 2 of those rotations occur twice. Another way to look at it is to rotate 2 triangles you need to rotate 6 points, but to rotate a square you only need to rotate 4 points, so what''s with the extra 2.

No, the solution is not to make a square structure. The solution is to make a pool of vertices, and to have the triangles, instead of holding the vertices, hold indexes into this pool. This way you only rotate a point once. When you do this to rotate a square you only need to rotate 4 points, though it still will be composed of 2 triangles.

Now, the way I handle this is to have the "Model" structure hold an array of vertices, that is simply a list of all the vertices in the Model. Then you rewrite the "Vertex" structure to hold an array of 3 ints (short or long depending on how complex you expect this to get, though short will probably do for most any model). Now, you can only rotate "Models" (though you can keep your old triangle struct for simple figures), but you should almost always only be rotating "models" anyways. The rotate function will now look something like this...

//irrelevant stuff trimmed
void rotate(Model *mdl){
for(int x=0;xnum_vertices;x++)
rotatepoint(mdl->vpool[x]);
//actually you''d probably want to store rotated points someplace
//else in the model
}

Then to get the verticies to draw or something you''d...

//just using draw as an example
void Drawtriangle(Triangle *tri){
pvpool=tri->parent->parent->vpool;
//parent is a pointer in triangle to the face the triangle is a //part of and there is a parent member in face that points to the //model the face is part of (in my setup).
//setting pvpool to that is just optimization, and clarity
VERTEX v1=pvpool[tri->vindex[0]]
VERTEX v2=pvpool[tri->vindex[1]]
VERTEX v3=pvpool[tri->vindex[2]]
//then do whatever with those
}

"It is one thing to use poorly coded programs. It is another to produce poorly coded programs" -- Me, as far as I know.
"It is one thing to use poorly coded programs. It is another to produce poorly coded programs" -- Me, as far as I know.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.