From: Akiko Date: Sun, 7 Jun 2015 13:48:33 +0000 (+0200) Subject: - another round of correct include names X-Git-Url: http://community.linux-addicted.net/gitweb/?p=genesis3d.git;a=commitdiff_plain;h=036e28a21fc90d17fee3e9cf83ed99770f16ac69 - another round of correct include names --- diff --git a/G3D/PtrTypes.h b/G3D/PtrTypes.h new file mode 100644 index 0000000..bbf79c8 --- /dev/null +++ b/G3D/PtrTypes.h @@ -0,0 +1,67 @@ +/****************************************************************************************/ +/* PtrTypes.c */ +/* */ +/* Description: File to resolve interdependency problems */ +/* */ +/* The contents of this file are subject to the Genesis3D Public License */ +/* Version 1.01 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://www.genesis3d.com */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ +/* the License for the specific language governing rights and limitations */ +/* under the License. */ +/* */ +/* The Original Code is Genesis3D, released March 25, 1999. */ +/* Genesis3D Version 1.1 released November 15, 1999 */ +/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */ +/* */ +/****************************************************************************************/ + +#ifndef GE_PTRTYPES_H +#define GE_PTRTYPES_H + +#include "BaseType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// System.h +typedef struct geEngine geEngine; + +// Light.h +typedef struct Light_LightInfo Light_LightInfo; + +// Surface.h +typedef struct Surf_SurfInfo Surf_SurfInfo; +typedef struct Surf_TexVert Surf_TexVert; + +// World.h +typedef struct geWorld geWorld; + +// Frustum.h +typedef struct Frustum_Info Frustum_Info; + +// World.h +typedef struct World_BSP World_BSP; +typedef struct geWorld_Leaf geWorld_Leaf; + + +// Mesh.h +typedef struct Mesh_MeshInfo Mesh_MeshInfo; +typedef struct Mesh_MeshDef Mesh_MeshDef; +typedef struct Mesh_RenderQ Mesh_RenderQ; + +// Entities.h +typedef struct geEntity_EntitySet geEntity_EntitySet; + +// User.h +typedef struct User_Info User_Info; +typedef struct gePoly gePoly; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/Actor.h b/include/Actor.h index 82cf213..e840384 100644 --- a/include/Actor.h +++ b/include/Actor.h @@ -83,10 +83,10 @@ #ifndef GE_ACTOR_H #define GE_ACTOR_H -#include "genesis.h" -#include "basetype.h" -#include "extbox.h" -#include "bitmap.h" +#include "Genesis.h" +#include "BaseType.h" +#include "ExtBox.h" +#include "Bitmap.h" #include "Motion.h" diff --git a/include/Bitmap.h b/include/Bitmap.h new file mode 100644 index 0000000..9b3d341 --- /dev/null +++ b/include/Bitmap.h @@ -0,0 +1,627 @@ +#ifndef BITMAP_H +#define BITMAP_H + +/****************************************************************************************/ +/* Bitmap.h */ +/* */ +/* Author: Charles Bloom */ +/* Description: Abstract Bitmap system */ +/* */ +/* The contents of this file are subject to the Genesis3D Public License */ +/* Version 1.01 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://www.genesis3d.com */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ +/* the License for the specific language governing rights and limitations */ +/* under the License. */ +/* */ +/* The Original Code is Genesis3D, released March 25, 1999. */ +/* Genesis3D Version 1.1 released November 15, 1999 */ +/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */ +/* */ +/****************************************************************************************/ + +#include "BaseType.h" +#include "PixelFormat.h" +#include "VFile.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***********************************************************************************/ + +typedef struct geBitmap geBitmap; +typedef struct geBitmap_Palette geBitmap_Palette; + +typedef struct geBitmap_Info +{ + int Width; + int Height; + int Stride; // stride is in *pixels* ; it is the step to the next line : Stride >= Width + gePixelFormat Format; + int MinimumMip; //*including* minimumMip == 0 often + int MaximumMip; //*including* maximumMip == nummips-1 + geBoolean HasColorKey; + uint32 ColorKey; // meaningless unless HasColorKey ; the ColorKey is a Pixel in Format + geBitmap_Palette * Palette; +} geBitmap_Info; + +/***********************************************************************************/ +// Bitmap methods + +// see a big comment at the end of this file + +/************************************************************************/ + +GENESISAPI geBitmap * GENESISCC geBitmap_Create(int Width, int Height, int MipCount, gePixelFormat Format ); +GENESISAPI void GENESISCC geBitmap_CreateRef(geBitmap *Bmp); + +GENESISAPI geBitmap * GENESISCC geBitmap_CreateFromInfo(const geBitmap_Info * pInfo); + +GENESISAPI geBitmap * GENESISCC geBitmap_CreateFromFile( geVFile *F ); +GENESISAPI geBitmap * GENESISCC geBitmap_CreateFromFileName(const geVFile *BaseFS,const char *Name); +GENESISAPI geBoolean GENESISCC geBitmap_WriteToFile( const geBitmap *Bmp, geVFile *F ); +GENESISAPI geBoolean GENESISCC geBitmap_WriteToFileName(const geBitmap * Bmp,const geVFile *BaseFS,const char *Name); + // BaseFS is not really const if it is a virtual file; + // it *is* const if it is a dos directory + +GENESISAPI geBoolean GENESISCC geBitmap_Destroy(geBitmap **Bmp); + // returns whether Bmp was actually destroyed : not success/failure + +GENESISAPI geBoolean GENESISCC geBitmap_GetInfo(const geBitmap *Bmp, geBitmap_Info *Info, geBitmap_Info *SecondaryInfo); + //LockForWrite returns data in Info's format + +GENESISAPI geBoolean GENESISCC geBitmap_Blit(const geBitmap *Src, int SrcPositionX, int SrcPositionY, + geBitmap *Dst, int DstPositionX, int DstPositionY, + int SizeX, int SizeY ); + +GENESISAPI geBoolean GENESISCC geBitmap_BlitMip(const geBitmap * Src, int SrcMip, geBitmap * Dst, int DstMip ); + // don't use this with Src == Dst, use UpdateMips instead ! + +GENESISAPI geBoolean GENESISCC geBitmap_BlitBitmap(const geBitmap * Src, geBitmap * Dst); + +GENESISAPI geBoolean GENESISCC geBitmap_BlitBestMip(const geBitmap * Src, geBitmap * Dst); + // blits the largest mip from Src that fits in Dst + +GENESISAPI geBoolean GENESISCC geBitmap_LockForRead( // a non-exclusive lock + const geBitmap * Bmp, + geBitmap ** Target, + int MinimumMip, + int MaximumMip, + gePixelFormat Format, + geBoolean RespectColorKey, + uint32 ColorKey); + // not really const, stores lock-count, but *data* is const + // will do a format conversion! + +GENESISAPI geBoolean GENESISCC geBitmap_LockForReadNative( + const geBitmap * Bmp, + geBitmap ** Target, + int MinimumMip, + int MaximumMip); + // lock for read in a format that gaurantee no conversions + // then do GetInfo on the locks to see what you have! + +GENESISAPI geBoolean GENESISCC geBitmap_LockForWrite( // an exclusive lock + geBitmap * Bmp, + geBitmap ** Target, + int MinimumMip, + int MaximumMip); + +GENESISAPI geBoolean GENESISCC geBitmap_LockForWriteFormat( + geBitmap * Bmp, + geBitmap ** Target, + int MinimumMip, + int MaximumMip, + gePixelFormat Format); + // Format must be one of the two returned in GetInfo !! + +GENESISAPI geBoolean GENESISCC geBitmap_UnLock(geBitmap *Bmp); // must be done on All locked mips +GENESISAPI geBoolean GENESISCC geBitmap_UnLockArray(geBitmap **Locks,int Size); + +GENESISAPI geBoolean GENESISCC geBitmap_SetFormat(geBitmap *Bmp, + gePixelFormat NewFormat, + geBoolean RespectColorKey, uint32 ColorKey, + const geBitmap_Palette * Palette); + // _SetFormat may cause you to lose color information! + // SetFormat does a conversion! + // if NewFormat is palettized and Palette is NULL, we create a palette for the bitmap! + +GENESISAPI geBoolean GENESISCC geBitmap_SetFormatMin(geBitmap *Bmp,gePixelFormat NewFormat); + // the Min version keeps colorkey & palette from the old format + +GENESISAPI geBoolean GENESISCC geBitmap_SetColorKey(geBitmap *Bmp, geBoolean HasColorKey, uint32 ColorKey, geBoolean Smart); + // SetColorKey discards old colorkey information! + // does not do a conversion (changes the colorkey in the current data + // if 'Smart' is on, we don't set HasColorKey to true unless it is actually used! + +GENESISAPI geBoolean GENESISCC geBitmap_GetAverageColor(const geBitmap *Bmp,int *pR,int *pG,int *pB); + // tells you the average color; computes it and caches it out + +GENESISAPI geBitmap_Palette * GENESISCC geBitmap_GetPalette(const geBitmap *Bmp); +GENESISAPI geBoolean GENESISCC geBitmap_SetPalette(geBitmap *Bmp, const geBitmap_Palette *Palette); + // _SetPal tries to _CreateRef your Palette, so no copy occurs & palettes may be shared + // you may _Destroy() palette after using it to set (though its bits may not be freed) + // (hence Palette is *not* const) + // Warning : SetPalette on any mip changes the palette of ALL mips ! + // see Palette note at _UnLock + // _SetPal destroys the bitmap's original palette and refs the new one, + // so if you setpal with the bitmap's palette, there is no net change in ref counts (good!) + +GENESISAPI geBoolean GENESISCC geBitmap_HasAlpha(const geBitmap * Bmp); + // returns true if bitmap has *any* type of alpha + +GENESISAPI geBitmap * GENESISCC geBitmap_GetAlpha(const geBitmap *Bmp); +GENESISAPI geBoolean GENESISCC geBitmap_SetAlpha(geBitmap *Bmp, const geBitmap *AlphaBmp); + // we Ref the AlphaBmp, so you may destroy it after calling Set() + // it may be NULL + // there's only one Alpha per bitmap (for the top Mip) right now + +GENESISAPI geBoolean GENESISCC geBitmap_SetGammaCorrection(geBitmap *Bmp,geFloat Gamma,geBoolean Apply); + // this Gamma does not change the *original* (system/secondary) bits + // it only affects the appearance when drawn + // note : if you write to the gamma corrected bits, you must gamma correct manually if you + // wish to fit in smoothly with the previous data + // warning : if you use this function with many different gammas, performance will suffer! + // use one global gamma for all bitmaps! try to let the engine manage gamma for you, + // via geEngine_SetGamma ! + +GENESISAPI geBoolean GENESISCC geBitmap_SetPreferredFormat(geBitmap *Bmp,gePixelFormat Format); +GENESISAPI gePixelFormat GENESISCC geBitmap_GetPreferredFormat(const geBitmap *Bmp); + +GENESISAPI void * GENESISCC geBitmap_GetBits(geBitmap *Bmp); // works only on a Lock() + +GENESISAPI geBoolean GENESISCC geBitmap_RefreshMips(geBitmap *Bmp); // rebuilds mips; *tries* to be smart & not overwrite manually-fixed mips + // RefreshMips does *not* build mips that don't exist +GENESISAPI geBoolean GENESISCC geBitmap_UpdateMips(geBitmap *Bmp,int SourceMip,int TargetMip); + // will create the target if it doesn't exist; + // will overwrite manually-fixed mips! +GENESISAPI geBoolean GENESISCC geBitmap_SetMipCount(geBitmap *Bmp,int Count); + // creates or destroys to match the new count + +GENESISAPI geBoolean GENESISCC geBitmap_ClearMips(geBitmap *Bmp); // Destroy all mips (except the first) ! + // use with care! this is not polite! + +// Shortcuts +GENESISAPI int GENESISCC geBitmap_Width(const geBitmap *Bitmap); +GENESISAPI int GENESISCC geBitmap_Height(const geBitmap *Bitmap); +GENESISAPI uint32 GENESISCC geBitmap_MipBytes(const geBitmap * Bitmap,int mip); + +/** +* +* if Bitmap is a lock for read, functions that modify it return failure +* if Bitmap is a lock for write, functions that modify it attempt to +* modify the owner of the lock +* +* warning : if you lock multiple mips for write, and then modify one of the mips +* (such as via SetPalette) it may affect the owner and all sibling mips! +* doing different SetPalettes with different palettes on different locked mips +* has undefined behavior! +* +**/ + +#ifdef _DEBUG + +GENESISAPI uint32 GENESISCC geBitmap_Debug_GetCount(void); + +GENESISAPI uint32 GENESISCC geBitmap_Debug_GetRefs(void); + // assert this is zero before you shutdown ! + +#endif + +/***********************************************************************************/ + +typedef enum +{ + GE_BITMAP_STREAMING_ERROR=0, + GE_BITMAP_STREAMING_NOT, + GE_BITMAP_STREAMING_STARTED, + GE_BITMAP_STREAMING_IDLE, + GE_BITMAP_STREAMING_CHANGED, + GE_BITMAP_STREAMING_DATADONE, + GE_BITMAP_STREAMING_DONE, +} geBitmap_StreamingStatus; + +GENESISAPI geBitmap_StreamingStatus GENESISCC geBitmap_GetStreamingStatus(const geBitmap *Bmp); + + /** on a file which is streaming, the sequence of returns looks like : + + GE_BITMAP_STREAMING_IDLE + GE_BITMAP_STREAMING_CHANGED + GE_BITMAP_STREAMING_IDLE + GE_BITMAP_STREAMING_IDLE + GE_BITMAP_STREAMING_CHANGED + ... + GE_BITMAP_STREAMING_DONE + GE_BITMAP_STREAMING_NOT + GE_BITMAP_STREAMING_NOT + GE_BITMAP_STREAMING_NOT + ... + + Status >= GE_BITMAP_STREAMING_STARTED means streaming has started & is in progress + + the user should never see _STARTED or _DATADONE + + ***/ + +/***********************************************************************************/ + +// palette methods : + +GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_Create(gePixelFormat Format,int Size); + +GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_CreateCopy(const geBitmap_Palette *Palette); + +GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_CreateFromFile(geVFile *F); + +GENESISAPI geBitmap_Palette * GENESISCC geBitmap_Palette_CreateFromBitmap(geBitmap * Bmp,geBoolean Slow); + // does GetPalette, and if NULL, then + // it create an optimal palette for a + // non-palettized bitmap + // (this is a create, you must destroy later!) + // put Slow == TRUE for higher quality & slower + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_SortColors(geBitmap_Palette * P,geBoolean Slower); + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_CreateRef(geBitmap_Palette *Palette); + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_Destroy(geBitmap_Palette ** ppPalette); + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_WriteToFile(const geBitmap_Palette *Palette,geVFile *F); + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetFormat(geBitmap_Palette * Palette,gePixelFormat Format); + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_Copy(const geBitmap_Palette * Src,geBitmap_Palette * Target); + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetInfo(const geBitmap_Palette *P,geBitmap_Info *Into); + // get the info as if it were a bitmap; Into->Height == 1 + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_Lock(geBitmap_Palette *Palette, void **pBits, gePixelFormat *pFormat,int *pSize); + // pFormat & pSize are optional + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_UnLock(geBitmap_Palette *Palette); + // palette unlock does NOT notify the bitmap that the palette has changed. + // call Bitmap_SetPalette() with the same palette pointer + // to tell the bitmap that it must to some processing + // (don't worry, it won't duplicate it or copy it onto itself) + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetData(const geBitmap_Palette *P, void *Into,gePixelFormat Format,int Colors); +GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetData( geBitmap_Palette *P,const void *From,gePixelFormat Format,int Colors); + // does Lock/UnLock for you + // From and Into are arrays of Colors*gePixelFormat_BytesPerPel bytes + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetEntryColor( geBitmap_Palette *P,int Color,int R,int G,int B,int A); +GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetEntryColor(const geBitmap_Palette *P,int Color,int *R,int *G,int *B,int *A); + // Set/Get does Lock/Unlock for you ; these are slow! do not use these to work on all the colors! + +GENESISAPI geBoolean GENESISCC geBitmap_Palette_SetEntry( geBitmap_Palette *P,int Color,uint32 Pixel); +GENESISAPI geBoolean GENESISCC geBitmap_Palette_GetEntry(const geBitmap_Palette *P,int Color,uint32 *Pixel); + +/***********************************************************************************/ + +/************************************************************************ + +A brief tutorial on the Bitmap system, by Charles Bloom, cbloom@wildtangent.com + +The Bitmap is a smart wrapper for complex functionality. You give it hints to +the opaque Bitmap object, and it tries its best to follow those hints, but it +may not always do so. The Bitmap is the owner of its bits; you must Lock the +bitmap to get permission to touch those bits, and UnLock to tell the bitmap +you are done. The format may change between two Locks. Bitmaps can also be +multiply owned, so you should account for the fact that others may touch your +bitmap between your uses. + +The Bitmap contains one or two pixel-sets representing an image. The "primary" is +a fast-blitting version of the image, and the "secondary" is a storage version +(eventually wavelet compressed) which can be used to rebuild the primary if it is +freed or damaged. Both cary a generalized format. + +Let's do an example. I want to load a bitmap, set it up for drawing with the +genesis Engine, and then blit some interactive stuff into it. + +************************************************************************/ + +#if 0 +// { +//----------------------------------------------------------------------------- + +void Init(geEngine * Engine); +void Shutdown(void); +void Draw(void); +void DrawPolite(void); + +static geBitmap * myBM = NULL; +static geEngine * myEngine = NULL; + +void Init(geEngine * Engine) +{ +geBoolean success; +geBitmap_Info Info; + + myEngine = Engine; // this is not looked well upon; for ease of demonstration only! + assert(Engine); + + myBM = geBitmap_CreateFromFileName(NULL,"mybitmap.bmp"); + + // CreateFromFile can load windows BMP files, or custom GeBm files. + + assert(myBM); + + // get the main info; I don't care about the secondary, so leave it NULL + + success = geBitmap_GetInfo(myBM,&Info,NULL); + assert(success); + + // make sure I loaded a bitmap in the format I understand ! + + if ( Info.Format == GE_PIXELFORMAT_8BIT_PAL ) + { + // I want palette index 255 to act as transparency, so I must use SetColorKey + + success = geBitmap_SetColorKey(myBM,GE_TRUE,255); + assert(success); + + // just for fun, let's modify the palette: + if (1) + { + geBitmap_Palette * Pal; + + // get the palette ; I don't care if its primary or secondary, so + /// I don't use the Info.Palette field + + Pal = geBitmap_GetPalette(myBM); + assert(Pal); + + // I'm only fiddling one entry, so don't bother with a full Lock() UnLock() + // sequence on the palette + + // make palette index zero bright red; we use alpha = 255 for opaque + + success = geBitmap_Palette_SetEntryColor(Pal,0,255,0,0,255); + assert(success); + + // tell the bitmap system you've changed the palette; this function + // is smart enough to not do unecessary copies or whatever. + + success = geBitmap_SetPalette(myBM,Pal); + assert(success); + } + + } + else + { + // otherwise, treat black as transparent, in whatever format I have + + success = geBitmap_SetColorKey(myBM,GE_TRUE,gePixelFormat_ComposePixel(Info.Format,0,0,0,0)); + assert(success); + } + + // note that I did NOT use SetFormat. SetFormat may do a conversion, and since the original + // bitmap was created without colorkey, it would have been converted to a new format but + // kept its property of having no colorkey! + // (SetFormat will fiddle the bits and whatever way necessary to keep bitmaps as visually similar + // as possible) + + // I want to fiddle the fast format in 565 later, so cue the bitmap to try to give me that format. + + success = geBitmap_SetPreferredFormat(myBM,GE_PIXELFORMAT_16BIT_565_RGB); + assert(success); + + // Add it to the engine so it can be used for drawing. + + success = geEngine_AddBitmap(myEngine,myBM); + assert(success); +} + +void Shutdown(void) +{ +geBoolean WasDestroyed; + + assert(myBM); + + // clean up + + geEngine_RemoveBitmap(myEngine,myBM); + + WasDestroyed = geBitmap_Destroy(&myBM); + + // someone else might have done _CreateRef on our bitmap, + // so we can't be sure it's actually destroyed. + // this code is still ready to be run again with a new call to Init() + + //assert(WasDestroyed); + + myBM = NULL; + myEngine = NULL; +} + +void Draw(void) +{ +geBitmap * Lock; +geBoolean success; +geBitmap_Info Info; +uint16 *bits,*bptr; +int x,y; + + // lets fiddle the bits. + // we need to lock the bitmap for write. + // LockForWrite is an exclusive lock, unlike LockForRead which is non-blocking + // request our favorite format, and only lock Mip 0 (the full size bitmap) + + success = geBitmap_LockForWriteFormat(myBM,&Lock,0,0,GE_PIXELFORMAT_16BIT_565_RGB); + if ( ! success ) + { + // well, we tried to be nice; if we were very polite, we would do a LockForWrite + // here, and try to fiddle the bits in whatever format we got; However, we aren't + // that polite, so we just do a _SetFormat + // + // note that we are destroying the original bitmap by changing its format + // we should only do this if we are going to draw into the bitmap + + success = geBitmap_SetFormat(myBM,GE_PIXELFORMAT_16BIT_565_RGB,GE_TRUE,0,NULL); + assert(success); + + // now we should be able to get the bits we want, *but* they may not be the + // primary (fast) format; oh well, it's the best we can do... + // (if you must have the fastest bits, then use only _LockForWrite, never LockForWriteFormat, + // which might have to do a conversion) + + success = geBitmap_LockForWriteFormat(myBM,&Lock,0,0,GE_PIXELFORMAT_16BIT_565_RGB); + assert(success); + } + + // now Lock is our bitmap in 565 + // we do a GetInfo because the Lock's info could be different than + // the original bitmap's (particularly the Palette & the Stride) + + success = geBitmap_GetInfo(Lock,&Info,NULL); + assert(success); + + // you can only call _GetBits on a locked bitmap + + bits = geBitmap_GetBits(Lock); + assert( bits ); + + bptr = bits; + for(y=0; y < Info.Height; y++) + { + for(x=0; x < Info.Width; x++) + { + uint16 R,G,B; + // make a silly 565 gradient + R = x & 0x1F; + G = x & 0x3F; + B = y & 0x1F; + + *bptr++ = (R<<11) + (G<<5) + B; + } + + // note that bptr is a word pointer, and Stride is in pixels : + + bptr += Info.Stride - Info.Width; + } + bits = bptr = NULL; + + // you call Unlock on all the mips you locked - not on the original bitmap! + + success = geBitmap_UnLock(Lock); + assert(success); + + // now, we only fiddled the full-size Mip, and there might be more, + // so lets percolate the changes into the smaller mips: + + success = geBitmap_RefreshMips(myBM); + assert(success); + + // a null rect means use the whole bitmap; + // Engine_DrawBitmap blits a 2d decal to the framebuffer (fast) + + success = geEngine_DrawBitmap(myEngine,myBM,NULL,0,0); + assert(success); + +} + +void DrawPolite(void) +{ +geBitmap * Lock; +geBoolean success; +geBitmap_Info Info; +void *bits; +int x,y; + + // this function does the same thing as Draw() , but is more polite + // lock in the fastest format (whatever it is) + // because we did SetPreferred, this should be 565_RGB, but might not be + + success = geBitmap_LockForWrite(myBM,&Lock,0,0); + assert(success); + + success = geBitmap_GetInfo(Lock,&Info,NULL); + assert(success); + + bits = geBitmap_GetBits(Lock); + assert( bits ); + + if ( Info.Format == GE_PIXELFORMAT_16BIT_565_RGB ) + { + uint16 *wptr; + + // our favorite format + + wptr = bits; + for(y=0; y < Info.Height; y++) + { + for(x=0; x < Info.Width; x++) + { + uint16 R,G,B; + // make a silly 565 gradient + R = x & 0x1F; + G = x & 0x3F; + B = y & 0x1F; + + *wptr++ = (R<<11) + (G<<5) + B; + } + wptr += Info.Stride - Info.Width; + } + } + else + { + uint8 * bptr; + + // oh well, do our best + // bitmaps must have had a good reason to not give us the format we preferred, + + bptr = bits; + for(y=0; y < Info.Height; y++) + { + for(x=0; x < Info.Width; x++) + { + uint32 R,G,B; + + // put a color in any format + + R = (x & 0x1F)<<3; + G = (x & 0x3F)<<2; + B = (y & 0x1F)<<3; + + // we use alpha of 255 for opaque + + gePixelFormat_PutColor(Info.Format,&bptr,R,G,B,255); + } + + bptr += (Info.Stride - Info.Width) * gePixelFormat_BytesPerPel(Info.Format); + } + } + bits = NULL; + + // same as before: + + success = geBitmap_UnLock(Lock); + assert(success); + + success = geBitmap_RefreshMips(myBM); + assert(success); + + success = geEngine_DrawBitmap(myEngine,myBM,NULL,0,0); + assert(success); + +} + +// end tutorial on the Bitmap system +//----------------------------------------------------------------------------- +// } + +/***********************************************************************************/ + +#endif +#ifdef __cplusplus +} +#endif + + +#endif + + diff --git a/include/Body.h b/include/Body.h new file mode 100644 index 0000000..dbe36b2 --- /dev/null +++ b/include/Body.h @@ -0,0 +1,136 @@ +/****************************************************************************************/ +/* BODY.H */ +/* */ +/* Author: Mike Sandige */ +/* Description: Actor body interface. */ +/* */ +/* The contents of this file are subject to the Genesis3D Public License */ +/* Version 1.01 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://www.genesis3d.com */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ +/* the License for the specific language governing rights and limitations */ +/* under the License. */ +/* */ +/* The Original Code is Genesis3D, released March 25, 1999. */ +/* Genesis3D Version 1.1 released November 15, 1999 */ +/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */ +/* */ +/****************************************************************************************/ +#ifndef GE_BODY_H +#define GE_BODY_H + +/* This object is for managing the data associated with a skeletal-based mesh, + a 'body'. + This object holds the geometry for the body and the list of materials needed. +*/ + +#include "BaseType.h" +#include "XForm3d.h" +#include "VFile.h" +#include "Bitmap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GE_BODY_NUMBER_OF_LOD (4) // 0 is highest detail +#define GE_BODY_NO_PARENT_BONE (-1) +#define GE_BODY_HIGHEST_LOD (0) + +#define GE_BODY_ROOT (-1) // for specifying 'root' bounding box. + +typedef struct geBody geBody; + + + +geBody *GENESISCC geBody_Create(void); + +void GENESISCC geBody_Destroy(geBody **B); + +geBoolean GENESISCC geBody_IsValid(const geBody *B); + + +geBoolean GENESISCC geBody_GetGeometryStats(const geBody *B, int lod, int *Vertices, int *Faces, int *Normals); + +geBoolean GENESISCC geBody_AddFace( geBody *B, + const geVec3d *Vertex1, const geVec3d *Normal1, + geFloat U1, geFloat V1, int BoneIndex1, + const geVec3d *Vertex2, const geVec3d *Normal2, + geFloat U2, geFloat V2, int BoneIndex2, + const geVec3d *Vertex3, const geVec3d *Normal3, + geFloat U3, geFloat V3, int BoneIndex3, + int MaterialIndex); + + // Bitmap is added to body. It's reference count is increased. Caller still owns a pointer + // to the bitmap, and is responsible for destroying it. +geBoolean GENESISCC geBody_AddMaterial( geBody *B, + const char *MaterialName, + geBitmap *Bitmap, + geFloat Red, + geFloat Green, + geFloat Blue, + int *MaterialIndex); + + // returned bitmap is a pointer to the bitmap in the body's list. It may not be destroyed. + // if caller would like to 'own' a copy of that bitmap pointer, it should call geBitmap_CreateRef() +geBoolean GENESISCC geBody_GetMaterial(const geBody *Body, int MaterialIndex, + const char **MaterialName, + geBitmap **Bitmap, geFloat *Red, geFloat *Green, geFloat *Blue); + + // Bitmap is set into the body. It's reference count is increased. Caller still owns a pointer + // to the bitmap, and is responsible for destroying it. +geBoolean GENESISCC geBody_SetMaterial(geBody *Body, int MaterialIndex, + geBitmap *Bitmap, geFloat Red, geFloat Green, geFloat Blue); + +int GENESISCC geBody_GetMaterialCount(const geBody *B); + +geBoolean GENESISCC geBody_AddBone( geBody *B, + int ParentBoneIndex, + const char *BoneName, + const geXForm3d *AttachmentMatrix, + int *BoneIndex); + +geBoolean GENESISCC geBody_ComputeLevelsOfDetail( geBody *B ,int Levels); + +int GENESISCC geBody_GetBoneCount(const geBody *B); + +void GENESISCC geBody_GetBone( const geBody *B, + int BoneIndex, + const char **BoneName, + geXForm3d *Attachment, + int *ParentBoneIndex); + +int32 GENESISCC geBody_GetBoneNameChecksum(const geBody *B); + +void GENESISCC geBody_SetBoundingBox( geBody *B, + int BoneIndex, // GE_BODY_ROOT for specifing 'root' bounding box. + const geVec3d *MinimumBoxCorner, + const geVec3d *MaximumBoxCorner); + + +geBoolean GENESISCC geBody_GetBoundingBox( const geBody *B, + int BoneIndex, // GE_BODY_ROOT for specifing 'root' bounding box. + geVec3d *MinimumBoxCorner, + geVec3d *MaximumBoxCorner); + +geBoolean GENESISCC geBody_GetBoneByName(const geBody* B, + const char* BoneName, + int* pBoneIndex, + geXForm3d* Attachment, + int* pParentBoneIndex); + +geBoolean GENESISCC geBody_WriteToFile(const geBody *B, geVFile *pFile); +geBody *GENESISCC geBody_CreateFromFile(geVFile *pFile); + + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/Genesis.h b/include/Genesis.h index da645a9..1aa48ad 100644 --- a/include/Genesis.h +++ b/include/Genesis.h @@ -26,7 +26,7 @@ #include "XForm3d.h" #include "GETypes.h" #include "ExtBox.h" -#include "vfile.h" +#include "VFile.h" #include "Bitmap.h" #ifdef __cplusplus diff --git a/include/Motion.h b/include/Motion.h new file mode 100644 index 0000000..980184b --- /dev/null +++ b/include/Motion.h @@ -0,0 +1,180 @@ +/****************************************************************************************/ +/* MOTION.H */ +/* */ +/* Author: Mike Sandige */ +/* Description: Motion interface. */ +/* */ +/* The contents of this file are subject to the Genesis3D Public License */ +/* Version 1.01 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://www.genesis3d.com */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ +/* the License for the specific language governing rights and limitations */ +/* under the License. */ +/* */ +/* The Original Code is Genesis3D, released March 25, 1999. */ +/* Genesis3D Version 1.1 released November 15, 1999 */ +/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */ +/* */ +/****************************************************************************************/ +#ifndef GE_MOTION_H +#define GE_MOTION_H + +/* motion + + This object is a list of named Path objects + +*/ + +#include +#include "BaseType.h" +#include "Path.h" +#include "VFile.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// GENESIS_PUBLIC_APIS +typedef struct geMotion geMotion; + +GENESISAPI geMotion *GENESISCC geMotion_Create(geBoolean ManageNames); + +GENESISAPI void GENESISCC geMotion_Destroy(geMotion **PM); + +// GENESIS_PRIVATE_APIS + +GENESISAPI geBoolean GENESISCC geMotion_IsValid(const geMotion *M); + + // AddPath adds a reference of P to the motion M. Ownership is shared - The caller must destroy P. +GENESISAPI geBoolean GENESISCC geMotion_AddPath(geMotion *M, gePath *P,const char *Name,int *Index); + +GENESISAPI geBoolean GENESISCC geMotion_HasNames(const geMotion *M); +GENESISAPI int32 GENESISCC geMotion_GetNameChecksum(const geMotion *M); + +GENESISAPI geBoolean GENESISCC geMotion_RemoveNames(geMotion *M); + +GENESISAPI void GENESISCC geMotion_SampleChannels(const geMotion *M, int PathIndex, geFloat Time, geQuaternion *Rotation, geVec3d *Translation); +GENESISAPI geBoolean GENESISCC geMotion_SampleChannelsNamed(const geMotion *M, const char *PathName, geFloat Time, geQuaternion *Rotation, geVec3d *Translation); + +GENESISAPI void GENESISCC geMotion_Sample(const geMotion *M, int PathIndex, geFloat Time, geXForm3d *Transform); +GENESISAPI geBoolean GENESISCC geMotion_SampleNamed(const geMotion *M, const char *PathName, geFloat Time, geXForm3d *Transform); + + // the returned Paths from _Get functions should not be destroyed. + // if ownership is desired, call gePath_CreateRef() to create another owner. + // an 'owner' has access to the object regardless of the number of other owners, and + // an owner must call the object's destroy method to relinquish ownership +GENESISAPI gePath *GENESISCC geMotion_GetPathNamed(const geMotion *M,const char *Name); +GENESISAPI const char *GENESISCC geMotion_GetNameOfPath(const geMotion *M, int Index); + +// GENESIS_PUBLIC_APIS +GENESISAPI gePath *GENESISCC geMotion_GetPath(const geMotion *M,int Index); +GENESISAPI int GENESISCC geMotion_GetPathCount(const geMotion *M); + + +GENESISAPI geBoolean GENESISCC geMotion_SetName(geMotion *M, const char * Name); +GENESISAPI const char *GENESISCC geMotion_GetName(const geMotion *M); + +// GENESIS_PRIVATE_APIS + + // support for compound motions. A motion can either have sub-motions, or be single motion. + // these functions support motions that have sub-motions. +GENESISAPI int GENESISCC geMotion_GetSubMotionCount(const geMotion*M); + + // the returned motions from these _Get functions should not be destroyed. + // if ownership is desired, call geMotion_CreateRef() to create another owner. + // an 'owner' has access to the object regardless of the number of other owners, and + // an owner must call the object's destroy method to relinquish ownership +GENESISAPI geMotion *GENESISCC geMotion_GetSubMotion(const geMotion *M,int Index); +GENESISAPI geMotion *GENESISCC geMotion_GetSubMotionNamed(const geMotion *M,const char *Name); +GENESISAPI geBoolean GENESISCC geMotion_AddSubMotion( + geMotion *ParentMotion, + geFloat TimeScale, // Scale factor for this submotion + geFloat TimeOffset, // Time in parent motion when submotion should start + geMotion *SubMotion, + geFloat StartTime, // Blend start time (relative to submotion) + geFloat StartMagnitude, // Blend start magnitude (0..1) + geFloat EndTime, // Blend ending time (relative to submotion) + geFloat EndMagnitude, // Blend ending magnitude (0..1) + const geXForm3d *Transform, // Base transform to apply to this submotion + int *Index); // returned motion index + +GENESISAPI geMotion *GENESISCC geMotion_RemoveSubMotion(geMotion *ParentMotion, int SubMotionIndex); + +// Get/Set submotion time offset. The time offset is the offset into the +// compound (parent) motion at which the submotion should start. +GENESISAPI geFloat GENESISCC geMotion_GetTimeOffset( const geMotion *M,int SubMotionIndex ); +GENESISAPI geBoolean GENESISCC geMotion_SetTimeOffset( geMotion *M,int SubMotionIndex,geFloat TimeOffset ); + +// Get/Set submotion time scale. Time scaling is applied to the submotion after the TimeOffset +// is applied. The formula is: (CurrentTime - TimeOffset) * TimeScale +GENESISAPI geFloat GENESISCC geMotion_GetTimeScale( const geMotion *M,int SubMotionIndex ); +GENESISAPI geBoolean GENESISCC geMotion_SetTimeScale( geMotion *M,int SubMotionIndex,geFloat TimeScale ); + +// Get blending amount for a particular submotion. The Time parameter is parent-relative. +GENESISAPI geFloat GENESISCC geMotion_GetBlendAmount( const geMotion *M, int SubMotionIndex, geFloat Time); + +// Get/Set blending path. The keyframe times in the blend path are relative to the submotion. +GENESISAPI gePath *GENESISCC geMotion_GetBlendPath( const geMotion *M,int SubMotionIndex ); +GENESISAPI geBoolean GENESISCC geMotion_SetBlendPath( geMotion *M,int SubMotionIndex, gePath *Blend ); + +GENESISAPI const geXForm3d *GENESISCC geMotion_GetBaseTransform( const geMotion *M,int SubMotionIndex ); +GENESISAPI geBoolean GENESISCC geMotion_SetBaseTransform( geMotion *M,int SubMotionIndex, geXForm3d *BaseTransform ); +GENESISAPI geBoolean GENESISCC geMotion_GetTransform(const geMotion *M, geFloat Time, geXForm3d *Transform); +// GENESIS_PUBLIC_APIS + + // gets time of first key and time of last key (as if motion did not loop) + // if there are no paths in the motion: returns GE_FALSE and times are not set + // otherwise returns GE_TRUE + // + // For a compound motion, GetTimeExtents will return the extents of the scaled submotions. + // For a single motion, no scaling is applied. +GENESISAPI geBoolean GENESISCC geMotion_GetTimeExtents(const geMotion *M,geFloat *StartTime,geFloat *EndTime); + +// Only one event is allowed per time key. + +GENESISAPI geBoolean GENESISCC geMotion_InsertEvent(geMotion *M, geFloat tKey, const char* String); + // Inserts the new event and corresponding string. + +GENESISAPI geBoolean GENESISCC geMotion_DeleteEvent(geMotion *M, geFloat tKey); + // Deletes the event + +GENESISAPI void GENESISCC geMotion_SetupEventIterator( + geMotion *M, + geFloat StartTime, // Inclusive search start + geFloat EndTime); // Non-inclusive search stop + // For searching or querying the array for events between two times + // times are compaired [StartTime,EndTime), '[' is inclusive, ')' is + // non-inclusive. This prepares the geMotion_GetNextEvent() function. + +GENESISAPI geBoolean GENESISCC geMotion_GetNextEvent( + geMotion *M, // Event list to iterate + geFloat *pTime, // Return time, if found + const char **ppEventString); // Return data, if found + // Iterates from StartTime to EndTime as setup in geMotion_SetupEventIterator() + // and for each event between these times [StartTime,EndTime) + // this function will return Time and EventString returned for that event + // and the iterator will be positioned for the next search. When there + // are no more events in the range, this function will return GE_FALSE (Time + // will be 0 and ppEventString will be empty). + +GENESISAPI geBoolean GENESISCC geMotion_GetEventExtents(const geMotion *M, + geFloat *FirstEventTime, + geFloat *LastEventTime); + // returns the time associated with the first and last events + // returns GE_FALSE if there are no events (and Times are not set) + + +// GENESIS_PRIVATE_APIS +GENESISAPI geMotion *GENESISCC geMotion_CreateFromFile(geVFile *f); +GENESISAPI geBoolean GENESISCC geMotion_WriteToFile(const geMotion *M, geVFile *f); +GENESISAPI geBoolean GENESISCC geMotion_WriteToBinaryFile(const geMotion *M,geVFile *pFile); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/Path.h b/include/Path.h new file mode 100644 index 0000000..b02a95d --- /dev/null +++ b/include/Path.h @@ -0,0 +1,153 @@ +/****************************************************************************************/ +/* PATH.H */ +/* */ +/* Author: Mike Sandige */ +/* Description: Time-indexed keyframe creation, maintenance, and sampling. */ +/* */ +/* The contents of this file are subject to the Genesis3D Public License */ +/* Version 1.01 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://www.genesis3d.com */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ +/* the License for the specific language governing rights and limitations */ +/* under the License. */ +/* */ +/* The Original Code is Genesis3D, released March 25, 1999. */ +/* Genesis3D Version 1.1 released November 15, 1999 */ +/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */ +/* */ +/****************************************************************************************/ +#ifndef GE_PATH_H +#define GE_PATH_H + +#include "BaseType.h" +#include "XForm3d.h" +#include "Quatern.h" +#include "VFile.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +// GENESIS_PUBLIC_APIS +typedef struct _gePath gePath; + +#define GE_PATH_ROTATION_CHANNEL 1 +#define GE_PATH_TRANSLATION_CHANNEL 2 + +#define GE_PATH_ALL_CHANNELS (GE_PATH_ROTATION_CHANNEL | GE_PATH_TRANSLATION_CHANNEL) + +#ifndef GE_PATH_ENUMS + #define GE_PATH_ENUMS + typedef enum + { + GE_PATH_INTERPOLATE_LINEAR = 0, // linear blend for translation or rotation channel + GE_PATH_INTERPOLATE_HERMITE, // hermite cubic spline for translation channel + GE_PATH_INTERPOLATE_SLERP, // spherical-linear blend for rotation channel + GE_PATH_INTERPOLATE_SQUAD, // higher order blend for rotation channel 'G1' continuity + //GE_PATH_INTEROPLATE_TRIPOD, // not supported yet. + GE_PATH_INTERPOLATE_HERMITE_ZERO_DERIV = 7 // hermite cubic with zero derivative at keyframes ('easing' curve) + }gePath_Interpolator; +#endif + +GENESISAPI void GENESISCC gePath_CreateRef( gePath *P ); + +GENESISAPI gePath *GENESISCC gePath_Create( + gePath_Interpolator TranslationInterpolation, // type of interpolation for translation channel + gePath_Interpolator RotationInterpolation, // type of interpolation for rotation channel + geBoolean Looped); // True if end of path is connected to head + // creates new gePath + // A looping path should have the same first & last point. The path + // generator will choose arbitrarily between these points for a + // sample exactly at the end of the loop. + +GENESISAPI gePath *GENESISCC gePath_CreateCopy( const gePath *P ); + +GENESISAPI void GENESISCC gePath_Destroy(gePath **PP); + // destroys path *PP + +//------------------ time based keyframe operations +GENESISAPI geBoolean GENESISCC gePath_InsertKeyframe( + gePath *P, + int ChannelMask, + geFloat Time, + const geXForm3d *Matrix); + // inserts a keyframe at a specific time. + +GENESISAPI geBoolean GENESISCC gePath_DeleteKeyframe( + gePath *P, + int Index, + int ChannelMask); + // deletes the nth keyframe + +GENESISAPI geBoolean GENESISCC gePath_GetTimeExtents( + const gePath *P, + geFloat *StartTime, + geFloat *EndTime); + // gets the time for the first and last keys in the path (ignoring looping) + // if there are no keys, return GE_FALSE and times are not set. + // returns GE_TRUE if there are keys. + +//----------------- index based keyframe operations +GENESISAPI void GENESISCC gePath_GetKeyframe( + const gePath *P, + int Index, // gets keyframe[index] + int Channel, // for this channel + geFloat *Time, // returns the time of the keyframe + geXForm3d *Matrix); // returns the matrix of the keyframe + // retrieves keyframe[index], and it's time + +GENESISAPI int GENESISCC gePath_GetKeyframeCount(const gePath *P,int Channel); + // retrieves count of keyframes for a specific channel + +GENESISAPI int GENESISCC gePath_GetKeyframeIndex(const gePath *P, int Channel, geFloat Time); + // retrieves the index of the keyframe at a specific time for a specific channel + +//----------------- sampling a path (time based) +GENESISAPI void GENESISCC gePath_Sample(const gePath *P, geFloat Time,geXForm3d *Matrix); + // returns a transform matrix sampled at 'Time'. + // p is not const because information is cached in p for next sample + +// GENESIS_PRIVATE_APIS +void GENESISCC gePath_SampleChannels( + const gePath *P, + geFloat Time, + geQuaternion *Rotation, + geVec3d *Translation); + // returns a rotation and a translation for the path at 'Time' + // p is not const because information is cached in p for next sample + +GENESISAPI geBoolean GENESISCC gePath_OffsetTimes(gePath *P, + int StartingIndex, int ChannelMask, geFloat TimeOffset ); + // slides all samples in path starting with StartingIndex down by TimeOffset + +GENESISAPI geBoolean GENESISCC gePath_ModifyKeyframe( + gePath *P, + int Index, + int ChannelMask, + const geXForm3d *Matrix); + + +// GENESIS_PUBLIC_APIS + +//------------------ saving/loading a path +GENESISAPI gePath* GENESISCC gePath_CreateFromFile(geVFile *F); + // loads a file (binary or ascii) + +GENESISAPI geBoolean GENESISCC gePath_WriteToFile(const gePath *P, geVFile *F); + // dumps formatted ascii to the file. + +GENESISAPI geBoolean GENESISCC gePath_WriteToBinaryFile(const gePath *P, geVFile *F); + // dumps a minimal binary image for fastest reading + + + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/include/Quatern.h b/include/Quatern.h new file mode 100644 index 0000000..b0669ff --- /dev/null +++ b/include/Quatern.h @@ -0,0 +1,237 @@ +/****************************************************************************************/ +/* QUATERN.H */ +/* */ +/* Author: Mike Sandige */ +/* Description: Quaternion mathematical system interface */ +/* */ +/* The contents of this file are subject to the Genesis3D Public License */ +/* Version 1.01 (the "License"); you may not use this file except in */ +/* compliance with the License. You may obtain a copy of the License at */ +/* http://www.genesis3d.com */ +/* */ +/* Software distributed under the License is distributed on an "AS IS" */ +/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */ +/* the License for the specific language governing rights and limitations */ +/* under the License. */ +/* */ +/* The Original Code is Genesis3D, released March 25, 1999. */ +/* Genesis3D Version 1.1 released November 15, 1999 */ +/* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */ +/* */ +/****************************************************************************************/ +#ifndef GE_QUATERNION_H +#define GE_QUATERNION_H + +/*************************************************************************** + + The quatern module contains basic support for a quaternion object. + + quaternions are an extension of complex numbers that allows an + expression for rotation that can be easily interpolated. geQuaternion_s are also + more numericaly stable for repeated rotations than matrices. + + + A quaternion is a 4 element 'vector' [w,x,y,z] where: + + q = w + xi + yj + zk + i*i = -1 + j*j = -1 + k*k = -1 + i*j = -j*i = k + j*k = -k*j = i + k*i = -i*k = j + q' (conjugate) = w - xi - yj - zk + ||q|| (magnitude) = sqrt(q*q') = sqrt(w*w + x*x + y*y + z*z) + unit quaternion ||q|| == 1; this implies q' == qinverse + quaternions are associative (q1*q2)*q3 == q1*(q2*q3) + quaternions are not commutative q1*q2 != q2*q1 + qinverse (inverse (1/q) ) = q'/(q*q') + + q can be expressed by w + xi + yj + zk or [w,x,y,z] + or as in this implementation (s,v) where s=w, and v=[x,y,z] + + quaternions can represent a rotation. The rotation is an angle t, around a + unit vector u. q=(s,v); s= cos(t/2); v= u*sin(t/2). + + quaternions can apply the rotation to a point. let the point be p [px,py,pz], + and let P be a quaternion(0,p). Protated = q*P*qinverse + ( Protated = q*P*q' if q is a unit quaternion) + + concatenation rotations is similar to matrix concatenation. given two rotations + q1 and q2, to rotate by q1, then q2: let qc = (q2*q1), then the combined + rotation is given by qc*P*qcinverse (= qc*P*qc' if q is a unit quaternion) + + multiplication: + q1 = w1 + x1i + y1j + z1k + q2 = w2 + x2i + y2j + z2k + q1*q2 = q3 = + (w1*w2 - x1*x2 - y1*y2 - z1*z2) {w3} + (w1*x2 + x1*w2 + y1*z2 - z1*y2)i {x3} + (w1*y2 - x1*z2 + y1*w2 + z1*x2)j {y3} + (w1*z2 + x1*y2 + y1*x2 + z1*w2)k {z3} + + also, + q1 = (s1,v1) = [s1,(x1,y1,z1)] + q2 = (s2,v2) = [s2,(x2,y2,z2)] + q1*q2 = q3 = (s1*s2 - dot_product(v1,v2), {s3} + (s1*v2 + s2*v1 + cross_product(v1,v2)) {v3} + + + interpolation - it is possible (and sometimes reasonable) to interpolate between + two quaternions by interpolating each component. This does not quarantee a + resulting unit quaternion, and will result in an animation with non-linear + rotational velocity. + + spherical interpolation: (slerp) treat the quaternions as vectors + find the angle between them (w = arccos(q1 dot q2) ). + given 0<=t<=1, q(t) = q1*(sin((1-t)*w)/sin(w) + q2 * sin(t*w)/sin(w). + since q == -q, care must be taken to rotate the proper way. + + this implementation uses the notation quaternion q = (quatS,quatV) + where quatS is a scalar, and quatV is a 3 element vector. + +********************************************/ + +#include "BaseType.h" +#include "XForm3d.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + geFloat W; + geFloat X,Y,Z; + //geVec3d QuatV; +} geQuaternion; + + +#define QUATERNION_PI (GE_PI) + +geBoolean GENESISCC geQuaternion_IsValid( const geQuaternion *Q ); + // return GE_TRUE if Q is non null and for has no NAN's in its components + +void GENESISCC geQuaternion_Set( geQuaternion *Q, geFloat W, geFloat X, geFloat Y, geFloat Z); + // set quaternion components. Doesn't normalize +void GENESISCC geQuaternion_SetVec3d( geQuaternion *Q, geFloat W, const geVec3d *V); + // set quaternion components. Doesn't normalize +GENESISAPI void GENESISCC geQuaternion_SetFromAxisAngle(geQuaternion *Q, const geVec3d *Axis, geFloat Theta); + // set a quaternion from an axis and a rotation around the axis +geBoolean GENESISCC geQuaternion_GetAxisAngle(const geQuaternion *Q, geVec3d *Axis, geFloat *Theta); + // gets an axis and angle of rotation around the axis from a quaternion + // returns GE_TRUE if there is an axis. + // returns GE_FALSE if there is no axis (and Axis is set to 0,0,0, and Theta is 0) + +void GENESISCC geQuaternion_Get( const geQuaternion *Q, + geFloat *W, geFloat *X, geFloat *Y, geFloat *Z); + // get quaternion components into W,X,Y,Z +void GENESISCC geQuaternion_GetVec3d( const geQuaternion *Q, geFloat *W, geVec3d *V); + // get quaternion components into W and V + +void GENESISCC geQuaternion_FromMatrix( + const geXForm3d *RotationMatrix, + geQuaternion *QDest); + // takes upper 3 by 3 portion of matrix (rotation sub matrix) + // and generates a quaternion + +GENESISAPI void GENESISCC geQuaternion_ToMatrix( + const geQuaternion *Q, + geXForm3d *RotationMatrixDest); + // takes a unit quaternion and makes RotationMatrixDest an equivelant rotation xform. + // (any translation in RotationMatrixDest will be list) + +void GENESISCC geQuaternion_Slerp( + const geQuaternion *Q0, + const geQuaternion *Q1, + geFloat T, + geQuaternion *QT); + // spherical interpolation between q0 and q1. 0<=t<=1 + // resulting quaternion is 'between' q0 and q1 + // with t==0 being all q0, and t==1 being all q1. + // returns a quaternion with a positive W - always takes shortest route + // through the positive W domain. + +void GENESISCC geQuaternion_SlerpNotShortest( + const geQuaternion *Q0, + const geQuaternion *Q1, + geFloat T, + geQuaternion *QT); + // spherical interpolation between q0 and q1. 0<=t<=1 + // resulting quaternion is 'between' q0 and q1 + // with t==0 being all q0, and t==1 being all q1. + + +void GENESISCC geQuaternion_Multiply( + const geQuaternion *Q1, + const geQuaternion *Q2, + geQuaternion *QProduct); + // multiplies q1 * q2, and places the result in q. + // no failure. renormalization not automatic + +void GENESISCC geQuaternion_Rotate( + const geQuaternion *Q, + const geVec3d *V, + geVec3d *VRotated); + // Rotates V by the quaternion Q, places the result in VRotated. + +geBoolean GENESISCC geQuaternion_IsUnit(const geQuaternion *Q); + // returns GE_TRUE if q is a unit quaternion. GE_FALSE otherwise. + +GENESISAPI geFloat GENESISCC geQuaternion_Normalize(geQuaternion *Q); + // normalizes q to be a unit quaternion. returns original magnitude of q + +GENESISAPI void GENESISCC geQuaternion_Copy(const geQuaternion *QSrc, geQuaternion *QDst); + // copies quaternion QSrc into QDst + +void GENESISCC geQuaternion_SetNoRotation(geQuaternion *Q); + // sets Q to be a quaternion with no rotation (like an identity matrix) + +void GENESISCC geQuaternion_Ln( + const geQuaternion *Q, + geQuaternion *LnQ); + // ln(Q) for unit quaternion only! + +void GENESISCC geQuaternion_Exp( + const geQuaternion *Q, + geQuaternion *ExpQ); + // exp(Q) for pure quaternion only! (zero scalar part (W)) + +void GENESISCC geQuaternion_Scale( + const geQuaternion *Q, + geFloat Scale, + geQuaternion *QScaled); + // Q = Q * Scale (result is not generally a unit quaternion!) + +void GENESISCC geQuaternion_Add( + const geQuaternion *Q1, + const geQuaternion *Q2, + geQuaternion *QSum); + // QSum = Q1 + Q2 (result is not generally a unit quaternion!) + +void GENESISCC geQuaternion_Subtract( + const geQuaternion *Q1, + const geQuaternion *Q2, + geQuaternion *QSum); + // QSum = Q1 - Q2 (result is not generally a unit quaternion!) + +void GENESISCC geQuaternion_Inverse(const geQuaternion *Q, geQuaternion *QInv); + // sets QInv to the inverse of Q. + +geFloat GENESISCC geQuaternion_Magnitude(const geQuaternion *Q); + // returns Magnitude of Q. + +geBoolean GENESISCC geQuaternion_Compare( geQuaternion *Q1, geQuaternion *Q2, geFloat Tolerance ); + // return GE_TRUE if quaternions differ elementwise by less than Tolerance. + + +#ifndef NDEBUG +void GENESISCC geQuaternion_SetMaximalAssertionMode( geBoolean Enable ); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif // GE_QUATERNION_H diff --git a/include/Sprite.h b/include/Sprite.h index 66b6002..5e54066 100644 --- a/include/Sprite.h +++ b/include/Sprite.h @@ -20,10 +20,10 @@ #ifndef GE_SPRITE_H #define GE_SPRITE_H -#include "genesis.h" -#include "basetype.h" -#include "extbox.h" -#include "bitmap.h" +#include "Genesis.h" +#include "BaseType.h" +#include "ExtBox.h" +#include "Bitmap.h" #ifdef GE_WORLD_H #include "camera.h" diff --git a/include/VFile.h b/include/VFile.h index bf06be9..2088bf8 100644 --- a/include/VFile.h +++ b/include/VFile.h @@ -26,7 +26,7 @@ extern "C" { #endif -#include "basetype.h" +#include "BaseType.h" typedef struct geVFile geVFile;