EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   OpenEQ::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=609)
-   -   eXtensible World File (https://www.eqemulator.org/forums/showthread.php?t=16154)

daeken_bb 10-03-2004 06:14 AM

Quote:

Originally Posted by Windcatcher
Edit #1: for frustum culling, you'll need bounding spheres in addition to bounding boxes (sphere culling should be the first step as it's way faster)

What I do is just take the longest side of the bounding box and treat that as the radius.

Windcatcher 10-03-2004 06:15 AM

The bit 2 in the polygon struct should be taken as temporary...at some point we'll need a full-blown alpha setting to handle semitransparency (e.g. windows), but this will do for now.

daeken_bb 10-03-2004 06:17 AM

Quote:

Originally Posted by jbb
Code:

struct Vertex {
  double x, y, z; // Position
  double u, v; // Texture coords
};

You might want to add vertex normals to that.

Done, thanks :)

daeken_bb 10-03-2004 06:18 AM

Quote:

Originally Posted by Windcatcher
The bit 2 in the polygon struct should be taken as temporary...at some point we'll need a full-blown alpha setting to handle semitransparency (e.g. windows), but this will do for now.

Shouldn't that stuff be done in textures, though?

Windcatcher 10-03-2004 06:22 AM

I don't know...we should probably talk about it. That's the way it's done in WLD, but I'm not sure it's the best way. Is it better to tie alpha to polygons or textures? When rendering, alpha is done at the poly level.

Edit: Here's what I've got so far:

Code:

Unit XWFFiles;

Interface

Uses Classes;

Const
  fourccTexture        = 'tex ';
  fourccVertex        = 'vert';
  fourccPolygon        = 'poly';
  fourccObject        = 'obj ';
  fourccOctreeParent  = 'octp';
  fourccOctreeEndpoint = 'octe';

Type
  TFourCC = Packed Array[0..3] Of Char;

  TXWFAtomRec = Packed Record
    FourCC  : TFourCC;
    Children : LongWord;
    Size    : LongWord;
  End;

  TXWFVertexGroupRec = Packed Record
    GroupID    : LongWord;
    NumVertices : LongWord;
  End;

  TXWFVertexRec = Packed Record
    X,Y,Z : Double;    // Position
    U,V  : Double;    // Texture coordinates
    I,J,K : Double;    // Normal
  End;

  TXWFPolygonGroupRec = Packed Record
    VertexGroupID : LongWord;
    NumPolygons  : LongWord;
  End;

  TXWFPolygonRec = Packed Record
    V1,V2,V3  : LongWord; // Vertex indices in the indicated vertex group
    TextureID : LongWord; // Texture ID
    Flags    : LongWord; // Bit 1 ... 0 = solid, 1 = can be walked through
                          // Bit 2 ... 1 = transparent (TEMPORARY UNTIL SHADERS ARE DEFINED)
  End;

  TXWFOctreeNodeRec = Packed Record
    Center : Packed Array[0..2] Of Double;
    Size  : Packed Array[0..2] Of Double;
  End;

  // Classes for dealing with atoms

  TXWFAtom = Class
    Atom    : TXWFAtomRec;
    Data    : Pointer;
    Children : TStringList; // Child atoms
    Constructor Create(Const AtomRec: TXWFAtomRec);
    Destructor  Destroy; Override;
    Procedure  ReadFromStream(Stream: TStream);
    Procedure  WriteToStream(Stream: TStream);
  End;

Implementation

Uses Math,SysUtils;

// ------------------------------
// Utility routines
// ------------------------------

Function StrLPas(P: PChar; MaxLen: Integer): String;
Var
  I  : Integer;
  St : String;

Begin
  I  := Min(MaxLen,StrLen(P));
  St := '';
  While Length(St) < I Do St := St + ' ';
  Move(P^,St[1],I);
  Result := St;
End; // StrLPas

// ------------------------------
// TXWFAtom
// ------------------------------

Constructor TXWFAtom.Create(Const AtomRec: TXWFAtomRec);
Begin
  Atom    := AtomRec;
  Children := TStringList.Create;
  If Atom.Size > 0 Then GetMem(Data,Atom.Size) Else Data := Nil;
End; // TXWFAtom.Create

Destructor TXWFAtom.Destroy;
Var I: Integer;
Begin
  For I := 0 To Children.Count - 1 Do Children.Objects[I].Free;
  Children.Free;
  If Data <> Nil Then FreeMem(Data,Atom.Size);
End; // TXWFAtom.Destroy

Procedure TXWFAtom.ReadFromStream(Stream: TStream);
Var
  ChildAtom : TXWFAtomRec;
  Child    : TXWFAtom;

Begin
  If Atom.Size > 0 Then Stream.Read(Data^,Atom.Size);
  Stream.Read(ChildAtom,SizeOf(ChildAtom));
  Child := TXWFAtom.Create(ChildAtom);
  Children.AddObject(StrLPas(Atom.FourCC,4),Child);
  Child.ReadFromStream(Stream);
End; // TXWFAtom.ReadFromStream

Procedure TXWFAtom.WriteToStream(Stream: TStream);
Var I: Integer;
Begin
  If Atom.Size > 0 Then Stream.Write(Data^,Atom.Size);
  For I := 0 To Children.Count - 1 Do TXWFAtom(Children.Objects[I]).WriteToStream(Stream);
