diff --git a/Extras/BulletColladaConverter/ColladaConverter.cpp b/Extras/BulletColladaConverter/ColladaConverter.cpp index 256fdb86d..36fb4a245 100644 --- a/Extras/BulletColladaConverter/ColladaConverter.cpp +++ b/Extras/BulletColladaConverter/ColladaConverter.cpp @@ -1032,7 +1032,7 @@ void ColladaConverter::prepareConstraints(ConstraintInput& input) /* * JC patch. Skip the rigid body if it doesn't have any DOM * node associated - e.g. because it was created directly, without - * the COLLADA file. + * the COLLADA file. */ if(!domRigidBody) continue; diff --git a/Extras/CMakeLists.txt b/Extras/CMakeLists.txt index 9ccdb3c47..774378f74 100644 --- a/Extras/CMakeLists.txt +++ b/Extras/CMakeLists.txt @@ -1 +1 @@ -SUBDIRS( glui iff ConvexDecomposition BulletColladaConverter LibXML COLLADA_DOM GIMPACTUtils ) +SUBDIRS( glui ConvexDecomposition BulletColladaConverter LibXML COLLADA_DOM GIMPACTUtils ) diff --git a/Extras/readblend/LICENSE.txt b/Extras/readblend/LICENSE.txt deleted file mode 100644 index 07b85e91c..000000000 --- a/Extras/readblend/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ - -Copyright (C) 2003-2006 Adam D. Moss (the "Author"). All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is fur- -nished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- -NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- -NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the Author of the -Software shall not be used in advertising or otherwise to promote the sale, -use or other dealings in this Software without prior written authorization -from the Author. diff --git a/Extras/readblend/Makefile b/Extras/readblend/Makefile deleted file mode 100644 index bf2358e51..000000000 --- a/Extras/readblend/Makefile +++ /dev/null @@ -1,36 +0,0 @@ - -CC = gcc -COPTS = -O2 -Wall - -#CC = gcc31 -#COPTS = -O2 -Wall -ggdb -lm - -#COPTS = -O3 -g -fno-inline-functions -ffast-math -pg -Wall -#COPTS = -ggdb -Wall - -CFLAGS = $(COPTS) $(INCS) -lm - -EXEC = testblend - -OBJ_SRCS = testblend.c readblend.c -OBJ_OBJS = $(OBJ_SRCS:.c=.o) - -%.o: %.c - ${CC} ${CFLAGS} -c $< -o $@ - -all: $(EXEC) - -clean: - rm -f $(EXEC) *.o gmon.out - -#dist: -# tar -hzvcf flynn-`cat VERSION`.tar.gz `cat MANIFEST` -# ls -la flynn-`cat VERSION`.tar.gz - -#testdist: -# tar -zvcf flynn-testdir.tar.gz test -# ls -la flynn-testdir.tar.gz - -$(EXEC): $(OBJ_OBJS) - $(CC) $(CFLAGS) $^ -o $@ - diff --git a/Extras/readblend/README.blendstruct b/Extras/readblend/README.blendstruct deleted file mode 100644 index 597bb787f..000000000 --- a/Extras/readblend/README.blendstruct +++ /dev/null @@ -1,26 +0,0 @@ -ReadBlend, a data extraction API for Blender's .blend files - -quick notes on the logical .blend file format as presented -by readblend: - - -BLENDFILE - | - |--BLENDFILE_VERSION - | - |--NUM_BLOCKS ... number of blocks in the file - |--BLOCK[NUM_BLOCKS] ... array of blocks - | - |--BLOCK_TAG ... general 'DATA', otherwise specialized type - | - |--OBJECT_TYPE ... the block is an array of objects of this type - |--OBJECT_COUNT ... this is the number of objects in the block - |--OBJECT[OBJECT_COUNT] ... array of objects - | - |--OBJECT - an OBJECT... - = ATOMIC type (uchar, float, etc) - or - = STRUCTURE (array of assorted OBJECTs, nested) - or - = POINTER (a reference to another BLOCK) diff --git a/Extras/readblend/ReadBlend.sln b/Extras/readblend/ReadBlend.sln deleted file mode 100644 index fe04c7d28..000000000 --- a/Extras/readblend/ReadBlend.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReadBlend", "ReadBlend.vcproj", "{74CA6BF4-60C4-4FE6-BAB5-31F31FA2A0B3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {74CA6BF4-60C4-4FE6-BAB5-31F31FA2A0B3}.Debug|Win32.ActiveCfg = Debug|Win32 - {74CA6BF4-60C4-4FE6-BAB5-31F31FA2A0B3}.Debug|Win32.Build.0 = Debug|Win32 - {74CA6BF4-60C4-4FE6-BAB5-31F31FA2A0B3}.Release|Win32.ActiveCfg = Release|Win32 - {74CA6BF4-60C4-4FE6-BAB5-31F31FA2A0B3}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Extras/readblend/ReadBlend.vcproj b/Extras/readblend/ReadBlend.vcproj deleted file mode 100644 index fbb49b582..000000000 --- a/Extras/readblend/ReadBlend.vcproj +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Extras/readblend/abs-file.h b/Extras/readblend/abs-file.h deleted file mode 100644 index 3e98ad06b..000000000 --- a/Extras/readblend/abs-file.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * stdio/physfs abstraction layer 2004-02-06 - * - * Adam D. Moss - * - * These wrapper macros and functions are designed to allow a program - * to perform file I/O with identical semantics and syntax regardless - * of whether PhysicsFS is being used or not. - */ -#ifndef _ABS_FILE_H -#define _ABS_FILE_H - -#ifdef WIN32 - - typedef unsigned char uint8_t; - typedef unsigned long int uint64_t; - typedef unsigned int uint32_t; - typedef int int32_t; - typedef unsigned short uint16_t; - typedef short int16_t; -#else -#include - -#endif - -/* -PLEASE NOTE: This license applies to abs-file.h ONLY; The version of -PhysicsFS itself which you are using may have been released under a -license with additional restrictions. - -Copyright (C) 2002-2004 Adam D. Moss (the "Author"). All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is fur- -nished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- -NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- -NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the Author of the -Software shall not be used in advertising or otherwise to promote the sale, -use or other dealings in this Software without prior written authorization -from the Author. -*/ - -#include -#include - -/* - * API: - * - * Macro/function use like stdio equivalent... - * -------------- ---------------------------- - * MY_FILETYPE FILE - * MY_OPEN_FOR_READ fopen(..., "rb") - * MY_READ fread(...) - * MY_GETC fgetc(...) - * MY_GETS fgets(...) - * MY_OPEN_FOR_WRITE fopen(..., "wb") - * MY_WRITE fwrite(...) - * MY_PUTC fputc(...) - * MY_PUTS fputs(...) - * MY_CLOSE fclose(...) - * MY_ATEOF feof(...) - * MY_TELL ftell(...) - * MY_SEEK fseek(..., SEEK_SET) - * MY_REWIND rewind(...) - * MY_SETBUFFER (not a standard for stdio, does nothing there) - * MY_FILELENGTH (not a standard for stdio, but implemented anyway) - */ - -/* - * Important DEFINEs: - * - * It is important to define these consistantly across the various - * compilation modules of your program if you wish to exchange file - * handles between them. - * - * USE_PHYSFS: Define USE_PHYSFS if PhysicsFS is being used; note that if - * you do intend to use PhysicsFS then you will still need to initialize - * PhysicsFS yourself and set up its search-paths. - * - * Optional DEFINEs: - * - * PHYSFS_DEFAULT_BUFFER_SIZE : If set then abs-file.h sets the - * PhysicsFS buffer size to this value whenever you open a file. You - * may over-ride this on a per-filehandle basis by using the - * MY_SETBUFFER() macro (which simply does nothing when not using - * PhysicsFS). If you have not defined this value explicitly then - * abs-file.h will default to the same default buffer size as used by - * stdio if it can be determined, or 8192 bytes otherwise. - */ - -#ifndef PHYSFS_DEFAULT_BUFFER_SIZE -#ifdef BUFSIZ -#define PHYSFS_DEFAULT_BUFFER_SIZE BUFSIZ -#else -#define PHYSFS_DEFAULT_BUFFER_SIZE 8192 -#endif -#endif - -#ifdef USE_PHYSFS - -#include -#define MY_FILETYPE PHYSFS_file -#define MY_SETBUFFER(fp,size) PHYSFS_setBuffer(fp,size) -#define MY_READ(p,s,n,fp) PHYSFS_read(fp,p,s,n) -#define MY_WRITE(p,s,n,fp) PHYSFS_write(fp,p,s,n) -#if PHYSFS_DEFAULT_BUFFER_SIZE -static MY_FILETYPE* MY_OPEN_FOR_READ(const char *const filename) -{ - MY_FILETYPE *const file = PHYSFS_openRead(filename); - if (file) { - MY_SETBUFFER(file, PHYSFS_DEFAULT_BUFFER_SIZE); - } - return file; -} -static MY_FILETYPE* MY_OPEN_FOR_WRITE(const char *const filename) -{ - MY_FILETYPE *const file = PHYSFS_openWrite(filename); - if (file) { - MY_SETBUFFER(file, PHYSFS_DEFAULT_BUFFER_SIZE); - } - return file; -} -#else -#define MY_OPEN_FOR_READ(fn) PHYSFS_openRead(fn) -#define MY_OPEN_FOR_WRITE(fn) PHYSFS_openWrite(fn) -#endif -static int MY_GETC(MY_FILETYPE *const fp) { - unsigned char c; - /*if (PHYSFS_eof(fp)) { - return EOF; - } - MY_READ(&c, 1, 1, fp);*/ - if (MY_READ(&c, 1, 1, fp) != 1) { - return EOF; - } - return c; -} -static char * MY_GETS(char * const str, const int size, - MY_FILETYPE *const fp) { - int i = 0; - int c; - do { - if (i == size-1) { - break; - } - c = MY_GETC(fp); - if (c == EOF) { - break; - } - str[i++] = c; - } while (c != '\0' && - c != -1 && - c != '\n'); - str[i] = '\0'; - if (i == 0) { - return NULL; - } - return str; -} -static int MY_PUTC(int c, MY_FILETYPE *const fp) { - unsigned char cc = (unsigned char)c; - if (MY_WRITE(&cc, 1, 1, fp) != 1) { - return EOF; - } - return (int)cc; -} -static int MY_PUTS(const char *s, MY_FILETYPE *const fp) { - int i = 0; - while (s[i] != '\0') { - if (MY_PUTC(s[i], fp) == EOF) { - return EOF; - } - ++i; - } - if (MY_PUTC('\n', fp) == EOF) { - return EOF; - } - return 0; -} -#define MY_CLOSE(fp) (0==PHYSFS_close(fp)) -#define MY_ATEOF(fp) PHYSFS_eof(fp) -#define MY_TELL(fp) PHYSFS_tell(fp) -#define MY_SEEK(fp,o) (0==PHYSFS_seek(fp,o)) -#define MY_REWIND(fp) MY_SEEK(fp,0) -#define MY_FILELENGTH(fp) PHYSFS_fileLength(fp) - -#else /* !USE_PHYSFS */ - -//#define USE_POSIX_FILES 1 -#ifdef USE_POSIX_FILES -#define MY_FILETYPE FILE -#define MY_READ(p,s,n,fp) fread(p,s,n,fp) -#define MY_WRITE(p,s,n,fp) fwrite(p,s,n,fp) -#define MY_OPEN_FOR_READ(n) fopen(n, "rb") -#define MY_OPEN_FOR_WRITE(n) fopen(n, "wb") -#define MY_GETC(fp) fgetc(fp) -#define MY_GETS(str,size,fp) fgets(str,size,fp) -#define MY_PUTC(c,fp) fputc(c,fp) -#define MY_PUTS(str,fp) fput(str,fp) -#define MY_CLOSE(fp) fclose(fp) -#define MY_ATEOF(fp) feof(fp) -#define MY_TELL(fp) ftell(fp) -#define MY_SEEK(fp,o) fseek(fp,o, SEEK_SET) -#define MY_REWIND(fp) rewind(fp) -#define MY_SETBUFFER(fp,size) -/* a TODO from ryan: "seeking to the end followed by an ftell() is probably -more portable, but you can also use fileno() to get a handle from a -(FILE *) to use with fstat()...on supported platforms, that is, most -platforms, this is probably faster." */ -static long MY_FILELENGTH(FILE *fp) { - long currentpos = ftell(fp); /* save current cursor position */ - long newpos; - fseek(fp, 0, SEEK_END); /* seek to end */ - newpos = ftell(fp); /* find position of end -- this is the length */ - fseek(fp, currentpos, SEEK_SET); /* restore previous cursor position */ - return newpos; -} -#else -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MY_FILETYPE char - - -long MY_FILELENGTH(FILE *fp); -MY_FILETYPE* MY_OPEN_FOR_READ(const char *const filename); -int MY_GETC(MY_FILETYPE *const fp); -void MY_SEEK(MY_FILETYPE* fp,int pos); -#define MY_REWIND(fp) MY_SEEK(fp,0) -int MY_READ(unsigned char* dest,int size,int num,MY_FILETYPE* fp); - -void MY_CLOSE(MY_FILETYPE* fp); -int MY_TELL(MY_FILETYPE* fp); -int MY_ATEOF(MY_FILETYPE* fp); - -#ifdef __cplusplus -} -#endif - -#endif //USE_POSIX_FILES - -#endif /* USE_PHYSFS */ - -#endif /* _ABS_FILE_H */ diff --git a/Extras/readblend/blendtype.h b/Extras/readblend/blendtype.h deleted file mode 100644 index da6feeb2e..000000000 --- a/Extras/readblend/blendtype.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef BLEND_TYPE_H -#define BLEND_TYPE_H -#include "abs-file.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _BlendField BlendField; -struct _BlendField { - char* field_bytes; - int field_bytes_count; - - /* the offset into field_bytes at which each field of a - structure begins. this is so we can keep the data aligned - correctly for various architectures. a non-structure type - is equivalent to a structure with a single field. - */ - int* field_offsets; - int field_offsets_count; -}; -struct _BlendBlock { - char tag[5]; - uint32_t blender_pointer; - /*void* fixed_pointer;*/ - - int type_index; - /* a block is simply an array of its type as defined by type_index. - array_entries is an array of pointers to each entry in the block's - array. - */ - BlendField *array_entries; - int array_entries_count; - void* customData; /* for Link blocks, with custom data such as .jpg pictures etc */ - int customDataSize; -}; - - -typedef struct _BlendBlock BlendBlock; - -/* the types extracted from the Blender file */ -typedef struct _BlendType BlendType; -struct _BlendType { - char* name; - int size; - - int is_struct; - - /* if is_struct... this defines the types of each of the structure fields */ - int fieldtypes_count; - int* fieldtypes; /* type indices */ - int fieldnames_count; - int* fieldnames; /* name indices */ -}; - - - - - - -/* the opaque BlendFile structure */ -typedef struct _BlendFile{ - BlendType* types; - int types_count; - - char* *names; - int names_count; - - int* strc_indices; - int strc_indices_count; - - BlendBlock *blocks; - int blocks_count; - - int name_undef; /* index of the name we add specially for top blocks */ - -} BlendFile; - - - - -#ifdef __cplusplus -} -#endif - -#endif //BLEND_TYPE_H \ No newline at end of file diff --git a/Extras/readblend/readblend.c b/Extras/readblend/readblend.c deleted file mode 100644 index bf720d9a5..000000000 --- a/Extras/readblend/readblend.c +++ /dev/null @@ -1,2795 +0,0 @@ -#include "blendtype.h" - -#include -//#include -#include -#include - -#include "abs-file.h" - -#ifndef USE_POSIX_FILES - - - - -static char* gBuffer = 0; -static int gCurrentFilePtr = 0; -static int gFileSize = 0; - - -long MY_FILELENGTH(FILE *fp) { - long currentpos = ftell(fp); /* save current cursor position */ - long newpos; - fseek(fp, 0, SEEK_END); /* seek to end */ - newpos = ftell(fp); /* find position of end -- this is the length */ - fseek(fp, currentpos, SEEK_SET); /* restore previous cursor position */ - return newpos; -} - - -MY_FILETYPE* MY_OPEN_FOR_READ(const char *const filename) -{ - FILE* gFile = fopen(filename,"rb"); - if (gFile) - { - long currentpos = ftell(gFile); /* save current cursor position */ - long newpos; - int bytesRead; - - fseek(gFile, 0, SEEK_END); /* seek to end */ - newpos = ftell(gFile); /* find position of end -- this is the length */ - fseek(gFile, currentpos, SEEK_SET); /* restore previous cursor position */ - gFileSize = newpos; - gBuffer = (char*)malloc(gFileSize); - bytesRead = fread(gBuffer,gFileSize,1,gFile); - gCurrentFilePtr = 0; - fclose(gFile); - gFile = 0; - return gBuffer; - } - return 0; -} - -int MY_GETC(MY_FILETYPE *const fp) -{ - return gBuffer[gCurrentFilePtr++]; -} - -void MY_SEEK(MY_FILETYPE* fp,int pos) -{ - gCurrentFilePtr = pos; -} - -#define MY_REWIND(fp) MY_SEEK(fp,0) -int MY_READ(unsigned char* dest,int size,int num,MY_FILETYPE* fp) -{ - int n; - memcpy(dest,&gBuffer[gCurrentFilePtr],size*num); - gCurrentFilePtr += size*num; - return num; -} - -void MY_CLOSE(MY_FILETYPE* fp) -{ - free(gBuffer); - gBuffer = 0; - gCurrentFilePtr = 0; - gFileSize = 0; - -} - -int MY_TELL(MY_FILETYPE* fp) -{ - return gCurrentFilePtr; -} - -int MY_ATEOF(MY_FILETYPE* fp) -{ - return gCurrentFilePtr -# define dprintf fprintf -# endif -#else -# define dprintf -#endif - -int tryit = 0; -int dumpNames= 1; - - -#include "readblend.h" - - -#define MAX_CACHED_IMAGES 1024 -BlendBlockPointer tCachedTPage[MAX_CACHED_IMAGES]; -bImage* tCachedImages[MAX_CACHED_IMAGES]; -int gNumCachedImages=0; - - -/* endianness conversion macros */ -#define BGETLEUINT16(p) ((uint16_t) ( \ - ( ((uint16_t)*( 1 + (uint8_t*)(p) ))<<8 ) | \ - ( ((uint16_t)*( 0 + (uint8_t*)(p) ))<<0 ) \ - ) ) -#define BGETLEINT16(p) ((int16_t) BGETLEUINT16(p)) -#define BGETLEUINT32(p) ((uint32_t) ( \ - ( ((uint32_t)*( 3 + (uint8_t*)(p) ))<<24 ) | \ - ( ((uint32_t)*( 2 + (uint8_t*)(p) ))<<16 ) | \ - ( ((uint32_t)*( 1 + (uint8_t*)(p) ))<<8 ) | \ - ( ((uint32_t)*( 0 + (uint8_t*)(p) ))<<0 ) \ - ) ) -#define BGETLEINT32(p) ((int32_t) BGETLEUINT32(p)) -#define BGETLEUINT64(p) ((uint64_t) ( \ - ( ((uint64_t)*( 7 + (uint8_t*)(p) ))<<56 ) | \ - ( ((uint64_t)*( 6 + (uint8_t*)(p) ))<<48 ) | \ - ( ((uint64_t)*( 5 + (uint8_t*)(p) ))<<40 ) | \ - ( ((uint64_t)*( 4 + (uint8_t*)(p) ))<<32 ) | \ - ( ((uint64_t)*( 3 + (uint8_t*)(p) ))<<24 ) | \ - ( ((uint64_t)*( 2 + (uint8_t*)(p) ))<<16 ) | \ - ( ((uint64_t)*( 1 + (uint8_t*)(p) ))<<8 ) | \ - ( ((uint64_t)*( 0 + (uint8_t*)(p) ))<<0 ) \ - ) ) -#define BGETLEINT64(p) ((int64_t) BGETLEUINT64(p)) -static float BGETLEFLOAT32(char *p) { - union { /* use type-punning, or aliasing optimization will kick our arse */ - uint32_t u32; - float f32; - } punner; - punner.u32 = BGETLEUINT32(p); - return punner.f32; -} -static double BGETLEDOUBLE64(char *p) { - union { /* use type-punning, or aliasing optimization will kick our arse */ - uint64_t u64; - float f64; - } punner; - punner.u64 = BGETLEUINT64(p); - return punner.f64; -} - - -static BlendFile* -bf_new(void) -{ - BlendFile *rtn = malloc(sizeof(BlendFile)); - if (!rtn) { - dprintf(stderr, "out of mem making bf handle\n"); - return NULL; - } - rtn->types = NULL; - rtn->types_count = 0; - rtn->names = NULL; - rtn->names_count = 0; - rtn->blocks = NULL; - rtn->blocks_count = 0; - rtn->strc_indices = NULL; - rtn->strc_indices_count = 0; - rtn->name_undef = -1; - return rtn; -} - - -static long -seek_past_string(MY_FILETYPE* file, const char *str) { - const int match_max = strlen(str); - int match_now = 0; - - do { - const char c = MY_GETC(file); - if (c == str[match_now]) { - ++match_now; - } else { - match_now = 0; - } - } while(match_now < match_max && - !MY_ATEOF(file)); - - if (MY_ATEOF(file)) { - return -1; - } - - return MY_TELL(file) - match_max; -} - -#define EXPANDO_MULTIPLE(ARRAY,ADDITIONPTR,NUMBER) \ - do { \ - (ARRAY) = realloc((ARRAY), sizeof((ARRAY)[0]) * (NUMBER +(ARRAY##_count))); \ - memcpy(&(ARRAY)[ARRAY##_count], ADDITIONPTR, sizeof((ARRAY)[0]) * NUMBER); \ - (ARRAY##_count) += NUMBER; \ - } while(0) - -#define EXPANDO(ARRAY,ADDITION) \ - do { \ - (ARRAY) = realloc((ARRAY), sizeof((ARRAY)[0]) * (1 + (ARRAY##_count))); \ - (ARRAY)[ARRAY##_count] = (ADDITION); \ - ++(ARRAY##_count); \ - } while(0) - -static unsigned short -read_ushort(MY_FILETYPE* file) { - unsigned char c[2]; - if (MY_READ(c, 2, 1, file) == 1) - { - return c[0] | (c[1]<<8); - } else { - return 0xFFFF; - } -} - - -static long -read_long(MY_FILETYPE* file) { - unsigned char c[4]; - if (MY_READ(c, 4, 1, file) == 1) { - return ((unsigned long)c[0] | (c[1]<<8) | (c[2]<<16) | (c[3]<<24)); - } else { - return 0xFFFFFFFF; - } -} - - -static unsigned long -read_ulong(MY_FILETYPE* file) { - unsigned char c[4]; - if (MY_READ(c, 4, 1, file) == 1) { - return c[0] | (c[1]<<8) | (c[2]<<16) | (c[3]<<24); - } else { - return 0xFFFFFFFF; - } -} - - -static int -name_is_pointer(char* name) { - int len = strlen(name); - /*fprintf(stderr,"[%s]",name);*/ - if (len >= 1) { - if (name[0] == '*') - return 1; - } - if (len >= 2) { - if (name[1] == '*') - return 1; - } - return 0; -} - - -/* note: we only deal with 1d or 2d arrays at the moment. haven't -seen any arrays of a higher order from Blender yet. */ -static int -name_is_array(char* name, int* dim1, int* dim2) { - int len = strlen(name); - /*fprintf(stderr,"[%s]",name);*/ - /*if (len >= 1) { - if (name[len-1] != ']') - return 1; - } - return 0;*/ - char *bp; - int num; - if (dim1) { - *dim1 = 1; - } - if (dim2) { - *dim2 = 1; - } - bp = strchr(name, '['); - if (!bp) { - return 0; - } - num = 0; - while (++bp < name+len-1) { - const char c = *bp; - if (c == ']') { - break; - } - if (c <= '9' && c >= '0') { - num *= 10; - num += (c - '0'); - } else { - dprintf(stderr, "array parse error.\n"); - return 0; - } - } - if (dim2) { - *dim2 = num; - } - - /* find second dim, if any. */ - bp = strchr(bp, '['); - if (!bp) { - return 1; /* at least we got the first dim. */ - } - num = 0; - while (++bp < name+len-1) { - const char c = *bp; - if (c == ']') { - break; - } - if (c <= '9' && c >= '0') { - num *= 10; - num += (c - '0'); - } else { - dprintf(stderr, "array2 parse error.\n"); - return 1; - } - } - if (dim1) { - if (dim2) { - *dim1 = *dim2; - *dim2 = num; - } else { - *dim1 = num; - } - } - - return 1; -} - - -#define SIZE_ROUNDUP(SIZE) (((SIZE) + sizeof(int) - 1) & ~(sizeof(int) - 1)) - - -static void -recursively_read_type(MY_FILETYPE* file, BlendFile* bf, - unsigned long section_type, - BlendField* field) -{ - char *new_data = NULL; - int new_data_size = 0; - int dim1, dim2; - - if (bf->types[section_type].is_struct) { - int i; - /*fprintf(stderr, "type%d(%s)is_struct(%d) ", section_type, bf->types[section_type].name, bf->types[section_type].size);*/ - for (i=0; itypes[section_type].fieldtypes_count; ++i) { - /*fprintf(stderr, "@%d ", i);*/ - int j,k; -#if 0 - if (name_is_array(bf->names[bf->types[section_type].fieldnames[i]], - &j,&k) || 1) { - dprintf(stderr, " %s/%s=[%d][%d] ", - bf->types[bf->types[section_type].fieldtypes[i]].name, - bf->names[bf->types[section_type].fieldnames[i]], j, k); - } -#endif - if (name_is_pointer(bf->names[bf->types[section_type].fieldnames[i]])) { - /*fprintf(stderr, "*(4) ");*/ - name_is_array(bf->names[bf->types[section_type].fieldnames[i]], - &dim1,&dim2); - new_data_size = SIZE_ROUNDUP(4); - new_data = malloc(new_data_size); - /*fprintf(stderr, " ");*/ - for (j=0; jfield_offsets, field->field_bytes_count); - - (field->field_offsets) = realloc((field->field_offsets), sizeof((field->field_offsets)[0]) * (1 + (field->field_offsets_count))); - (field->field_offsets)[field->field_offsets_count] = (field->field_bytes_count); - ++(field->field_offsets_count); - - - // EXPANDO_MULTIPLE(field->field_bytes, new_data, new_data_size); - { - (field->field_bytes) = realloc((field->field_bytes), sizeof((field->field_bytes)[0]) * (new_data_size +(field->field_bytes_count))); - memcpy(&(field->field_bytes)[field->field_bytes_count], new_data, sizeof((field->field_bytes)[0]) * new_data_size); - (field->field_bytes_count) += new_data_size; - } - - /*fprintf(stderr, "N*(%d) ", new_data_size);*/ - } - } - free(new_data); - } else { - name_is_array(bf->names[bf->types[section_type].fieldnames[i]], - &dim1,&dim2); - /*fprintf(stderr, " ");*/ - for (j=0; jtypes[section_type].fieldtypes[i], - field); - } - } - } - } - } else { - /*fprintf(stderr, "type%d(%s)plain(%d) ", section_type, bf->types[section_type].name, bf->types[section_type].size); */ - new_data_size = SIZE_ROUNDUP(bf->types[section_type].size); - /*fprintf(stderr, "%d... ", bf->types[section_type].size); - if (bf->types[section_type].size > 4) { - fprintf(stderr, "%d ", field->field_bytes_count); - }*/ - if (new_data_size) { - new_data = malloc(new_data_size); - MY_READ(new_data, 1, bf->types[section_type].size, file); - EXPANDO(field->field_offsets, field->field_bytes_count); - EXPANDO_MULTIPLE(field->field_bytes, new_data, new_data_size); - /*fprintf(stderr, "ND(%d) ", new_data_size); */ - free(new_data); - } else { - dprintf(stderr, " ", - bf->types[section_type].size); - } - } - -} - - -static BlendField -read_type(MY_FILETYPE* file, BlendFile* bf, - unsigned long section_type) -{ - BlendField rtn; - - rtn.field_bytes = NULL; - rtn.field_bytes_count = 0; - rtn.field_offsets = NULL; - rtn.field_offsets_count = 0; - - recursively_read_type(file, bf, section_type, &rtn); - - return rtn; -} - - -static int -blend_read_data(MY_FILETYPE* file, BlendFile* bf) -{ - long next_block_start = 12; - int finished_extracting = 0; - char section_name[5] = {0,0, 0,0, 0}; - - /* slurp up the whole file block by block! */ - - do { - unsigned long section_size; - unsigned long section_pointer; - unsigned long section_type; - unsigned long section_ents; - MY_SEEK(file, next_block_start); - - MY_READ(section_name, 4, 1, file); - - - if (strcmp(section_name, "DNA1") != 0) { - - - int i; - BlendBlock block; - - - if (strcmp(section_name, "IM") == 0) { - //printf("image\n"); - } - - - - - if (strcmp(section_name, "IP") == 0) { -// printf("ipo\n"); - } - - section_size = read_ulong(file); - section_pointer = read_ulong(file); - section_type = read_ulong(file); - section_type = bf->strc_indices[section_type]; - section_ents = read_ulong(file); - - if (dumpNames) - { -// printf("section_name = %s, section_type = %d / %s\n",section_name,section_type,bf->types[section_type]); - - } - - memcpy(block.tag, section_name, 4); - block.tag[4] = '\0'; - block.type_index = section_type; - block.blender_pointer = section_pointer; - /*block.fixed_pointer = NULL;*/ - block.array_entries = NULL; - block.array_entries_count = 0; - block.customData = 0; - block.customDataSize = 0; - - // dprintf(stderr, "\nsizeof(%s)=%ld: %s[%ld]\n", section_name, section_size, bf->types[section_type].name, section_ents); - - if (strcmp("Link",bf->types[section_type].name)==0) - { - if (section_size>0) - { - //read customData - block.customData= (char*)malloc(section_size); - block.customDataSize = section_size; - MY_READ(block.customData,1,section_size,file); - } - } else - { - for (i=0; iblocks, block); - - next_block_start += 4+4+4+4+4 + section_size; - -#ifdef B_DEBUG - if (MY_TELL(file) > next_block_start) { - //dprintf(stderr, " **OVER-READ(%ld,%ld)** ", MY_TELL(file), next_block_start); - if (strcmp(bf->types[section_type].name, "Link") == 0 && - MY_TELL(file) - next_block_start == 4) { - //dprintf(stderr, "<- don't panic, known Link struct weirdness."); - } else { - dprintf(stderr, "<- okay, PANIC!"); - } - //dprintf(stderr, "\n"); - } else if (MY_TELL(file) < next_block_start) { - /*dprintf(stderr, " **under-READ(%ld,%ld)** ", - MY_TELL(file), next_block_start);*/ - } else { - /*dprintf(stderr, " :) ");*/ - } -#endif - - } else { - finished_extracting = 1; - } - - } while (!finished_extracting); - - return 1; -} - - -BlendFile* -blend_read(MY_FILETYPE* file) -{ - char blender_mark[10] = {0,0,0,0, 0,0,0,0,0,0}; - BlendFile *bf; - long sdnaname_offs, type_offs, tlen_offs, strc_offs, endb_offs; - long sdnaname_size, type_size, tlen_size, strc_size; - long sdnaname_ents, type_ents, tlen_ents, strc_ents; - - MY_REWIND(file); - - /* Check file signature */ - - MY_READ(blender_mark, 1, 9, file); - if (strcmp(blender_mark, "BLENDER_v") != 0) { - dprintf(stderr, "Not a valid Blender file (.blend file needs to be written on a 32bit little-endian machine)\n"); - return NULL; - } - - /* Alloc a handle to return */ - - bf = bf_new(); - - /* Scan the whole file (!) for file section markers */ - - sdnaname_offs = seek_past_string(file, "SDNANAME"); - sdnaname_ents = read_long(file); - type_offs = seek_past_string(file, "TYPE"); - type_ents = read_long(file); - tlen_offs = seek_past_string(file, "TLEN"); - tlen_ents = type_ents; - strc_offs = seek_past_string(file, "STRC"); - strc_ents = read_long(file); - endb_offs = seek_past_string(file, "ENDB"); - - if (sdnaname_offs == -1 || type_offs == -1 || tlen_offs == -1 || - strc_offs == -1 || endb_offs == -1) { - dprintf(stderr, "Couldn't find all necessary file markers. :(\n"); - return NULL; - } - - /* Move marker offsets to point to the start of each one's block */ - - sdnaname_offs += 8 + 4; - sdnaname_size = type_offs - sdnaname_offs; - - type_offs += 4 + 4; - type_size = tlen_offs - type_offs; - - tlen_offs += 4; - tlen_size = strc_offs - tlen_offs; - - strc_offs += 4 + 4; - strc_size = endb_offs - strc_offs; - - /* read the NAME table */ - - MY_SEEK(file, sdnaname_offs); - { - long offs = 0; - int i; - char *top_block_name; - - for (i=0; inames, this_name_chars); - } - - /* our top-block name */ -#define BLEND_TOP_BLOCK_NAME "READBLEND_TOP_BLOCK" - top_block_name = calloc(1, 1+strlen(BLEND_TOP_BLOCK_NAME)); - strcpy(top_block_name, BLEND_TOP_BLOCK_NAME); - bf->name_undef = bf->names_count; - EXPANDO(bf->names, top_block_name); - } - - /* read the TYPE table */ - - MY_SEEK(file, type_offs); - { - long offs = 0; - int i; - - for (i=0; itypes, bt); - } - } - - /* read the TLEN table */ - - MY_SEEK(file, tlen_offs); - { - int i; - for (i=0; itypes_count; ++i) { - unsigned short len = read_ushort(file); - bf->types[i].size = len; - /*fprintf(stderr, "sizeof(%s)=%d ", bf->types[i].name, len); */ - } - } - - /* Read the STRC table */ - - MY_SEEK(file, strc_offs); - { - int i,j; - for (i=0; itypes[struc_type_index].is_struct = 1; - EXPANDO(bf->strc_indices, struc_type_index); - /*dprintf(stderr, "\n%s: ", bf->types[struc_type_index].name); */ - for (j=0; jtypes[struc_type_index].fieldtypes, ftype); - EXPANDO(bf->types[struc_type_index].fieldnames, fname); - /*dprintf(stderr, "%s %s , ", bf->types[ftype].name, bf->names[fname]); */ - } - } - } - - blend_read_data(file, bf); - - /* Return the new handle */ - - return bf; -} - - -static void free_btype_inner(BlendType *btype) -{ - if (btype->name) { - free(btype->name); - } else { - dprintf(stderr, "null typename.\n"); - } - - if (btype->fieldtypes) { - free(btype->fieldtypes); - } - - if (btype->fieldnames) { - free(btype->fieldnames); - } -} - - -static void free_bfield_inner(BlendField *bfield) -{ - if (bfield->field_bytes) { - free(bfield->field_bytes); - } - - if (bfield->field_offsets) { - free(bfield->field_offsets); - } -} - - -static void free_bblock_inner(BlendBlock *bblock) -{ - int i; - - for (i=0; iarray_entries_count; ++i) { - free_bfield_inner(&bblock->array_entries[i]); - } - free(bblock->array_entries); -} - - -void -blend_free(BlendFile* blend_file) -{ - int i; - - for (i=0; itypes_count; ++i) { - free_btype_inner(&blend_file->types[i]); - } - if (blend_file->types) { - free(blend_file->types); - } - - for (i=0; inames_count; ++i) { - if (blend_file->names[i]) { - free(blend_file->names[i]); - } else { - dprintf(stderr, "null name.\n"); - } - } - if (blend_file->names) { - free(blend_file->names); - } - - for (i=0; iblocks_count; ++i) { - free_bblock_inner(&blend_file->blocks[i]); - } - if (blend_file->blocks) { - free(blend_file->blocks); - } - - if (blend_file->strc_indices) { - free(blend_file->strc_indices); - } - - free(blend_file); -} - - -/******************************************************************** -* done with the reading/parsing logic; now for the querying logic * -********************************************************************/ - - - -/******************************************************************** -* LOW-LEVEL * -********************************************************************/ - - - -const char* -blend_block_get_tagname(BlendFile* blend_file, - BlendBlockPointer block) -{ - const BlendBlock *const bb = block; - return bb->tag; -} - - -const char* -blend_block_get_typename(BlendFile* blend_file, - BlendBlockPointer block) -{ - const BlendBlock *const bb = block; - return blend_file->types[bb->type_index].name; -} - - -int -blend_block_get_entry_count(BlendFile* blend_file, - BlendBlockPointer block) -{ - const BlendBlock *const bb = block; - return bb->array_entries_count;; -} - - -void -blend_foreach_block(BlendFile* blend_file, - BlendBlockCallback* func, - void* userdata) -{ - int i; - for (i=0; iblocks_count; ++i) { - if (!func(&blend_file->blocks[i], blend_file, userdata)) return; - } -} - - -static int -blend_type_basename_compare(const char *fancy, const char *raw) { - const int flen = strlen(fancy); - const int rlen = strlen(raw); - int i, strcmp_result = 123; - - i = 0; - while (i < flen && (fancy[i]=='*' || fancy[i]=='(')) { - ++i; - } - - strcmp_result = strncmp(&fancy[i], raw, rlen); - - if (strcmp_result == 0 && flen > rlen+i) { - i = rlen + i; - if (fancy[i] != ')' && fancy[i] != '(' && fancy[i] != '[') { - strcmp_result = -1; - } - } - - return strcmp_result; -} - - -static BlendObjType -typestring_to_blendobj_type(BlendFile* blend_file, - const char* type_name) -{ - if (blend_type_basename_compare(type_name, "char") == 0) { - return BLEND_OBJ_CHAR8; - } else if (blend_type_basename_compare(type_name, "uchar") == 0) { - return BLEND_OBJ_UCHAR8; - } else if (blend_type_basename_compare(type_name, "short") == 0) { - return BLEND_OBJ_SHORT16; - } else if (blend_type_basename_compare(type_name, "ushort") == 0) { - return BLEND_OBJ_USHORT16; - } else if (blend_type_basename_compare(type_name, "int") == 0) { - return BLEND_OBJ_LONG32; - } else if (blend_type_basename_compare(type_name, "long") == 0) { - return BLEND_OBJ_LONG32; - } else if (blend_type_basename_compare(type_name, "ulong") == 0) { - return BLEND_OBJ_ULONG32; - } else if (blend_type_basename_compare(type_name, "float") == 0) { - return BLEND_OBJ_FLOAT; - } else if (blend_type_basename_compare(type_name, "double") == 0) { - return BLEND_OBJ_DOUBLE; - } else if (blend_type_basename_compare(type_name, "void") == 0) { - return BLEND_OBJ_OPAQUE; - } else { - return BLEND_OBJ_STRUCT; /* structure */ - } -} - - -static BlendObjType -typelong_to_blendobj_type(BlendFile* blend_file, - long btype, long bname) -{ - if (name_is_pointer(blend_file->names[bname])) { - return BLEND_OBJ_POINTER; - } else if (blend_file->types[btype].is_struct) { - return BLEND_OBJ_STRUCT; - } else { - return typestring_to_blendobj_type(blend_file, - blend_file->types[btype].name); - } -} - - -BlendObjType -blend_object_type(BlendFile* blend_file, - BlendObject obj) { - return typelong_to_blendobj_type(blend_file, - obj.type, - obj.name); -} - - -BlendBlockPointer -blend_block_from_blendpointer(BlendFile *blend_file, - uint32_t blendpointer) -{ - int i; - - /* fprintf(stderr, "%04x: ", blendpointer);*/ - - if (blendpointer != 0) { - for (i=0; iblocks_count; ++i) { - /*fprintf(stderr, "%04x? ", blend_file->blocks[i].blender_pointer); */ - if (blend_file->blocks[i].blender_pointer == blendpointer) { - return &blend_file->blocks[i]; - } - } - } - - return NULL; -} - - -static BlendBlockPointer -blend_block_from_object(BlendFile *blend_file, - BlendObject *obj) { - return obj->block; -} - - -int -blend_object_array_getdata(BlendFile* blend_file, - void* dest, BlendObject obj, - int dim_index_1, int dim_index_2) -{ - const char* type_name = blend_file->types[obj.type].name; - const BlendBlock *const bb = obj.block; - BlendField *bf = &bb->array_entries[obj.entry_index]; - void* data; - int dim1, dim2; - - if (!bf) - return 0; - - name_is_array(blend_file->names[obj.name], &dim1, &dim2); - /*dprintf(stderr, "copying:'%s'[%d][%d] (of [%d][%d]) ", type_name, dim_index_1, dim_index_2, dim1, dim2);*/ - - if (dim_index_1 >= dim1 || - dim_index_2 >= dim2) { - dprintf(stderr, "Array index (%d,%d) out of bounds for dimensionality [%d][%d]\n", dim_index_1, dim_index_2, dim1, dim2); - return 0; - } - - data = &bf->field_bytes[bf->field_offsets[obj.field_index + - dim2*dim_index_1 + dim_index_2]]; - /*dprintf(stderr, "fi[%d]byteo[%d]", obj.field_index, - bf->field_offsets[obj.field_index + - dim2*dim_index_1 + dim_index_2]);*/ - - if (name_is_pointer(blend_file->names[obj.name])) { - *(BlendBlockPointer*)dest = - blend_block_from_blendpointer(blend_file, - BGETLEUINT32(data)); - return 1; - } - - /* FIXME: might be a good idea to do less-crappy word-size conversions - here -- these might read beyond the end of malloc'd blocks if we - ever change our field-padding policy. There were endian problems - too; these are believed fixed now. */ - /* The signed conversions look strange because they have to sign-expand - negative results without relying on right-shifts which have undefined - behaviour on negative data according to ANSI C. */ - if (blend_type_basename_compare(type_name, "char") == 0) { - *(char*)dest = (*(char*)data) << (8*sizeof(char)-8) / (1<<(8*sizeof(char)-8)); - } else if (blend_type_basename_compare(type_name, "uchar") == 0) { - *(unsigned char*)dest = *(unsigned char*)data; - } else if (blend_type_basename_compare(type_name, "short") == 0) { - *(int16_t*)dest = BGETLEINT16(data) << (8*sizeof(int16_t)-16) / (1<<(8*sizeof(int16_t)-16)); - } else if (blend_type_basename_compare(type_name, "ushort") == 0) { - *(uint16_t*)dest = BGETLEUINT16(data); - } else if (blend_type_basename_compare(type_name, "int") == 0) { - *(int32_t*)dest = BGETLEINT32(data) << (8*sizeof(int32_t)-32) / (1<<(8*sizeof(int32_t)-32)); - } else if (blend_type_basename_compare(type_name, "long") == 0) { - *(int32_t*)dest = BGETLEINT32(data) << (8*sizeof(int32_t)-32) / (1<<(8*sizeof(int32_t)-32)); - } else if (blend_type_basename_compare(type_name, "ulong") == 0) { - *(uint32_t*)dest = BGETLEUINT32(data); - } else if (blend_type_basename_compare(type_name, "float") == 0) { - *(float*)dest = BGETLEFLOAT32(data); - /*fprintf(stderr, "GOT{%f'%f} ", *(float*)dest, *(float*)data);*/ - } else if (blend_type_basename_compare(type_name, "double") == 0) { - *(double*)dest = BGETLEDOUBLE64(data); - } else if (blend_type_basename_compare(type_name, "void") == 0) { - dprintf(stderr, "Tried to fetch a void.\n"); - return 0; - } else { - dprintf(stderr, "Tried to fetch a whole structure.\n"); - return 0; - } - return 1; /* success */ -} - - -int -blend_object_getdata(BlendFile* blend_file, - void* dest, BlendObject obj) -{ - int dim1, dim2; - - if (name_is_array(blend_file->names[obj.name], &dim1, &dim2)) { - if (dim1 != 1 || dim2 != 1) { - dprintf(stderr, "Tried to fetch a whole array.\n"); - return 0; - } - } - - return (blend_object_array_getdata(blend_file, dest, obj, 0, 0)); -} - - -/* recursively count the number of fields and array items in this -structure, for the purposes of skipping in the field offset array */ -static long -get_num_type_segments(BlendFile* blend_file, - BlendObject obj) -{ - int i; - long rtn = 0; - int dim1,dim2; - - name_is_array(blend_file->names[obj.name], - &dim1, &dim2); - - if (name_is_pointer(blend_file->names[obj.name]) || - !blend_file->types[obj.type].is_struct) { - return (1 * dim1 * dim2); - } - - /* fprintf(stderr, "STRUCTYAYYY ");*/ - - for (i=0; itypes[obj.type].fieldnames_count; ++i) { - BlendObject qo = obj; - qo.type = blend_file->types[obj.type].fieldtypes[i]; - qo.name = blend_file->types[obj.type].fieldnames[i]; - qo.field_index = i; - rtn += get_num_type_segments(blend_file, qo) * dim1 * dim2; - } - - return (rtn); -} - - -int -blend_object_structure_getfield(BlendFile* blend_file, - BlendObject *result, - BlendObject obj, - const char* field_name) -{ - if (blend_file->types[obj.type].is_struct) { - int i; - int field_index = 0; - for (i=0; itypes[obj.type].fieldnames_count; ++i) { - if (blend_type_basename_compare( - blend_file->names[blend_file->types[obj.type].fieldnames[i]], - field_name) - == 0) { - result->type = blend_file->types[obj.type].fieldtypes[i]; - result->name = blend_file->types[obj.type].fieldnames[i]; - result->block = obj.block; - result->entry_index = obj.entry_index; - result->field_index = field_index; - return 1; - } - - { - BlendObject qo = obj; - int fos; - qo.type = blend_file->types[obj.type].fieldtypes[i]; - qo.name = blend_file->types[obj.type].fieldnames[i]; - qo.field_index = field_index; - fos = get_num_type_segments(blend_file, qo); - /*fprintf(stderr, ">>%s %s:%d ", - blend_file->types[qo.type].name, - blend_file->names[qo.name], fos);*/ - field_index += fos; - } - } - return 0; - } else { - dprintf(stderr, "Indexed object isn't a structure!\n"); - return 0; - } -} - - -void -blend_object_array_getdims(BlendFile* blend_file, - BlendObject obj, - int* dim1, int* dim2) -{ - name_is_array(blend_file->names[obj.name], - dim1, dim2); -} - - -BlendObject -blend_block_get_object(BlendFile* blend_file, - BlendBlockPointer block, - int entry_index) -{ - BlendObject bo; - const BlendBlock *const bb = block; - /*BlendField *bf = &bb->array_entries[entry_index]; */ - - bo.type = bb->type_index; - bo.name = blend_file->name_undef; - bo.block = block; - bo.entry_index = entry_index; - bo.field_index = 0; - - return bo; -} - - - - -/******************************************************************** -* MID-LEVEL * -********************************************************************/ - - -/* general helpers */ - - -int -blend_object_getstring(BlendFile* blend_file, - BlendObject obj, - char *dest, int max_chars) -{ - int strpos = 0; - int dim1, dim2; - int rtn = 1; - BlendObjType bo_type; - - name_is_array(blend_file->names[obj.name], - &dim1, &dim2); - - if (dim2 < max_chars) { - max_chars = dim2; - } - - bo_type = blend_object_type(blend_file, obj); - if (! (bo_type==BLEND_OBJ_CHAR8 || bo_type==BLEND_OBJ_UCHAR8)) { - dprintf(stderr, "tried to get string from an object that's not of type uchar/char. (is type %d)\n", bo_type); - rtn = 0; - goto done; - } - - for (strpos=0; strposIDname) { /* don't freak out, but hmm, do we do the right thing? */ - const int strl = strlen(ifd->IDname); - char *obj_string = malloc(3+ strl); - - for (i=0; iIDname) == 0) { - ifd->found = obj; - ifd->success = 1; - want_more = 0; - goto done; - } else { - /* next entry please. */ - } - } - -done:; - free(obj_string); - } - - return want_more; -} - - -int -blend_object_get_by_IDname(BlendFile* blend_file, - BlendObject *result, - const char* IDname) -{ - IDFinderData ifd; - - ifd.success = 0; - ifd.IDname = IDname; - ifd.just_print_it = 0; - - blend_foreach_block(blend_file, block_ID_finder, &ifd); - - if (!ifd.success) { - return 0; - } - - *result = ifd.found; - return 1; -} - - -void -blend_dump_typedefs(BlendFile* bf) -{ - int i; - - /* dump out display of types and their sizes */ - for (i=0; itypes_count; ++i) { - /* if (!bf->types[i].is_struct)*/ - { - printf("%3d: sizeof(%s%s)=%d", - i, - bf->types[i].is_struct ? "struct " : "atomic ", - bf->types[i].name, bf->types[i].size); - if (bf->types[i].is_struct) { - int j; - printf(", %d fields: { ", bf->types[i].fieldtypes_count); - for (j=0; jtypes[i].fieldtypes_count; ++j) { - printf("%s %s", - bf->types[bf->types[i].fieldtypes[j]].name, - bf->names[bf->types[i].fieldnames[j]]); - if (j == bf->types[i].fieldtypes_count-1) { - printf(";}"); - } else { - printf("; "); - } - } - } - printf("\n\n"); - - } - } -} - - -void -blend_dump_blocks(BlendFile* bf) -{ - int i; - IDFinderData ifd; - - ifd.success = 0; - ifd.IDname = NULL; - ifd.just_print_it = 1; - - for (i=0; iblocks_count; ++i) { - BlendBlock* bb = &bf->blocks[i]; - printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", - bb->tag, /*bb->blender_pointer,*/ bb, - bf->types[bb->type_index].name, - bb->array_entries_count); - block_ID_finder(bb, bf, &ifd); - printf("\n"); - } -} - - -int -blend_obj_is_rootobject(BlendFile *bf, BlendObject *objobj) { - BlendObject obj; - BlendBlockPointer block; - if ((blend_object_structure_getfield(bf, &obj, *objobj, "parent") && - blend_object_getdata(bf, &block, obj))) { - return (block == NULL); - } - return 0; -} - - -BlendLayerMask -blend_obj_get_layermask(BlendFile *bf, BlendObject *objobj) { - BlendObject obj; - int32_t ldata; - if ((blend_object_structure_getfield(bf, &obj, *objobj, "lay") && - blend_object_getdata(bf, &ldata, obj))) { - return (BlendLayerMask) ldata; - } - return 0; -} - - -/* Bizarrely, blender doesn't seem to carry a mapping of parent -to children -- only of children to parent. So, to find the children -of an Object we have to scan all objects to see if their parent is -the Object in question. */ -typedef struct { - BlendBlockPointer wanted_parent; - BlendBlockPointer child; - int just_counting; - int num_so_far; - int wanted_index; -} childfinderData; -static BLENDBLOCKCALLBACK_RETURN -block_childfinder(BLENDBLOCKCALLBACK_ARGS) { - childfinderData *cfd = (childfinderData *)userdata; - const char *tagname = blend_block_get_typename(blend_file, block); - int entry_count = blend_block_get_entry_count(blend_file, block); - int want_more = 1; - int i; - - if (strcmp(tagname, "Object") == 0) { - /* Is Object */ - for (i=0; iwanted_parent) { - if ((cfd->num_so_far == cfd->wanted_index) && - !cfd->just_counting) { - cfd->child = block; - want_more = 0; - } - ++cfd->num_so_far; - } else { - cfd->child = NULL; - } - } - } - } - - return want_more; -} - -int -blend_obj_get_childcount(BlendFile *bf, BlendObject *objobj) { - childfinderData cfd; - cfd.wanted_parent = blend_block_from_object(bf, objobj); - cfd.child = NULL; - cfd.just_counting = 1; - cfd.num_so_far = 0; - cfd.wanted_index = 0; - blend_foreach_block(bf, block_childfinder, &cfd); - return cfd.num_so_far; -} - -BlendBlockPointer -blend_obj_get_child(BlendFile *bf, BlendObject *objobj, int childnum) { - childfinderData cfd; - cfd.wanted_parent = blend_block_from_object(bf, objobj); - cfd.child = NULL; - cfd.just_counting = 0; - cfd.num_so_far = 0; - cfd.wanted_index = childnum; - blend_foreach_block(bf, block_childfinder, &cfd); - return cfd.child; -} - - -/******************************************************************** -* HIGH-LEVEL * -********************************************************************/ - -#ifndef LEN3POW2 -/* length squared */ -#define LEN3POW2(xd,yd,zd) ((xd)*(xd) + (yd)*(yd) + (zd)*(zd)) -#endif - -#ifndef LEN3 -/* length (expensive) */ -#define LEN3(xd,yd,zd) (sqrt(LEN3POW2((xd),(yd),(zd)))) -#endif - -#ifndef NORMALIZE3 -/* vector normalization (expensive) */ -#define NORMALIZE3(xd,yd,zd) \ - do { \ - const double norm3_macro_len3 = LEN3((xd),(yd),(zd)); \ - if (norm3_macro_len3 != 0.0F) \ -{ \ - (xd) = (xd) / norm3_macro_len3; \ - (yd) = (yd) / norm3_macro_len3; \ - (zd) = (zd) / norm3_macro_len3; \ -} \ - } while (0) -#endif - - -static void bMatIdentity(bMatrix mat) { - int i,j; - for (i=0; i<4; ++i) { - for (j=0; j<4; ++j) { - mat[i][j] = 0.0f; - } - mat[i][i] = 1.0f; - } -} - -static void bMatMultVec(float xyz[3], bMatrix mat) { - int i; - float r[3]; - for (i=0; i<3; ++i) { - r[i] = 0.0f; - } - for (i=0; i<3; ++i) { - r[i] += xyz[0] * mat[0][i]; - r[i] += xyz[1] * mat[1][i]; - r[i] += xyz[2] * mat[2][i]; - r[i] += 1.0f * mat[3][i]; - } - for (i=0; i<3; ++i) { - xyz[i] = r[i]; - } -} - -bMesh *blend_alloc_mesh(void) { - return malloc(sizeof(bMesh)); -} - -void -blend_init_mesh(bMesh *mesh) -{ - int i,j; - mesh->vert = NULL; - mesh->vert_count = 0; - mesh->face = NULL; - mesh->face_count = 0; - mesh->material = NULL; -} - -void -blend_free_mesh_inner(bMesh *mesh) -{ - if (mesh->vert) { - free(mesh->vert); - } - if (mesh->face) { - free(mesh->face); - } - if (mesh->material) { - blend_free_material(mesh->material); - } -} - -void -blend_free_mesh(bMesh *mesh) -{ - blend_free_mesh_inner(mesh); - free(mesh); -} - - -bObj * -blend_alloc_obj(void) { - return malloc(sizeof(bObj)); -} - -void -blend_init_obj(bObj *obj) { - obj->type = BOBJ_TYPE_UNKNOWN; - obj->name = NULL; - bMatIdentity(obj->transform); - bMatIdentity(obj->parentimat); - obj->location[0] = - obj->location[1] = - obj->location[2] = 0.0f; - obj->scaling[0] = - obj->scaling[1] = - obj->scaling[2] = 1.0f; - obj->rotphr[0] = - obj->rotphr[1] = - obj->rotphr[2] = 0.0f; - obj->data.dummy = NULL; - obj->transflags = 0; -} - -void -blend_free_obj_inner(bObj *obj) { - if (obj->name) { - free(obj->name); - } - switch (obj->type) { - case BOBJ_TYPE_MESH: - blend_free_mesh(obj->data.mesh); - case BOBJ_TYPE_UNKNOWN: - case BOBJ_TYPE_NULL: - default: - break; - } -} - -void -blend_free_obj(bObj *obj) { - blend_free_obj_inner(obj); - free(obj); -} - -void -blend_acquire_obj_from_obj(BlendFile *bf, BlendObject *objobj, - bObj *outobj, BlendObject **mallocdoutblendobject) -{ - - BlendObject obj, dataobj; - BlendBlockPointer block,ipoblock,curveblock=0; - short sdata = 12345; - -#define B_IDNAME_MAX_SIZE 80 - char *idname = malloc(1 + B_IDNAME_MAX_SIZE); - float fdata1, fdata2, fdata3; - - if (mallocdoutblendobject) *mallocdoutblendobject = NULL; - - blend_init_obj(outobj); - - if (!(blend_object_structure_getfield(bf, &obj, *objobj, - "type") && - blend_object_getdata(bf, &sdata, obj))) - { - abort(); /* couldn't get type */ - } else { - switch (sdata) { - case 1: /* mesh */ - outobj->type = BOBJ_TYPE_MESH; break; - case 10: /* lamp */ - outobj->type = BOBJ_TYPE_LAMP; break; - case 11: /* camera */ - outobj->type = BOBJ_TYPE_CAMERA; break; - default: - outobj->type = BOBJ_TYPE_UNKNOWN; break; - } - } - - if (blend_object_get_IDname(bf, *objobj, idname, B_IDNAME_MAX_SIZE)) { - outobj->name = idname; - } else { - free(idname); - abort(); /* couldn't get obj name */ - } - - /* now we override the mesh transform with the object's. should - we merge, instead??? - hm, dunno, don't think so. */ - - - if (blend_object_structure_getfield(bf, &obj, *objobj, "loc") && - blend_object_array_getdata(bf, &fdata1, obj, 0,0) && - blend_object_array_getdata(bf, &fdata2, obj, 0,1) && - blend_object_array_getdata(bf, &fdata3, obj, 0,2)) { - outobj->location[0] = fdata1; - outobj->location[1] = fdata2; - outobj->location[2] = fdata3; - } else { - outobj->location[0] = - outobj->location[1] = - outobj->location[2] = 0.0f; - } - - if (blend_object_structure_getfield(bf, &obj, *objobj, "size") && - blend_object_array_getdata(bf, &fdata1, obj, 0,0) && - blend_object_array_getdata(bf, &fdata2, obj, 0,1) && - blend_object_array_getdata(bf, &fdata3, obj, 0,2)) { - outobj->scaling[0] = fdata1; - outobj->scaling[1] = fdata2; - outobj->scaling[2] = fdata3; - } else { - outobj->scaling[0] = - outobj->scaling[1] = - outobj->scaling[2] = 1.0f; - } - - if (blend_object_structure_getfield(bf, &obj, *objobj, "rot") && - blend_object_array_getdata(bf, &fdata1, obj, 0,0) && - blend_object_array_getdata(bf, &fdata2, obj, 0,1) && - blend_object_array_getdata(bf, &fdata3, obj, 0,2)) { - outobj->rotphr[0] = fdata1; - outobj->rotphr[1] = fdata2; - outobj->rotphr[2] = fdata3; - } else { - outobj->rotphr[0] = - outobj->rotphr[1] = - outobj->rotphr[2] = 0.0f; - } - - if (blend_object_structure_getfield(bf, &obj, *objobj, "parentinv")) { - int i,j; - for (i=0; i<4; ++i) { - for (j=0; j<4; ++j) { - blend_object_array_getdata(bf, &fdata1, obj, i,j); - outobj->parentimat[i][j] = fdata1; - } - } - } -#if 0 - if (blend_object_structure_getfield(bf, &obj, *objobj, "transflag")) { - char cdata; - /* TODO: decode what these flags precisely mean. */ - /* top bit is 'powertrack' */ - if (blend_object_getdata(bf, &cdata, obj)) { - outobj->transflags = (unsigned char)cdata; - } - } -#endif - - outobj->mass = 0.f; - if (blend_object_structure_getfield(bf, &obj, *objobj, "mass")) - { - float mass; - if (blend_object_getdata(bf, &mass, obj)) - { - outobj->mass = mass; - } - } - - - if ((blend_object_structure_getfield(bf, &obj, *objobj,"ipo") && blend_object_getdata(bf, &ipoblock, obj))) - { - if (ipoblock) - { - BlendObject ipo = blend_block_get_object(bf, ipoblock, 0); -#define MAX_CHARS 31 - char iponame[MAX_CHARS]; - BlendObject obj2,obj3; - - blend_object_get_IDname(bf,ipo,iponame,MAX_CHARS-1); -// printf("ipo.ID.name = %s\n",iponame); - - if (blend_object_structure_getfield(bf, &obj2, ipo,"curve")) - { - BlendBlock* block = (BlendBlock*)obj2.block; - - - void** ptrptr = &block->array_entries->field_bytes[block->array_entries->field_offsets[obj2.field_index]]; - BlendBlockPointer ptr = *ptrptr; - //ptrptr++; contains the 'last' pointer - if (ptr) - { - BlendBlockPointer curveblockptr = blend_block_from_blendpointer(bf, ptr); - BlendObject curve = blend_block_get_object(bf, curveblockptr, 0); - - } - - } - - - } - } - - - - - outobj->boundtype = 0; - if (blend_object_structure_getfield(bf, &obj, *objobj, "boundtype")) - { - short int boundtype; - if (blend_object_getdata(bf, &boundtype, obj)) - { - outobj->boundtype= boundtype; - } - } - - outobj->gameflag = 0; - if (blend_object_structure_getfield(bf, &obj, *objobj, "gameflag")) - { - int gameflag; - if (blend_object_getdata(bf, &gameflag, obj)) - { - outobj->gameflag= gameflag; - } - } - - - - - if (blend_object_structure_getfield(bf, &obj, *objobj, "obmat")) { - int i,j; - for (i=0; i<4; ++i) { - for (j=0; j<4; ++j) { - blend_object_array_getdata(bf, &fdata1, obj, i,j); - outobj->transform[i][j] = fdata1; - dprintf(stderr, "%0.3f ", fdata1); - } - dprintf(stderr, "\n"); - } - } - - /* get actual mesh obj here */ - - if (! (blend_object_structure_getfield(bf, &obj, *objobj, "data") && - blend_object_getdata(bf, &block, obj))) - { - printf("no mesh\n"); - outobj->data.mesh = 0; - return; - //abort(); - } - - if (block == NULL) { - outobj->type = BOBJ_TYPE_NULL; - } else { - dataobj = blend_block_get_object(bf, block, 0); - if (mallocdoutblendobject) { - *mallocdoutblendobject = malloc(sizeof(BlendObject)); - **mallocdoutblendobject = dataobj; - } - } - - - switch (outobj->type) { - case BOBJ_TYPE_MESH: - outobj->data.mesh = blend_alloc_mesh(); - blend_acquire_mesh_from_obj(bf, &dataobj, outobj->data.mesh); - break; - case BOBJ_TYPE_UNKNOWN: - default: - case BOBJ_TYPE_NULL: - outobj->data.dummy = NULL; - break; - } - -} - - - -bTexLayer * -blend_alloc_texlayer(void) { - return malloc(sizeof(bTexLayer)); -} - -void -blend_init_texlayer(bTexLayer *tl) { - tl->filename = NULL; - tl->affects_mask = 0; - tl->blend_mode = BTEX_BLEND_NORMAL; - tl->coords_type = BTEX_COORDS_NONE; - tl->is_st_clamped = 0; - tl->flags = 0; - tl->Nflags = tl->Ntype = 0; - tl->xrepeat = tl->yrepeat = 1; -} - -static void -blend_free_texlayer_inner(bTexLayer *tl) { - if (tl->filename) { - free(tl->filename); - } -} - -void -blend_free_texlayer(bTexLayer *tl) { - blend_free_texlayer_inner(tl); - free(tl); -} - - -void /* MTex */ -blend_acquire_texlayer_from_obj(BlendFile *bf, BlendObject *tlobj, - bTexLayer *tl) -{ - BlendObject obj; - BlendBlockPointer tex_block; - short sdata = 12345; - - blend_init_texlayer(tl); - - if (!(blend_object_structure_getfield(bf, &obj, *tlobj, - "mapto") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } - if (sdata & 0x01) { - tl->affects_mask |= BTEX_AFFECT_COLOUR; - } - if (sdata & 0x40) { - tl->affects_mask |= BTEX_AFFECT_EMIT; - } - if (sdata & 0x80) { - tl->affects_mask |= BTEX_AFFECT_ALPHA; - } - /* note: mapto not fully decoded. */ - - if (!(blend_object_structure_getfield(bf, &obj, *tlobj, - "texflag") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } - if (sdata & 0x02) { - tl->affects_mask |= BTEX_AFFECT_STENCIL; - } - - if (!(blend_object_structure_getfield(bf, &obj, *tlobj, - "texco") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } - switch (sdata) { - case 1: - case 2: - tl->coords_type = BTEX_COORDS_REFLECT; - break; - case 16: - tl->coords_type = BTEX_COORDS_UV; - break; - default: - /* I haven't seen this happen, but it probably does... */ - tl->coords_type = BTEX_COORDS_NONE; - break; - } - - if (!(blend_object_structure_getfield(bf, &obj, *tlobj, - "blendtype") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } - tl->blend_mode = sdata; /* not decoded yet :( */ - - if (blend_object_structure_getfield(bf, &obj, *tlobj, "tex") && - blend_object_getdata(bf, &tex_block, obj) && tex_block) { - BlendObject tobj = blend_block_get_object(bf, tex_block, 0); - BlendBlockPointer im_block; - BlendObject obj; - - if (!(blend_object_structure_getfield(bf, &obj, tobj, "extend") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } - tl->is_st_clamped = !(sdata & 2 /*'repeat'*/); - /*fprintf(stderr, "CLAMP=%d (was %d)\n", tl->is_st_clamped, sdata);*/ - if (!(blend_object_structure_getfield(bf, &obj, tobj, "xrepeat") && - blend_object_getdata(bf, &sdata, obj))) { - tl->xrepeat = 1; - } else { - tl->xrepeat = sdata; - } - if (!(blend_object_structure_getfield(bf, &obj, tobj, "yrepeat") && - blend_object_getdata(bf, &sdata, obj))) { - tl->yrepeat = 1; - } else { - tl->yrepeat = sdata; - } - if (!(blend_object_structure_getfield(bf, &obj, tobj, "flag") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } else { - tl->flags = sdata; - } - if (!(blend_object_structure_getfield(bf, &obj, tobj, "imaflag") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } else { - if (sdata & 0x0001) { - tl->flags |= BIMG_FLAG_INTERPOLATE; - } - if (sdata & 0x0004) { - tl->flags |= BIMG_FLAG_MIPMAP; - } - if (sdata & 0x0100) { - tl->flags |= BIMG_FLAG_ANTIALIAS; - } - } - if (!(blend_object_structure_getfield(bf, &obj, tobj, "type") && - blend_object_getdata(bf, &sdata, obj))) { - abort(); - } else { - tl->Ntype = sdata; - } - if (blend_object_structure_getfield(bf, &obj, tobj, "ima") && - blend_object_getdata(bf, &im_block, obj) && im_block) { - BlendObject imobj = blend_block_get_object(bf, im_block, 0); -#define BF_IMAGE_FILENAME_MAXSIZE 160 - tl->filename = malloc(BF_IMAGE_FILENAME_MAXSIZE); - if (!(blend_object_structure_getfield(bf, &obj, imobj, "name") && - blend_object_getstring(bf, obj, - tl->filename, BF_IMAGE_FILENAME_MAXSIZE))) { - abort(); - } - } - } else { - abort(); - } -} - - -bMaterial * -blend_alloc_material(void) { - return malloc(sizeof(bMaterial)); -} - -void -blend_init_material(bMaterial *mat) { - int i; - for (i=0; itex_layer[i] = NULL; - } - mat->feature_mask = 0; - for (i=0; i<4; ++i) { - mat->colour_rgba[i] = 1.0f; - } - mat->emit = 0.0f; -} - -void -blend_free_material(bMaterial *mat) { - int i; - for (i=0; itex_layer[i]) { - blend_free_texlayer(mat->tex_layer[i]); - } - } -} - -void -blend_acquire_material_from_obj(BlendFile *bf, BlendObject *matobj, - bMaterial *mat) -{ - BlendObject obj; - int i; - int32_t ldata = 123456; - float fdata = 123456.0; - - blend_init_material(mat); - - if ((blend_object_structure_getfield(bf, &obj, *matobj, "r") && - blend_object_getdata(bf, &fdata, obj))) { - mat->colour_rgba[0] = fdata; - } - if ((blend_object_structure_getfield(bf, &obj, *matobj, "g") && - blend_object_getdata(bf, &fdata, obj))) { - mat->colour_rgba[1] = fdata; - } - if ((blend_object_structure_getfield(bf, &obj, *matobj, "b") && - blend_object_getdata(bf, &fdata, obj))) { - mat->colour_rgba[2] = fdata; - } - if ((blend_object_structure_getfield(bf, &obj, *matobj, "alpha") && - blend_object_getdata(bf, &fdata, obj))) { - mat->colour_rgba[3] = fdata; - } - if ((blend_object_structure_getfield(bf, &obj, *matobj, "emit") && - blend_object_getdata(bf, &fdata, obj))) { - mat->emit = fdata; - } - - if (!(blend_object_structure_getfield(bf, &obj, *matobj, "mode") && - blend_object_getdata(bf, &ldata, obj))) { - abort(); - } - if (ldata & 0x04) { - mat->feature_mask |= BMAT_FEATURE_SHADELESS; - } - if (ldata & 0x08) { - mat->feature_mask |= BMAT_FEATURE_WIRE; - } - if (ldata & 0x10) { - mat->feature_mask |= BMAT_FEATURE_VCOLLIGHT; - } - if (ldata & 0x80) { - mat->feature_mask |= BMAT_FEATURE_VCOLPAINT; - } - if (ldata & (1024 | 512 | 256)) { /* not sure about this, it's strange. */ - mat->feature_mask |= BMAT_FEATURE_TEXFACE; - } - - for (i=0; itex_layer[i] = blend_alloc_texlayer(); - /*fprintf(stderr, "GETTING LAYER AT POS %d\n", i);*/ - blend_acquire_texlayer_from_obj(bf, &tlobj, mat->tex_layer[i]); - } else { - /*fprintf(stderr, "NOTHING FOUND AT POS %d\n", i);*/ - } - } -} - -void -blend_acquire_mesh_from_obj(BlendFile *bf, BlendObject *meobj, bMesh *mesh) -{ - { - BlendObject obj; - BlendBlockPointer vblock, fblock, cblock, ttblock,mtblock,dblock, matlink; - int i; - int32_t ldata = 123456; - float fdata1, fdata2, fdata3; - - blend_init_mesh(mesh); - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "totvert") && - blend_object_getdata(bf, &ldata, obj))) - { - printf("invalid mesh 0x1\n"); - meobj->type = BOBJ_TYPE_INVALID_MESH; - return; - } - mesh->vert_count = ldata; - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "totface") && - blend_object_getdata(bf, &ldata, obj))) - { - printf("invalid mesh 0x2\n"); - meobj->type = BOBJ_TYPE_INVALID_MESH; - return; - } - mesh->face_count = ldata; - - dprintf(stderr, "%d verts, %d faces...\n", mesh->vert_count, mesh->face_count); - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "mface") && - blend_object_getdata(bf, &fblock, obj))) - { - printf("invalid mesh 0x3\n"); - meobj->type = BOBJ_TYPE_INVALID_MESH; - return; - } - /* null fblock is okay */ - - if (blend_object_structure_getfield(bf, &obj, *meobj, - "mat") && - blend_object_getdata(bf, &matlink, obj) && matlink) { - /* found an indirect material link, follow it */ - BlendObject matlinkobj = blend_block_get_object(bf, matlink, 0); - BlendBlockPointer matblock; - if (obj.block) - { - if (blend_object_structure_getfield(bf, &obj, matlinkobj, - "next") && - blend_object_getdata(bf, &matblock, obj)) { - if (matblock) { - BlendObject matobj = blend_block_get_object(bf, matblock, 0); - mesh->material = blend_alloc_material(); - blend_acquire_material_from_obj(bf, &matobj, mesh->material); - } else { - /* um, okay, link went nowhere, leave mesh->material NULL */ - } - } else { - //abort();//might fail? - } - } - } else { - /* no material -- mesh->material will remain NULL */ - } - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "mvert") && - blend_object_getdata(bf, &vblock, obj))) { - abort(); - } - /* null vblock is okay */ - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "tface") && - blend_object_getdata(bf, &ttblock, obj))) { - abort(); - } - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "mtface") && - blend_object_getdata(bf, &mtblock, obj))) { - mtblock=0; - } - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "mcol") && - blend_object_getdata(bf, &cblock, obj))) { - abort(); - } - - if (!(blend_object_structure_getfield(bf, &obj, *meobj, - "dvert") && - blend_object_getdata(bf, &dblock, obj))) { - /* sometimes there isn't a dvert block... */ - dblock = NULL; - } - - mesh->vert = malloc(sizeof(bVert) * mesh->vert_count); - - for (i=0; ivert_count; ++i) { - BlendObject obj = blend_block_get_object(bf, vblock, i); - BlendObject aobj; - float fdata1, fdata2, fdata3; - int32_t sdata1, sdata2, sdata3; - char cdata; - - mesh->vert[i].xyz[0] = - mesh->vert[i].xyz[1] = - mesh->vert[i].xyz[2] = -12345; - mesh->vert[i].cnormal[0] = - mesh->vert[i].cnormal[1] = - mesh->vert[i].cnormal[2] = -12345; - mesh->vert[i].mat = -1; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "co") && - blend_object_array_getdata(bf, &fdata1, aobj, 0,0) && - blend_object_array_getdata(bf, &fdata2, aobj, 0,1) && - blend_object_array_getdata(bf, &fdata3, aobj, 0,2))) { - abort(); - } - mesh->vert[i].xyz[0] = fdata1; - mesh->vert[i].xyz[1] = fdata2; - mesh->vert[i].xyz[2] = fdata3; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "no") && - blend_object_array_getdata(bf, &sdata1, aobj, 0,0) && - blend_object_array_getdata(bf, &sdata2, aobj, 0,1) && - blend_object_array_getdata(bf, &sdata3, aobj, 0,2))) { - abort(); - } - mesh->vert[i].cnormal[0] = sdata1; - mesh->vert[i].cnormal[1] = sdata2; - mesh->vert[i].cnormal[2] = sdata3; - /*fprintf(stderr, "%f ", LEN3(mesh->vert[i].normal[0], - mesh->vert[i].normal[1], - mesh->vert[i].normal[2]));*/ - if (sdata1 != 0 || sdata2 != 0 || sdata3 != 0) { - NORMALIZE3(mesh->vert[i].cnormal[0], - mesh->vert[i].cnormal[1], - mesh->vert[i].cnormal[2]); - } - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "mat_nr") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->vert[i].mat = cdata; - } - - mesh->face = malloc(sizeof(bFace) * mesh->face_count); - - for (i=0; iface_count; ++i) { - int j,k; - BlendObject obj = blend_block_get_object(bf, fblock, i); - BlendObject aobj; - char cdata; - - mesh->face[i].v[0] = mesh->face[i].v[1] = - mesh->face[i].v[2] = mesh->face[i].v[3] = -1; - mesh->face[i].mat = -1; - mesh->face[i].flags = 0; - - for (j=0; j<4; ++j) { - for (k=0; k<3; ++k) { - mesh->face[i].rgba[j][k] = 1.0; - } - mesh->face[i].rgba[j][3] = 1.0f; - mesh->face[i].uv[j][0] = 0.0f; - mesh->face[i].uv[j][1] = 0.0f; - mesh->face[i].m_image = NULL; - } - - if (blend_object_structure_getfield(bf, &aobj, obj, "v1")) { - if (0!=strcmp(bf->types[aobj.type].name,"int") && - 0!=strcmp(bf->types[aobj.type].name,"ushort")) { - dprintf(stderr, "Expected vertex-index type to be 'ushort' or 'int', got '%s'\n", bf->types[aobj.type].name); - abort(); - } - - if (0==strcmp(bf->types[aobj.type].name,"int")) { - /* index type is a 32bit int, generated by newish Blenders */ - int32_t idata; - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v1") && - blend_object_getdata(bf, &idata, aobj))) { - abort(); - } - mesh->face[i].v[0] = idata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v2") && - blend_object_getdata(bf, &idata, aobj))) { - abort(); - } - mesh->face[i].v[1] = idata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v3") && - blend_object_getdata(bf, &idata, aobj))) { - abort(); - } - mesh->face[i].v[2] = idata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v4") && - blend_object_getdata(bf, &idata, aobj))) { - abort(); - } - mesh->face[i].v[3] = idata; - } else { - /* index type is a 16bit ushort, generated by old Blenders */ - uint16_t usdata; - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v1") && - blend_object_getdata(bf, &usdata, aobj))) { - abort(); - } - mesh->face[i].v[0] = usdata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v2") && - blend_object_getdata(bf, &usdata, aobj))) { - abort(); - } - mesh->face[i].v[1] = usdata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v3") && - blend_object_getdata(bf, &usdata, aobj))) { - abort(); - } - mesh->face[i].v[2] = usdata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "v4") && - blend_object_getdata(bf, &usdata, aobj))) { - abort(); - } - mesh->face[i].v[3] = usdata; - } - } else { - abort(); - } - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "mat_nr") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->face[i].mat = cdata; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "flag") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->face[i].flags = cdata; - } - - if (cblock) { - /* we have vertex colours */ - for (i=0; iface_count; ++i) { - int j; - unsigned char cdata; - BlendObject aobj; - for (j=0; j<4; ++j) { - BlendObject obj = blend_block_get_object(bf, cblock, i*4+j); - if (!(blend_object_structure_getfield(bf, &aobj, obj, "b") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->face[i].rgba[j][0] = cdata / 255.0f; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "g") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->face[i].rgba[j][1] = cdata / 255.0f; - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "r") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->face[i].rgba[j][2] = cdata / 255.0f; - - /* alpha seems to be nonsense :( */ - /* - if (!(blend_object_structure_getfield(bf, &aobj, obj, "a") && - blend_object_getdata(bf, &cdata, aobj))) { - abort(); - } - mesh->face[i].rgba[j][3] = cdata / 255.0f; - */ - mesh->face[i].rgba[j][3] = 1.0f; - } - } - } else { - /* !cblock (no vertex colours) */ - for (i=0; iface_count; ++i) { - int j; - for (j=0; j<4; ++j) { - mesh->face[i].rgba[j][0] = 1.0f; - mesh->face[i].rgba[j][1] = 1.0f; - mesh->face[i].rgba[j][2] = 1.0f; - mesh->face[i].rgba[j][3] = 1.0f; - } - } - } - - if (mtblock) - { - /* we have tex co-ords */ - for (i=0; iface_count; ++i) - { - int j,k; - void *pdata; - BlendObject aobj; - BlendObject obj = blend_block_get_object(bf, mtblock, i); - BlendObject obj2,obj3; - unsigned char flag; - unsigned short int mode; - - BlendBlockPointer tpageptr; - - if (blend_object_structure_getfield(bf, &obj3, obj, "flag")) - { - blend_object_getdata(bf, &flag, obj3); - mesh->face[i].m_flag = flag; - } else - { - mesh->face[i].m_flag = 0; - } - - if (blend_object_structure_getfield(bf, &obj3, obj, "mode")) - { - blend_object_getdata(bf, &mode, obj3); - mesh->face[i].m_mode = mode; - } else - { - mesh->face[i].m_mode = 0; - } - - if ((blend_object_structure_getfield(bf, &obj3, obj, "tpage") - && blend_object_getdata(bf, &tpageptr, obj3))) - { - - mesh->face[i].m_image = 0; - - for (j=0; j<4; ++j) - { - uint32_t uldata; - for (k=0; k<2; ++k) { - float fdata; - if (!(blend_object_structure_getfield(bf, &aobj, obj, "uv") && - blend_object_array_getdata(bf, &fdata, aobj, j,k))) { - abort(); - } - mesh->face[i].uv[j][k] = fdata; - } - mesh->face[i].uv[j][1] = 1.0f - mesh->face[i].uv[j][1]; - /* texture face colour... not sure how this conceptually - differs from the face vertex colours, but it does. */ - - /* in its usual inconsistant style, blender packs this - RGBA value into the bytes of an unsigned long... */ - - } - - //printf("got tpage\n"); - - { - int k; - for (k=0;kface[i].m_image=tCachedImages[k]; - break; - } - } - } - - if (!mesh->face[i].m_image) - { - bImage* bimg= (bImage*)malloc (sizeof(bImage)); - tCachedImages[gNumCachedImages]=bimg; - tCachedTPage[gNumCachedImages] = tpageptr; - gNumCachedImages++; - mesh->face[i].m_image = bimg; - bimg->m_packedImagePtr = 0; - bimg->m_sizePackedImage = 0; - - if (tpageptr) - { - BlendObject name_block; - BlendObject tpage = blend_block_get_object(bf,tpageptr,0); - - BlendObject okblock; - - - if ((blend_object_structure_getfield(bf, &okblock, tpage, "ok"))) - { - short int okval; - if (blend_object_getdata(bf,&okval,okblock)) - { -// printf("ok=%d\n",okval); - bimg->m_ok = okval; - } else - { - bimg->m_ok=0; - } - - } - - if ((blend_object_structure_getfield(bf, &okblock, tpage, "xrep"))) - { - short int xrep; - if (blend_object_getdata(bf,&xrep,okblock)) - { -// printf("xrep=%d\n",xrep); - bimg->m_xrep = xrep; - } else - { - bimg->m_xrep = 0; - } - } - - if ((blend_object_structure_getfield(bf, &okblock, tpage, "yrep"))) - { - short int yrep; - if (blend_object_getdata(bf,&yrep,okblock)) - { -// printf("yrep=%d\n",yrep); - bimg->m_yrep = yrep; - } else - { - bimg->m_yrep = 0; - } - } - - mesh->face[i].image_id = 0; - { - BlendBlockPointer packptr; - - if ((blend_object_structure_getfield(bf, &obj3, tpage, "packedfile") - && blend_object_getdata(bf, &packptr, obj3))) - { - if (packptr) - { - BlendObject packfile= blend_block_get_object(bf,packptr,0); - BlendBlockPointer dataptr; - if ((blend_object_structure_getfield(bf, &obj3, packfile, "data") - && blend_object_getdata(bf, &dataptr, obj3))) - { - /*BlendObject data= blend_block_get_object(bf,dataptr,0); - char dest[1024]; - blend_object_getstring(bf,data,dest,1023); - */ - -// printf("...\n"); - - //if (blend_object_structure_getfield(bf, &obj2, ipo,"curve")) - { - BlendBlock* block = (BlendBlock*)obj3.block; - - - void** ptrptr = &block->array_entries->field_bytes[block->array_entries->field_offsets[obj3.field_index]]; - BlendBlockPointer ptr = *ptrptr; - if (ptr) - { - BlendBlockPointer curveblockptr = blend_block_from_blendpointer(bf, ptr); - BlendObject curve = blend_block_get_object(bf, curveblockptr, 0); - BlendBlock* bb = (BlendBlock* )curve.block; - BlendBlock imgblock; - mesh->face[i].image_id = bb->blender_pointer; - //imgblock = blend_block_get_object(bf, bb->blender_pointer, 0); - bimg->m_packedImagePtr = bb->customData; - bimg->m_sizePackedImage = bb->customDataSize; - } - - } - } - - - } - - } - } - - - - - if ((blend_object_structure_getfield(bf, &name_block, tpage, "name"))) - { - int max_chars=127; - - if (blend_object_getstring(bf,name_block,bimg->m_imagePathName, max_chars)) - { -// printf("texname=%s\n",bimg->m_imagePathName); - } - - } - - - - } - - } - - - } - - - - - } - } - else - { - if (ttblock) { - /* we have tex co-ords */ - for (i=0; iface_count; ++i) { - int j,k; - void *pdata; - BlendObject aobj; - BlendObject obj = blend_block_get_object(bf, ttblock, i); - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "tpage") && - blend_object_getdata(bf, &pdata, aobj))) { - abort(); - } - mesh->face[i].image_id = pdata; - - for (j=0; j<4; ++j) { - uint32_t uldata; - for (k=0; k<2; ++k) { - float fdata; - if (!(blend_object_structure_getfield(bf, &aobj, obj, "uv") && - blend_object_array_getdata(bf, &fdata, aobj, j,k))) { - abort(); - } - mesh->face[i].uv[j][k] = fdata; - } - mesh->face[i].uv[j][1] = 1.0f - mesh->face[i].uv[j][1]; - /* texture face colour... not sure how this conceptually - differs from the face vertex colours, but it does. */ - if (!(blend_object_structure_getfield(bf, &aobj, obj, "col") && - blend_object_array_getdata(bf, &uldata, aobj, 0,j))) { - abort(); - } - /* in its usual inconsistant style, blender packs this - RGBA value into the bytes of an unsigned long... */ - mesh->face[i].rgba2[j][0] = ((uldata >> 24) & 0xFF) / 255.0f; - mesh->face[i].rgba2[j][1] = ((uldata >> 16) & 0xFF) / 255.0f; - mesh->face[i].rgba2[j][2] = ((uldata >> 8) & 0xFF) / 255.0f; - mesh->face[i].rgba2[j][3] = ((uldata >> 0) & 0xFF) / 255.0f; - } - /*mesh->face[i].uv[0][0]=0; mesh->face[i].uv[0][1]=0; - mesh->face[i].uv[1][0]=1; mesh->face[i].uv[1][1]=0; - mesh->face[i].uv[2][0]=1; mesh->face[i].uv[2][1]=1; - mesh->face[i].uv[3][0]=0; mesh->face[i].uv[3][1]=1;*/ - - } - } else { - /* !tblock (no texture co-ords, no face tex-colours) */ - for (i=0; iface_count; ++i) { - int j; - for (j=0; j<4; ++j) { - mesh->face[i].rgba2[j][0] = 1.0f; - mesh->face[i].rgba2[j][1] = 1.0f; - mesh->face[i].rgba2[j][2] = 1.0f; - mesh->face[i].rgba2[j][3] = 1.0f; - } - } - } - } - - if (mtblock) - { - BlendObject obj = blend_block_get_object(bf, mtblock, 0); - - //6155 - } - - - if (dblock) { - /* we have vertex deformation weights */ - for (i=0; ivert_count; ++i) { - int j; - int32_t ldata; - float fdata; - BlendBlockPointer pdata; - BlendObject aobj; - BlendObject obj = blend_block_get_object(bf, dblock, i); - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "totweight") && - blend_object_getdata(bf, &ldata, aobj))) { - abort(); - } - mesh->vert[i].deform_weights_count = ldata; - mesh->vert[i].deform_weights = malloc(ldata*sizeof(bDeformWeight)); - - if (!(blend_object_structure_getfield(bf, &aobj, obj, "dw") && - blend_object_getdata(bf, &pdata, aobj))) { - abort(); - } - - for (j=0; jvert[i].deform_weights_count; ++j) { - BlendObject dwobj = blend_block_get_object(bf, pdata, j); - - if (!(blend_object_structure_getfield(bf, &aobj, dwobj, "def_nr") - && blend_object_getdata(bf, &ldata, aobj))) { - abort(); - } - mesh->vert[i].deform_weights[j].bone_id = ldata; - - if (!(blend_object_structure_getfield(bf, &aobj, dwobj, "weight") - && blend_object_getdata(bf, &fdata, aobj))) { - abort(); - } - mesh->vert[i].deform_weights[j].weight = fdata; - } - } - } else { - /* !dblock (no vertex deformation weights) */ - for (i=0; ivert_count; ++i) { - mesh->vert[i].deform_weights = NULL; - mesh->vert[i].deform_weights_count = 0; - } - } - } -} - - - -void -blend_acquire_mesh(const char *fname, const char *want_name, bMesh *mesh) -{ - BlendFile* bf; - MY_FILETYPE *fp; - - fp = MY_OPEN_FOR_READ(fname); - - if (!fp) { - dprintf(stderr, "couldn't open file %s.\n", fname); - abort(); - } - - bf = blend_read(fp); - { - BlendObject meobj; - if (!blend_object_get_by_IDname(bf, &meobj, want_name)) { - dprintf(stderr, "couldn't find %s.\n", want_name); - abort(); - } - blend_dump_blocks(bf); - blend_acquire_mesh_from_obj(bf, &meobj, mesh); - } - blend_free(bf); - - MY_CLOSE(fp); -} - - -/* apply pitch, head, roll */ -static void bRotPHR(float xyz[3], const float rot[3]) { - float rx,ry,rz; - float ix,iy,iz; - float cosang, sinang; - - ix = xyz[0]; iy = xyz[1]; iz = xyz[2]; - - cosang = cos(rot[0]); - sinang = sin(rot[0]); - /* pitch */ - rx = ix; - ry = iy * cosang - iz * sinang; - rz = iy * sinang + iz * cosang; - - ix = rx; iy = ry; iz = rz; - - cosang = cos(rot[1]); - sinang = sin(rot[1]); - /* head */ - rx = ix * cosang + iz * sinang; - ry = iy; - rz = -ix * sinang + iz * cosang; - - ix = rx; iy = ry; iz = rz; - - cosang = cos(rot[2]); - sinang = sin(rot[2]); - /* roll */ - rx = ix * cosang - iy * sinang; - ry = ix * sinang + iy * cosang; - rz = iz; - - xyz[0] = rx; xyz[1] = ry; xyz[2] = rz; -} - - -void -blend_transform_mesh_from_obj(bMesh *mesh, bObj *obj) { - int i; - for (i=0; ivert_count; ++i) { - /* this one looks good. */ - bMatMultVec(mesh->vert[i].xyz, obj->transform); - bRotPHR(mesh->vert[i].cnormal, obj->rotphr); - } -} - diff --git a/Extras/readblend/readblend.h b/Extras/readblend/readblend.h deleted file mode 100644 index 102686049..000000000 --- a/Extras/readblend/readblend.h +++ /dev/null @@ -1,492 +0,0 @@ -/*************************************************************** - * readblend.h -- - * ReadBlend, a data extraction API for Blender's .blend files - * - * (c) 2003 Adam D. Moss - * - */ - -/* VERSION HISTORY - * 2003-04-05 : v1.0 - * 2008-10-05 : v1.1-beta - */ - -/* Blender files are 'curiously' structured and this is mirrored in - * the low-level data access API (the section labelled 'Low-level - * querying functions'). - * - * The mid-level data access API (the section labelled 'Mid-level - * querying functions') tries to provide some handy utilities to - * ease your data-extraction pain, and finally the (partially written) - * high-level data access API incorporates semantic knowledge of Blender's - * useful high-level types such as Meshes and Materials to shield you - * from the full horror. - */ -#ifndef _READBLEND_H -#define _READBLEND_H - -#include -//#include -#include -#include //size_t for MSVC 6.0 - -//#include -#include - -#include "abs-file.h" - -/* TODO: Doxygen me. */ - - -#include "blendtype.h" - -#ifdef __cplusplus -extern "C" { -#endif - - - -/**************************************/ -/* .blend handle load/free functions */ -/*************************************/ - - -/* Pass in an already-opened file handle; this function will then - examine the file to check that it is a Blender file and scan the - entire file to extract all vital information (quite expensive) - before any query operations can be performed. The resulting - .blend data handle is returned. -*/ - -BlendFile* blend_read(MY_FILETYPE* file); - - -/* Free all of the given BlendFile data (note: obviously, do not attempt - to extract data from a BlendFile which has been freed!) */ - -void blend_free(BlendFile* blend_file); - - -/********************************/ -/* Public data querying types */ -/********************************/ - - -/* heed this enum well. */ -typedef enum { - /* you're unlikely to encounter these in the wild. */ - BLEND_OBJ_NULL, - BLEND_OBJ_OPAQUE, - - /* these object types are fetchable as-is */ - BLEND_OBJ_UCHAR8, - BLEND_OBJ_CHAR8, - BLEND_OBJ_USHORT16, - BLEND_OBJ_SHORT16, - BLEND_OBJ_ULONG32, - BLEND_OBJ_LONG32, - BLEND_OBJ_FLOAT, - BLEND_OBJ_DOUBLE, - BLEND_OBJ_POINTER, - - /* you'll need to extract the fields from these individually */ - BLEND_OBJ_STRUCT -} BlendObjType; - -typedef void* BlendBlockPointer; - -/* note: treat this as an opaque type and you'll live longer. */ -typedef struct { - long type; long name; BlendBlockPointer block; - long entry_index; long field_index; -} BlendObject; - - -/* The callback type for passing to blend_foreach_block() (the callback - should return zero if it doesn't want to see any more blocks.) */ -#define BLENDBLOCKCALLBACK_RETURN int -#define BLENDBLOCKCALLBACK_ARGS BlendBlockPointer block, \ - BlendFile* blend_file, \ - void* userdata -typedef BLENDBLOCKCALLBACK_RETURN(BlendBlockCallback) - (BLENDBLOCKCALLBACK_ARGS); - - -/********************************/ -/* File info dumping functions */ -/********************************/ - -/* these functions simply print dumps of information about the given - BlendFile. These are vital for familiarising yourself with the - structure of Blender's various scene objects if you're using the - low/mid-level APIs to construct queries to extract information about - specific types of objects that haven't been conveniently abstracted by - the high-level API yet. (That is, most of them right now, particularly - the more obscure or deprecated ones.) */ - -/* print out the size, field-types and field-names of all of the varieties - of types (atomic and struct) represented within this BlendFile. The - sizes are the in-file representations; the in-memory representations - are potentially subject to additional padding and conversions. -*/ -void blend_dump_typedefs(BlendFile* bf); - -/* For every top-level block of data in the file, print the block's - tag, its in-memory address, its type, and the number of entries of that - type. (Every pointer in a structure should point to one of these - in-memory block addresses because we convert from in-file pointers to - in-memory pointers automagically; a few in-file pointers within structures - do actually point somewhere into the middle of a block or nowhere, which we - don't currently support and silently convert to NULL.) Also, any structs - at the top-level with an id->name have that name printed out. */ -void blend_dump_blocks(BlendFile* bf); - - -/********************************/ -/* Low-level querying functions */ -/********************************/ - - -/* Calls the user-supplied callback function for every top-level - data block in the .blend file. You can use this to count blocks - (which is pretty pointless) or search for a particular block you're - interested in. */ -void blend_foreach_block(BlendFile* blend_file, - BlendBlockCallback* func, - void* userdata); - -/* Returns the tag-name ('IM', 'DATA', 'ME', etc) for the given - top-level data block. */ -const char* blend_block_get_tagname(BlendFile* blend_file, - BlendBlockPointer block); - -/* Returns the type of the given top-level data block in raw - string form ('uchar', 'float', 'MFace', 'Mesh', etc). */ -const char* blend_block_get_typename(BlendFile* blend_file, - BlendBlockPointer block); - -/* Translate a pointer from the file's raw data into a BlendBlockPointer - that you can query via the API. You will usually NOT need to ever - use this unless you're manually extracting pointers from opaque raw data - types. Returns NULL on failure or if the input pointer is really NULL. */ -BlendBlockPointer blend_block_from_blendpointer(BlendFile *blend_file, - uint32_t blendpointer); - -/* Returns the number of entries there are in the given top-level - data block (a top-level data block is like an array of entries of a specific - Blender type, this type usually being one of Blender's structs). */ -int blend_block_get_entry_count(BlendFile* blend_file, - BlendBlockPointer block); - -/* This gets an object handle on the Nth piece of data (in the range - 0..TOTAL-1, where TOTAL is the figure returned by - blend_block_get_entry_count() ) in the given top-level block. */ -BlendObject blend_block_get_object(BlendFile* blend_file, - BlendBlockPointer block, - int entry_index); - -/* Returns a BlendObjType enum handy for checking that the general type - of the object you have a handle on is what you're expecting. */ -BlendObjType blend_object_type(BlendFile* blend_file, - BlendObject obj); - -/* Given a BlendObject of type BLEND_OBJ_STRUCT in 'obj', fill in the - BlendObject pointed to by 'result' with a handle to the named - field of that structure (note that the resulting data object might - itself be a structure!). 0 is returned on failure (i.e. this structure - does not have a field of the requested name, or you supplied an - object which is not a structure). */ -int blend_object_structure_getfield(BlendFile* blend_file, - BlendObject *result, - BlendObject obj, - const char* field_name); - -/* Gets the size (in elements) of an object which is a 1D or 2D array. - A non-array is equivalent to an array of size 1x1. A 1D array will - always have dim1 == 1. */ -void blend_object_array_getdims(BlendFile* blend_file, - BlendObject obj, - int* dim1, int* dim2); - -/* This fetches a piece of data from the .blend file in a format - suitable for your architecture (i.e. ints will be of proper size - and endianness, pointers are transformed to valid BlendBlockPointers - or NULL, etc) into the address pointed to by dest. It's up to you to - check that the data you're asking for will fit into the type you're - trying to put it in (use blend_object_type() and see the BlendObjType - enum to check that the object's type is the one you're expecting.) - - Composite structures (BLEND_OBJ_STRUCT) are not handled atomically; - use blend_object_structure_getfield() to extract each named field from - a structure individually. - - 1 is returned on success. Failure occurs when you try to extract - data from a structure (see blend_object_structure_getfield()) or - an array (use blend_object_array_getdata()). -*/ -int blend_object_getdata(BlendFile* blend_file, - void* dest, BlendObject obj); - -/* This operates like blend_object_getdata() except that it is happy - to copy an item of data out of an array. The array is always treated - as two-dimensional (data[dimension1][dimension2]); if you're accessing - a one-dimensional array then simply specify dim_index_1 as 0. - (Indices are in the range 0..DIMSIZE-1.) - - Similarly, plain non-array data can be fetched by specifying - dim_index_1 == dim_index_2 == 0. This makes - blend_object_array_getdata(bf, dest, obj, 0, 0) equivalent to - blend_object_getdata(bf, dest, obj) except that it is happy to - be called with an array, from which it will extract the first - element. - - Like blend_object_getdata(), it will not fetch a structure (from - an array of structures; fortunately I've not seen a .blend file - featuring an array of structures so we'll bridge that API gap - when we come to it). - */ -int blend_object_array_getdata(BlendFile* blend_file, - void* dest, BlendObject obj, - int dim_index_1, int dim_index_2); - -/********************************/ -/* Mid-level querying functions */ -/********************************/ - -typedef unsigned long BlendLayerMask; - -/* extract a string from a char-array or uchar-array object, up to - max_chars in length including the \0 terminator. If the object is - a two-dimensional array then the first string is extracted. Returns - 0 on failure. -*/ -int blend_object_getstring(BlendFile* blend_file, - BlendObject obj, - char *dest, int max_chars); - -/* Searches the file for a top-level object with the given ID name. - Typical ID names are 'OBCamera', 'MECircle.003', 'MAplastic', 'TEgrass' etc. - The first two characters of an ID name keep the namespaces separate, - so that a material (MA) with the name 'metal' is distinguishable from - a texture (TE) with the name 'metal'. That's a foible of Blender itself. - - blend_object_get_by_IDname() returns 0 on failure. It only returns one - object of the given IDname; there should indeed be only one, as Blender - enforces this uniqueness. - */ -int blend_object_get_by_IDname(BlendFile* blend_file, - BlendObject *result, - const char* IDname); -/* get string from [obj].ID.name -- caller allocs/frees */ -int blend_object_get_IDname(BlendFile* blend_file, - BlendObject obj, - char *dest, int max_chars); - -/* returns !0 if the blender Object whose handle is objobj is a top-level - object -- that is, it's not a child of another Object. */ -int blend_obj_is_rootobject(BlendFile *bf, BlendObject *objobj); -/* return the layers (bitmask) that an Object lives on. */ -BlendLayerMask blend_obj_get_layermask(BlendFile *bf, BlendObject *objobj); - -/* These functions can be a bit slow -- each one requires a linear scan - of the file's blocks. But they're handy... */ -/* Return number of children that this Object has. Can be 0. */ -int blend_obj_get_childcount(BlendFile *bf, BlendObject *objobj); -/* Gets child number childnum of the Object. childnum=0 returns - the first, childnum=1 returns the second, etc. */ -BlendBlockPointer blend_obj_get_child(BlendFile *bf, BlendObject *objobj, - int childnum); - -/*********************************/ -/* High-level querying functions */ -/*********************************/ - -typedef struct { - int bone_id; - float weight; -} bDeformWeight; - -typedef struct { - float xyz[3]; - float cnormal[3]; /* cosmetic normal */ - int mat; - bDeformWeight* deform_weights; - int deform_weights_count; -} bVert; - - -#define BVERT_HAS_CNORMAL(BV) ((BV)->cnormal[0] != 0.0f || \ - (BV)->cnormal[1] != 0.0f || \ - (BV)->cnormal[2] != 0.0f) - -#define BFACE_FLAG_SMOOTH 0x01 - -typedef struct _bImage { - - void* m_packedImagePtr; - int m_sizePackedImage; - char m_imagePathName [128]; - - int m_ok; - - int m_xrep; - int m_yrep; - -} bImage; - -typedef struct { - int v[4]; - float rgba[4][4]; /* vertex colours */ - float rgba2[4][4]; /* texture face colours (errrr...?) */ - float uv[4][2]; - bImage* m_image; - int mat; - unsigned char flags; - int m_flag; - int m_mode; - BlendBlockPointer image_id; -} bFace; - - -#define BFACE_HAS_TEXTURE(BF) ((BF)->image_id != NULL) -#define BFACE_IS_QUAD(BF) ((BF)->v[3] != 0) -#define BFACE_IS_TRI(BF) ((BF)->v[2] != 0 && (BF)->v[3] == 0) -#define BFACE_IS_LINE(BF) ((BF)->v[1] != 0 && (BF)->v[2] == 0) - -typedef enum { - BTEX_AFFECT_COLOUR = 0x01, - BTEX_AFFECT_ALPHA = 0x02, - BTEX_AFFECT_EMIT = 0x04, - BTEX_AFFECT_NORMAL = 0x08, - BTEX_AFFECT_NEGNORM = 0x10, - BTEX_AFFECT_STENCIL = 0x20 /* not really an 'affect' in blender, but it is */ -} bTexLayerAffects; - -typedef enum { - BTEX_BLEND_NORMAL, /* 'mix' */ - BTEX_BLEND_MULTIPLY, /* 'mul' -- modulate. */ - BTEX_BLEND_ADD, - BTEX_BLEND_SUB -} bTexLayerBlendmode; - -typedef enum { - BTEX_COORDS_NONE, - BTEX_COORDS_UV, - BTEX_COORDS_REFLECT -} bTexLayerCoordsType; - -typedef enum { - BIMG_FLAG_INTERPOLATE = 0x01, /* upsample */ - BIMG_FLAG_ANTIALIAS = 0x02, /* downsample */ - BIMG_FLAG_MIPMAP = 0x04 /* use mipmaps */ -} bTexImageFlags; - -typedef struct { - char *filename; /* image file name -- absolute path! -- NULL if not image. */ - bTexLayerAffects affects_mask; - bTexLayerBlendmode blend_mode; - bTexLayerCoordsType coords_type; - /* Tex substruct */ - int is_st_clamped; /* otherwise, repeat... (GL texwrap mode.) */ - bTexImageFlags flags; - short Nflags, Ntype; /* not decoded yet */ - short xrepeat, yrepeat; /* amounts to scale texcoords by, really */ -} bTexLayer; - -typedef enum { - BMAT_FEATURE_VCOLLIGHT = 0x01, - BMAT_FEATURE_VCOLPAINT = 0x02, - BMAT_FEATURE_TEXFACE = 0x04, - BMAT_FEATURE_SHADELESS = 0x08, - BMAT_FEATURE_WIRE = 0x10 /* wireframe rendering */ -} bMatFeatureMask; - -#define BLENDER_MAX_TEX_LAYERS 8 -typedef struct { - bTexLayer *tex_layer[BLENDER_MAX_TEX_LAYERS]; - bMatFeatureMask feature_mask; - float colour_rgba[4]; /* main material colour */ - float emit; /* emissive strength, 0..1 */ -} bMaterial; - -typedef float bMatrix[4][4]; - -typedef struct _bMesh{ - bVert *vert; - int vert_count; - bFace *face; - int face_count; - bMaterial *material; /* or NULL if none */ -} bMesh; - -typedef enum { - BOBJ_TYPE_UNKNOWN, - BOBJ_TYPE_NULL, /* indicates object has no data associated with it! */ - BOBJ_TYPE_MESH, - BOBJ_TYPE_INVALID_MESH, - BOBJ_TYPE_CAMERA, - BOBJ_TYPE_LAMP -} bObjType; - -typedef enum { - BAQ_INCLUDE_CHILDREN = 0x0001 -} bAcquireFlags; - -typedef struct _bObj{ - bObjType type; - char *name; - - bMatrix transform; /* local transformation matrix */ - bMatrix parentimat; /* parent's inverse transform matrix */ - float scaling[3]; /* scaling component of transform */ - float rotphr[3]; /* pitch/head/roll rotation component of transform (use for normals) */ - float location[3]; /* location component of transform */ - unsigned char transflags; /* NOT DECODED YET, RAW BYTE */ - float mass;//used for rigid body dynamics - int gameflag; //used to detect object type (static, ghost, dynamic, rigid body, soft body) - int boundtype; //used to detect collision shape type - - union { - void *dummy; - bMesh *mesh; - } data; - -} bObj; - - -bObj *blend_alloc_obj(void); -void blend_init_obj(bObj *obj); -void blend_free_obj(bObj *obj); -void blend_free_obj_inner(bObj *obj); -void blend_acquire_obj_from_obj(BlendFile *bf, BlendObject *objobj, - bObj *outobj, - /* malloc'd BlendObject will be written here if pointer if non-NULL: */ BlendObject **outblendobject); - -bMesh *blend_alloc_mesh(void); -void blend_init_mesh(bMesh *mesh); -void blend_free_mesh_inner(bMesh *mesh); -void blend_free_mesh(bMesh *mesh); -void blend_acquire_mesh(const char *fname, const char *want_name, bMesh *mesh); -void blend_acquire_mesh_from_obj(BlendFile *bf, - BlendObject *meobj, - bMesh *mesh); -/* apply transformation found in 'obj' to 'mesh' */ -void blend_transform_mesh_from_obj(bMesh *mesh, bObj *obj); - -bMaterial *blend_alloc_material(void); -void blend_init_material(bMaterial *mat); -void blend_free_material(bMaterial *mat); -void blend_acquire_material_from_obj(BlendFile *bf, BlendObject *meobj, - bMaterial *mat); - -bTexLayer *blend_alloc_texlayer(void); -void blend_init_texlayer(bTexLayer *tl); -void blend_free_texlayer(bTexLayer *tl); -void blend_acquire_texlayer_from_obj(BlendFile *bf, BlendObject *tlobj, - bTexLayer *tl); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/readblend/testblend.c b/Extras/readblend/testblend.c deleted file mode 100644 index 86e207176..000000000 --- a/Extras/readblend/testblend.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include - -#include "abs-file.h" - -#include "readblend.h" -#include "blendtype.h" - -#define MAX_MESHES 10 -bMesh gMeshes[MAX_MESHES]; -int gNumMesh = 0; - -#define MAX_OBJECTS 10 -bObj gObjects[MAX_OBJECTS]; -int gNumObjects = 0; - -void crawl(BlendFile* blend_file, - BlendObject obj) -{ - BlendObject data_obj; - BlendObject data_obj2; - - BlendBlock* tmpBlock=0; - - { - const char* type_name = blend_file->types[obj.type].name; - if (strcmp(type_name,"Object")==0) - { - if (gNumObjects