End; // TXWFAtom.WriteToStream

End.


daeken_bb 10-03-2004 06:24 AM

Quote:

Originally Posted by Windcatcher
I don't know...we should probably talk about it. That's the way it's done in WLD, but I'm not sure it's the best way. Is it better to tie alpha to polygons or textures? When rendering, alpha is done at the poly level.

I personally would prefer have it as a texture issue. It'd greatly simplify things from a rendering perspective... I'd assume that it'd simplify texture creation as well.

Windcatcher 10-03-2004 06:29 AM

Well...there's more than one kind of alpha we're dealing with. There's alpha in the texture data, for instance tree leaves have the transparent bits with alpha = 0, and there's also overall polygon alpha (for semitransparency). It's possible to have masked textures with transparent bits that also use polygon alpha. A good example is a texture that represents glass -- most of the texture has the alpha at 0, but those parts that don't should be semitransparent. It can be done either in the texture or in the polygon, but not supporting both means needing a separate texture for every different overall alpha level you want to use in a zone.

daeken_bb 10-03-2004 06:30 AM

Quote:

Originally Posted by Windcatcher
Well...there's more than one kind of alpha we're dealing with. There's alpha in the texture data, for instance tree leaves have the transparent bits with alpha = 0, and there's also overall polygon alpha (for semitransparency). It's possible to have masked textures with transparent bits that also use polygon alpha. A good example is a texture that represents glass -- most of the texture has the alpha at 0, but those parts that don't should be semitransparent. It can be done either in the texture or in the polygon, but not supporting both means needing a separate texture for every different overall alpha level you want to use in a zone.

Hm, ok.

Can we put that off until the second revision of the file format? :)

jbb 10-03-2004 06:36 AM

You're going to want alpha in the textures, at least allowing 0% and 100% transparency so you can texture things like leaves on trees that have gaps between them.

Using values inbetween is of course harder as it required you to depth sort the polygons before drawing them to work right.

On the Vertex format - you might want to have location, normal, texture coordinates in that order rather that the one you have now. I know you're using opengl but if it doesn't matter for opengl then you might as well well make it as easy to use for all possible platforms.

As for the main file format, it would seem easier to me to load an index to all the file fragments rather than have to skip through the file looking for what you wanted. That's really what I mentioned zip for, was the index at the end of the file

EDIT: I meant to say the DirectX is slightly easier if the vertex compoents are in that order so why make it harder if it doesn't matter to opengl

Windcatcher 10-03-2004 07:42 AM

One thing I'd like to point out is how the vertex group and polygon group structures all start with two ulongs, group ID and count. Tnis is a good thing because as I implement this I can implement them as one generic container class and use the same code for both (where the constructor takes an extra argument specifying the size in bytes of the individual records they contain).

Windcatcher 10-03-2004 08:29 AM

Should we always insist that the first node in the tree is an octp node (that is, it's divided at least once), or should we allow the initial node to be an octe node if the zone is (very) small? For that matter, is it really necessary to have two types, or can we just have one type and know if it's the end node by the number of children (either 8 or 1)?

daeken_bb 10-03-2004 08:36 AM

Quote:

Originally Posted by Windcatcher
Should we always insist that the first node in the tree is an octp node (that is, it's divided at least once), or should we allow the initial node to be an octe node if the zone is (very) small? For that matter, is it really necessary to have two types, or can we just have one type and know if it's the end node by the number of children (either 8 or 1)?

Well, not every file will have an octree at all. Only zones will have the octree, so I think that requiring an octp is a bad idea. I think we should have to have an octp in a wld-, that way we can combine a world, objects, and other things in a single file.

Windcatcher 10-03-2004 08:40 AM

Sorry, that's what I meant. I'm looking at integratnig this with OpenZone, after all. In a wld-, should we demand that the first node of the octree is an octp or can we allow it to be an octe? It relates to the logic when exporting the zone, whether or not to divide it based on the zone size. For instance, right now I do BSP division only if an extent is larger than some threshold. It seems to me that it would be a lot cleaner to just have octp nodes, since the renderer has to process them all anyway...but I'm more familiar with BSP trees so it's hard for me to say.

daeken_bb 10-03-2004 08:51 AM

Quote:

Originally Posted by Windcatcher
Sorry, that's what I meant. I'm looking at integratnig this with OpenZone, after all. In a wld-, should we demand that the first node of the octree is an octp or can we allow it to be an octe? It relates to the logic when exporting the zone, whether or not to divide it based on the zone size. For instance, right now I do BSP division only if an extent is larger than some threshold. It seems to me that it would be a lot cleaner to just have octp nodes, since the renderer has to process them all anyway...but I'm more familiar with BSP trees so it's hard for me to say.

Hmm... I think an octr node wouldn't be such a bad idea. Then we just look at the _types_ of the children, not the number. This also allows us to have less than 8 children in an octree node, that way we don't have any empties.

So it's just the Octree header and then either 1 poly node or 2-8 other octr nodes. Simple enough.

Windcatcher 10-03-2004 08:54 AM

Okay, that's how I'll code it then.


All times are GMT -4. The time now is 11:55 PM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.