# HG changeset patch # User John Tsiombikas # Date 1397714022 -10800 # Node ID 99715321ad6dcd5e5c904eefd7211c313a7808d9 # Parent dad392c710dfd3bf4194e5fce8be0a693da8161e# Parent cd7efb8757e152603c467b8b81638789d07296ed merged diff -r dad392c710df -r 99715321ad6d Makefile --- a/Makefile Thu Apr 17 08:50:36 2014 +0300 +++ b/Makefile Thu Apr 17 08:53:42 2014 +0300 @@ -10,11 +10,9 @@ openctm = libs/openctm/libopenctm.a tinyxml2 = libs/tinyxml2/libtinyxml2.a -vmath = libs/vmath/libvmath.a -anim = libs/anim/libanim.a -extinc = -Ilibs/openctm -Ilibs/tinyxml2 -Ilibs/anim -extlibs = $(openctm) $(tinyxml2) $(anim) $(vmath) +extinc = -Ilibs/openctm -Ilibs/tinyxml2 +extlibs = $(openctm) $(tinyxml2) name = goat3d so_major = 0 @@ -37,7 +35,7 @@ CC = clang CXX = clang++ CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(pic) $(extinc) -LDFLAGS = $(extlibs) -lpthread +LDFLAGS = $(extlibs) -lvmath -lanim -lpthread .PHONY: all all: $(lib_so) $(lib_a) @@ -56,14 +54,6 @@ $(tinyxml2): $(MAKE) -C libs/tinyxml2 -.PHONY: $(vmath) -$(vmath): - $(MAKE) -C libs/vmath - -.PHONY: $(anim) -$(anim): - $(MAKE) -C libs/anim - -include $(dep) %.d: %.cc @@ -73,6 +63,11 @@ clean: rm -f $(obj) $(lib_a) $(lib_so) +.PHONY: cleanlibs +cleanlibs: + $(MAKE) -C libs/openctm clean + $(MAKE) -C libs/tinyxml2 clean + .PHONY: cleandep cleandep: rm -f $(dep) diff -r dad392c710df -r 99715321ad6d converters/ass2goat/.clang_complete --- a/converters/ass2goat/.clang_complete Thu Apr 17 08:50:36 2014 +0300 +++ b/converters/ass2goat/.clang_complete Thu Apr 17 08:53:42 2014 +0300 @@ -1,2 +1,3 @@ -I../../src -I/usr/local/include +-I/usr/local/include/assimp diff -r dad392c710df -r 99715321ad6d converters/ass2goat/src/main.c --- a/converters/ass2goat/src/main.c Thu Apr 17 08:50:36 2014 +0300 +++ b/converters/ass2goat/src/main.c Thu Apr 17 08:53:42 2014 +0300 @@ -5,28 +5,52 @@ #include "assimp/postprocess.h" #include "assimp/scene.h" -int convert(const char *infname, const char *outfname); +enum { + CONV_SCENE, + CONV_ANIM +}; + +int convert(const char *infname); +int convert_anim(const char *infname); void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl); +void process_mesh(struct goat3d *goat, struct goat3d_mesh *mesh, struct aiMesh *aimesh); void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode); +int process_anim(struct goat3d *goat, struct aiAnimation *aianim); +static int output_filename(char *buf, int bufsz, const char *fname, const char *suffix); +static long assimp_time(const struct aiAnimation *anim, double aitime); int main(int argc, char **argv) { int i, num_done = 0; + int conv_targ = CONV_SCENE; for(i=1; i %s\n", argv[i], outfname); - convert(argv[i], outfname); num_done++; } } @@ -39,7 +63,7 @@ return 0; } -#define PPFLAGS \ +#define SCE_PPFLAGS \ (aiProcess_Triangulate | \ aiProcess_GenNormals | \ aiProcess_JoinIdenticalVertices | \ @@ -47,13 +71,23 @@ aiProcess_LimitBoneWeights | \ aiProcess_GenUVCoords) -int convert(const char *infname, const char *outfname) +#define ANM_PPFLAGS \ + (aiProcess_LimitBoneWeights) + +int convert(const char *infname) { - int i; + int i, bufsz; const struct aiScene *aiscn; struct goat3d *goat; + char *outfname; - if(!(aiscn = aiImportFile(infname, PPFLAGS))) { + bufsz = output_filename(0, 0, infname, "goat3d"); + outfname = alloca(bufsz); + output_filename(outfname, bufsz, infname, "goat3d"); + printf("converting %s -> %s\n", infname, outfname); + + + if(!(aiscn = aiImportFile(infname, SCE_PPFLAGS))) { fprintf(stderr, "failed to import %s\n", infname); return -1; } @@ -68,6 +102,14 @@ goat3d_add_mtl(goat, mat); } + for(i=0; i<(int)aiscn->mNumMeshes; i++) { + struct aiMesh *aimesh = aiscn->mMeshes[i]; + struct goat3d_mesh *mesh = goat3d_create_mesh(); + + process_mesh(goat, mesh, aimesh); + goat3d_add_mesh(goat, mesh); + } + for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) { process_node(goat, 0, aiscn->mRootNode->mChildren[i]); } @@ -78,6 +120,42 @@ return 0; } +int convert_anim(const char *infname) +{ + int i, bufsz; + const struct aiScene *aiscn; + struct goat3d *goat; + char *outfname; + + bufsz = output_filename(0, 0, infname, "goatanim"); + outfname = alloca(bufsz); + output_filename(outfname, bufsz, infname, "goatanim"); + printf("converting %s -> %s\n", infname, outfname); + + + if(!(aiscn = aiImportFile(infname, ANM_PPFLAGS))) { + fprintf(stderr, "failed to import %s\n", infname); + return -1; + } + + goat = goat3d_create(); + + for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) { + process_node(goat, 0, aiscn->mRootNode->mChildren[i]); + } + + for(i=0; imNumAnimations; i++) { + if(process_anim(goat, aiscn->mAnimations[i]) == -1) { + return -1; + } + } + + goat3d_save_anim(goat, outfname); + goat3d_free(goat); + aiReleaseImport(aiscn); + return 0; +} + void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl) { struct aiString aistr; @@ -126,11 +204,60 @@ goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, aistr.data); } if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_OPACITY(0), &aistr) == aiReturn_SUCCESS) { - // TODO this is semantically inverted... maybe add an alpha attribute? + /* TODO this is semantically inverted... maybe add an alpha attribute? */ goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, aistr.data); } } +void process_mesh(struct goat3d *goat, struct goat3d_mesh *mesh, struct aiMesh *aimesh) +{ + int i, num_verts, num_faces; + struct goat3d_material *mtl; + + if(aimesh->mName.length > 0) { + goat3d_set_mesh_name(mesh, aimesh->mName.data); + } + + if((mtl = goat3d_get_mtl(goat, aimesh->mMaterialIndex))) { + goat3d_set_mesh_mtl(mesh, mtl); + } + + num_verts = aimesh->mNumVertices; + num_faces = aimesh->mNumFaces; + + for(i=0; imVertices + i; + goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_VERTEX, v->x, v->y, v->z); + + if(aimesh->mNormals) { + v = aimesh->mNormals + i; + goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_NORMAL, v->x, v->y, v->z); + } + if(aimesh->mTangents) { + v = aimesh->mTangents + i; + goat3d_add_mesh_attrib3f(mesh, GOAT3D_MESH_ATTR_TANGENT, v->x, v->y, v->z); + } + if(aimesh->mTextureCoords[0]) { + v = aimesh->mTextureCoords[0] + i; + goat3d_add_mesh_attrib2f(mesh, GOAT3D_MESH_ATTR_TEXCOORD, v->x, v->y); + } + if(aimesh->mColors[0]) { + col = aimesh->mColors[0] + i; + goat3d_add_mesh_attrib4f(mesh, GOAT3D_MESH_ATTR_COLOR, col->r, col->g, col->b, col->a); + } + /* TODO: add bones */ + } + + for(i=0; imFaces + i; + + goat3d_add_mesh_face(mesh, face->mIndices[0], face->mIndices[1], face->mIndices[2]); + } +} + void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode) { int i; @@ -145,3 +272,108 @@ goat3d_add_node(goat, node); } + +int process_anim(struct goat3d *goat, struct aiAnimation *aianim) +{ + int i, j, num_nodes, rnodes_count; + const char *anim_name; + + if(aianim->mName.length <= 0) { + anim_name = "unnamed"; + } else { + anim_name = aianim->mName.data; + } + + num_nodes = goat3d_get_node_count(goat); + + rnodes_count = 0; + for(i=0; imNumChannels; i++) { + struct goat3d_node *node; + struct aiNodeAnim *ainodeanim = aianim->mChannels[i]; + + /* find the node it refers to */ + const char *nodename = ainodeanim->mNodeName.data; + if(!(node = goat3d_get_node_by_name(goat, nodename))) { + fprintf(stderr, "failed to process animation for unknown node: %s\n", nodename); + return -1; + } + + /* add all the keys ... */ + for(j=0; j<(int)ainodeanim->mNumPositionKeys; j++) { + struct aiVectorKey *key = ainodeanim->mPositionKeys + j; + long tm = assimp_time(aianim, key->mTime); + goat3d_set_node_position(node, key->mValue.x, key->mValue.y, key->mValue.z, tm); + } + + for(j=0; j<(int)ainodeanim->mNumRotationKeys; j++) { + struct aiQuatKey *key = ainodeanim->mRotationKeys + j; + long tm = assimp_time(aianim, key->mTime); + goat3d_set_node_rotation(node, key->mValue.x, key->mValue.y, key->mValue.z, key->mValue.w, tm); + } + + for(j=0; j<(int)ainodeanim->mNumScalingKeys; j++) { + struct aiVectorKey *key = ainodeanim->mScalingKeys + j; + long tm = assimp_time(aianim, key->mTime); + goat3d_set_node_scaling(node, key->mValue.x, key->mValue.y, key->mValue.z, tm); + } + } + + return 0; +} + +static int output_filename(char *buf, int bufsz, const char *fname, const char *suffix) +{ + int reqsz, namesz; + char *tmpfname; + const char *fname_end, *lastdot; + + lastdot = strrchr(fname, '.'); + + fname_end = lastdot ? lastdot : fname + strlen(fname); + namesz = fname_end - fname; + reqsz = namesz + strlen(suffix) + 2; /* plus 1 for the dot */ + + if(buf && bufsz) { + tmpfname = alloca(namesz + 1); + memcpy(tmpfname, fname, namesz); + tmpfname[namesz] = 0; + + if(suffix) { + snprintf(buf, bufsz, "%s.%s", tmpfname, suffix); + } else { + strncpy(buf, tmpfname, bufsz); + } + buf[bufsz - 1] = 0; + } + + return reqsz; +} + +static long assimp_time(const struct aiAnimation *anim, double aitime) +{ + double sec; + if(anim->mTicksPerSecond < 1e-6) { + /* assume time in frames? */ + sec = aitime / 30.0; + } else { + sec = aitime / anim->mTicksPerSecond; + } + return (long)(sec * 1000.0); +} diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/maxgoat.rc Binary file exporters/maxgoat/maxgoat.rc has changed diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/maxgoat.vcxproj --- a/exporters/maxgoat/maxgoat.vcxproj Thu Apr 17 08:50:36 2014 +0300 +++ b/exporters/maxgoat/maxgoat.vcxproj Thu Apr 17 08:53:42 2014 +0300 @@ -100,16 +100,16 @@ Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;MAXGOAT_EXPORTS;%(PreprocessorDefinitions);BUILD_MAXPLUGIN 4996;4244 - $(SolutionDir)\src + $(SolutionDir)\src;$(ProjectDir) Windows true - goat3d-x64.lib;%(AdditionalDependencies) + libvmath-x64-dbg.lib;libanim-x64.lib;goat3d-x64.lib;%(AdditionalDependencies) $(TargetDir);%(AdditionalLibraryDirectories) - copy /Y "$(TargetPath)" "$(ADSK_3DSMAX_x64_2014)plugins\$(ProjectName).dle" + copy /Y "$(TargetPath)" "$(ADSK_3DSMAX_x64_2014)plugins\$(TargetFileName)" @@ -140,22 +140,36 @@ true WIN32;NDEBUG;_WINDOWS;_USRDLL;MAXGOAT_EXPORTS;%(PreprocessorDefinitions) 4996;4244 - $(SolutionDir)\src + $(SolutionDir)\src;$(ProjectDir) Windows true true true - goat3d-x64.lib;%(AdditionalDependencies) + libvmath-x64.lib;libanim-x64.lib;goat3d-x64.lib;%(AdditionalDependencies) $(TargetDir);%(AdditionalLibraryDirectories) - copy /Y "$(TargetPath)" "$(ADSK_3DSMAX_x64_2014)plugins\$(ProjectName).dle" + copy /Y "$(TargetPath)" "$(ADSK_3DSMAX_x64_2014)plugins\$(TargetFileName)" + + + + + + + + + + + + + + diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/maxgoat.vcxproj.filters --- a/exporters/maxgoat/maxgoat.vcxproj.filters Thu Apr 17 08:50:36 2014 +0300 +++ b/exporters/maxgoat/maxgoat.vcxproj.filters Thu Apr 17 08:53:42 2014 +0300 @@ -3,12 +3,36 @@ {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;h src + + src + + + src + + + + + src + + + src + + + src + + + + + + + + \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/msglogo3d.bmp Binary file exporters/maxgoat/msglogo3d.bmp has changed diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/resource.h Binary file exporters/maxgoat/resource.h has changed diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/src/logger.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat/src/logger.cc Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,31 @@ +#include +#include +#include "logger.h" + +static FILE *logfile; + +bool maxlog_open(const char *fname) +{ + if(!(logfile = fopen(fname, "wb"))) { + return false; + } + setvbuf(logfile, 0, _IONBF, 0); + return true; +} + +void maxlog_close() +{ + if(logfile) { + fclose(logfile); + } +} + +void maxlog(const char *fmt, ...) +{ + if(!logfile) return; + + va_list ap; + va_start(ap, fmt); + vfprintf(logfile, fmt, ap); + va_end(ap); +} \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/src/logger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat/src/logger.h Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,8 @@ +#ifndef MAXLOGGER_H_ +#define MAXLOGGER_H_ + +bool maxlog_open(const char *fname); +void maxlog_close(); +void maxlog(const char *fmt, ...); + +#endif /* MAXLOGGER_H_ */ \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/src/maxgoat.cc --- a/exporters/maxgoat/src/maxgoat.cc Thu Apr 17 08:50:36 2014 +0300 +++ b/exporters/maxgoat/src/maxgoat.cc Thu Apr 17 08:53:42 2014 +0300 @@ -13,7 +13,10 @@ #include "IGameExport.h" #include "IConversionmanager.h" #include "goat3d.h" +#include "minwin.h" #include "config.h" +#include "logger.h" +#include "resource.h" #pragma comment (lib, "core.lib") @@ -31,8 +34,7 @@ #define VERSION(major, minor) \ ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor))) -static FILE *logfile; -static HINSTANCE hinst; +HINSTANCE hinst; class GoatExporter : public SceneExport { private: @@ -115,17 +117,55 @@ MessageBoxA(win, "Goat3D exporter plugin", "About this plugin", 0); } +static INT_PTR CALLBACK handle_dlg_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam) +{ + switch(msg) { + case WM_INITDIALOG: + CheckDlgButton(win, IDC_GOAT_NODES, 1); + CheckDlgButton(win, IDC_GOAT_MESHES, 1); + CheckDlgButton(win, IDC_GOAT_LIGHTS, 1); + CheckDlgButton(win, IDC_GOAT_CAMERAS, 1); + break; + + case WM_COMMAND: + switch(LOWORD(wparam)) { + case IDOK: + EndDialog(win, 1); + break; + + case IDCANCEL: + EndDialog(win, 0); + break; + + default: + return 0; + } + break; + + default: + return 0; + } + + return 1; +} + int GoatExporter::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL non_interactive, DWORD opt) { + if(!DialogBox(hinst, MAKEINTRESOURCE(IDD_GOAT_SCE), 0, handle_dlg_events)) { + maxlog("canceled!\n"); + return IMPEXP_CANCEL; + } + mtlmap.clear(); nodemap.clear(); char fname[512]; wcstombs(fname, name, sizeof fname - 1); + maxlog("Exporting Goat3D Scene (text) file: %s\n", fname); if(!(igame = GetIGameInterface())) { - fprintf(logfile, "failed to get the igame interface\n"); + maxlog("failed to get the igame interface\n"); return IMPEXP_FAIL; } IGameConversionManager *cm = GetConversionManager(); @@ -406,6 +446,7 @@ HINSTANCE HInstance() { return hinst; } }; +// TODO: make 2 class descriptors, one for goat3d, one for goat3danim static GoatClassDesc class_desc; BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved) @@ -446,18 +487,13 @@ SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path); strcat(path, "/testexp.log"); - if((logfile = fopen(path, "w"))) { - setvbuf(logfile, 0, _IONBF, 0); - } + maxlog_open(path); return TRUE; } __declspec(dllexport) int LibShutdown() { - if(logfile) { - fclose(logfile); - logfile = 0; - } + maxlog_close(); return TRUE; } diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/src/minwin.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat/src/minwin.cc Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,170 @@ +#include +#include +#include "minwin.h" +#include "logger.h" + +#define GOATSCE_WCLASS "goatsce-window" + +struct MinWidget { + HWND win; + + MWCallback cbfunc; + void *cbcls; + + MinWidget() { win = 0; cbfunc = 0; cbcls = 0; } +}; + +static void init(); +static MinWidget *createwin(MinWidget *parent, const char *cls, const char *name, + unsigned int style, int x, int y, int xsz, int ysz); +static LRESULT CALLBACK handle_msg(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam); + +extern HINSTANCE hinst; // defined in maxgoat.cc + +void mw_set_callback(MinWidget *w, MWCallback func, void *cls) +{ + w->cbfunc = func; + w->cbcls = cls; +} + +MinWidget *mw_create_window(MinWidget *parent, const char *name, int x, int y, int xsz, int ysz) +{ + unsigned int style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; + if(parent) { + style |= WS_CHILD; + } + + maxlog("creating window: %s\n", name); + + MinWidget *w = createwin(parent, GOATSCE_WCLASS, name, style, x, y, xsz, ysz); + return w; +} + +MinWidget *mw_create_button(MinWidget *parent, const char *text, int x, int y, int xsz, int ysz) +{ + unsigned int style = BS_PUSHBUTTON | WS_VISIBLE; + if(parent) { + style |= WS_CHILD; + } + + maxlog("creating button: %s\n", text); + + MinWidget *w = createwin(parent, "BUTTON", text, style, x, y, xsz, ysz); + return w; +} + +MinWidget *mw_create_checkbox(MinWidget *parent, const char *text, int x, int y, int xsz, int ysz, bool checked) +{ + unsigned int style = BS_CHECKBOX | WS_VISIBLE; + if(parent) { + style |= WS_CHILD; + } + + maxlog("creating checkbox: %s\n", text); + + MinWidget *w = createwin(parent, "CHECKBOX", text, style, x, y, xsz, ysz); + return w; +} + +static DWORD WINAPI gui_thread_func(void *cls); + +void mw_test() +{ + init(); + + HANDLE thread = CreateThread(0, 0, gui_thread_func, 0, 0, 0); + //WaitForSingleObject(thread, 5000); +} + +static DWORD WINAPI gui_thread_func(void *cls) +{ + MinWidget *win = mw_create_window(0, "test window!", -1, -1, 400, 400); + MinWidget *bn_ok = mw_create_button(win, "Ok", 50, 100, 150, 40); + MinWidget *bn_cancel = mw_create_button(win, "Cancel", 250, 100, 150, 40); + MinWidget *ck_lights = mw_create_checkbox(win, "Export lights", 20, 20, 250, 40, true); + MinWidget *ck_cameras = mw_create_checkbox(win, "Export cameras", 20, 60, 250, 40, true); + + MSG msg; + while(GetMessage(&msg, win->win, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + DestroyWindow(win->win); + delete bn_ok; + delete bn_cancel; + delete ck_lights; + delete ck_cameras; + delete win; + + return 0; +} + +static void init() +{ + static bool done_init; + if(done_init) { + return; + } + done_init = true; + + size_t sz = mbstowcs(0, GOATSCE_WCLASS, 0); + wchar_t *cname = new wchar_t[sz + 1]; + mbstowcs(cname, GOATSCE_WCLASS, sz + 1); + + WNDCLASS wc; + memset(&wc, 0, sizeof wc); + wc.lpszClassName = cname; + wc.hInstance = hinst; + wc.lpfnWndProc = handle_msg; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.hCursor = LoadCursor(0, IDC_ARROW); + + RegisterClass(&wc); +} + +static MinWidget *createwin(MinWidget *parent, const char *cls, const char *name, + unsigned int style, int x, int y, int xsz, int ysz) +{ + init(); + + MinWidget *w = new MinWidget; + + size_t sz = mbstowcs(0, cls, 0); + wchar_t *wcls = new wchar_t[sz + 1]; + mbstowcs(wcls, cls, sz + 1); + + sz = mbstowcs(0, name, 0); + wchar_t *wname = new wchar_t[sz + 1]; + mbstowcs(wname, name, sz + 1); + + if(x <= 0) x = CW_USEDEFAULT; + if(y <= 0) y = CW_USEDEFAULT; + + w->win = CreateWindow(wcls, wname, style, x, y, xsz, ysz, parent ? parent->win : 0, 0, hinst, 0); + + delete [] wcls; + delete [] wname; + + if(!w->win) { + delete w; + return 0; + } + return w; +} + + +static LRESULT CALLBACK handle_msg(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam) +{ + switch(msg) { + case WM_CLOSE: + DestroyWindow(win); + break; + + default: + return DefWindowProc(win, msg, wparam, lparam); + } + + return 0; +} \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat/src/minwin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat/src/minwin.h Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,15 @@ +#ifndef MINWIN_H_ +#define MINWIN_H_ + +struct MinWidget; +typedef void (*MWCallback)(MinWidget*, void*); + +void mw_set_callback(MinWidget *w, MWCallback func, void *cls); + +MinWidget *mw_create_window(MinWidget *parent, const char *name, int x, int y, int xsz, int ysz); +MinWidget *mw_create_button(MinWidget *parent, const char *text, int x, int y, int xsz, int ysz); +MinWidget *mw_create_checkbox(MinWidget *parent, const char *text, int x, int y, int xsz, int ysz, bool checked); + +void mw_test(); + +#endif // MINWIN_H_ \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat_stub/maxgoat_stub.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat_stub/maxgoat_stub.vcxproj Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {941007A1-6375-4507-8745-FC3EA9DF010B} + Win32Proj + maxgoat_stub + + + + DynamicLibrary + true + v100 + Unicode + + + DynamicLibrary + true + v100 + Unicode + + + DynamicLibrary + false + v100 + true + Unicode + + + DynamicLibrary + false + v100 + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + false + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MAXGOAT_STUB_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MAXGOAT_STUB_EXPORTS;%(PreprocessorDefinitions) + 4996 + + + Windows + true + + + copy /Y "$(TargetPath)" "$(ADSK_3DSMAX_x64_2014)plugins\$(ProjectName).dle" + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MAXGOAT_STUB_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MAXGOAT_STUB_EXPORTS;%(PreprocessorDefinitions) + 4996 + + + Windows + true + true + true + + + copy /Y "$(TargetPath)" "$(ADSK_3DSMAX_x64_2014)plugins\$(ProjectName).dle" + + + + + + + + + \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat_stub/maxgoat_stub.vcxproj.filters --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat_stub/maxgoat_stub.vcxproj.filters Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff -r dad392c710df -r 99715321ad6d exporters/maxgoat_stub/src/stub.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/exporters/maxgoat_stub/src/stub.cc Thu Apr 17 08:53:42 2014 +0300 @@ -0,0 +1,267 @@ +#include +#include +#include +#include +#include +#include +#include +#include "max.h" +#include "impexp.h" // SceneExport +#include "iparamb2.h" // ClassDesc2 +#include "plugapi.h" +#include "IGame.h" +#include "IGameExport.h" +#include "IConversionmanager.h" + + +#pragma comment (lib, "core.lib") +#pragma comment (lib, "geom.lib") +#pragma comment (lib, "gfx.lib") +#pragma comment (lib, "mesh.lib") +#pragma comment (lib, "maxutil.lib") +#pragma comment (lib, "maxscrpt.lib") +#pragma comment (lib, "paramblk2.lib") +#pragma comment (lib, "msxml2.lib") +#pragma comment (lib, "igame.lib") +#pragma comment (lib, "comctl32.lib") + + +#define VER_MAJOR 1 +#define VER_MINOR 0 +#define VERSION(major, minor) \ + ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor))) + +typedef int (*PluginInitFunc)(); +typedef int (*PluginShutdownFunc)(); +typedef ClassDesc *(*PluginClassDescFunc)(int); + +static FILE *logfile; +static HINSTANCE hinst; +static const wchar_t *copyright_str = L"Copyright 2013 (C) John Tsiombikas - GNU General Public License v3, see COPYING for details."; + +class GoatExporterStub : public SceneExport { +public: + IGameScene *igame; + + int ExtCount() { return 1; } + const TCHAR *Ext(int n) { return L"goatsce"; } + const TCHAR *LongDesc() { return L"Goat3D Scene file"; } + const TCHAR *ShortDesc() { return L"Goat3D Scene"; } + const TCHAR *AuthorName() { return L"John Tsiombikas"; } + const TCHAR *CopyrightMessage() { return copyright_str; } + const TCHAR *OtherMessage1() { return L"foo1"; } + const TCHAR *OtherMessage2() { return L"foo2"; } + unsigned int Version() { return VERSION(VER_MAJOR, VER_MINOR); } + void ShowAbout(HWND win) { MessageBoxA(win, "Goat3D exporter", "About this plugin", 0); } + + int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0); +}; + +class GoatAnimExporterStub : public SceneExport { +public: + IGameScene *igame; + + int ExtCount() { return 1; } + const TCHAR *Ext(int n) { return L"goatanm"; } + const TCHAR *LongDesc() { return L"Goat3D Animation file"; } + const TCHAR *ShortDesc() { return L"Goat3D Animation"; } + const TCHAR *AuthorName() { return L"John Tsiombikas"; } + const TCHAR *CopyrightMessage() { return copyright_str; } + const TCHAR *OtherMessage1() { return L"bar1"; } + const TCHAR *OtherMessage2() { return L"bar2"; } + unsigned int Version() { return VERSION(VER_MAJOR, VER_MINOR); } + void ShowAbout(HWND win) { MessageBoxA(win, "Goat3D anim exporter", "About this plugin", 0); } + + int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0); +}; + +static const char *find_dll_dir() +{ + static char path[MAX_PATH]; + + HMODULE dll; + if(!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCSTR)find_dll_dir, &dll)) { + return 0; + } + GetModuleFileNameA(dll, path, sizeof path); + + char *last_slash = strrchr(path, '\\'); + if(last_slash && last_slash[1]) { + *last_slash = 0; + } + + return path; +} + +static int do_export(int which, const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL non_int, DWORD opt) +{ + const char *dll_fname = "maxgoat.dll"; + char *dll_path; + HMODULE dll = 0; + PluginInitFunc init; + PluginShutdownFunc shutdown; + PluginClassDescFunc get_class_desc; + ClassDesc *desc; + SceneExport *ex; + int result = IMPEXP_FAIL; + + const char *plugdir = find_dll_dir(); + if(plugdir) { + dll_path = new char[strlen(dll_fname) + strlen(plugdir) + 2]; + sprintf(dll_path, "%s\\%s", plugdir, dll_fname); + } else { + dll_path = new char[strlen(dll_fname) + 1]; + strcpy(dll_path, dll_fname); + } + + if(!(dll = LoadLibraryA(dll_path))) { + fprintf(logfile, "failed to load exporter: %s\n", dll_path); + goto done; + } + + if(!(get_class_desc = (PluginClassDescFunc)GetProcAddress(dll, "LibClassDesc"))) { + fprintf(logfile, "maxgoat.dll is invalid (no LibClassDesc function)\n"); + goto done; + } + + // first initialize the library + if((init = (PluginInitFunc)GetProcAddress(dll, "LibInitialize"))) { + if(!init()) { + fprintf(logfile, "exporter initialization failed!\n"); + goto done; + } + } + + if(!(desc = get_class_desc(which))) { + fprintf(logfile, "failed to get the class descriptor\n"); + goto done; + } + + if(!(ex = (SceneExport*)desc->Create())) { + fprintf(logfile, "failed to create exporter class instance\n"); + goto done; + } + + result = ex->DoExport(name, eiface, iface); + delete ex; + + if((shutdown = (PluginShutdownFunc)GetProcAddress(dll, "LibShutdown"))) { + shutdown(); + } + +done: + delete [] dll_path; + if(dll) { + FreeLibrary(dll); + } + return result; +} + +int GoatExporterStub::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, + BOOL non_interactive, DWORD opt) +{ + return do_export(0, name, eiface, iface, non_interactive, opt); +} + + +int GoatAnimExporterStub::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, + BOOL non_interactive, DWORD opt) +{ + return do_export(1, name, eiface, iface, non_interactive, opt); +} + +// ------------------------------------------ + +class GoatClassDesc : public ClassDesc2 { +public: + int IsPublic() { return TRUE; } + void *Create(BOOL loading = FALSE) { return new GoatExporterStub; } + const TCHAR *ClassName() { return L"GoatExporterStub"; } + SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } + Class_ID ClassID() { return Class_ID(0x2e4e6311, 0x2b154d91); } + const TCHAR *Category() { return L"Mutant Stargoat"; } + + const TCHAR *InternalName() { return L"GoatExporterStub"; } + HINSTANCE HInstance() { return hinst; } +}; + +class GoatAnimClassDesc : public ClassDesc2 { +public: + int IsPublic() { return TRUE; } + void *Create(BOOL loading = FALSE) { return new GoatAnimExporterStub; } + const TCHAR *ClassName() { return L"GoatAnimExporterStub"; } + SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } + Class_ID ClassID() { return Class_ID(0x75054666, 0x45487285); } + const TCHAR *Category() { return L"Mutant Stargoat"; } + + const TCHAR *InternalName() { return L"GoatAnimExporterStub"; } + HINSTANCE HInstance() { return hinst; } +}; + + +static GoatClassDesc class_desc; +static GoatAnimClassDesc anim_class_desc; + +BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved) +{ + if(reason == DLL_PROCESS_ATTACH) { + hinst = inst_handle; + DisableThreadLibraryCalls(hinst); + } + return TRUE; +} + +extern "C" { + +__declspec(dllexport) const TCHAR *LibDescription() +{ + return L"Goat3D exporter stub"; +} + +__declspec(dllexport) int LibNumberClasses() +{ + return 2; +} + +__declspec(dllexport) ClassDesc *LibClassDesc(int i) +{ + switch(i) { + case 0: + return &class_desc; + case 1: + return &anim_class_desc; + default: + break; + } + return 0; +} + +__declspec(dllexport) ULONG LibVersion() +{ + return Get3DSMAXVersion(); +} + +__declspec(dllexport) int LibInitialize() +{ + static char path[1024]; + + SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path); + strcat(path, "/testexpstub.log"); + + if((logfile = fopen(path, "w"))) { + setvbuf(logfile, 0, _IONBF, 0); + } + return TRUE; +} + +__declspec(dllexport) int LibShutdown() +{ + if(logfile) { + fclose(logfile); + logfile = 0; + } + return TRUE; +} + +} // extern "C" \ No newline at end of file diff -r dad392c710df -r 99715321ad6d goat3d-vs2012.sln --- a/goat3d-vs2012.sln Thu Apr 17 08:50:36 2014 +0300 +++ b/goat3d-vs2012.sln Thu Apr 17 08:53:42 2014 +0300 @@ -8,30 +8,53 @@ {86BF319B-9222-4805-918D-DC1B9F77BCEF} = {86BF319B-9222-4805-918D-DC1B9F77BCEF} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "maxgoat_stub", "exporters\maxgoat_stub\maxgoat_stub.vcxproj", "{941007A1-6375-4507-8745-FC3EA9DF010B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 + Release|Mixed Platforms = Release|Mixed Platforms Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Debug|Win32.ActiveCfg = Debug|Win32 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Debug|Win32.Build.0 = Debug|Win32 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Debug|x64.ActiveCfg = Debug|x64 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Debug|x64.Build.0 = Debug|x64 + {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Release|Mixed Platforms.Build.0 = Release|Win32 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Release|Win32.ActiveCfg = Release|Win32 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Release|Win32.Build.0 = Release|Win32 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Release|x64.ActiveCfg = Release|x64 {86BF319B-9222-4805-918D-DC1B9F77BCEF}.Release|x64.Build.0 = Release|x64 + {5BDDFFC1-7900-45D2-92F5-525361057554}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {5BDDFFC1-7900-45D2-92F5-525361057554}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {5BDDFFC1-7900-45D2-92F5-525361057554}.Debug|Win32.ActiveCfg = Debug|Win32 {5BDDFFC1-7900-45D2-92F5-525361057554}.Debug|Win32.Build.0 = Debug|Win32 {5BDDFFC1-7900-45D2-92F5-525361057554}.Debug|x64.ActiveCfg = Debug|x64 {5BDDFFC1-7900-45D2-92F5-525361057554}.Debug|x64.Build.0 = Debug|x64 + {5BDDFFC1-7900-45D2-92F5-525361057554}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {5BDDFFC1-7900-45D2-92F5-525361057554}.Release|Mixed Platforms.Build.0 = Release|Win32 {5BDDFFC1-7900-45D2-92F5-525361057554}.Release|Win32.ActiveCfg = Release|Win32 {5BDDFFC1-7900-45D2-92F5-525361057554}.Release|Win32.Build.0 = Release|Win32 {5BDDFFC1-7900-45D2-92F5-525361057554}.Release|x64.ActiveCfg = Release|x64 {5BDDFFC1-7900-45D2-92F5-525361057554}.Release|x64.Build.0 = Release|x64 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Debug|Win32.ActiveCfg = Debug|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Debug|Win32.Build.0 = Debug|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Debug|x64.ActiveCfg = Debug|x64 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Debug|x64.Build.0 = Debug|x64 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Release|Mixed Platforms.Build.0 = Release|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Release|Win32.ActiveCfg = Release|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Release|Win32.Build.0 = Release|Win32 + {941007A1-6375-4507-8745-FC3EA9DF010B}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff -r dad392c710df -r 99715321ad6d goat3d.vcxproj --- a/goat3d.vcxproj Thu Apr 17 08:50:36 2014 +0300 +++ b/goat3d.vcxproj Thu Apr 17 08:53:42 2014 +0300 @@ -19,9 +19,6 @@ - - - @@ -34,16 +31,6 @@ - - - - - - - - - - @@ -57,9 +44,6 @@ - - - @@ -71,21 +55,10 @@ - - - - - - - - - - - - + @@ -97,13 +70,6 @@ - - - - - - - {86BF319B-9222-4805-918D-DC1B9F77BCEF} Win32Proj @@ -164,8 +130,9 @@ Level3 Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - 4244 + WIN32;_DEBUG;_LIB;OPENCTM_STATIC;%(PreprocessorDefinitions) + 4244;4305;4996 + $(ProjectDir)\libs\openctm;$(ProjectDir)\libs\openctm\liblzma;$(ProjectDir)\libs\tinyxml2 Windows @@ -180,7 +147,7 @@ Disabled WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);OPENCTM_STATIC;BUILD_MAXPLUGIN 4244;4305;4996 - $(SolutionDir)\src;$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2;$(SolutionDir)\libs\anim;$(SolutionDir)\libs\vmath + $(SolutionDir)\src;$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2 Windows @@ -199,8 +166,9 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - 4244 + WIN32;NDEBUG;_LIB;OPENCTM_STATIC;%(PreprocessorDefinitions) + 4244;4305;4996 + $(ProjectDir)\libs\openctm;$(ProjectDir)\libs\openctm\liblzma;$(ProjectDir)\libs\tinyxml2 Windows @@ -219,7 +187,7 @@ true WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);OPENCTM_STATIC 4244;4305;4996 - $(SolutionDir)\src;$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2;$(SolutionDir)\libs\anim;$(SolutionDir)\libs\vmath + $(SolutionDir)\src;$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2 Windows diff -r dad392c710df -r 99715321ad6d goat3d.vcxproj.filters --- a/goat3d.vcxproj.filters Thu Apr 17 08:50:36 2014 +0300 +++ b/goat3d.vcxproj.filters Thu Apr 17 08:53:42 2014 +0300 @@ -17,12 +17,6 @@ {18a85bea-ddb2-49a1-a7b1-bd11b23d5549} - - {dc4ab435-af1e-4786-8011-a7a793e229eb} - - - {05d8010d-b4d9-4829-80ea-8c8d018e1e04} - @@ -94,45 +88,6 @@ libs\openctm\liblzma - - libs\anim - - - libs\anim - - - libs\anim - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - @@ -207,67 +162,8 @@ libs\openctm\liblzma - - libs\anim - - - libs\anim - - - libs\anim - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath + + src - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - - libs\vmath - - \ No newline at end of file diff -r dad392c710df -r 99715321ad6d libs/anim/Makefile --- a/libs/anim/Makefile Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -src = $(wildcard *.c) -obj = $(src:.c=.o) -lib = libanim.a - -ifneq ($(shell uname -s), Darwin) - pic = -fPIC -endif - -CFLAGS = -pedantic -Wall -g $(pic) -CXXFLAGS = -pedantic -Wall -g $(pic) - -$(lib): $(obj) - $(AR) rcs $@ $(obj) - -.PHONY: clean -clean: - rm -f $(obj) $(lib) diff -r dad392c710df -r 99715321ad6d libs/anim/anim.c --- a/libs/anim/anim.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,946 +0,0 @@ -#include -#include -#include -#include "anim.h" -#include "dynarr.h" - -#define ROT_USE_SLERP - -static void invalidate_cache(struct anm_node *node); - -int anm_init_animation(struct anm_animation *anim) -{ - int i, j; - static const float defaults[] = { - 0.0f, 0.0f, 0.0f, /* default position */ - 0.0f, 0.0f, 0.0f, 1.0f, /* default rotation quat */ - 1.0f, 1.0f, 1.0f /* default scale factor */ - }; - - anim->name = 0; - - for(i=0; itracks + i) == -1) { - for(j=0; jtracks + i); - } - } - anm_set_track_default(anim->tracks + i, defaults[i]); - } - return 0; -} - -void anm_destroy_animation(struct anm_animation *anim) -{ - int i; - for(i=0; itracks + i); - } - free(anim->name); -} - -void anm_set_animation_name(struct anm_animation *anim, const char *name) -{ - char *newname = malloc(strlen(name) + 1); - if(!newname) return; - - strcpy(newname, name); - - free(anim->name); - anim->name = newname; -} - -/* ---- node implementation ----- */ - -int anm_init_node(struct anm_node *node) -{ - memset(node, 0, sizeof *node); - - node->cur_anim[1] = -1; - - if(!(node->animations = dynarr_alloc(1, sizeof *node->animations))) { - return -1; - } - if(anm_init_animation(node->animations) == -1) { - dynarr_free(node->animations); - return -1; - } - - /* initialize thread-local matrix cache */ - pthread_key_create(&node->cache_key, 0); - pthread_mutex_init(&node->cache_list_lock, 0); - - return 0; -} - -void anm_destroy_node(struct anm_node *node) -{ - int i; - free(node->name); - - for(i=0; ianimations + i); - } - dynarr_free(node->animations); - - /* destroy thread-specific cache */ - pthread_key_delete(node->cache_key); - - while(node->cache_list) { - struct mat_cache *tmp = node->cache_list; - node->cache_list = tmp->next; - free(tmp); - } -} - -void anm_destroy_node_tree(struct anm_node *tree) -{ - struct anm_node *c, *tmp; - - if(!tree) return; - - c = tree->child; - while(c) { - tmp = c; - c = c->next; - - anm_destroy_node_tree(tmp); - } - anm_destroy_node(tree); -} - -struct anm_node *anm_create_node(void) -{ - struct anm_node *n; - - if((n = malloc(sizeof *n))) { - if(anm_init_node(n) == -1) { - free(n); - return 0; - } - } - return n; -} - -void anm_free_node(struct anm_node *node) -{ - anm_destroy_node(node); - free(node); -} - -void anm_free_node_tree(struct anm_node *tree) -{ - struct anm_node *c, *tmp; - - if(!tree) return; - - c = tree->child; - while(c) { - tmp = c; - c = c->next; - - anm_free_node_tree(tmp); - } - - anm_free_node(tree); -} - -int anm_set_node_name(struct anm_node *node, const char *name) -{ - char *str; - - if(!(str = malloc(strlen(name) + 1))) { - return -1; - } - strcpy(str, name); - free(node->name); - node->name = str; - return 0; -} - -const char *anm_get_node_name(struct anm_node *node) -{ - return node->name ? node->name : ""; -} - -void anm_link_node(struct anm_node *p, struct anm_node *c) -{ - c->next = p->child; - p->child = c; - - c->parent = p; - invalidate_cache(c); -} - -int anm_unlink_node(struct anm_node *p, struct anm_node *c) -{ - struct anm_node *iter; - - if(p->child == c) { - p->child = c->next; - c->next = 0; - invalidate_cache(c); - return 0; - } - - iter = p->child; - while(iter->next) { - if(iter->next == c) { - iter->next = c->next; - c->next = 0; - invalidate_cache(c); - return 0; - } - } - return -1; -} - -void anm_set_pivot(struct anm_node *node, vec3_t piv) -{ - node->pivot = piv; -} - -vec3_t anm_get_pivot(struct anm_node *node) -{ - return node->pivot; -} - - -/* animation management */ - -int anm_use_node_animation(struct anm_node *node, int aidx) -{ - if(aidx == node->cur_anim[0] && node->cur_anim[1] == -1) { - return 0; /* no change, no invalidation */ - } - - if(aidx < 0 || aidx >= anm_get_animation_count(node)) { - return -1; - } - - node->cur_anim[0] = aidx; - node->cur_anim[1] = -1; - node->cur_mix = 0; - node->blend_dur = -1; - - invalidate_cache(node); - return 0; -} - -int anm_use_node_animations(struct anm_node *node, int aidx, int bidx, float t) -{ - int num_anim; - - if(node->cur_anim[0] == aidx && node->cur_anim[1] == bidx && - fabs(t - node->cur_mix) < 1e-6) { - return 0; /* no change, no invalidation */ - } - - num_anim = anm_get_animation_count(node); - if(aidx < 0 || aidx >= num_anim) { - return anm_use_animation(node, bidx); - } - if(bidx < 0 || bidx >= num_anim) { - return anm_use_animation(node, aidx); - } - node->cur_anim[0] = aidx; - node->cur_anim[1] = bidx; - node->cur_mix = t; - - invalidate_cache(node); - return 0; -} - -int anm_use_animation(struct anm_node *node, int aidx) -{ - struct anm_node *child; - - if(anm_use_node_animation(node, aidx) == -1) { - return -1; - } - - child = node->child; - while(child) { - if(anm_use_animation(child, aidx) == -1) { - return -1; - } - child = child->next; - } - return 0; -} - -int anm_use_animations(struct anm_node *node, int aidx, int bidx, float t) -{ - struct anm_node *child; - - if(anm_use_node_animations(node, aidx, bidx, t) == -1) { - return -1; - } - - child = node->child; - while(child) { - if(anm_use_animations(child, aidx, bidx, t) == -1) { - return -1; - } - child = child->next; - } - return 0; - -} - -void anm_set_node_animation_offset(struct anm_node *node, anm_time_t offs, int which) -{ - if(which < 0 || which >= 2) { - return; - } - node->cur_anim_offset[which] = offs; -} - -anm_time_t anm_get_animation_offset(const struct anm_node *node, int which) -{ - if(which < 0 || which >= 2) { - return 0; - } - return node->cur_anim_offset[which]; -} - -void anm_set_animation_offset(struct anm_node *node, anm_time_t offs, int which) -{ - struct anm_node *c = node->child; - while(c) { - anm_set_animation_offset(c, offs, which); - c = c->next; - } - - anm_set_node_animation_offset(node, offs, which); -} - -int anm_get_active_animation_index(const struct anm_node *node, int which) -{ - if(which < 0 || which >= 2) return -1; - return node->cur_anim[which]; -} - -struct anm_animation *anm_get_active_animation(const struct anm_node *node, int which) -{ - int idx = anm_get_active_animation_index(node, which); - if(idx < 0 || idx >= anm_get_animation_count(node)) { - return 0; - } - return node->animations + idx; -} - -float anm_get_active_animation_mix(const struct anm_node *node) -{ - return node->cur_mix; -} - -int anm_get_animation_count(const struct anm_node *node) -{ - return dynarr_size(node->animations); -} - -int anm_add_node_animation(struct anm_node *node) -{ - struct anm_animation newanim; - anm_init_animation(&newanim); - - node->animations = dynarr_push(node->animations, &newanim); - return 0; -} - -int anm_remove_node_animation(struct anm_node *node, int idx) -{ - fprintf(stderr, "anm_remove_animation: unimplemented!"); - abort(); - return 0; -} - -int anm_add_animation(struct anm_node *node) -{ - struct anm_node *child; - - if(anm_add_node_animation(node) == -1) { - return -1; - } - - child = node->child; - while(child) { - if(anm_add_animation(child)) { - return -1; - } - child = child->next; - } - return 0; -} - -int anm_remove_animation(struct anm_node *node, int idx) -{ - struct anm_node *child; - - if(anm_remove_node_animation(node, idx) == -1) { - return -1; - } - - child = node->child; - while(child) { - if(anm_remove_animation(child, idx) == -1) { - return -1; - } - child = child->next; - } - return 0; -} - -struct anm_animation *anm_get_animation(struct anm_node *node, int idx) -{ - if(idx < 0 || idx > anm_get_animation_count(node)) { - return 0; - } - return node->animations + idx; -} - -struct anm_animation *anm_get_animation_by_name(struct anm_node *node, const char *name) -{ - return anm_get_animation(node, anm_find_animation(node, name)); -} - -int anm_find_animation(struct anm_node *node, const char *name) -{ - int i, count = anm_get_animation_count(node); - for(i=0; ianimations[i].name, name) == 0) { - return i; - } - } - return -1; -} - -/* all the rest act on the current animation(s) */ - -void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in) -{ - int i; - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(!anim) return; - - for(i=0; itracks + i, in); - } - invalidate_cache(node); -} - -void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex) -{ - int i; - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(!anim) return; - - for(i=0; itracks + i, ex); - } - invalidate_cache(node); -} - -void anm_set_node_active_animation_name(struct anm_node *node, const char *name) -{ - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(!anim) return; - - anm_set_animation_name(anim, name); -} - -void anm_set_active_animation_name(struct anm_node *node, const char *name) -{ - struct anm_node *child; - - anm_set_node_active_animation_name(node, name); - - child = node->child; - while(child) { - anm_set_active_animation_name(child, name); - child = child->next; - } -} - -const char *anm_get_active_animation_name(struct anm_node *node) -{ - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(anim) { - return anim->name; - } - return 0; -} - -/* ---- high level animation blending ---- */ -void anm_transition(struct anm_node *node, int anmidx, anm_time_t start, anm_time_t dur) -{ - struct anm_node *c = node->child; - - if(anmidx == node->cur_anim[0]) { - return; - } - - while(c) { - anm_transition(c, anmidx, start, dur); - c = c->next; - } - - anm_node_transition(node, anmidx, start, dur); -} - -void anm_node_transition(struct anm_node *node, int anmidx, anm_time_t start, anm_time_t dur) -{ - if(anmidx == node->cur_anim[0]) { - return; - } - - node->cur_anim[1] = anmidx; - node->cur_anim_offset[1] = start; - node->blend_dur = dur; -} - - -#define BLEND_START_TM node->cur_anim_offset[1] - -static anm_time_t animation_time(struct anm_node *node, anm_time_t tm, int which) -{ - float t; - - if(node->blend_dur >= 0) { - /* we're in transition... */ - t = (float)(tm - BLEND_START_TM) / (float)node->blend_dur; - if(t < 0.0) t = 0.0; - - node->cur_mix = t; - - if(t > 1.0) { - /* switch completely over to the target animation and stop blending */ - anm_use_node_animation(node, node->cur_anim[1]); - node->cur_anim_offset[0] = node->cur_anim_offset[1]; - } - } - - return tm - node->cur_anim_offset[which]; -} - - -void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm) -{ - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(!anim) return; - - anm_set_value(anim->tracks + ANM_TRACK_POS_X, tm, pos.x); - anm_set_value(anim->tracks + ANM_TRACK_POS_Y, tm, pos.y); - anm_set_value(anim->tracks + ANM_TRACK_POS_Z, tm, pos.z); - invalidate_cache(node); -} - - -vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm) -{ - vec3_t v; - anm_time_t tm0 = animation_time(node, tm, 0); - struct anm_animation *anim0 = anm_get_active_animation(node, 0); - struct anm_animation *anim1 = anm_get_active_animation(node, 1); - - if(!anim0) { - return v3_cons(0, 0, 0); - } - - v.x = anm_get_value(anim0->tracks + ANM_TRACK_POS_X, tm0); - v.y = anm_get_value(anim0->tracks + ANM_TRACK_POS_Y, tm0); - v.z = anm_get_value(anim0->tracks + ANM_TRACK_POS_Z, tm0); - - if(anim1) { - vec3_t v1; - anm_time_t tm1 = animation_time(node, tm, 1); - v1.x = anm_get_value(anim1->tracks + ANM_TRACK_POS_X, tm1); - v1.y = anm_get_value(anim1->tracks + ANM_TRACK_POS_Y, tm1); - v1.z = anm_get_value(anim1->tracks + ANM_TRACK_POS_Z, tm1); - - v.x = v.x + (v1.x - v.x) * node->cur_mix; - v.y = v.y + (v1.y - v.y) * node->cur_mix; - v.z = v.z + (v1.z - v.z) * node->cur_mix; - } - - return v; -} - -void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm) -{ - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(!anim) return; - - anm_set_value(anim->tracks + ANM_TRACK_ROT_X, tm, rot.x); - anm_set_value(anim->tracks + ANM_TRACK_ROT_Y, tm, rot.y); - anm_set_value(anim->tracks + ANM_TRACK_ROT_Z, tm, rot.z); - anm_set_value(anim->tracks + ANM_TRACK_ROT_W, tm, rot.w); - invalidate_cache(node); -} - -static quat_t get_node_rotation(struct anm_node *node, anm_time_t tm, struct anm_animation *anim) -{ -#ifndef ROT_USE_SLERP - quat_t q; - q.x = anm_get_value(anim->tracks + ANM_TRACK_ROT_X, tm); - q.y = anm_get_value(anim->tracks + ANM_TRACK_ROT_Y, tm); - q.z = anm_get_value(anim->tracks + ANM_TRACK_ROT_Z, tm); - q.w = anm_get_value(anim->tracks + ANM_TRACK_ROT_W, tm); - return q; -#else - int idx0, idx1, last_idx; - anm_time_t tstart, tend; - float t, dt; - struct anm_track *track_x, *track_y, *track_z, *track_w; - quat_t q, q1, q2; - - track_x = anim->tracks + ANM_TRACK_ROT_X; - track_y = anim->tracks + ANM_TRACK_ROT_Y; - track_z = anim->tracks + ANM_TRACK_ROT_Z; - track_w = anim->tracks + ANM_TRACK_ROT_W; - - if(!track_x->count) { - q.x = track_x->def_val; - q.y = track_y->def_val; - q.z = track_z->def_val; - q.w = track_w->def_val; - return q; - } - - last_idx = track_x->count - 1; - - tstart = track_x->keys[0].time; - tend = track_x->keys[last_idx].time; - - if(tstart == tend) { - q.x = track_x->keys[0].val; - q.y = track_y->keys[0].val; - q.z = track_z->keys[0].val; - q.w = track_w->keys[0].val; - return q; - } - - tm = anm_remap_time(track_x, tm, tstart, tend); - - idx0 = anm_get_key_interval(track_x, tm); - assert(idx0 >= 0 && idx0 < track_x->count); - idx1 = idx0 + 1; - - if(idx0 == last_idx) { - q.x = track_x->keys[idx0].val; - q.y = track_y->keys[idx0].val; - q.z = track_z->keys[idx0].val; - q.w = track_w->keys[idx0].val; - return q; - } - - dt = (float)(track_x->keys[idx1].time - track_x->keys[idx0].time); - t = (float)(tm - track_x->keys[idx0].time) / dt; - - q1.x = track_x->keys[idx0].val; - q1.y = track_y->keys[idx0].val; - q1.z = track_z->keys[idx0].val; - q1.w = track_w->keys[idx0].val; - - q2.x = track_x->keys[idx1].val; - q2.y = track_y->keys[idx1].val; - q2.z = track_z->keys[idx1].val; - q2.w = track_w->keys[idx1].val; - - /*q1 = quat_normalize(q1); - q2 = quat_normalize(q2);*/ - - return quat_slerp(q1, q2, t); -#endif -} - -quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm) -{ - quat_t q; - anm_time_t tm0 = animation_time(node, tm, 0); - struct anm_animation *anim0 = anm_get_active_animation(node, 0); - struct anm_animation *anim1 = anm_get_active_animation(node, 1); - - if(!anim0) { - return quat_identity(); - } - - q = get_node_rotation(node, tm0, anim0); - - if(anim1) { - anm_time_t tm1 = animation_time(node, tm, 1); - quat_t q1 = get_node_rotation(node, tm1, anim1); - - q = quat_slerp(q, q1, node->cur_mix); - } - return q; -} - -void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm) -{ - struct anm_animation *anim = anm_get_active_animation(node, 0); - if(!anim) return; - - anm_set_value(anim->tracks + ANM_TRACK_SCL_X, tm, scl.x); - anm_set_value(anim->tracks + ANM_TRACK_SCL_Y, tm, scl.y); - anm_set_value(anim->tracks + ANM_TRACK_SCL_Z, tm, scl.z); - invalidate_cache(node); -} - -vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm) -{ - vec3_t v; - anm_time_t tm0 = animation_time(node, tm, 0); - struct anm_animation *anim0 = anm_get_active_animation(node, 0); - struct anm_animation *anim1 = anm_get_active_animation(node, 1); - - if(!anim0) { - return v3_cons(1, 1, 1); - } - - v.x = anm_get_value(anim0->tracks + ANM_TRACK_SCL_X, tm0); - v.y = anm_get_value(anim0->tracks + ANM_TRACK_SCL_Y, tm0); - v.z = anm_get_value(anim0->tracks + ANM_TRACK_SCL_Z, tm0); - - if(anim1) { - vec3_t v1; - anm_time_t tm1 = animation_time(node, tm, 1); - v1.x = anm_get_value(anim1->tracks + ANM_TRACK_SCL_X, tm1); - v1.y = anm_get_value(anim1->tracks + ANM_TRACK_SCL_Y, tm1); - v1.z = anm_get_value(anim1->tracks + ANM_TRACK_SCL_Z, tm1); - - v.x = v.x + (v1.x - v.x) * node->cur_mix; - v.y = v.y + (v1.y - v.y) * node->cur_mix; - v.z = v.z + (v1.z - v.z) * node->cur_mix; - } - - return v; -} - - -vec3_t anm_get_position(struct anm_node *node, anm_time_t tm) -{ - mat4_t xform; - vec3_t pos = {0.0, 0.0, 0.0}; - - if(!node->parent) { - return anm_get_node_position(node, tm); - } - - anm_get_matrix(node, xform, tm); - return v3_transform(pos, xform); -} - -quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm) -{ - quat_t rot, prot; - rot = anm_get_node_rotation(node, tm); - - if(!node->parent) { - return rot; - } - - prot = anm_get_rotation(node->parent, tm); - return quat_mul(prot, rot); -} - -vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm) -{ - vec3_t s, ps; - s = anm_get_node_scaling(node, tm); - - if(!node->parent) { - return s; - } - - ps = anm_get_scaling(node->parent, tm); - return v3_mul(s, ps); -} - -void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) -{ - int i; - mat4_t rmat; - vec3_t pos, scale; - quat_t rot; - - pos = anm_get_node_position(node, tm); - rot = anm_get_node_rotation(node, tm); - scale = anm_get_node_scaling(node, tm); - - m4_set_translation(mat, node->pivot.x, node->pivot.y, node->pivot.z); - - quat_to_mat4(rmat, rot); - for(i=0; i<3; i++) { - mat[i][0] = rmat[i][0]; - mat[i][1] = rmat[i][1]; - mat[i][2] = rmat[i][2]; - } - /* this loop is equivalent to: m4_mult(mat, mat, rmat); */ - - mat[0][0] *= scale.x; mat[0][1] *= scale.y; mat[0][2] *= scale.z; mat[0][3] += pos.x; - mat[1][0] *= scale.x; mat[1][1] *= scale.y; mat[1][2] *= scale.z; mat[1][3] += pos.y; - mat[2][0] *= scale.x; mat[2][1] *= scale.y; mat[2][2] *= scale.z; mat[2][3] += pos.z; - - m4_translate(mat, -node->pivot.x, -node->pivot.y, -node->pivot.z); - - /* that's basically: pivot * rotation * translation * scaling * -pivot */ -} - -void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) -{ - mat4_t tmp; - anm_get_node_matrix(node, tmp, tm); - m4_inverse(mat, tmp); -} - -void anm_eval_node(struct anm_node *node, anm_time_t tm) -{ - anm_get_node_matrix(node, node->matrix, tm); -} - -void anm_eval(struct anm_node *node, anm_time_t tm) -{ - struct anm_node *c; - - anm_eval_node(node, tm); - - if(node->parent) { - /* due to post-order traversal, the parent matrix is already evaluated */ - m4_mult(node->matrix, node->parent->matrix, node->matrix); - } - - /* recersively evaluate all children */ - c = node->child; - while(c) { - anm_eval(c, tm); - c = c->next; - } -} - -void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) -{ - struct mat_cache *cache = pthread_getspecific(node->cache_key); - if(!cache) { - cache = malloc(sizeof *cache); - assert(cache); - - pthread_mutex_lock(&node->cache_list_lock); - cache->next = node->cache_list; - node->cache_list = cache; - pthread_mutex_unlock(&node->cache_list_lock); - - cache->time = ANM_TIME_INVAL; - cache->inv_time = ANM_TIME_INVAL; - pthread_setspecific(node->cache_key, cache); - } - - if(cache->time != tm) { - anm_get_node_matrix(node, cache->matrix, tm); - - if(node->parent) { - mat4_t parent_mat; - - anm_get_matrix(node->parent, parent_mat, tm); - m4_mult(cache->matrix, parent_mat, cache->matrix); - } - cache->time = tm; - } - m4_copy(mat, cache->matrix); -} - -void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) -{ - struct mat_cache *cache = pthread_getspecific(node->cache_key); - if(!cache) { - cache = malloc(sizeof *cache); - assert(cache); - - pthread_mutex_lock(&node->cache_list_lock); - cache->next = node->cache_list; - node->cache_list = cache; - pthread_mutex_unlock(&node->cache_list_lock); - - cache->inv_time = ANM_TIME_INVAL; - cache->inv_time = ANM_TIME_INVAL; - pthread_setspecific(node->cache_key, cache); - } - - if(cache->inv_time != tm) { - anm_get_matrix(node, mat, tm); - m4_inverse(cache->inv_matrix, mat); - cache->inv_time = tm; - } - m4_copy(mat, cache->inv_matrix); -} - -anm_time_t anm_get_start_time(struct anm_node *node) -{ - int i, j; - struct anm_node *c; - anm_time_t res = LONG_MAX; - - for(j=0; j<2; j++) { - struct anm_animation *anim = anm_get_active_animation(node, j); - if(!anim) break; - - for(i=0; itracks[i].count) { - anm_time_t tm = anim->tracks[i].keys[0].time; - if(tm < res) { - res = tm; - } - } - } - } - - c = node->child; - while(c) { - anm_time_t tm = anm_get_start_time(c); - if(tm < res) { - res = tm; - } - c = c->next; - } - return res; -} - -anm_time_t anm_get_end_time(struct anm_node *node) -{ - int i, j; - struct anm_node *c; - anm_time_t res = LONG_MIN; - - for(j=0; j<2; j++) { - struct anm_animation *anim = anm_get_active_animation(node, j); - if(!anim) break; - - for(i=0; itracks[i].count) { - anm_time_t tm = anim->tracks[i].keys[anim->tracks[i].count - 1].time; - if(tm > res) { - res = tm; - } - } - } - } - - c = node->child; - while(c) { - anm_time_t tm = anm_get_end_time(c); - if(tm > res) { - res = tm; - } - c = c->next; - } - return res; -} - -static void invalidate_cache(struct anm_node *node) -{ - struct mat_cache *cache = pthread_getspecific(node->cache_key); - if(cache) { - cache->time = cache->inv_time = ANM_TIME_INVAL; - } -} diff -r dad392c710df -r 99715321ad6d libs/anim/anim.h --- a/libs/anim/anim.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,219 +0,0 @@ -#ifndef LIBANIM_H_ -#define LIBANIM_H_ - -#include "config.h" - -#include - -#include -#include -#include -#include "track.h" - -enum { - ANM_TRACK_POS_X, - ANM_TRACK_POS_Y, - ANM_TRACK_POS_Z, - - ANM_TRACK_ROT_X, - ANM_TRACK_ROT_Y, - ANM_TRACK_ROT_Z, - ANM_TRACK_ROT_W, - - ANM_TRACK_SCL_X, - ANM_TRACK_SCL_Y, - ANM_TRACK_SCL_Z, - - ANM_NUM_TRACKS -}; - -struct anm_animation { - char *name; - struct anm_track tracks[ANM_NUM_TRACKS]; -}; - -struct anm_node { - char *name; - - int cur_anim[2]; - anm_time_t cur_anim_offset[2]; - float cur_mix; - - /* high-level animation blending transition duration */ - anm_time_t blend_dur; - - struct anm_animation *animations; - vec3_t pivot; - - /* matrix cache */ - struct mat_cache { - mat4_t matrix, inv_matrix; - anm_time_t time, inv_time; - struct mat_cache *next; - } *cache_list; - pthread_key_t cache_key; - pthread_mutex_t cache_list_lock; - - /* matrix calculated by anm_eval functions (no locking, meant as a pre-pass) */ - mat4_t matrix; - - struct anm_node *parent; - struct anm_node *child; - struct anm_node *next; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int anm_init_animation(struct anm_animation *anim); -void anm_destroy_animation(struct anm_animation *anim); - -void anm_set_animation_name(struct anm_animation *anim, const char *name); - - -/* ---- node/hierarchy management ---- */ - -/* node constructor and destructor */ -int anm_init_node(struct anm_node *node); -void anm_destroy_node(struct anm_node *node); - -/* recursively destroy an animation node tree */ -void anm_destroy_node_tree(struct anm_node *tree); - -/* helper functions to allocate/construct and destroy/free with - * a single call. They call anm_init_node and anm_destroy_node - * internally. - */ -struct anm_node *anm_create_node(void); -void anm_free_node(struct anm_node *node); - -/* recursively destroy and free the nodes of a node tree */ -void anm_free_node_tree(struct anm_node *tree); - -int anm_set_node_name(struct anm_node *node, const char *name); -const char *anm_get_node_name(struct anm_node *node); - -/* link and unlink nodes with parent/child relations */ -void anm_link_node(struct anm_node *parent, struct anm_node *child); -int anm_unlink_node(struct anm_node *parent, struct anm_node *child); - -void anm_set_pivot(struct anm_node *node, vec3_t pivot); -vec3_t anm_get_pivot(struct anm_node *node); - -/* ---- multiple animations and animation blending ---- */ - -/* set active animation(s) */ -int anm_use_node_animation(struct anm_node *node, int aidx); -int anm_use_node_animations(struct anm_node *node, int aidx, int bidx, float t); -/* recursive variants */ -int anm_use_animation(struct anm_node *node, int aidx); -int anm_use_animations(struct anm_node *node, int aidx, int bidx, float t); - -/* set/get current animation offset(s) */ -void anm_set_node_animation_offset(struct anm_node *node, anm_time_t offs, int which); -anm_time_t anm_get_animation_offset(const struct anm_node *node, int which); -/* recursive variant */ -void anm_set_animation_offset(struct anm_node *node, anm_time_t offs, int which); - -/* returns the requested current animation index, which can be 0 or 1 */ -int anm_get_active_animation_index(const struct anm_node *node, int which); -/* returns the requested current animation, which can be 0 or 1 */ -struct anm_animation *anm_get_active_animation(const struct anm_node *node, int which); -float anm_get_active_animation_mix(const struct anm_node *node); - -int anm_get_animation_count(const struct anm_node *node); - -/* add/remove an animation to the specified node */ -int anm_add_node_animation(struct anm_node *node); -int anm_remove_node_animation(struct anm_node *node, int idx); - -/* add/remove an animation to the specified node and all it's descendants */ -int anm_add_animation(struct anm_node *node); -int anm_remove_animation(struct anm_node *node, int idx); - -struct anm_animation *anm_get_animation(struct anm_node *node, int idx); -struct anm_animation *anm_get_animation_by_name(struct anm_node *node, const char *name); - -int anm_find_animation(struct anm_node *node, const char *name); - -/* set the interpolator for the (first) currently active animation */ -void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in); -/* set the extrapolator for the (first) currently active animation */ -void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex); - -/* set the name of the currently active animation of this node only */ -void anm_set_node_active_animation_name(struct anm_node *node, const char *name); -/* recursively set the name of the currently active animation for this node - * and all it's descendants */ -void anm_set_active_animation_name(struct anm_node *node, const char *name); -/* get the name of the currently active animation of this node */ -const char *anm_get_active_animation_name(struct anm_node *node); - - -/* ---- high level animation blending interface ---- */ -/* XXX this convenience interface assumes monotonically increasing time values - * in all subsequent calls to anm_get_* and anm_eval_* functions. - * - * anmidx: index of the animation to transition to - * start: when to start the transition - * dur: transition duration - * - * sets up a transition from the current animation (cur_anim[0]) to another animation. - * at time start + dur, the transition will be completed, cur_anim[0] will be the new - * animation and cur_anim_offset[0] will be equal to start. - */ -void anm_transition(struct anm_node *node, int anmidx, anm_time_t start, anm_time_t dur); -/* non-recursive variant, acts on a single node (you probably DON'T want to use this) */ -void anm_node_transition(struct anm_node *node, int anmidx, anm_time_t start, anm_time_t dur); - - -/* ---- keyframes / PRS interpolation ---- */ - -void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm); -vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm); - -void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm); -quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm); - -void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm); -vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm); - -/* these three return the full p/r/s taking hierarchy into account */ -vec3_t anm_get_position(struct anm_node *node, anm_time_t tm); -quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm); -vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm); - -/* those return the start and end times of the whole tree */ -anm_time_t anm_get_start_time(struct anm_node *node); -anm_time_t anm_get_end_time(struct anm_node *node); - - -/* ---- transformation matrices ---- */ - -/* these calculate the matrix and inverse matrix of this node alone */ -void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); -void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); - -/* ---- top-down matrix calculation interface ---- */ - -/* calculate and set the matrix of this node */ -void anm_eval_node(struct anm_node *node, anm_time_t tm); -/* calculate and set the matrix of this node and all its children recursively */ -void anm_eval(struct anm_node *node, anm_time_t tm); - - -/* ---- bottom-up lazy matrix calculation interface ---- */ - -/* These calculate the matrix and inverse matrix of this node taking hierarchy - * into account. The results are cached in thread-specific storage and returned - * if there's no change in time or tracks from the last query... - */ -void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); -void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); - -#ifdef __cplusplus -} -#endif - -#endif /* LIBANIM_H_ */ diff -r dad392c710df -r 99715321ad6d libs/anim/config.h --- a/libs/anim/config.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -#ifndef ANIM_CONFIG_H_ -#define ANIM_CONFIG_H_ - -#undef ANIM_THREAD_SAFE - -#endif /* ANIM_CONFIG_H_ */ diff -r dad392c710df -r 99715321ad6d libs/anim/dynarr.c --- a/libs/anim/dynarr.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -#include -#include -#include -#include "dynarr.h" - -/* The array descriptor keeps auxilliary information needed to manipulate - * the dynamic array. It's allocated adjacent to the array buffer. - */ -struct arrdesc { - int nelem, szelem; - int max_elem; - int bufsz; /* not including the descriptor */ -}; - -#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc))) - -void *dynarr_alloc(int elem, int szelem) -{ - struct arrdesc *desc; - - if(!(desc = malloc(elem * szelem + sizeof *desc))) { - return 0; - } - desc->nelem = desc->max_elem = elem; - desc->szelem = szelem; - desc->bufsz = elem * szelem; - return (char*)desc + sizeof *desc; -} - -void dynarr_free(void *da) -{ - if(da) { - free(DESC(da)); - } -} - -void *dynarr_resize(void *da, int elem) -{ - int newsz; - void *tmp; - struct arrdesc *desc; - - if(!da) return 0; - desc = DESC(da); - - newsz = desc->szelem * elem; - - if(!(tmp = realloc(desc, newsz + sizeof *desc))) { - return 0; - } - desc = tmp; - - desc->nelem = desc->max_elem = elem; - desc->bufsz = newsz; - return (char*)desc + sizeof *desc; -} - -int dynarr_empty(void *da) -{ - return DESC(da)->nelem ? 0 : 1; -} - -int dynarr_size(void *da) -{ - return DESC(da)->nelem; -} - - -/* stack semantics */ -void *dynarr_push(void *da, void *item) -{ - struct arrdesc *desc; - int nelem; - - desc = DESC(da); - nelem = desc->nelem; - - if(nelem >= desc->max_elem) { - /* need to resize */ - struct arrdesc *tmp; - int newsz = desc->max_elem ? desc->max_elem * 2 : 1; - - if(!(tmp = dynarr_resize(da, newsz))) { - fprintf(stderr, "failed to resize\n"); - return da; - } - da = tmp; - desc = DESC(da); - desc->nelem = nelem; - } - - memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem); - return da; -} - -void *dynarr_pop(void *da) -{ - struct arrdesc *desc; - int nelem; - - desc = DESC(da); - nelem = desc->nelem; - - if(!nelem) return da; - - if(nelem <= desc->max_elem / 3) { - /* reclaim space */ - struct arrdesc *tmp; - int newsz = desc->max_elem / 2; - - if(!(tmp = dynarr_resize(da, newsz))) { - fprintf(stderr, "failed to resize\n"); - return da; - } - da = tmp; - desc = DESC(da); - desc->nelem = nelem; - } - desc->nelem--; - - return da; -} diff -r dad392c710df -r 99715321ad6d libs/anim/dynarr.h --- a/libs/anim/dynarr.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -#ifndef DYNARR_H_ -#define DYNARR_H_ - -void *dynarr_alloc(int elem, int szelem); -void dynarr_free(void *da); -void *dynarr_resize(void *da, int elem); - -int dynarr_empty(void *da); -int dynarr_size(void *da); - -/* stack semantics */ -void *dynarr_push(void *da, void *item); -void *dynarr_pop(void *da); - - -#endif /* DYNARR_H_ */ diff -r dad392c710df -r 99715321ad6d libs/anim/track.c --- a/libs/anim/track.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,316 +0,0 @@ -#include -#include -#include -#include "track.h" -#include "dynarr.h" - -static int keycmp(const void *a, const void *b); -static int find_prev_key(struct anm_keyframe *arr, int start, int end, anm_time_t tm); - -static float interp_step(float v0, float v1, float v2, float v3, float t); -static float interp_linear(float v0, float v1, float v2, float v3, float t); -static float interp_cubic(float v0, float v1, float v2, float v3, float t); - -static anm_time_t remap_extend(anm_time_t tm, anm_time_t start, anm_time_t end); -static anm_time_t remap_clamp(anm_time_t tm, anm_time_t start, anm_time_t end); -static anm_time_t remap_repeat(anm_time_t tm, anm_time_t start, anm_time_t end); -static anm_time_t remap_pingpong(anm_time_t tm, anm_time_t start, anm_time_t end); - -/* XXX keep this in sync with enum anm_interpolator at track.h */ -static float (*interp[])(float, float, float, float, float) = { - interp_step, - interp_linear, - interp_cubic, - 0 -}; - -/* XXX keep this in sync with enum anm_extrapolator at track.h */ -static anm_time_t (*remap_time[])(anm_time_t, anm_time_t, anm_time_t) = { - remap_extend, - remap_clamp, - remap_repeat, - remap_pingpong, - 0 -}; - -int anm_init_track(struct anm_track *track) -{ - memset(track, 0, sizeof *track); - - if(!(track->keys = dynarr_alloc(0, sizeof *track->keys))) { - return -1; - } - track->interp = ANM_INTERP_LINEAR; - track->extrap = ANM_EXTRAP_CLAMP; - return 0; -} - -void anm_destroy_track(struct anm_track *track) -{ - dynarr_free(track->keys); -} - -struct anm_track *anm_create_track(void) -{ - struct anm_track *track; - - if((track = malloc(sizeof *track))) { - if(anm_init_track(track) == -1) { - free(track); - return 0; - } - } - return track; -} - -void anm_free_track(struct anm_track *track) -{ - anm_destroy_track(track); - free(track); -} - -void anm_copy_track(struct anm_track *dest, const struct anm_track *src) -{ - free(dest->name); - if(dest->keys) { - dynarr_free(dest->keys); - } - - if(src->name) { - dest->name = malloc(strlen(src->name) + 1); - strcpy(dest->name, src->name); - } - - dest->count = src->count; - dest->keys = dynarr_alloc(src->count, sizeof *dest->keys); - memcpy(dest->keys, src->keys, src->count * sizeof *dest->keys); - - dest->def_val = src->def_val; - dest->interp = src->interp; - dest->extrap = src->extrap; -} - -int anm_set_track_name(struct anm_track *track, const char *name) -{ - char *tmp; - - if(!(tmp = malloc(strlen(name) + 1))) { - return -1; - } - free(track->name); - track->name = tmp; - return 0; -} - -const char *anm_get_track_name(struct anm_track *track) -{ - return track->name; -} - -void anm_set_track_interpolator(struct anm_track *track, enum anm_interpolator in) -{ - track->interp = in; -} - -void anm_set_track_extrapolator(struct anm_track *track, enum anm_extrapolator ex) -{ - track->extrap = ex; -} - -anm_time_t anm_remap_time(struct anm_track *track, anm_time_t tm, anm_time_t start, anm_time_t end) -{ - return remap_time[track->extrap](tm, start, end); -} - -void anm_set_track_default(struct anm_track *track, float def) -{ - track->def_val = def; -} - -int anm_set_keyframe(struct anm_track *track, struct anm_keyframe *key) -{ - int idx = anm_get_key_interval(track, key->time); - - /* if we got a valid keyframe index, compare them... */ - if(idx >= 0 && idx < track->count && keycmp(key, track->keys + idx) == 0) { - /* ... it's the same key, just update the value */ - track->keys[idx].val = key->val; - } else { - /* ... it's a new key, add it and re-sort them */ - void *tmp; - if(!(tmp = dynarr_push(track->keys, key))) { - return -1; - } - track->keys = tmp; - /* TODO lazy qsort */ - qsort(track->keys, ++track->count, sizeof *track->keys, keycmp); - } - return 0; -} - -static int keycmp(const void *a, const void *b) -{ - return ((struct anm_keyframe*)a)->time - ((struct anm_keyframe*)b)->time; -} - -struct anm_keyframe *anm_get_keyframe(struct anm_track *track, int idx) -{ - if(idx < 0 || idx >= track->count) { - return 0; - } - return track->keys + idx; -} - -int anm_get_key_interval(struct anm_track *track, anm_time_t tm) -{ - int last; - - if(!track->count || tm < track->keys[0].time) { - return -1; - } - - last = track->count - 1; - if(tm > track->keys[last].time) { - return last; - } - - return find_prev_key(track->keys, 0, last, tm); -} - -static int find_prev_key(struct anm_keyframe *arr, int start, int end, anm_time_t tm) -{ - int mid; - - if(end - start <= 1) { - return start; - } - - mid = (start + end) / 2; - if(tm < arr[mid].time) { - return find_prev_key(arr, start, mid, tm); - } - if(tm > arr[mid].time) { - return find_prev_key(arr, mid, end, tm); - } - return mid; -} - -int anm_set_value(struct anm_track *track, anm_time_t tm, float val) -{ - struct anm_keyframe key; - key.time = tm; - key.val = val; - - return anm_set_keyframe(track, &key); -} - -float anm_get_value(struct anm_track *track, anm_time_t tm) -{ - int idx0, idx1, last_idx; - anm_time_t tstart, tend; - float t, dt; - float v0, v1, v2, v3; - - if(!track->count) { - return track->def_val; - } - - last_idx = track->count - 1; - - tstart = track->keys[0].time; - tend = track->keys[last_idx].time; - - if(tstart == tend) { - return track->keys[0].val; - } - - tm = remap_time[track->extrap](tm, tstart, tend); - - idx0 = anm_get_key_interval(track, tm); - assert(idx0 >= 0 && idx0 < track->count); - idx1 = idx0 + 1; - - if(idx0 == last_idx) { - return track->keys[idx0].val; - } - - dt = (float)(track->keys[idx1].time - track->keys[idx0].time); - t = (float)(tm - track->keys[idx0].time) / dt; - - v1 = track->keys[idx0].val; - v2 = track->keys[idx1].val; - - /* get the neigboring values to allow for cubic interpolation */ - v0 = idx0 > 0 ? track->keys[idx0 - 1].val : v1; - v3 = idx1 < last_idx ? track->keys[idx1 + 1].val : v2; - - return interp[track->interp](v0, v1, v2, v3, t); -} - - -static float interp_step(float v0, float v1, float v2, float v3, float t) -{ - return v1; -} - -static float interp_linear(float v0, float v1, float v2, float v3, float t) -{ - return v1 + (v2 - v1) * t; -} - -static float interp_cubic(float a, float b, float c, float d, float t) -{ - float x, y, z, w; - float tsq = t * t; - - x = -a + 3.0 * b - 3.0 * c + d; - y = 2.0 * a - 5.0 * b + 4.0 * c - d; - z = c - a; - w = 2.0 * b; - - return 0.5 * (x * tsq * t + y * tsq + z * t + w); -} - -static anm_time_t remap_extend(anm_time_t tm, anm_time_t start, anm_time_t end) -{ - return remap_repeat(tm, start, end); -} - -static anm_time_t remap_clamp(anm_time_t tm, anm_time_t start, anm_time_t end) -{ - if(start == end) { - return start; - } - return tm < start ? start : (tm >= end ? end - 1 : tm); -} - -static anm_time_t remap_repeat(anm_time_t tm, anm_time_t start, anm_time_t end) -{ - anm_time_t x, interv = end - start; - - if(interv == 0) { - return start; - } - - x = (tm - start) % interv; - if(x < 0) { - x += interv; - } - return x + start; - - /*if(tm < start) { - while(tm < start) { - tm += interv; - } - return tm; - } - return (tm - start) % interv + start;*/ -} - -static anm_time_t remap_pingpong(anm_time_t tm, anm_time_t start, anm_time_t end) -{ - anm_time_t interv = end - start; - anm_time_t x = remap_repeat(tm, start, end + interv); - - return x > end ? end + interv - x : x; -} diff -r dad392c710df -r 99715321ad6d libs/anim/track.h --- a/libs/anim/track.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* An animation track defines the values of a single scalar over time - * and supports various interpolation and extrapolation modes. - */ -#ifndef LIBANIM_TRACK_H_ -#define LIBANIM_TRACK_H_ - -#include -#include "config.h" - -enum anm_interpolator { - ANM_INTERP_STEP, - ANM_INTERP_LINEAR, - ANM_INTERP_CUBIC -}; - -enum anm_extrapolator { - ANM_EXTRAP_EXTEND, /* extend to infinity */ - ANM_EXTRAP_CLAMP, /* clamp to last value */ - ANM_EXTRAP_REPEAT, /* repeat motion */ - ANM_EXTRAP_PINGPONG /* repeat with mirroring */ -}; - -typedef long anm_time_t; -#define ANM_TIME_INVAL LONG_MIN - -#define ANM_SEC2TM(x) ((anm_time_t)((x) * 1000)) -#define ANM_MSEC2TM(x) ((anm_time_t)(x)) -#define ANM_TM2SEC(x) ((x) / 1000.0) -#define ANM_TM2MSEC(x) (x) - -struct anm_keyframe { - anm_time_t time; - float val; -}; - -struct anm_track { - char *name; - int count; - struct anm_keyframe *keys; - - float def_val; - - enum anm_interpolator interp; - enum anm_extrapolator extrap; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/* track constructor and destructor */ -int anm_init_track(struct anm_track *track); -void anm_destroy_track(struct anm_track *track); - -/* helper functions that use anm_init_track and anm_destroy_track internally */ -struct anm_track *anm_create_track(void); -void anm_free_track(struct anm_track *track); - -/* copies track src to dest - * XXX: dest must have been initialized first - */ -void anm_copy_track(struct anm_track *dest, const struct anm_track *src); - -int anm_set_track_name(struct anm_track *track, const char *name); -const char *anm_get_track_name(struct anm_track *track); - -void anm_set_track_interpolator(struct anm_track *track, enum anm_interpolator in); -void anm_set_track_extrapolator(struct anm_track *track, enum anm_extrapolator ex); - -anm_time_t anm_remap_time(struct anm_track *track, anm_time_t tm, anm_time_t start, anm_time_t end); - -void anm_set_track_default(struct anm_track *track, float def); - -/* set or update a keyframe */ -int anm_set_keyframe(struct anm_track *track, struct anm_keyframe *key); - -/* get the idx-th keyframe, returns null if it doesn't exist */ -struct anm_keyframe *anm_get_keyframe(struct anm_track *track, int idx); - -/* Finds the 0-based index of the intra-keyframe interval which corresponds - * to the specified time. If the time falls exactly onto the N-th keyframe - * the function returns N. - * - * Special cases: - * - if the time is before the first keyframe -1 is returned. - * - if the time is after the last keyframe, the index of the last keyframe - * is returned. - */ -int anm_get_key_interval(struct anm_track *track, anm_time_t tm); - -int anm_set_value(struct anm_track *track, anm_time_t tm, float val); - -/* evaluates and returns the value of the track for a particular time */ -float anm_get_value(struct anm_track *track, anm_time_t tm); - -#ifdef __cplusplus -} -#endif - - -#endif /* LIBANIM_TRACK_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/Makefile --- a/libs/vmath/Makefile Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -csrc = $(wildcard *.c) -ccsrc = $(wildcard *.cc) -obj = $(csrc:.c=.o) $(ccsrc:.cc=.o) -lib = libvmath.a - -ifneq ($(shell uname -s), Darwin) - pic = -fPIC -endif - -CFLAGS = -pedantic -Wall -g $(pic) -CXXFLAGS = -pedantic -Wall -g $(pic) - -$(lib): $(obj) - $(AR) rcs $@ $(obj) - -.PHONY: clean -clean: - rm -f $(obj) $(lib) diff -r dad392c710df -r 99715321ad6d libs/vmath/basis.cc --- a/libs/vmath/basis.cc Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -#include "basis.h" -#include "vmath.h" - -Basis::Basis() -{ - i = Vector3(1, 0, 0); - j = Vector3(0, 1, 0); - k = Vector3(0, 0, 1); -} - -Basis::Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k) -{ - this->i = i; - this->j = j; - this->k = k; -} - -Basis::Basis(const Vector3 &dir, bool left_handed) -{ - k = dir; - j = Vector3(0, 1, 0); - i = cross_product(j, k); - j = cross_product(k, i); -} - -/** Rotate with euler angles */ -void Basis::rotate(scalar_t x, scalar_t y, scalar_t z) { - Matrix4x4 RotMat; - RotMat.set_rotation(Vector3(x, y, z)); - i.transform(RotMat); - j.transform(RotMat); - k.transform(RotMat); -} - -/** Rotate by axis-angle specification */ -void Basis::rotate(const Vector3 &axis, scalar_t angle) { - Quaternion q; - q.set_rotation(axis, angle); - i.transform(q); - j.transform(q); - k.transform(q); -} - -/** Rotate with a 4x4 matrix */ -void Basis::rotate(const Matrix4x4 &mat) { - i.transform(mat); - j.transform(mat); - k.transform(mat); -} - -/** Rotate with a quaternion */ -void Basis::rotate(const Quaternion &quat) { - i.transform(quat); - j.transform(quat); - k.transform(quat); -} - -/** Extract a rotation matrix from the orthogonal basis */ -Matrix3x3 Basis::create_rotation_matrix() const { - return Matrix3x3( i.x, j.x, k.x, - i.y, j.y, k.y, - i.z, j.z, k.z); -} diff -r dad392c710df -r 99715321ad6d libs/vmath/basis.h --- a/libs/vmath/basis.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_BASIS_H_ -#define VMATH_BASIS_H_ - -#include "vector.h" -#include "matrix.h" - -enum { - LEFT_HANDED, - RIGHT_HANDED -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k); -void basis_matrix_dir(mat4_t res, vec3_t dir); - -#ifdef __cplusplus -} /* extern "C" */ - -class Basis { -public: - Vector3 i, j, k; - - Basis(); - Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k); - Basis(const Vector3 &dir, bool left_handed = true); - - void rotate(scalar_t x, scalar_t y, scalar_t z); - void rotate(const Vector3 &axis, scalar_t angle); - void rotate(const Matrix4x4 &mat); - void rotate(const Quaternion &quat); - - Matrix3x3 create_rotation_matrix() const; -}; -#endif /* __cplusplus */ - -#endif /* VMATH_BASIS_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/basis_c.c --- a/libs/vmath/basis_c.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include "basis.h" -#include "matrix.h" - -void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k) -{ - m4_identity(res); - m4_set_column(res, v4_cons(i.x, i.y, i.z, 1.0), 0); - m4_set_column(res, v4_cons(j.x, j.y, j.z, 1.0), 1); - m4_set_column(res, v4_cons(k.x, k.y, k.z, 1.0), 2); -} - -void basis_matrix_dir(mat4_t res, vec3_t dir) -{ - vec3_t k = v3_normalize(dir); - vec3_t j = {0, 1, 0}; - vec3_t i = v3_cross(j, k); - j = v3_cross(k, i); - basis_matrix(res, i, j, k); -} diff -r dad392c710df -r 99715321ad6d libs/vmath/geom.c --- a/libs/vmath/geom.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - - -#include -#include "geom.h" -#include "vector.h" - -plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d) -{ - plane_t p; - p.norm.x = nx; - p.norm.y = ny; - p.norm.z = nz; - p.d = d; - return p; -} - -plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2) -{ - vec3_t a, b, norm; - - a = v3_sub(v1, v0); - b = v3_sub(v2, v0); - norm = v3_cross(a, b); - norm = v3_normalize(norm); - - return plane_ptnorm(v0, norm); -} - -plane_t plane_ptnorm(vec3_t pt, vec3_t normal) -{ - plane_t plane; - - plane.norm = normal; - plane.d = v3_dot(pt, normal); - - return plane; -} - -plane_t plane_invert(plane_t p) -{ - p.norm = v3_neg(p.norm); - p.d = -p.d; - return p; -} - -scalar_t plane_signed_dist(plane_t plane, vec3_t pt) -{ - vec3_t pp = plane_point(plane); - vec3_t pptopt = v3_sub(pt, pp); - return v3_dot(pptopt, plane.norm); -} - -scalar_t plane_dist(plane_t plane, vec3_t pt) -{ - return fabs(plane_signed_dist(plane, pt)); -} - -vec3_t plane_point(plane_t plane) -{ - return v3_scale(plane.norm, plane.d); -} - -int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos) -{ - vec3_t pt, orig_to_pt; - scalar_t ndotdir; - - pt = plane_point(plane); - ndotdir = v3_dot(plane.norm, ray.dir); - - if(fabs(ndotdir) < 1e-7) { - return 0; - } - - if(pos) { - orig_to_pt = v3_sub(pt, ray.origin); - *pos = v3_dot(plane.norm, orig_to_pt) / ndotdir; - } - return 1; -} - -sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad) -{ - sphere_t sph; - sph.pos.x = x; - sph.pos.y = y; - sph.pos.z = z; - sph.rad = rad; - return sph; -} - -int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos) -{ - scalar_t a, b, c, d, sqrt_d, t1, t2, t; - - a = v3_dot(ray.dir, ray.dir); - b = 2.0 * ray.dir.x * (ray.origin.x - sph.pos.x) + - 2.0 * ray.dir.y * (ray.origin.y - sph.pos.y) + - 2.0 * ray.dir.z * (ray.origin.z - sph.pos.z); - c = v3_dot(sph.pos, sph.pos) + v3_dot(ray.origin, ray.origin) + - 2.0 * v3_dot(v3_neg(sph.pos), ray.origin) - sph.rad * sph.rad; - - d = b * b - 4.0 * a * c; - if(d < 0.0) { - return 0; - } - - sqrt_d = sqrt(d); - t1 = (-b + sqrt_d) / (2.0 * a); - t2 = (-b - sqrt_d) / (2.0 * a); - - if(t1 < 1e-7 || t1 > 1.0) { - t1 = t2; - } - if(t2 < 1e-7 || t2 > 1.0) { - t2 = t1; - } - t = t1 < t2 ? t1 : t2; - - if(t < 1e-7 || t > 1.0) { - return 0; - } - - if(pos) { - *pos = t; - } - return 1; -} - -int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad) -{ - return -1; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/geom.h --- a/libs/vmath/geom.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2012 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ -#ifndef LIBVMATH_GEOM_H_ -#define LIBVMATH_GEOM_H_ - -#include "vector.h" -#include "ray.h" - -typedef struct { - vec3_t norm; - scalar_t d; -} plane_t; - -typedef struct { - vec3_t pos; - scalar_t rad; -} sphere_t; - -typedef struct { - vec3_t min, max; -} aabox_t; - -#ifdef __cplusplus -extern "C" { -#endif - -/* planes are good... you need planes, yes you do */ -plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d); -plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2); -plane_t plane_ptnorm(vec3_t pt, vec3_t normal); - -plane_t plane_invert(plane_t p); - -scalar_t plane_signed_dist(plane_t plane, vec3_t pt); -scalar_t plane_dist(plane_t plane, vec3_t pt); -vec3_t plane_point(plane_t plane); - -int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos); - -/* spheres always come in handy */ -sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad); - -int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos); -int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad); - -#ifdef __cplusplus -} - -/* TODO -class Plane : public plane_t { -public: -}; -*/ - -#endif - -#endif /* LIBVMATH_GEOM_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/matrix.cc --- a/libs/vmath/matrix.cc Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,821 +0,0 @@ -#include -#include -#include "matrix.h" -#include "vector.h" -#include "quat.h" - -using namespace std; - -// ----------- Matrix3x3 -------------- - -Matrix3x3 Matrix3x3::identity = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); - -Matrix3x3::Matrix3x3() -{ - *this = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); -} - -Matrix3x3::Matrix3x3( scalar_t m11, scalar_t m12, scalar_t m13, - scalar_t m21, scalar_t m22, scalar_t m23, - scalar_t m31, scalar_t m32, scalar_t m33) -{ - m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; - m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; - m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; -} - -Matrix3x3::Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec) -{ - set_row_vector(ivec, 0); - set_row_vector(jvec, 1); - set_row_vector(kvec, 2); -} - -Matrix3x3::Matrix3x3(const mat3_t cmat) -{ - memcpy(m, cmat, sizeof(mat3_t)); -} - -Matrix3x3::Matrix3x3(const Matrix4x4 &mat4x4) -{ - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - m[i][j] = mat4x4[i][j]; - } - } -} - -Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2) -{ - Matrix3x3 res; - const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; - scalar_t *dest = res.m[0]; - - for(int i=0; i<9; i++) { - *dest++ = *op1++ + *op2++; - } - return res; -} - -Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2) -{ - Matrix3x3 res; - const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; - scalar_t *dest = res.m[0]; - - for(int i=0; i<9; i++) { - *dest++ = *op1++ - *op2++; - } - return res; -} - -Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2) -{ - Matrix3x3 res; - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j]; - } - } - return res; -} - -void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2) -{ - scalar_t *op1 = m1.m[0]; - const scalar_t *op2 = m2.m[0]; - - for(int i=0; i<9; i++) { - *op1++ += *op2++; - } -} - -void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2) -{ - scalar_t *op1 = m1.m[0]; - const scalar_t *op2 = m2.m[0]; - - for(int i=0; i<9; i++) { - *op1++ -= *op2++; - } -} - -void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2) -{ - Matrix3x3 res; - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j]; - } - } - memcpy(m1.m, res.m, 9 * sizeof(scalar_t)); -} - -Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar) -{ - Matrix3x3 res; - const scalar_t *mptr = mat.m[0]; - scalar_t *dptr = res.m[0]; - - for(int i=0; i<9; i++) { - *dptr++ = *mptr++ * scalar; - } - return res; -} - -Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat) -{ - Matrix3x3 res; - const scalar_t *mptr = mat.m[0]; - scalar_t *dptr = res.m[0]; - - for(int i=0; i<9; i++) { - *dptr++ = *mptr++ * scalar; - } - return res; -} - -void operator *=(Matrix3x3 &mat, scalar_t scalar) -{ - scalar_t *mptr = mat.m[0]; - - for(int i=0; i<9; i++) { - *mptr++ *= scalar; - } -} - -void Matrix3x3::translate(const Vector2 &trans) -{ - Matrix3x3 tmat(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1); - *this *= tmat; -} - -void Matrix3x3::set_translation(const Vector2 &trans) -{ - *this = Matrix3x3(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1); -} - -void Matrix3x3::rotate(scalar_t angle) -{ - scalar_t cos_a = cos(angle); - scalar_t sin_a = sin(angle); - Matrix3x3 rmat( cos_a, -sin_a, 0, - sin_a, cos_a, 0, - 0, 0, 1); - *this *= rmat; -} - -void Matrix3x3::set_rotation(scalar_t angle) -{ - scalar_t cos_a = cos(angle); - scalar_t sin_a = sin(angle); - *this = Matrix3x3(cos_a, -sin_a, 0, sin_a, cos_a, 0, 0, 0, 1); -} - -void Matrix3x3::rotate(const Vector3 &euler_angles) -{ - Matrix3x3 xrot, yrot, zrot; - - xrot = Matrix3x3( 1, 0, 0, - 0, cos(euler_angles.x), -sin(euler_angles.x), - 0, sin(euler_angles.x), cos(euler_angles.x)); - - yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), - 0, 1, 0, - -sin(euler_angles.y), 0, cos(euler_angles.y)); - - zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, - sin(euler_angles.z), cos(euler_angles.z), 0, - 0, 0, 1); - - *this *= xrot * yrot * zrot; -} - -void Matrix3x3::set_rotation(const Vector3 &euler_angles) -{ - Matrix3x3 xrot, yrot, zrot; - - xrot = Matrix3x3( 1, 0, 0, - 0, cos(euler_angles.x), -sin(euler_angles.x), - 0, sin(euler_angles.x), cos(euler_angles.x)); - - yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), - 0, 1, 0, - -sin(euler_angles.y), 0, cos(euler_angles.y)); - - zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, - sin(euler_angles.z), cos(euler_angles.z), 0, - 0, 0, 1); - - *this = xrot * yrot * zrot; -} - -void Matrix3x3::rotate(const Vector3 &axis, scalar_t angle) -{ - scalar_t sina = (scalar_t)sin(angle); - scalar_t cosa = (scalar_t)cos(angle); - scalar_t invcosa = 1-cosa; - scalar_t nxsq = axis.x * axis.x; - scalar_t nysq = axis.y * axis.y; - scalar_t nzsq = axis.z * axis.z; - - Matrix3x3 xform; - xform.m[0][0] = nxsq + (1-nxsq) * cosa; - xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; - xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; - - xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; - xform.m[1][1] = nysq + (1-nysq) * cosa; - xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; - - xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; - xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; - xform.m[2][2] = nzsq + (1-nzsq) * cosa; - - *this *= xform; -} - -void Matrix3x3::set_rotation(const Vector3 &axis, scalar_t angle) -{ - scalar_t sina = (scalar_t)sin(angle); - scalar_t cosa = (scalar_t)cos(angle); - scalar_t invcosa = 1-cosa; - scalar_t nxsq = axis.x * axis.x; - scalar_t nysq = axis.y * axis.y; - scalar_t nzsq = axis.z * axis.z; - - reset_identity(); - m[0][0] = nxsq + (1-nxsq) * cosa; - m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; - m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; - m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; - m[1][1] = nysq + (1-nysq) * cosa; - m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; - m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; - m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; - m[2][2] = nzsq + (1-nzsq) * cosa; -} - -// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes -// article "Quaternion Calculus and Fast Animation". -// adapted from: http://www.geometrictools.com/LibMathematics/Algebra/Wm5Quaternion.inl -Quaternion Matrix3x3::get_rotation_quat() const -{ - static const int next[3] = {1, 2, 0}; - - float quat[4]; - - scalar_t trace = m[0][0] + m[1][1] + m[2][2]; - scalar_t root; - - if(trace > 0.0f) { - // |w| > 1/2 - root = sqrt(trace + 1.0f); // 2w - quat[0] = 0.5f * root; - root = 0.5f / root; // 1 / 4w - quat[1] = (m[2][1] - m[1][2]) * root; - quat[2] = (m[0][2] - m[2][0]) * root; - quat[3] = (m[1][0] - m[0][1]) * root; - } else { - // |w| <= 1/2 - int i = 0; - if(m[1][1] > m[0][0]) { - i = 1; - } - if(m[2][2] > m[i][i]) { - i = 2; - } - int j = next[i]; - int k = next[j]; - - root = sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0f); - quat[i + 1] = 0.5f * root; - root = 0.5f / root; - quat[0] = (m[k][j] - m[j][k]) * root; - quat[j + 1] = (m[j][i] - m[i][j]) * root; - quat[k + 1] = (m[k][i] - m[i][k]) * root; - } - return Quaternion(quat[0], quat[1], quat[2], quat[3]); -} - -void Matrix3x3::scale(const Vector3 &scale_vec) -{ - Matrix3x3 smat( scale_vec.x, 0, 0, - 0, scale_vec.y, 0, - 0, 0, scale_vec.z); - *this *= smat; -} - -void Matrix3x3::set_scaling(const Vector3 &scale_vec) -{ - *this = Matrix3x3( scale_vec.x, 0, 0, - 0, scale_vec.y, 0, - 0, 0, scale_vec.z); -} - -void Matrix3x3::set_column_vector(const Vector3 &vec, unsigned int col_index) -{ - m[0][col_index] = vec.x; - m[1][col_index] = vec.y; - m[2][col_index] = vec.z; -} - -void Matrix3x3::set_row_vector(const Vector3 &vec, unsigned int row_index) -{ - m[row_index][0] = vec.x; - m[row_index][1] = vec.y; - m[row_index][2] = vec.z; -} - -Vector3 Matrix3x3::get_column_vector(unsigned int col_index) const -{ - return Vector3(m[0][col_index], m[1][col_index], m[2][col_index]); -} - -Vector3 Matrix3x3::get_row_vector(unsigned int row_index) const -{ - return Vector3(m[row_index][0], m[row_index][1], m[row_index][2]); -} - -void Matrix3x3::transpose() -{ - Matrix3x3 tmp = *this; - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - m[i][j] = tmp[j][i]; - } - } -} - -Matrix3x3 Matrix3x3::transposed() const -{ - Matrix3x3 res; - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - res[i][j] = m[j][i]; - } - } - return res; -} - -scalar_t Matrix3x3::determinant() const -{ - return m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) - - m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) + - m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0]); -} - -Matrix3x3 Matrix3x3::inverse() const -{ - // TODO: implement 3x3 inverse - return *this; -} - -ostream &operator <<(ostream &out, const Matrix3x3 &mat) -{ - for(int i=0; i<3; i++) { - char str[100]; - sprintf(str, "[ %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2]); - out << str; - } - return out; -} - - - -/* ----------------- Matrix4x4 implementation --------------- */ - -Matrix4x4 Matrix4x4::identity = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - -Matrix4x4::Matrix4x4() -{ - *this = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); -} - -Matrix4x4::Matrix4x4( scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, - scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, - scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, - scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44) -{ - m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14; - m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24; - m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34; - m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44; -} - -Matrix4x4::Matrix4x4(const mat4_t cmat) -{ - memcpy(m, cmat, sizeof(mat4_t)); -} - -Matrix4x4::Matrix4x4(const Matrix3x3 &mat3x3) -{ - reset_identity(); - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - m[i][j] = mat3x3[i][j]; - } - } -} - -Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2) -{ - Matrix4x4 res; - const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; - scalar_t *dest = res.m[0]; - - for(int i=0; i<16; i++) { - *dest++ = *op1++ + *op2++; - } - return res; -} - -Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2) -{ - Matrix4x4 res; - const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; - scalar_t *dest = res.m[0]; - - for(int i=0; i<16; i++) { - *dest++ = *op1++ - *op2++; - } - return res; -} - -void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2) -{ - scalar_t *op1 = m1.m[0]; - const scalar_t *op2 = m2.m[0]; - - for(int i=0; i<16; i++) { - *op1++ += *op2++; - } -} - -void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2) -{ - scalar_t *op1 = m1.m[0]; - const scalar_t *op2 = m2.m[0]; - - for(int i=0; i<16; i++) { - *op1++ -= *op2++; - } -} - -Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar) -{ - Matrix4x4 res; - const scalar_t *mptr = mat.m[0]; - scalar_t *dptr = res.m[0]; - - for(int i=0; i<16; i++) { - *dptr++ = *mptr++ * scalar; - } - return res; -} - -Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat) -{ - Matrix4x4 res; - const scalar_t *mptr = mat.m[0]; - scalar_t *dptr = res.m[0]; - - for(int i=0; i<16; i++) { - *dptr++ = *mptr++ * scalar; - } - return res; -} - -void operator *=(Matrix4x4 &mat, scalar_t scalar) -{ - scalar_t *mptr = mat.m[0]; - - for(int i=0; i<16; i++) { - *mptr++ *= scalar; - } -} - -void Matrix4x4::translate(const Vector3 &trans) -{ - Matrix4x4 tmat(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1); - *this *= tmat; -} - -void Matrix4x4::set_translation(const Vector3 &trans) -{ - *this = Matrix4x4(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1); -} - -Vector3 Matrix4x4::get_translation() const -{ - return Vector3(m[0][3], m[1][3], m[2][3]); -} - -void Matrix4x4::rotate(const Vector3 &euler_angles) -{ - Matrix3x3 xrot, yrot, zrot; - - xrot = Matrix3x3( 1, 0, 0, - 0, cos(euler_angles.x), -sin(euler_angles.x), - 0, sin(euler_angles.x), cos(euler_angles.x)); - - yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), - 0, 1, 0, - -sin(euler_angles.y), 0, cos(euler_angles.y)); - - zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, - sin(euler_angles.z), cos(euler_angles.z), 0, - 0, 0, 1); - - *this *= Matrix4x4(xrot * yrot * zrot); -} - -void Matrix4x4::set_rotation(const Vector3 &euler_angles) -{ - Matrix3x3 xrot, yrot, zrot; - - xrot = Matrix3x3( 1, 0, 0, - 0, cos(euler_angles.x), -sin(euler_angles.x), - 0, sin(euler_angles.x), cos(euler_angles.x)); - - yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), - 0, 1, 0, - -sin(euler_angles.y), 0, cos(euler_angles.y)); - - zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, - sin(euler_angles.z), cos(euler_angles.z), 0, - 0, 0, 1); - - *this = Matrix4x4(xrot * yrot * zrot); -} - -void Matrix4x4::rotate(const Vector3 &axis, scalar_t angle) -{ - scalar_t sina = (scalar_t)sin(angle); - scalar_t cosa = (scalar_t)cos(angle); - scalar_t invcosa = 1-cosa; - scalar_t nxsq = axis.x * axis.x; - scalar_t nysq = axis.y * axis.y; - scalar_t nzsq = axis.z * axis.z; - - Matrix4x4 xform; - xform[0][0] = nxsq + (1-nxsq) * cosa; - xform[0][1] = axis.x * axis.y * invcosa - axis.z * sina; - xform[0][2] = axis.x * axis.z * invcosa + axis.y * sina; - xform[1][0] = axis.x * axis.y * invcosa + axis.z * sina; - xform[1][1] = nysq + (1-nysq) * cosa; - xform[1][2] = axis.y * axis.z * invcosa - axis.x * sina; - xform[2][0] = axis.x * axis.z * invcosa - axis.y * sina; - xform[2][1] = axis.y * axis.z * invcosa + axis.x * sina; - xform[2][2] = nzsq + (1-nzsq) * cosa; - - *this *= xform; -} - -void Matrix4x4::set_rotation(const Vector3 &axis, scalar_t angle) -{ - scalar_t sina = (scalar_t)sin(angle); - scalar_t cosa = (scalar_t)cos(angle); - scalar_t invcosa = 1-cosa; - scalar_t nxsq = axis.x * axis.x; - scalar_t nysq = axis.y * axis.y; - scalar_t nzsq = axis.z * axis.z; - - reset_identity(); - m[0][0] = nxsq + (1-nxsq) * cosa; - m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; - m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; - m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; - m[1][1] = nysq + (1-nysq) * cosa; - m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; - m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; - m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; - m[2][2] = nzsq + (1-nzsq) * cosa; -} - -void Matrix4x4::rotate(const Quaternion &quat) -{ - *this *= quat.get_rotation_matrix(); -} - -void Matrix4x4::set_rotation(const Quaternion &quat) -{ - *this = quat.get_rotation_matrix(); -} - -Quaternion Matrix4x4::get_rotation_quat() const -{ - Matrix3x3 mat3 = *this; - return mat3.get_rotation_quat(); -} - -void Matrix4x4::scale(const Vector4 &scale_vec) -{ - Matrix4x4 smat( scale_vec.x, 0, 0, 0, - 0, scale_vec.y, 0, 0, - 0, 0, scale_vec.z, 0, - 0, 0, 0, scale_vec.w); - *this *= smat; -} - -void Matrix4x4::set_scaling(const Vector4 &scale_vec) -{ - *this = Matrix4x4( scale_vec.x, 0, 0, 0, - 0, scale_vec.y, 0, 0, - 0, 0, scale_vec.z, 0, - 0, 0, 0, scale_vec.w); -} - -Vector3 Matrix4x4::get_scaling() const -{ - Vector3 vi = get_row_vector(0); - Vector3 vj = get_row_vector(1); - Vector3 vk = get_row_vector(2); - - return Vector3(vi.length(), vj.length(), vk.length()); -} - -void Matrix4x4::set_perspective(float vfov, float aspect, float znear, float zfar) -{ - float f = 1.0f / tan(vfov * 0.5f); - float dz = znear - zfar; - - reset_identity(); - - m[0][0] = f / aspect; - m[1][1] = f; - m[2][2] = (zfar + znear) / dz; - m[3][2] = -1.0f; - m[2][3] = 2.0f * zfar * znear / dz; - m[3][3] = 0.0f; -} - -void Matrix4x4::set_orthographic(float left, float right, float bottom, float top, float znear, float zfar) -{ - float dx = right - left; - float dy = top - bottom; - float dz = zfar - znear; - - reset_identity(); - - m[0][0] = 2.0 / dx; - m[1][1] = 2.0 / dy; - m[2][2] = -2.0 / dz; - m[0][3] = -(right + left) / dx; - m[1][3] = -(top + bottom) / dy; - m[2][3] = -(zfar + znear) / dz; -} - -void Matrix4x4::set_column_vector(const Vector4 &vec, unsigned int col_index) -{ - m[0][col_index] = vec.x; - m[1][col_index] = vec.y; - m[2][col_index] = vec.z; - m[3][col_index] = vec.w; -} - -void Matrix4x4::set_row_vector(const Vector4 &vec, unsigned int row_index) -{ - m[row_index][0] = vec.x; - m[row_index][1] = vec.y; - m[row_index][2] = vec.z; - m[row_index][3] = vec.w; -} - -Vector4 Matrix4x4::get_column_vector(unsigned int col_index) const -{ - return Vector4(m[0][col_index], m[1][col_index], m[2][col_index], m[3][col_index]); -} - -Vector4 Matrix4x4::get_row_vector(unsigned int row_index) const -{ - return Vector4(m[row_index][0], m[row_index][1], m[row_index][2], m[row_index][3]); -} - -void Matrix4x4::transpose() -{ - Matrix4x4 tmp = *this; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - m[i][j] = tmp[j][i]; - } - } -} - -Matrix4x4 Matrix4x4::transposed() const -{ - Matrix4x4 res; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - res[i][j] = m[j][i]; - } - } - return res; -} - -scalar_t Matrix4x4::determinant() const -{ - scalar_t det11 = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + - (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); - - scalar_t det12 = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); - - scalar_t det13 = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - - (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - scalar_t det14 = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - - (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + - (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14; -} - - -Matrix4x4 Matrix4x4::adjoint() const -{ - Matrix4x4 coef; - - coef.m[0][0] = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + - (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); - coef.m[0][1] = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); - coef.m[0][2] = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - - (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - coef.m[0][3] = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - - (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + - (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - coef.m[1][0] = (m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + - (m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); - coef.m[1][1] = (m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); - coef.m[1][2] = (m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - - (m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - coef.m[1][3] = (m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - - (m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + - (m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - coef.m[2][0] = (m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - - (m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) + - (m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])); - coef.m[2][1] = (m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - - (m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])); - coef.m[2][2] = (m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) - - (m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); - coef.m[2][3] = (m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) - - (m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) + - (m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); - - coef.m[3][0] = (m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - - (m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) + - (m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])); - coef.m[3][1] = (m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - - (m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])); - coef.m[3][2] = (m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) - - (m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); - coef.m[3][3] = (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) - - (m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) + - (m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); - - coef.transpose(); - - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j]; - if(i%2) coef.m[i][j] = -coef.m[i][j]; - } - } - - return coef; -} - -Matrix4x4 Matrix4x4::inverse() const -{ - Matrix4x4 adj = adjoint(); - - return adj * (1.0f / determinant()); -} - -ostream &operator <<(ostream &out, const Matrix4x4 &mat) -{ - for(int i=0; i<4; i++) { - char str[100]; - sprintf(str, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2], (float)mat.m[i][3]); - out << str; - } - return out; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/matrix.h --- a/libs/vmath/matrix.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,260 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_MATRIX_H_ -#define VMATH_MATRIX_H_ - -#include -#include "vmath_types.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* C matrix 3x3 functions */ -static VMATH_INLINE void m3_identity(mat3_t m); -static VMATH_INLINE void m3_cons(mat3_t m, - scalar_t m11, scalar_t m12, scalar_t m13, - scalar_t m21, scalar_t m22, scalar_t m23, - scalar_t m31, scalar_t m32, scalar_t m33); -static VMATH_INLINE void m3_copy(mat3_t dest, mat3_t src); -void m3_to_m4(mat4_t dest, mat3_t src); - -void m3_print(FILE *fp, mat3_t m); - -/* C matrix 4x4 functions */ -static VMATH_INLINE void m4_identity(mat4_t m); -static VMATH_INLINE void m4_cons(mat4_t m, - scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, - scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, - scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, - scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44); -static VMATH_INLINE void m4_copy(mat4_t dest, mat4_t src); -void m4_to_m3(mat3_t dest, mat4_t src); - -static VMATH_INLINE void m4_mult(mat4_t res, mat4_t m1, mat4_t m2); - -void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z); -void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z); - -void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z); - -void m4_set_rotation_x(mat4_t m, scalar_t angle); -void m4_rotate_x(mat4_t m, scalar_t angle); -void m4_set_rotation_y(mat4_t m, scalar_t angle); -void m4_rotate_y(mat4_t m, scalar_t angle); -void m4_set_rotation_z(mat4_t m, scalar_t angle); -void m4_rotate_z(mat4_t m, scalar_t angle); -/* axis-angle rotation */ -void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); -void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); -/* concatentate a rotation quaternion */ -void m4_rotate_quat(mat4_t m, quat_t q); - -void m4_set_scaling(mat4_t m, scalar_t x, scalar_t y, scalar_t z); -void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z); - -static VMATH_INLINE void m4_set_column(mat4_t m, vec4_t v, int idx); -static VMATH_INLINE void m4_set_row(mat4_t m, vec4_t v, int idx); - -void m4_transpose(mat4_t res, mat4_t m); -scalar_t m4_determinant(mat4_t m); -void m4_adjoint(mat4_t res, mat4_t m); -void m4_inverse(mat4_t res, mat4_t m); - -void m4_print(FILE *fp, mat4_t m); - -#ifdef __cplusplus -} - -/* when included from C++ source files, also define the matrix classes */ -#include - -/** 3x3 matrix */ -class Matrix3x3 { -public: - scalar_t m[3][3]; - - static Matrix3x3 identity; - - Matrix3x3(); - Matrix3x3( scalar_t m11, scalar_t m12, scalar_t m13, - scalar_t m21, scalar_t m22, scalar_t m23, - scalar_t m31, scalar_t m32, scalar_t m33); - Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec); - Matrix3x3(const mat3_t cmat); - - Matrix3x3(const Matrix4x4 &mat4x4); - - /* binary operations matrix (op) matrix */ - friend Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2); - friend Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2); - friend Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2); - - friend void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2); - friend void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2); - friend void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2); - - /* binary operations matrix (op) scalar and scalar (op) matrix */ - friend Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar); - friend Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat); - - friend void operator *=(Matrix3x3 &mat, scalar_t scalar); - - VMATH_INLINE scalar_t *operator [](int index); - VMATH_INLINE const scalar_t *operator [](int index) const; - - VMATH_INLINE void reset_identity(); - - void translate(const Vector2 &trans); - void set_translation(const Vector2 &trans); - - void rotate(scalar_t angle); /* 2d rotation */ - void rotate(const Vector3 &euler_angles); /* 3d rotation with euler angles */ - void rotate(const Vector3 &axis, scalar_t angle); /* 3d axis/angle rotation */ - void set_rotation(scalar_t angle); - void set_rotation(const Vector3 &euler_angles); - void set_rotation(const Vector3 &axis, scalar_t angle); - Quaternion get_rotation_quat() const; - - void scale(const Vector3 &scale_vec); - void set_scaling(const Vector3 &scale_vec); - - void set_column_vector(const Vector3 &vec, unsigned int col_index); - void set_row_vector(const Vector3 &vec, unsigned int row_index); - Vector3 get_column_vector(unsigned int col_index) const; - Vector3 get_row_vector(unsigned int row_index) const; - - void transpose(); - Matrix3x3 transposed() const; - scalar_t determinant() const; - Matrix3x3 inverse() const; - - friend std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat); -}; - -/* binary operations matrix (op) matrix */ -Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2); -Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2); -Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2); - -void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2); -void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2); -void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2); - -/* binary operations matrix (op) scalar and scalar (op) matrix */ -Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar); -Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat); - -void operator *=(Matrix3x3 &mat, scalar_t scalar); - -std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat); - - - -/** 4x4 matrix */ -class Matrix4x4 { -public: - scalar_t m[4][4]; - - static Matrix4x4 identity; - - Matrix4x4(); - Matrix4x4( scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, - scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, - scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, - scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44); - Matrix4x4(const mat4_t cmat); - - Matrix4x4(const Matrix3x3 &mat3x3); - - /* binary operations matrix (op) matrix */ - friend Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2); - friend Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2); - friend Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2); - - friend void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2); - friend void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2); - friend VMATH_INLINE void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2); - - /* binary operations matrix (op) scalar and scalar (op) matrix */ - friend Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar); - friend Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat); - - friend void operator *=(Matrix4x4 &mat, scalar_t scalar); - - VMATH_INLINE scalar_t *operator [](int index); - VMATH_INLINE const scalar_t *operator [](int index) const; - - VMATH_INLINE void reset_identity(); - - void translate(const Vector3 &trans); - void set_translation(const Vector3 &trans); - Vector3 get_translation() const; /* extract translation */ - - void rotate(const Vector3 &euler_angles); /* 3d rotation with euler angles */ - void rotate(const Vector3 &axis, scalar_t angle); /* 3d axis/angle rotation */ - void rotate(const Quaternion &quat); - void set_rotation(const Vector3 &euler_angles); - void set_rotation(const Vector3 &axis, scalar_t angle); - void set_rotation(const Quaternion &quat); - Quaternion get_rotation_quat() const; /* extract rotation */ - - void scale(const Vector4 &scale_vec); - void set_scaling(const Vector4 &scale_vec); - Vector3 get_scaling() const; /* extract scaling */ - - void set_perspective(float vfov, float aspect, float znear, float zfar); - void set_orthographic(float left, float right, float bottom, float top, float znear = -1.0, float zfar = 1.0); - - void set_column_vector(const Vector4 &vec, unsigned int col_index); - void set_row_vector(const Vector4 &vec, unsigned int row_index); - Vector4 get_column_vector(unsigned int col_index) const; - Vector4 get_row_vector(unsigned int row_index) const; - - void transpose(); - Matrix4x4 transposed() const; - scalar_t determinant() const; - Matrix4x4 adjoint() const; - Matrix4x4 inverse() const; - - friend std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat); -}; - -/* binary operations matrix (op) matrix */ -Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2); -Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2); -VMATH_INLINE Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2); - -void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2); -void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2); -VMATH_INLINE void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2); - -/* binary operations matrix (op) scalar and scalar (op) matrix */ -Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar); -Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat); - -void operator *=(Matrix4x4 &mat, scalar_t scalar); - -std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat); - -#endif /* __cplusplus */ - -#include "matrix.inl" - -#endif /* VMATH_MATRIX_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/matrix.inl --- a/libs/vmath/matrix.inl Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* C matrix 3x3 functions */ -static VMATH_INLINE void m3_identity(mat3_t m) -{ - static const mat3_t id = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; - memcpy(m, id, sizeof id); -} - -static VMATH_INLINE void m3_cons(mat3_t m, - scalar_t m11, scalar_t m12, scalar_t m13, - scalar_t m21, scalar_t m22, scalar_t m23, - scalar_t m31, scalar_t m32, scalar_t m33) -{ - m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; - m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; - m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; -} - -static VMATH_INLINE void m3_copy(mat3_t dest, mat3_t src) -{ - memcpy(dest, src, sizeof(mat3_t)); -} - - -/* C matrix 4x4 functions */ -static VMATH_INLINE void m4_identity(mat4_t m) -{ - static const mat4_t id = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; - memcpy(m, id, sizeof id); -} - -static VMATH_INLINE void m4_cons(mat4_t m, - scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, - scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, - scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, - scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44) -{ - m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14; - m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24; - m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34; - m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44; -} - -static VMATH_INLINE void m4_copy(mat4_t dest, mat4_t src) -{ - memcpy(dest, src, sizeof(mat4_t)); -} - -static VMATH_INLINE void m4_mult(mat4_t res, mat4_t m1, mat4_t m2) -{ - mat4_t tmp; - - /* - int i, j; - for(i=0; i<4; i++) { - for(j=0; j<4; j++) { - tmp[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j] + m1[i][3] * m2[3][j]; - } - } - */ - - tmp[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0] + m1[0][3] * m2[3][0]; - tmp[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1] + m1[0][3] * m2[3][1]; - tmp[0][2] = m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2] + m1[0][3] * m2[3][2]; - tmp[0][3] = m1[0][0] * m2[0][3] + m1[0][1] * m2[1][3] + m1[0][2] * m2[2][3] + m1[0][3] * m2[3][3]; - - tmp[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0] + m1[1][3] * m2[3][0]; - tmp[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1] + m1[1][3] * m2[3][1]; - tmp[1][2] = m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2] + m1[1][3] * m2[3][2]; - tmp[1][3] = m1[1][0] * m2[0][3] + m1[1][1] * m2[1][3] + m1[1][2] * m2[2][3] + m1[1][3] * m2[3][3]; - - tmp[2][0] = m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0] + m1[2][3] * m2[3][0]; - tmp[2][1] = m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1] + m1[2][3] * m2[3][1]; - tmp[2][2] = m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2] + m1[2][3] * m2[3][2]; - tmp[2][3] = m1[2][0] * m2[0][3] + m1[2][1] * m2[1][3] + m1[2][2] * m2[2][3] + m1[2][3] * m2[3][3]; - - tmp[3][0] = m1[3][0] * m2[0][0] + m1[3][1] * m2[1][0] + m1[3][2] * m2[2][0] + m1[3][3] * m2[3][0]; - tmp[3][1] = m1[3][0] * m2[0][1] + m1[3][1] * m2[1][1] + m1[3][2] * m2[2][1] + m1[3][3] * m2[3][1]; - tmp[3][2] = m1[3][0] * m2[0][2] + m1[3][1] * m2[1][2] + m1[3][2] * m2[2][2] + m1[3][3] * m2[3][2]; - tmp[3][3] = m1[3][0] * m2[0][3] + m1[3][1] * m2[1][3] + m1[3][2] * m2[2][3] + m1[3][3] * m2[3][3]; - - m4_copy(res, tmp); -} - -static VMATH_INLINE void m4_set_column(mat4_t m, vec4_t v, int idx) -{ - m[0][idx] = v.x; - m[1][idx] = v.y; - m[2][idx] = v.z; - m[3][idx] = v.w; -} - -static VMATH_INLINE void m4_set_row(mat4_t m, vec4_t v, int idx) -{ - m[idx][0] = v.x; - m[idx][1] = v.y; - m[idx][2] = v.z; - m[idx][3] = v.w; -} - -#ifdef __cplusplus -} /* extern "C" */ - - -/* unrolled to hell and VMATH_INLINE */ -VMATH_INLINE Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2) -{ - Matrix4x4 res; - - /* - for(i=0; i<4; i++) { - for(j=0; j<4; j++) { - res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j]; - } - } - */ - - res.m[0][0] = m1.m[0][0] * m2.m[0][0] + m1.m[0][1] * m2.m[1][0] + m1.m[0][2] * m2.m[2][0] + m1.m[0][3] * m2.m[3][0]; - res.m[0][1] = m1.m[0][0] * m2.m[0][1] + m1.m[0][1] * m2.m[1][1] + m1.m[0][2] * m2.m[2][1] + m1.m[0][3] * m2.m[3][1]; - res.m[0][2] = m1.m[0][0] * m2.m[0][2] + m1.m[0][1] * m2.m[1][2] + m1.m[0][2] * m2.m[2][2] + m1.m[0][3] * m2.m[3][2]; - res.m[0][3] = m1.m[0][0] * m2.m[0][3] + m1.m[0][1] * m2.m[1][3] + m1.m[0][2] * m2.m[2][3] + m1.m[0][3] * m2.m[3][3]; - - res.m[1][0] = m1.m[1][0] * m2.m[0][0] + m1.m[1][1] * m2.m[1][0] + m1.m[1][2] * m2.m[2][0] + m1.m[1][3] * m2.m[3][0]; - res.m[1][1] = m1.m[1][0] * m2.m[0][1] + m1.m[1][1] * m2.m[1][1] + m1.m[1][2] * m2.m[2][1] + m1.m[1][3] * m2.m[3][1]; - res.m[1][2] = m1.m[1][0] * m2.m[0][2] + m1.m[1][1] * m2.m[1][2] + m1.m[1][2] * m2.m[2][2] + m1.m[1][3] * m2.m[3][2]; - res.m[1][3] = m1.m[1][0] * m2.m[0][3] + m1.m[1][1] * m2.m[1][3] + m1.m[1][2] * m2.m[2][3] + m1.m[1][3] * m2.m[3][3]; - - res.m[2][0] = m1.m[2][0] * m2.m[0][0] + m1.m[2][1] * m2.m[1][0] + m1.m[2][2] * m2.m[2][0] + m1.m[2][3] * m2.m[3][0]; - res.m[2][1] = m1.m[2][0] * m2.m[0][1] + m1.m[2][1] * m2.m[1][1] + m1.m[2][2] * m2.m[2][1] + m1.m[2][3] * m2.m[3][1]; - res.m[2][2] = m1.m[2][0] * m2.m[0][2] + m1.m[2][1] * m2.m[1][2] + m1.m[2][2] * m2.m[2][2] + m1.m[2][3] * m2.m[3][2]; - res.m[2][3] = m1.m[2][0] * m2.m[0][3] + m1.m[2][1] * m2.m[1][3] + m1.m[2][2] * m2.m[2][3] + m1.m[2][3] * m2.m[3][3]; - - res.m[3][0] = m1.m[3][0] * m2.m[0][0] + m1.m[3][1] * m2.m[1][0] + m1.m[3][2] * m2.m[2][0] + m1.m[3][3] * m2.m[3][0]; - res.m[3][1] = m1.m[3][0] * m2.m[0][1] + m1.m[3][1] * m2.m[1][1] + m1.m[3][2] * m2.m[2][1] + m1.m[3][3] * m2.m[3][1]; - res.m[3][2] = m1.m[3][0] * m2.m[0][2] + m1.m[3][1] * m2.m[1][2] + m1.m[3][2] * m2.m[2][2] + m1.m[3][3] * m2.m[3][2]; - res.m[3][3] = m1.m[3][0] * m2.m[0][3] + m1.m[3][1] * m2.m[1][3] + m1.m[3][2] * m2.m[2][3] + m1.m[3][3] * m2.m[3][3]; - - return res; -} - -VMATH_INLINE void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2) -{ - Matrix4x4 res = m1 * m2; - m1 = res; -} - - -VMATH_INLINE scalar_t *Matrix3x3::operator [](int index) -{ - return m[index]; -} - -VMATH_INLINE const scalar_t *Matrix3x3::operator [](int index) const -{ - return m[index]; -} - -VMATH_INLINE void Matrix3x3::reset_identity() -{ - *this = identity; -} - -VMATH_INLINE scalar_t *Matrix4x4::operator [](int index) -{ - return m[index]; -} - -VMATH_INLINE const scalar_t *Matrix4x4::operator [](int index) const -{ - return m[index]; -} - -VMATH_INLINE void Matrix4x4::reset_identity() -{ - *this = identity; -} -#endif /* __cplusplus */ diff -r dad392c710df -r 99715321ad6d libs/vmath/matrix_c.c --- a/libs/vmath/matrix_c.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - - -#include -#include "matrix.h" -#include "vector.h" -#include "quat.h" - -void m3_to_m4(mat4_t dest, mat3_t src) -{ - int i, j; - - memset(dest, 0, sizeof(mat4_t)); - for(i=0; i<3; i++) { - for(j=0; j<3; j++) { - dest[i][j] = src[i][j]; - } - } - dest[3][3] = 1.0; -} - -void m3_print(FILE *fp, mat3_t m) -{ - int i; - for(i=0; i<3; i++) { - fprintf(fp, "[ %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2]); - } -} - -/* C matrix 4x4 functions */ -void m4_to_m3(mat3_t dest, mat4_t src) -{ - int i, j; - for(i=0; i<3; i++) { - for(j=0; j<3; j++) { - dest[i][j] = src[i][j]; - } - } -} - -void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z) -{ - m4_identity(m); - m[0][3] = x; - m[1][3] = y; - m[2][3] = z; -} - -void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z) -{ - mat4_t tm; - m4_set_translation(tm, x, y, z); - m4_mult(m, m, tm); -} - -void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z) -{ - m4_rotate_x(m, x); - m4_rotate_y(m, y); - m4_rotate_z(m, z); -} - -void m4_set_rotation_x(mat4_t m, scalar_t angle) -{ - m4_identity(m); - m[1][1] = cos(angle); m[1][2] = -sin(angle); - m[2][1] = sin(angle); m[2][2] = cos(angle); -} - -void m4_rotate_x(mat4_t m, scalar_t angle) -{ - mat4_t rm; - m4_set_rotation_x(m, angle); - m4_mult(m, m, rm); -} - -void m4_set_rotation_y(mat4_t m, scalar_t angle) -{ - m4_identity(m); - m[0][0] = cos(angle); m[0][2] = sin(angle); - m[2][0] = -sin(angle); m[2][2] = cos(angle); -} - -void m4_rotate_y(mat4_t m, scalar_t angle) -{ - mat4_t rm; - m4_set_rotation_y(rm, angle); - m4_mult(m, m, rm); -} - -void m4_set_rotation_z(mat4_t m, scalar_t angle) -{ - m4_identity(m); - m[0][0] = cos(angle); m[0][1] = -sin(angle); - m[1][0] = sin(angle); m[1][1] = cos(angle); -} - -void m4_rotate_z(mat4_t m, scalar_t angle) -{ - mat4_t rm; - m4_set_rotation_z(rm, angle); - m4_mult(m, m, rm); -} - -void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) -{ - scalar_t sina = sin(angle); - scalar_t cosa = cos(angle); - scalar_t one_minus_cosa = 1.0 - cosa; - scalar_t nxsq = x * x; - scalar_t nysq = y * y; - scalar_t nzsq = z * z; - - m[0][0] = nxsq + (1.0 - nxsq) * cosa; - m[0][1] = x * y * one_minus_cosa - z * sina; - m[0][2] = x * z * one_minus_cosa + y * sina; - m[1][0] = x * y * one_minus_cosa + z * sina; - m[1][1] = nysq + (1.0 - nysq) * cosa; - m[1][2] = y * z * one_minus_cosa - x * sina; - m[2][0] = x * z * one_minus_cosa - y * sina; - m[2][1] = y * z * one_minus_cosa + x * sina; - m[2][2] = nzsq + (1.0 - nzsq) * cosa; - - /* the rest are identity */ - m[3][0] = m[3][1] = m[3][2] = m[0][3] = m[1][3] = m[2][3] = 0.0; - m[3][3] = 1.0; -} - -void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) -{ - mat4_t xform; - m4_set_rotation_axis(xform, angle, x, y, z); - m4_mult(m, m, xform); -} - -void m4_rotate_quat(mat4_t m, quat_t q) -{ - mat4_t rm; - quat_to_mat4(rm, q); - m4_mult(m, m, rm); -} - -void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z) -{ - mat4_t sm; - m4_identity(sm); - sm[0][0] = x; - sm[1][1] = y; - sm[2][2] = z; - m4_mult(m, m, sm); -} - -void m4_transpose(mat4_t res, mat4_t m) -{ - int i, j; - mat4_t tmp; - m4_copy(tmp, m); - - for(i=0; i<4; i++) { - for(j=0; j<4; j++) { - res[i][j] = tmp[j][i]; - } - } -} - -scalar_t m4_determinant(mat4_t m) -{ - scalar_t det11 = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + - (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); - - scalar_t det12 = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); - - scalar_t det13 = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - - (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - scalar_t det14 = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - - (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + - (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14; -} - -void m4_adjoint(mat4_t res, mat4_t m) -{ - int i, j; - mat4_t coef; - - coef[0][0] = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + - (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); - coef[0][1] = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); - coef[0][2] = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - - (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - coef[0][3] = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - - (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + - (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - coef[1][0] = (m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + - (m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); - coef[1][1] = (m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - - (m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); - coef[1][2] = (m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - - (m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + - (m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - coef[1][3] = (m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - - (m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + - (m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); - - coef[2][0] = (m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - - (m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) + - (m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])); - coef[2][1] = (m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - - (m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])); - coef[2][2] = (m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) - - (m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); - coef[2][3] = (m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) - - (m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) + - (m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); - - coef[3][0] = (m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - - (m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) + - (m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])); - coef[3][1] = (m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - - (m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])); - coef[3][2] = (m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) - - (m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + - (m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); - coef[3][3] = (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) - - (m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) + - (m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); - - m4_transpose(res, coef); - - for(i=0; i<4; i++) { - for(j=0; j<4; j++) { - res[i][j] = j % 2 ? -res[i][j] : res[i][j]; - if(i % 2) res[i][j] = -res[i][j]; - } - } -} - -void m4_inverse(mat4_t res, mat4_t m) -{ - int i, j; - mat4_t adj; - scalar_t det; - - m4_adjoint(adj, m); - det = m4_determinant(m); - - for(i=0; i<4; i++) { - for(j=0; j<4; j++) { - res[i][j] = adj[i][j] / det; - } - } -} - -void m4_print(FILE *fp, mat4_t m) -{ - int i; - for(i=0; i<4; i++) { - fprintf(fp, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2], (float)m[i][3]); - } -} diff -r dad392c710df -r 99715321ad6d libs/vmath/quat.cc --- a/libs/vmath/quat.cc Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -#include "quat.h" -#include "vmath.h" - -Quaternion::Quaternion() -{ - s = 1.0; - v.x = v.y = v.z = 0.0; -} - -Quaternion::Quaternion(scalar_t s, const Vector3 &v) -{ - this->s = s; - this->v = v; -} - -Quaternion::Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z) -{ - v.x = x; - v.y = y; - v.z = z; - this->s = s; -} - -Quaternion::Quaternion(const Vector3 &axis, scalar_t angle) -{ - set_rotation(axis, angle); -} - -Quaternion::Quaternion(const quat_t &quat) -{ - v.x = quat.x; - v.y = quat.y; - v.z = quat.z; - s = quat.w; -} - -Quaternion Quaternion::operator +(const Quaternion &quat) const -{ - return Quaternion(s + quat.s, v + quat.v); -} - -Quaternion Quaternion::operator -(const Quaternion &quat) const -{ - return Quaternion(s - quat.s, v - quat.v); -} - -Quaternion Quaternion::operator -() const -{ - return Quaternion(-s, -v); -} - -/** Quaternion Multiplication: - * Q1*Q2 = [s1*s2 - v1.v2, s1*v2 + s2*v1 + v1(x)v2] - */ -Quaternion Quaternion::operator *(const Quaternion &quat) const -{ - Quaternion newq; - newq.s = s * quat.s - dot_product(v, quat.v); - newq.v = quat.v * s + v * quat.s + cross_product(v, quat.v); - return newq; -} - -void Quaternion::operator +=(const Quaternion &quat) -{ - *this = Quaternion(s + quat.s, v + quat.v); -} - -void Quaternion::operator -=(const Quaternion &quat) -{ - *this = Quaternion(s - quat.s, v - quat.v); -} - -void Quaternion::operator *=(const Quaternion &quat) -{ - *this = *this * quat; -} - -void Quaternion::reset_identity() -{ - s = 1.0; - v.x = v.y = v.z = 0.0; -} - -Quaternion Quaternion::conjugate() const -{ - return Quaternion(s, -v); -} - -scalar_t Quaternion::length() const -{ - return (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); -} - -/** Q * ~Q = ||Q||^2 */ -scalar_t Quaternion::length_sq() const -{ - return v.x*v.x + v.y*v.y + v.z*v.z + s*s; -} - -void Quaternion::normalize() -{ - scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); - v.x /= len; - v.y /= len; - v.z /= len; - s /= len; -} - -Quaternion Quaternion::normalized() const -{ - Quaternion nq = *this; - scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); - nq.v.x /= len; - nq.v.y /= len; - nq.v.z /= len; - nq.s /= len; - return nq; -} - -/** Quaternion Inversion: Q^-1 = ~Q / ||Q||^2 */ -Quaternion Quaternion::inverse() const -{ - Quaternion inv = conjugate(); - scalar_t lensq = length_sq(); - inv.v /= lensq; - inv.s /= lensq; - - return inv; -} - - -void Quaternion::set_rotation(const Vector3 &axis, scalar_t angle) -{ - scalar_t half_angle = angle / 2.0; - s = cos(half_angle); - v = axis * sin(half_angle); -} - -void Quaternion::rotate(const Vector3 &axis, scalar_t angle) -{ - Quaternion q; - scalar_t half_angle = angle / 2.0; - q.s = cos(half_angle); - q.v = axis * sin(half_angle); - - *this *= q; -} - -void Quaternion::rotate(const Quaternion &q) -{ - *this = q * *this * q.conjugate(); -} - -Matrix3x3 Quaternion::get_rotation_matrix() const -{ - return Matrix3x3( - 1.0 - 2.0 * v.y*v.y - 2.0 * v.z*v.z, 2.0 * v.x * v.y - 2.0 * s * v.z, 2.0 * v.z * v.x + 2.0 * s * v.y, - 2.0 * v.x * v.y + 2.0 * s * v.z, 1.0 - 2.0 * v.x*v.x - 2.0 * v.z*v.z, 2.0 * v.y * v.z - 2.0 * s * v.x, - 2.0 * v.z * v.x - 2.0 * s * v.y, 2.0 * v.y * v.z + 2.0 * s * v.x, 1.0 - 2.0 * v.x*v.x - 2.0 * v.y*v.y); -} - - -/** Spherical linear interpolation (slerp) */ -Quaternion slerp(const Quaternion &quat1, const Quaternion &q2, scalar_t t) -{ - Quaternion q1; - scalar_t dot = q1.s * q2.s + q1.v.x * q2.v.x + q1.v.y * q2.v.y + q1.v.z * q2.v.z; - - if(dot < 0.0) { - /* make sure we interpolate across the shortest arc */ - q1 = -quat1; - dot = -dot; - } else { - q1 = quat1; - } - - /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to - * floating point imprecisions - */ - if(dot < -1.0) dot = -1.0; - if(dot > 1.0) dot = 1.0; - - scalar_t angle = acos(dot); - scalar_t a, b; - - scalar_t sin_angle = sin(angle); - if(fabs(sin_angle) < SMALL_NUMBER) { - /* for very small angles or completely opposite orientations - * use linear interpolation to avoid div/zero (in the first case it makes sense, - * the second case is pretty much undefined anyway I guess ... - */ - a = 1.0f - t; - b = t; - } else { - a = sin((1.0f - t) * angle) / sin_angle; - b = sin(t * angle) / sin_angle; - } - - scalar_t x = q1.v.x * a + q2.v.x * b; - scalar_t y = q1.v.y * a + q2.v.y * b; - scalar_t z = q1.v.z * a + q2.v.z * b; - scalar_t s = q1.s * a + q2.s * b; - - return Quaternion(s, Vector3(x, y, z)); -} - - -std::ostream &operator <<(std::ostream &out, const Quaternion &q) -{ - out << "(" << q.s << ", " << q.v << ")"; - return out; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/quat.h --- a/libs/vmath/quat.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_QUATERNION_H_ -#define VMATH_QUATERNION_H_ - -#include -#include "vmath_types.h" -#include "vector.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define quat_cons(s, x, y, z) v4_cons(x, y, z, s) -#define quat_vec(q) v3_cons((q).x, (q).y, (q).z) -#define quat_s(q) ((q).w) -#define quat_identity() quat_cons(1.0, 0.0, 0.0, 0.0) -void quat_print(FILE *fp, quat_t q); - -#define quat_add v4_add -#define quat_sub v4_sub -#define quat_neg v4_neg - -static VMATH_INLINE quat_t quat_mul(quat_t q1, quat_t q2); - -static VMATH_INLINE quat_t quat_conjugate(quat_t q); - -#define quat_length v4_length -#define quat_length_sq v4_length_sq - -#define quat_normalize v4_normalize -static VMATH_INLINE quat_t quat_inverse(quat_t q); - -quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); -quat_t quat_rotate_quat(quat_t q, quat_t rotq); - -static VMATH_INLINE void quat_to_mat3(mat3_t res, quat_t q); -static VMATH_INLINE void quat_to_mat4(mat4_t res, quat_t q); - -#define quat_lerp quat_slerp -quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t); - - -#ifdef __cplusplus -} /* extern "C" */ - -#include - -/* Quaternion */ -class Quaternion { -public: - scalar_t s; - Vector3 v; - - Quaternion(); - Quaternion(scalar_t s, const Vector3 &v); - Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z); - Quaternion(const Vector3 &axis, scalar_t angle); - Quaternion(const quat_t &quat); - - Quaternion operator +(const Quaternion &quat) const; - Quaternion operator -(const Quaternion &quat) const; - Quaternion operator -() const; - Quaternion operator *(const Quaternion &quat) const; - - void operator +=(const Quaternion &quat); - void operator -=(const Quaternion &quat); - void operator *=(const Quaternion &quat); - - void reset_identity(); - - Quaternion conjugate() const; - - scalar_t length() const; - scalar_t length_sq() const; - - void normalize(); - Quaternion normalized() const; - - Quaternion inverse() const; - - void set_rotation(const Vector3 &axis, scalar_t angle); - void rotate(const Vector3 &axis, scalar_t angle); - /* note: this is a totally different operation from the above - * this treats the quaternion as signifying direction and rotates - * it by a rotation quaternion by rot * q * rot' - */ - void rotate(const Quaternion &q); - - Matrix3x3 get_rotation_matrix() const; -}; - -Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t); -VMATH_INLINE Quaternion lerp(const Quaternion &q1, const Quaternion &q2, scalar_t t); - -std::ostream &operator <<(std::ostream &out, const Quaternion &q); - -#endif /* __cplusplus */ - -#include "quat.inl" - -#endif /* VMATH_QUATERNION_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/quat.inl --- a/libs/vmath/quat.inl Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include "vector.h" -#include "matrix.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -static VMATH_INLINE quat_t quat_mul(quat_t q1, quat_t q2) -{ - quat_t res; - vec3_t v1 = quat_vec(q1); - vec3_t v2 = quat_vec(q2); - - res.w = q1.w * q2.w - v3_dot(v1, v2); - /* resvec = v2 * q1 + v1 * q2 + cross(v1, v2) */ - res.x = v2.x * q1.w + v1.x * q2.w + (v1.y * v2.z - v1.z * v2.y); - res.y = v2.y * q1.w + v1.y * q2.w + (v1.z * v2.x - v1.x * v2.z); - res.z = v2.z * q1.w + v1.z * q2.w + (v1.x * v2.y - v1.y * v2.x); - return res; -} - -static VMATH_INLINE quat_t quat_conjugate(quat_t q) -{ - q.x = -q.x; - q.y = -q.y; - q.z = -q.z; - return q; -} - -static VMATH_INLINE quat_t quat_inverse(quat_t q) -{ - scalar_t lensq = quat_length_sq(q); - q = quat_conjugate(q); - q.x /= lensq; - q.y /= lensq; - q.z /= lensq; - q.w /= lensq; - return q; -} - -static VMATH_INLINE void quat_to_mat3(mat3_t res, quat_t q) -{ - m3_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y - 2.0 * q.w * q.z, 2.0 * q.z * q.x + 2.0 * q.w * q.y, - 2.0 * q.x * q.y + 2.0 * q.w * q.z, 1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z - 2.0 * q.w * q.x, - 2.0 * q.z * q.x - 2.0 * q.w * q.y, 2.0 * q.y * q.z + 2.0 * q.w * q.x, 1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y); -} - -static VMATH_INLINE void quat_to_mat4(mat4_t res, quat_t q) -{ - m4_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y - 2.0 * q.w * q.z, 2.0 * q.z * q.x + 2.0 * q.w * q.y, 0, - 2.0 * q.x * q.y + 2.0 * q.w * q.z, 1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z - 2.0 * q.w * q.x, 0, - 2.0 * q.z * q.x - 2.0 * q.w * q.y, 2.0 * q.y * q.z + 2.0 * q.w * q.x, 1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y, 0, - 0, 0, 0, 1); -} - -#ifdef __cplusplus -} /* extern "C" */ - -VMATH_INLINE Quaternion lerp(const Quaternion &a, const Quaternion &b, scalar_t t) -{ - return slerp(a, b, t); -} -#endif /* __cplusplus */ diff -r dad392c710df -r 99715321ad6d libs/vmath/quat_c.c --- a/libs/vmath/quat_c.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - - -#include -#include -#include "quat.h" - -void quat_print(FILE *fp, quat_t q) -{ - fprintf(fp, "([ %.4f %.4f %.4f ] %.4f)", q.x, q.y, q.z, q.w); -} - -quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) -{ - quat_t rq; - scalar_t half_angle = angle * 0.5; - scalar_t sin_half = sin(half_angle); - - rq.w = cos(half_angle); - rq.x = x * sin_half; - rq.y = y * sin_half; - rq.z = z * sin_half; - - return quat_mul(q, rq); -} - -quat_t quat_rotate_quat(quat_t q, quat_t rotq) -{ - return quat_mul(quat_mul(rotq, q), quat_conjugate(rotq)); -} - -quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t) -{ - quat_t res; - scalar_t a, b, angle, sin_angle, dot; - - dot = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; - if(dot < 0.0) { - /* make sure we interpolate across the shortest arc */ - q1.x = -q1.x; - q1.y = -q1.y; - q1.z = -q1.z; - q1.w = -q1.w; - dot = -dot; - } - - /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to - * floating point imprecisions - */ - if(dot < -1.0) dot = -1.0; - if(dot > 1.0) dot = 1.0; - - angle = acos(dot); - sin_angle = sin(angle); - - if(fabs(sin_angle) < SMALL_NUMBER) { - /* for very small angles or completely opposite orientations - * use linear interpolation to avoid div/zero (in the first case it makes sense, - * the second case is pretty much undefined anyway I guess ... - */ - a = 1.0f - t; - b = t; - } else { - a = sin((1.0f - t) * angle) / sin_angle; - b = sin(t * angle) / sin_angle; - } - - res.x = q1.x * a + q2.x * b; - res.y = q1.y * a + q2.y * b; - res.z = q1.z * a + q2.z * b; - res.w = q1.w * a + q2.w * b; - return res; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/ray.cc --- a/libs/vmath/ray.cc Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -#include "ray.h" -#include "vector.h" - -scalar_t Ray::env_ior = 1.0; - -Ray::Ray() -{ - ior = env_ior; - energy = 1.0; - time = 0; - iter = 0; -} - -Ray::Ray(const Vector3 &origin, const Vector3 &dir) -{ - this->origin = origin; - this->dir = dir; - ior = env_ior; - energy = 1.0; - time = 0; - iter = 0; -} - -void Ray::transform(const Matrix4x4 &xform) -{ - Matrix4x4 upper = xform; - upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; - upper[3][3] = 1.0; - - dir.transform(upper); - origin.transform(xform); -} - -Ray Ray::transformed(const Matrix4x4 &xform) const -{ - Ray foo = *this; - foo.transform(xform); - return foo; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/ray.h --- a/libs/vmath/ray.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_RAY_H_ -#define VMATH_RAY_H_ - -#include "matrix.h" -#include "vector.h" - -typedef struct { - vec3_t origin, dir; -} ray_t; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -static VMATH_INLINE ray_t ray_cons(vec3_t origin, vec3_t dir); -ray_t ray_transform(ray_t r, mat4_t m); - -#ifdef __cplusplus -} /* __cplusplus */ - -#include - -class Ray { -public: - static scalar_t env_ior; - - Vector3 origin, dir; - scalar_t energy; - int iter; - scalar_t ior; - long time; - - Ray(); - Ray(const Vector3 &origin, const Vector3 &dir); - - void transform(const Matrix4x4 &xform); - Ray transformed(const Matrix4x4 &xform) const; -}; - -VMATH_INLINE Ray reflect_ray(const Ray &inray, const Vector3 &norm); -VMATH_INLINE Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t from_ior, scalar_t to_ior); -#endif /* __cplusplus */ - -#include "ray.inl" - -#endif /* VMATH_RAY_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/ray.inl --- a/libs/vmath/ray.inl Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -static VMATH_INLINE ray_t ray_cons(vec3_t origin, vec3_t dir) -{ - ray_t r; - r.origin = origin; - r.dir = dir; - return r; -} - -#ifdef __cplusplus -} - -VMATH_INLINE Ray reflect_ray(const Ray &inray, const Vector3 &norm) -{ - Ray ray = inray; - ray.dir = ray.dir.reflection(norm); - return ray; -} - -VMATH_INLINE Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t from_ior, scalar_t to_ior) -{ - Ray ray = inray; - ray.dir = ray.dir.refraction(norm, from_ior, to_ior); - - /* check TIR */ - if(dot_product(ray.dir, norm) > 0.0) { - return reflect_ray(inray, norm); - } - return ray; -} -#endif /* __cplusplus */ diff -r dad392c710df -r 99715321ad6d libs/vmath/ray_c.c --- a/libs/vmath/ray_c.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include "ray.h" -#include "vector.h" - -ray_t ray_transform(ray_t r, mat4_t xform) -{ - mat4_t upper; - vec3_t dir; - - m4_copy(upper, xform); - upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; - upper[3][3] = 1.0; - - dir = v3_sub(r.dir, r.origin); - dir = v3_transform(dir, upper); - r.origin = v3_transform(r.origin, xform); - r.dir = v3_add(dir, r.origin); - return r; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/sphvec.cc --- a/libs/vmath/sphvec.cc Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#include "sphvec.h" -#include "vector.h" - -/* theta: 0 <= theta <= 2pi, the angle around Y axis. - * phi: 0 <= phi <= pi, the angle from Y axis. - * r: radius. - */ -SphVector::SphVector(scalar_t theta, scalar_t phi, scalar_t r) { - this->theta = theta; - this->phi = phi; - this->r = r; -} - -/* Constructs a spherical coordinate vector from a cartesian vector */ -SphVector::SphVector(const Vector3 &cvec) { - *this = cvec; -} - -/* Assignment operator that converts cartesian to spherical coords */ -SphVector &SphVector::operator =(const Vector3 &cvec) { - r = cvec.length(); - //theta = atan2(cvec.y, cvec.x); - theta = atan2(cvec.z, cvec.x); - //phi = acos(cvec.z / r); - phi = acos(cvec.y / r); - return *this; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/sphvec.h --- a/libs/vmath/sphvec.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_SPHVEC_H_ -#define VMATH_SPHVEC_H_ - -#include "vmath_types.h" - -#ifdef __cplusplus -/* Vector in spherical coordinates */ -class SphVector { -public: - scalar_t theta, phi, r; - - SphVector(scalar_t theta = 0.0, scalar_t phi = 0.0, scalar_t r = 1.0); - SphVector(const Vector3 &cvec); - SphVector &operator =(const Vector3 &cvec); -}; -#endif /* __cplusplus */ - -#endif /* VMATH_SPHVEC_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/vector.cc --- a/libs/vmath/vector.cc Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +0,0 @@ -#include "vector.h" -#include "vmath.h" - -// ---------- Vector2 ----------- - -Vector2::Vector2(scalar_t x, scalar_t y) -{ - this->x = x; - this->y = y; -} - -Vector2::Vector2(const vec2_t &vec) -{ - x = vec.x; - y = vec.y; -} - -Vector2::Vector2(const Vector3 &vec) -{ - x = vec.x; - y = vec.y; -} - -Vector2::Vector2(const Vector4 &vec) -{ - x = vec.x; - y = vec.y; -} - -void Vector2::normalize() -{ - scalar_t len = length(); - x /= len; - y /= len; -} - -Vector2 Vector2::normalized() const -{ - scalar_t len = length(); - return Vector2(x / len, y / len); -} - -void Vector2::transform(const Matrix3x3 &mat) -{ - scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2]; - y = mat[1][0] * x + mat[1][1] * y + mat[1][2]; - x = nx; -} - -Vector2 Vector2::transformed(const Matrix3x3 &mat) const -{ - Vector2 vec; - vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2]; - vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2]; - return vec; -} - -void Vector2::rotate(scalar_t angle) -{ - *this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y); -} - -Vector2 Vector2::rotated(scalar_t angle) const -{ - return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y); -} - -Vector2 Vector2::reflection(const Vector2 &normal) const -{ - return 2.0 * dot_product(*this, normal) * normal - *this; -} - -Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const -{ - // quick and dirty implementation :) - Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior); - return Vector2(v3refr.x, v3refr.y); -} - -std::ostream &operator <<(std::ostream &out, const Vector2 &vec) -{ - out << "[" << vec.x << " " << vec.y << "]"; - return out; -} - - - -// --------- Vector3 ---------- - -Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z) -{ - this->x = x; - this->y = y; - this->z = z; -} - -Vector3::Vector3(const vec3_t &vec) -{ - x = vec.x; - y = vec.y; - z = vec.z; -} - -Vector3::Vector3(const Vector2 &vec) -{ - x = vec.x; - y = vec.y; - z = 1; -} - -Vector3::Vector3(const Vector4 &vec) -{ - x = vec.x; - y = vec.y; - z = vec.z; -} - -Vector3::Vector3(const SphVector &sph) -{ - *this = sph; -} - -Vector3 &Vector3::operator =(const SphVector &sph) -{ - x = sph.r * cos(sph.theta) * sin(sph.phi); - z = sph.r * sin(sph.theta) * sin(sph.phi); - y = sph.r * cos(sph.phi); - return *this; -} - -void Vector3::normalize() -{ - scalar_t len = length(); - x /= len; - y /= len; - z /= len; -} - -Vector3 Vector3::normalized() const -{ - scalar_t len = length(); - return Vector3(x / len, y / len, z / len); -} - -Vector3 Vector3::reflection(const Vector3 &normal) const -{ - return 2.0 * dot_product(*this, normal) * normal - *this; -} - -Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const -{ - return refraction(normal, src_ior / dst_ior); -} - -Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const -{ - scalar_t cos_inc = dot_product(*this, -normal); - - scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0); - - if(radical < 0.0) { // total internal reflection - return -reflection(normal); - } - - scalar_t beta = ior * cos_inc - sqrt(radical); - - return *this * ior + normal * beta; -} - -void Vector3::transform(const Matrix3x3 &mat) -{ - scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z; - scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z; - z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z; - x = nx; - y = ny; -} - -Vector3 Vector3::transformed(const Matrix3x3 &mat) const -{ - Vector3 vec; - vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z; - vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z; - vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z; - return vec; -} - -void Vector3::transform(const Matrix4x4 &mat) -{ - scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; - scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; - z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; - x = nx; - y = ny; -} - -Vector3 Vector3::transformed(const Matrix4x4 &mat) const -{ - Vector3 vec; - vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; - vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; - vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; - return vec; -} - -void Vector3::transform(const Quaternion &quat) -{ - Quaternion vq(0.0f, *this); - vq = quat * vq * quat.inverse(); - *this = vq.v; -} - -Vector3 Vector3::transformed(const Quaternion &quat) const -{ - Quaternion vq(0.0f, *this); - vq = quat * vq * quat.inverse(); - return vq.v; -} - -void Vector3::rotate(const Vector3 &euler) -{ - Matrix4x4 rot; - rot.set_rotation(euler); - transform(rot); -} - -Vector3 Vector3::rotated(const Vector3 &euler) const -{ - Matrix4x4 rot; - rot.set_rotation(euler); - return transformed(rot); -} - -std::ostream &operator <<(std::ostream &out, const Vector3 &vec) -{ - out << "[" << vec.x << " " << vec.y << " " << vec.z << "]"; - return out; -} - - -// -------------- Vector4 -------------- -Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w) -{ - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -Vector4::Vector4(const vec4_t &vec) -{ - x = vec.x; - y = vec.y; - z = vec.z; - w = vec.w; -} - -Vector4::Vector4(const Vector2 &vec) -{ - x = vec.x; - y = vec.y; - z = 1; - w = 1; -} - -Vector4::Vector4(const Vector3 &vec) -{ - x = vec.x; - y = vec.y; - z = vec.z; - w = 1; -} - -void Vector4::normalize() -{ - scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w); - x /= len; - y /= len; - z /= len; - w /= len; -} - -Vector4 Vector4::normalized() const -{ - scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w); - return Vector4(x / len, y / len, z / len, w / len); -} - -void Vector4::transform(const Matrix4x4 &mat) -{ - scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w; - scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w; - scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w; - w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w; - x = nx; - y = ny; - z = nz; -} - -Vector4 Vector4::transformed(const Matrix4x4 &mat) const -{ - Vector4 vec; - vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w; - vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w; - vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w; - vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w; - return vec; -} - -// TODO: implement 4D vector reflection -Vector4 Vector4::reflection(const Vector4 &normal) const -{ - return *this; -} - -// TODO: implement 4D vector refraction -Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const -{ - return *this; -} - -std::ostream &operator <<(std::ostream &out, const Vector4 &vec) -{ - out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]"; - return out; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/vector.h --- a/libs/vmath/vector.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_VECTOR_H_ -#define VMATH_VECTOR_H_ - -#include -#include "vmath_types.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* C 2D vector functions */ -static VMATH_INLINE vec2_t v2_cons(scalar_t x, scalar_t y); -static VMATH_INLINE void v2_print(FILE *fp, vec2_t v); - -static VMATH_INLINE vec2_t v2_add(vec2_t v1, vec2_t v2); -static VMATH_INLINE vec2_t v2_sub(vec2_t v1, vec2_t v2); -static VMATH_INLINE vec2_t v2_scale(vec2_t v, scalar_t s); -static VMATH_INLINE scalar_t v2_dot(vec2_t v1, vec2_t v2); -static VMATH_INLINE scalar_t v2_length(vec2_t v); -static VMATH_INLINE scalar_t v2_length_sq(vec2_t v); -static VMATH_INLINE vec2_t v2_normalize(vec2_t v); - -static VMATH_INLINE vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t); - -/* C 3D vector functions */ -static VMATH_INLINE vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z); -static VMATH_INLINE void v3_print(FILE *fp, vec3_t v); - -static VMATH_INLINE vec3_t v3_add(vec3_t v1, vec3_t v2); -static VMATH_INLINE vec3_t v3_sub(vec3_t v1, vec3_t v2); -static VMATH_INLINE vec3_t v3_neg(vec3_t v); -static VMATH_INLINE vec3_t v3_mul(vec3_t v1, vec3_t v2); -static VMATH_INLINE vec3_t v3_scale(vec3_t v1, scalar_t s); -static VMATH_INLINE scalar_t v3_dot(vec3_t v1, vec3_t v2); -static VMATH_INLINE vec3_t v3_cross(vec3_t v1, vec3_t v2); -static VMATH_INLINE scalar_t v3_length(vec3_t v); -static VMATH_INLINE scalar_t v3_length_sq(vec3_t v); -static VMATH_INLINE vec3_t v3_normalize(vec3_t v); -static VMATH_INLINE vec3_t v3_transform(vec3_t v, mat4_t m); - -static VMATH_INLINE vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z); -static VMATH_INLINE vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); -static VMATH_INLINE vec3_t v3_rotate_quat(vec3_t v, quat_t q); - -static VMATH_INLINE vec3_t v3_reflect(vec3_t v, vec3_t n); - -static VMATH_INLINE vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t); - -/* C 4D vector functions */ -static VMATH_INLINE vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w); -static VMATH_INLINE void v4_print(FILE *fp, vec4_t v); - -static VMATH_INLINE vec4_t v4_add(vec4_t v1, vec4_t v2); -static VMATH_INLINE vec4_t v4_sub(vec4_t v1, vec4_t v2); -static VMATH_INLINE vec4_t v4_neg(vec4_t v); -static VMATH_INLINE vec4_t v4_mul(vec4_t v1, vec4_t v2); -static VMATH_INLINE vec4_t v4_scale(vec4_t v, scalar_t s); -static VMATH_INLINE scalar_t v4_dot(vec4_t v1, vec4_t v2); -static VMATH_INLINE scalar_t v4_length(vec4_t v); -static VMATH_INLINE scalar_t v4_length_sq(vec4_t v); -static VMATH_INLINE vec4_t v4_normalize(vec4_t v); -static VMATH_INLINE vec4_t v4_transform(vec4_t v, mat4_t m); - -#ifdef __cplusplus -} /* extern "C" */ - -/* when included from C++ source files, also define the vector classes */ -#include - -/** 2D Vector */ -class Vector2 { -public: - scalar_t x, y; - - Vector2(scalar_t x = 0.0, scalar_t y = 0.0); - Vector2(const vec2_t &vec); - Vector2(const Vector3 &vec); - Vector2(const Vector4 &vec); - - VMATH_INLINE scalar_t &operator [](int elem); - VMATH_INLINE const scalar_t &operator [](int elem) const; - - VMATH_INLINE scalar_t length() const; - VMATH_INLINE scalar_t length_sq() const; - void normalize(); - Vector2 normalized() const; - - void transform(const Matrix3x3 &mat); - Vector2 transformed(const Matrix3x3 &mat) const; - - void rotate(scalar_t angle); - Vector2 rotated(scalar_t angle) const; - - Vector2 reflection(const Vector2 &normal) const; - Vector2 refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const; -}; - -/* unary operations */ -VMATH_INLINE Vector2 operator -(const Vector2 &vec); - -/* binary vector (op) vector operations */ -VMATH_INLINE scalar_t dot_product(const Vector2 &v1, const Vector2 &v2); - -VMATH_INLINE Vector2 operator +(const Vector2 &v1, const Vector2 &v2); -VMATH_INLINE Vector2 operator -(const Vector2 &v1, const Vector2 &v2); -VMATH_INLINE Vector2 operator *(const Vector2 &v1, const Vector2 &v2); -VMATH_INLINE Vector2 operator /(const Vector2 &v1, const Vector2 &v2); -VMATH_INLINE bool operator ==(const Vector2 &v1, const Vector2 &v2); - -VMATH_INLINE void operator +=(Vector2 &v1, const Vector2 &v2); -VMATH_INLINE void operator -=(Vector2 &v1, const Vector2 &v2); -VMATH_INLINE void operator *=(Vector2 &v1, const Vector2 &v2); -VMATH_INLINE void operator /=(Vector2 &v1, const Vector2 &v2); - -/* binary vector (op) scalar and scalar (op) vector operations */ -VMATH_INLINE Vector2 operator +(const Vector2 &vec, scalar_t scalar); -VMATH_INLINE Vector2 operator +(scalar_t scalar, const Vector2 &vec); -VMATH_INLINE Vector2 operator -(const Vector2 &vec, scalar_t scalar); -VMATH_INLINE Vector2 operator *(const Vector2 &vec, scalar_t scalar); -VMATH_INLINE Vector2 operator *(scalar_t scalar, const Vector2 &vec); -VMATH_INLINE Vector2 operator /(const Vector2 &vec, scalar_t scalar); - -VMATH_INLINE void operator +=(Vector2 &vec, scalar_t scalar); -VMATH_INLINE void operator -=(Vector2 &vec, scalar_t scalar); -VMATH_INLINE void operator *=(Vector2 &vec, scalar_t scalar); -VMATH_INLINE void operator /=(Vector2 &vec, scalar_t scalar); - -std::ostream &operator <<(std::ostream &out, const Vector2 &vec); - -VMATH_INLINE Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t); -VMATH_INLINE Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1, - const Vector2 &v2, const Vector2 &v3, scalar_t t); - -/* 3D Vector */ -class Vector3 { -public: - scalar_t x, y, z; - - Vector3(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0); - Vector3(const vec3_t &vec); - Vector3(const Vector2 &vec); - Vector3(const Vector4 &vec); - Vector3(const SphVector &sph); - - Vector3 &operator =(const SphVector &sph); - - VMATH_INLINE scalar_t &operator [](int elem); - VMATH_INLINE const scalar_t &operator [](int elem) const; - - VMATH_INLINE scalar_t length() const; - VMATH_INLINE scalar_t length_sq() const; - void normalize(); - Vector3 normalized() const; - - void transform(const Matrix3x3 &mat); - Vector3 transformed(const Matrix3x3 &mat) const; - void transform(const Matrix4x4 &mat); - Vector3 transformed(const Matrix4x4 &mat) const; - void transform(const Quaternion &quat); - Vector3 transformed(const Quaternion &quat) const; - - void rotate(const Vector3 &euler); - Vector3 rotated(const Vector3 &euler) const; - - Vector3 reflection(const Vector3 &normal) const; - Vector3 refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const; - Vector3 refraction(const Vector3 &normal, scalar_t ior) const; -}; - -/* unary operations */ -VMATH_INLINE Vector3 operator -(const Vector3 &vec); - -/* binary vector (op) vector operations */ -VMATH_INLINE scalar_t dot_product(const Vector3 &v1, const Vector3 &v2); -VMATH_INLINE Vector3 cross_product(const Vector3 &v1, const Vector3 &v2); - -VMATH_INLINE Vector3 operator +(const Vector3 &v1, const Vector3 &v2); -VMATH_INLINE Vector3 operator -(const Vector3 &v1, const Vector3 &v2); -VMATH_INLINE Vector3 operator *(const Vector3 &v1, const Vector3 &v2); -VMATH_INLINE Vector3 operator /(const Vector3 &v1, const Vector3 &v2); -VMATH_INLINE bool operator ==(const Vector3 &v1, const Vector3 &v2); - -VMATH_INLINE void operator +=(Vector3 &v1, const Vector3 &v2); -VMATH_INLINE void operator -=(Vector3 &v1, const Vector3 &v2); -VMATH_INLINE void operator *=(Vector3 &v1, const Vector3 &v2); -VMATH_INLINE void operator /=(Vector3 &v1, const Vector3 &v2); - -/* binary vector (op) scalar and scalar (op) vector operations */ -VMATH_INLINE Vector3 operator +(const Vector3 &vec, scalar_t scalar); -VMATH_INLINE Vector3 operator +(scalar_t scalar, const Vector3 &vec); -VMATH_INLINE Vector3 operator -(const Vector3 &vec, scalar_t scalar); -VMATH_INLINE Vector3 operator *(const Vector3 &vec, scalar_t scalar); -VMATH_INLINE Vector3 operator *(scalar_t scalar, const Vector3 &vec); -VMATH_INLINE Vector3 operator /(const Vector3 &vec, scalar_t scalar); - -VMATH_INLINE void operator +=(Vector3 &vec, scalar_t scalar); -VMATH_INLINE void operator -=(Vector3 &vec, scalar_t scalar); -VMATH_INLINE void operator *=(Vector3 &vec, scalar_t scalar); -VMATH_INLINE void operator /=(Vector3 &vec, scalar_t scalar); - -std::ostream &operator <<(std::ostream &out, const Vector3 &vec); - -VMATH_INLINE Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t); -VMATH_INLINE Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1, - const Vector3 &v2, const Vector3 &v3, scalar_t t); - -/* 4D Vector */ -class Vector4 { -public: - scalar_t x, y, z, w; - - Vector4(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0, scalar_t w = 0.0); - Vector4(const vec4_t &vec); - Vector4(const Vector2 &vec); - Vector4(const Vector3 &vec); - - VMATH_INLINE scalar_t &operator [](int elem); - VMATH_INLINE const scalar_t &operator [](int elem) const; - - VMATH_INLINE scalar_t length() const; - VMATH_INLINE scalar_t length_sq() const; - void normalize(); - Vector4 normalized() const; - - void transform(const Matrix4x4 &mat); - Vector4 transformed(const Matrix4x4 &mat) const; - - Vector4 reflection(const Vector4 &normal) const; - Vector4 refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const; -}; - - -/* unary operations */ -VMATH_INLINE Vector4 operator -(const Vector4 &vec); - -/* binary vector (op) vector operations */ -VMATH_INLINE scalar_t dot_product(const Vector4 &v1, const Vector4 &v2); -VMATH_INLINE Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3); - -VMATH_INLINE Vector4 operator +(const Vector4 &v1, const Vector4 &v2); -VMATH_INLINE Vector4 operator -(const Vector4 &v1, const Vector4 &v2); -VMATH_INLINE Vector4 operator *(const Vector4 &v1, const Vector4 &v2); -VMATH_INLINE Vector4 operator /(const Vector4 &v1, const Vector4 &v2); -VMATH_INLINE bool operator ==(const Vector4 &v1, const Vector4 &v2); - -VMATH_INLINE void operator +=(Vector4 &v1, const Vector4 &v2); -VMATH_INLINE void operator -=(Vector4 &v1, const Vector4 &v2); -VMATH_INLINE void operator *=(Vector4 &v1, const Vector4 &v2); -VMATH_INLINE void operator /=(Vector4 &v1, const Vector4 &v2); - -/* binary vector (op) scalar and scalar (op) vector operations */ -VMATH_INLINE Vector4 operator +(const Vector4 &vec, scalar_t scalar); -VMATH_INLINE Vector4 operator +(scalar_t scalar, const Vector4 &vec); -VMATH_INLINE Vector4 operator -(const Vector4 &vec, scalar_t scalar); -VMATH_INLINE Vector4 operator *(const Vector4 &vec, scalar_t scalar); -VMATH_INLINE Vector4 operator *(scalar_t scalar, const Vector4 &vec); -VMATH_INLINE Vector4 operator /(const Vector4 &vec, scalar_t scalar); - -VMATH_INLINE void operator +=(Vector4 &vec, scalar_t scalar); -VMATH_INLINE void operator -=(Vector4 &vec, scalar_t scalar); -VMATH_INLINE void operator *=(Vector4 &vec, scalar_t scalar); -VMATH_INLINE void operator /=(Vector4 &vec, scalar_t scalar); - -std::ostream &operator <<(std::ostream &out, const Vector4 &vec); - -VMATH_INLINE Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t); -VMATH_INLINE Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1, - const Vector4 &v2, const Vector4 &v3, scalar_t t); - -#endif /* __cplusplus */ - -#include "vector.inl" - -#endif /* VMATH_VECTOR_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/vector.inl --- a/libs/vmath/vector.inl Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,761 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* C 2D vector functions */ -static VMATH_INLINE vec2_t v2_cons(scalar_t x, scalar_t y) -{ - vec2_t v; - v.x = x; - v.y = y; - return v; -} - -static VMATH_INLINE void v2_print(FILE *fp, vec2_t v) -{ - fprintf(fp, "[ %.4f %.4f ]", v.x, v.y); -} - -static VMATH_INLINE vec2_t v2_add(vec2_t v1, vec2_t v2) -{ - vec2_t res; - res.x = v1.x + v2.x; - res.y = v1.y + v2.y; - return res; -} - -static VMATH_INLINE vec2_t v2_sub(vec2_t v1, vec2_t v2) -{ - vec2_t res; - res.x = v1.x - v2.x; - res.y = v1.y - v2.y; - return res; -} - -static VMATH_INLINE vec2_t v2_scale(vec2_t v, scalar_t s) -{ - vec2_t res; - res.x = v.x * s; - res.y = v.y * s; - return res; -} - -static VMATH_INLINE scalar_t v2_dot(vec2_t v1, vec2_t v2) -{ - return v1.x * v2.x + v1.y * v2.y; -} - -static VMATH_INLINE scalar_t v2_length(vec2_t v) -{ - return sqrt(v.x * v.x + v.y * v.y); -} - -static VMATH_INLINE scalar_t v2_length_sq(vec2_t v) -{ - return v.x * v.x + v.y * v.y; -} - -static VMATH_INLINE vec2_t v2_normalize(vec2_t v) -{ - scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y); - v.x /= len; - v.y /= len; - return v; -} - -static VMATH_INLINE vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t) -{ - vec2_t res; - res.x = v1.x + (v2.x - v1.x) * t; - res.y = v1.y + (v2.y - v1.y) * t; - return res; -} - - -/* C 3D vector functions */ -static VMATH_INLINE vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z) -{ - vec3_t v; - v.x = x; - v.y = y; - v.z = z; - return v; -} - -static VMATH_INLINE void v3_print(FILE *fp, vec3_t v) -{ - fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z); -} - -static VMATH_INLINE vec3_t v3_add(vec3_t v1, vec3_t v2) -{ - v1.x += v2.x; - v1.y += v2.y; - v1.z += v2.z; - return v1; -} - -static VMATH_INLINE vec3_t v3_sub(vec3_t v1, vec3_t v2) -{ - v1.x -= v2.x; - v1.y -= v2.y; - v1.z -= v2.z; - return v1; -} - -static VMATH_INLINE vec3_t v3_neg(vec3_t v) -{ - v.x = -v.x; - v.y = -v.y; - v.z = -v.z; - return v; -} - -static VMATH_INLINE vec3_t v3_mul(vec3_t v1, vec3_t v2) -{ - v1.x *= v2.x; - v1.y *= v2.y; - v1.z *= v2.z; - return v1; -} - -static VMATH_INLINE vec3_t v3_scale(vec3_t v1, scalar_t s) -{ - v1.x *= s; - v1.y *= s; - v1.z *= s; - return v1; -} - -static VMATH_INLINE scalar_t v3_dot(vec3_t v1, vec3_t v2) -{ - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; -} - -static VMATH_INLINE vec3_t v3_cross(vec3_t v1, vec3_t v2) -{ - vec3_t v; - v.x = v1.y * v2.z - v1.z * v2.y; - v.y = v1.z * v2.x - v1.x * v2.z; - v.z = v1.x * v2.y - v1.y * v2.x; - return v; -} - -static VMATH_INLINE scalar_t v3_length(vec3_t v) -{ - return sqrt(v.x * v.x + v.y * v.y + v.z * v.z); -} - -static VMATH_INLINE scalar_t v3_length_sq(vec3_t v) -{ - return v.x * v.x + v.y * v.y + v.z * v.z; -} - -static VMATH_INLINE vec3_t v3_normalize(vec3_t v) -{ - scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); - v.x /= len; - v.y /= len; - v.z /= len; - return v; -} - -static VMATH_INLINE vec3_t v3_transform(vec3_t v, mat4_t m) -{ - vec3_t res; - res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3]; - res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3]; - res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]; - return res; -} - -static VMATH_INLINE vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z) -{ - void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t); - - mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; - m4_rotate(m, x, y, z); - return v3_transform(v, m); -} - -static VMATH_INLINE vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) -{ - void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t); - - mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; - m4_rotate_axis(m, angle, x, y, z); - return v3_transform(v, m); -} - -static VMATH_INLINE vec3_t v3_rotate_quat(vec3_t v, quat_t q) -{ - quat_t quat_rotate_quat(quat_t, quat_t); - - quat_t vq = v4_cons(v.x, v.y, v.z, 0.0); - quat_t res = quat_rotate_quat(vq, q); - return v3_cons(res.x, res.y, res.z); -} - -static VMATH_INLINE vec3_t v3_reflect(vec3_t v, vec3_t n) -{ - scalar_t dot = v3_dot(v, n); - return v3_sub(v3_scale(n, dot * 2.0), v); -} - -static VMATH_INLINE vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t) -{ - v1.x += (v2.x - v1.x) * t; - v1.y += (v2.y - v1.y) * t; - v1.z += (v2.z - v1.z) * t; - return v1; -} - -/* C 4D vector functions */ -static VMATH_INLINE vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w) -{ - vec4_t v; - v.x = x; - v.y = y; - v.z = z; - v.w = w; - return v; -} - -static VMATH_INLINE void v4_print(FILE *fp, vec4_t v) -{ - fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w); -} - -static VMATH_INLINE vec4_t v4_add(vec4_t v1, vec4_t v2) -{ - v1.x += v2.x; - v1.y += v2.y; - v1.z += v2.z; - v1.w += v2.w; - return v1; -} - -static VMATH_INLINE vec4_t v4_sub(vec4_t v1, vec4_t v2) -{ - v1.x -= v2.x; - v1.y -= v2.y; - v1.z -= v2.z; - v1.w -= v2.w; - return v1; -} - -static VMATH_INLINE vec4_t v4_neg(vec4_t v) -{ - v.x = -v.x; - v.y = -v.y; - v.z = -v.z; - v.w = -v.w; - return v; -} - -static VMATH_INLINE vec4_t v4_mul(vec4_t v1, vec4_t v2) -{ - v1.x *= v2.x; - v1.y *= v2.y; - v1.z *= v2.z; - v1.w *= v2.w; - return v1; -} - -static VMATH_INLINE vec4_t v4_scale(vec4_t v, scalar_t s) -{ - v.x *= s; - v.y *= s; - v.z *= s; - v.w *= s; - return v; -} - -static VMATH_INLINE scalar_t v4_dot(vec4_t v1, vec4_t v2) -{ - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; -} - -static VMATH_INLINE scalar_t v4_length(vec4_t v) -{ - return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); -} - -static VMATH_INLINE scalar_t v4_length_sq(vec4_t v) -{ - return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; -} - -static VMATH_INLINE vec4_t v4_normalize(vec4_t v) -{ - scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); - v.x /= len; - v.y /= len; - v.z /= len; - v.w /= len; - return v; -} - -static VMATH_INLINE vec4_t v4_transform(vec4_t v, mat4_t m) -{ - vec4_t res; - res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w; - res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w; - res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w; - res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w; - return res; -} - -#ifdef __cplusplus -} /* extern "C" */ - - -/* --------------- C++ part -------------- */ - -VMATH_INLINE scalar_t &Vector2::operator [](int elem) { - return elem ? y : x; -} - -VMATH_INLINE const scalar_t &Vector2::operator [](int elem) const { - return elem ? y : x; -} - -VMATH_INLINE Vector2 operator -(const Vector2 &vec) { - return Vector2(-vec.x, -vec.y); -} - -VMATH_INLINE scalar_t dot_product(const Vector2 &v1, const Vector2 &v2) { - return v1.x * v2.x + v1.y * v2.y; -} - -VMATH_INLINE Vector2 operator +(const Vector2 &v1, const Vector2 &v2) { - return Vector2(v1.x + v2.x, v1.y + v2.y); -} - -VMATH_INLINE Vector2 operator -(const Vector2 &v1, const Vector2 &v2) { - return Vector2(v1.x - v2.x, v1.y - v2.y); -} - -VMATH_INLINE Vector2 operator *(const Vector2 &v1, const Vector2 &v2) { - return Vector2(v1.x * v2.x, v1.y * v2.y); -} - -VMATH_INLINE Vector2 operator /(const Vector2 &v1, const Vector2 &v2) { - return Vector2(v1.x / v2.x, v1.y / v2.y); -} - -VMATH_INLINE bool operator ==(const Vector2 &v1, const Vector2 &v2) { - return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER); -} - -VMATH_INLINE void operator +=(Vector2 &v1, const Vector2 &v2) { - v1.x += v2.x; - v1.y += v2.y; -} - -VMATH_INLINE void operator -=(Vector2 &v1, const Vector2 &v2) { - v1.x -= v2.x; - v1.y -= v2.y; -} - -VMATH_INLINE void operator *=(Vector2 &v1, const Vector2 &v2) { - v1.x *= v2.x; - v1.y *= v2.y; -} - -VMATH_INLINE void operator /=(Vector2 &v1, const Vector2 &v2) { - v1.x /= v2.x; - v1.y /= v2.y; -} - -VMATH_INLINE Vector2 operator +(const Vector2 &vec, scalar_t scalar) { - return Vector2(vec.x + scalar, vec.y + scalar); -} - -VMATH_INLINE Vector2 operator +(scalar_t scalar, const Vector2 &vec) { - return Vector2(vec.x + scalar, vec.y + scalar); -} - -VMATH_INLINE Vector2 operator -(scalar_t scalar, const Vector2 &vec) { - return Vector2(vec.x - scalar, vec.y - scalar); -} - -VMATH_INLINE Vector2 operator *(const Vector2 &vec, scalar_t scalar) { - return Vector2(vec.x * scalar, vec.y * scalar); -} - -VMATH_INLINE Vector2 operator *(scalar_t scalar, const Vector2 &vec) { - return Vector2(vec.x * scalar, vec.y * scalar); -} - -VMATH_INLINE Vector2 operator /(const Vector2 &vec, scalar_t scalar) { - return Vector2(vec.x / scalar, vec.y / scalar); -} - -VMATH_INLINE void operator +=(Vector2 &vec, scalar_t scalar) { - vec.x += scalar; - vec.y += scalar; -} - -VMATH_INLINE void operator -=(Vector2 &vec, scalar_t scalar) { - vec.x -= scalar; - vec.y -= scalar; -} - -VMATH_INLINE void operator *=(Vector2 &vec, scalar_t scalar) { - vec.x *= scalar; - vec.y *= scalar; -} - -VMATH_INLINE void operator /=(Vector2 &vec, scalar_t scalar) { - vec.x /= scalar; - vec.y /= scalar; -} - -VMATH_INLINE scalar_t Vector2::length() const { - return sqrt(x*x + y*y); -} - -VMATH_INLINE scalar_t Vector2::length_sq() const { - return x*x + y*y; -} - -VMATH_INLINE Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t) -{ - return a + (b - a) * t; -} - -VMATH_INLINE Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1, - const Vector2 &v2, const Vector2 &v3, scalar_t t) -{ - scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); - scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); - scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); - return Vector2(x, y); -} - - -/* ------------- Vector3 -------------- */ - -VMATH_INLINE scalar_t &Vector3::operator [](int elem) { - return elem ? (elem == 1 ? y : z) : x; -} - -VMATH_INLINE const scalar_t &Vector3::operator [](int elem) const { - return elem ? (elem == 1 ? y : z) : x; -} - -/* unary operations */ -VMATH_INLINE Vector3 operator -(const Vector3 &vec) { - return Vector3(-vec.x, -vec.y, -vec.z); -} - -/* binary vector (op) vector operations */ -VMATH_INLINE scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) { - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; -} - -VMATH_INLINE Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) { - return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); -} - - -VMATH_INLINE Vector3 operator +(const Vector3 &v1, const Vector3 &v2) { - return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); -} - -VMATH_INLINE Vector3 operator -(const Vector3 &v1, const Vector3 &v2) { - return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); -} - -VMATH_INLINE Vector3 operator *(const Vector3 &v1, const Vector3 &v2) { - return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); -} - -VMATH_INLINE Vector3 operator /(const Vector3 &v1, const Vector3 &v2) { - return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); -} - -VMATH_INLINE bool operator ==(const Vector3 &v1, const Vector3 &v2) { - return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER); -} - -VMATH_INLINE void operator +=(Vector3 &v1, const Vector3 &v2) { - v1.x += v2.x; - v1.y += v2.y; - v1.z += v2.z; -} - -VMATH_INLINE void operator -=(Vector3 &v1, const Vector3 &v2) { - v1.x -= v2.x; - v1.y -= v2.y; - v1.z -= v2.z; -} - -VMATH_INLINE void operator *=(Vector3 &v1, const Vector3 &v2) { - v1.x *= v2.x; - v1.y *= v2.y; - v1.z *= v2.z; -} - -VMATH_INLINE void operator /=(Vector3 &v1, const Vector3 &v2) { - v1.x /= v2.x; - v1.y /= v2.y; - v1.z /= v2.z; -} -/* binary vector (op) scalar and scalar (op) vector operations */ -VMATH_INLINE Vector3 operator +(const Vector3 &vec, scalar_t scalar) { - return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar); -} - -VMATH_INLINE Vector3 operator +(scalar_t scalar, const Vector3 &vec) { - return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar); -} - -VMATH_INLINE Vector3 operator -(const Vector3 &vec, scalar_t scalar) { - return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar); -} - -VMATH_INLINE Vector3 operator *(const Vector3 &vec, scalar_t scalar) { - return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar); -} - -VMATH_INLINE Vector3 operator *(scalar_t scalar, const Vector3 &vec) { - return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar); -} - -VMATH_INLINE Vector3 operator /(const Vector3 &vec, scalar_t scalar) { - return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar); -} - -VMATH_INLINE void operator +=(Vector3 &vec, scalar_t scalar) { - vec.x += scalar; - vec.y += scalar; - vec.z += scalar; -} - -VMATH_INLINE void operator -=(Vector3 &vec, scalar_t scalar) { - vec.x -= scalar; - vec.y -= scalar; - vec.z -= scalar; -} - -VMATH_INLINE void operator *=(Vector3 &vec, scalar_t scalar) { - vec.x *= scalar; - vec.y *= scalar; - vec.z *= scalar; -} - -VMATH_INLINE void operator /=(Vector3 &vec, scalar_t scalar) { - vec.x /= scalar; - vec.y /= scalar; - vec.z /= scalar; -} - -VMATH_INLINE scalar_t Vector3::length() const { - return sqrt(x*x + y*y + z*z); -} -VMATH_INLINE scalar_t Vector3::length_sq() const { - return x*x + y*y + z*z; -} - -VMATH_INLINE Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) { - return a + (b - a) * t; -} - -VMATH_INLINE Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1, - const Vector3 &v2, const Vector3 &v3, scalar_t t) -{ - scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); - scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); - scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); - scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t); - return Vector3(x, y, z); -} - -/* ----------- Vector4 ----------------- */ - -VMATH_INLINE scalar_t &Vector4::operator [](int elem) { - return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x; -} - -VMATH_INLINE const scalar_t &Vector4::operator [](int elem) const { - return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x; -} - -VMATH_INLINE Vector4 operator -(const Vector4 &vec) { - return Vector4(-vec.x, -vec.y, -vec.z, -vec.w); -} - -VMATH_INLINE scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) { - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; -} - -VMATH_INLINE Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) { - scalar_t a, b, c, d, e, f; /* Intermediate Values */ - Vector4 result; - - /* Calculate intermediate values. */ - a = (v2.x * v3.y) - (v2.y * v3.x); - b = (v2.x * v3.z) - (v2.z * v3.x); - c = (v2.x * v3.w) - (v2.w * v3.x); - d = (v2.y * v3.z) - (v2.z * v3.y); - e = (v2.y * v3.w) - (v2.w * v3.y); - f = (v2.z * v3.w) - (v2.w * v3.z); - - /* Calculate the result-vector components. */ - result.x = (v1.y * f) - (v1.z * e) + (v1.w * d); - result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b); - result.z = (v1.x * e) - (v1.y * c) + (v1.w * a); - result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a); - return result; -} - -VMATH_INLINE Vector4 operator +(const Vector4 &v1, const Vector4 &v2) { - return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); -} - -VMATH_INLINE Vector4 operator -(const Vector4 &v1, const Vector4 &v2) { - return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); -} - -VMATH_INLINE Vector4 operator *(const Vector4 &v1, const Vector4 &v2) { - return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w); -} - -VMATH_INLINE Vector4 operator /(const Vector4 &v1, const Vector4 &v2) { - return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w); -} - -VMATH_INLINE bool operator ==(const Vector4 &v1, const Vector4 &v2) { - return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && - (fabs(v1.y - v2.y) < XSMALL_NUMBER) && - (fabs(v1.z - v2.z) < XSMALL_NUMBER) && - (fabs(v1.w - v2.w) < XSMALL_NUMBER); -} - -VMATH_INLINE void operator +=(Vector4 &v1, const Vector4 &v2) { - v1.x += v2.x; - v1.y += v2.y; - v1.z += v2.z; - v1.w += v2.w; -} - -VMATH_INLINE void operator -=(Vector4 &v1, const Vector4 &v2) { - v1.x -= v2.x; - v1.y -= v2.y; - v1.z -= v2.z; - v1.w -= v2.w; -} - -VMATH_INLINE void operator *=(Vector4 &v1, const Vector4 &v2) { - v1.x *= v2.x; - v1.y *= v2.y; - v1.z *= v2.z; - v1.w *= v2.w; -} - -VMATH_INLINE void operator /=(Vector4 &v1, const Vector4 &v2) { - v1.x /= v2.x; - v1.y /= v2.y; - v1.z /= v2.z; - v1.w /= v2.w; -} - -/* binary vector (op) scalar and scalar (op) vector operations */ -VMATH_INLINE Vector4 operator +(const Vector4 &vec, scalar_t scalar) { - return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar); -} - -VMATH_INLINE Vector4 operator +(scalar_t scalar, const Vector4 &vec) { - return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar); -} - -VMATH_INLINE Vector4 operator -(const Vector4 &vec, scalar_t scalar) { - return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar); -} - -VMATH_INLINE Vector4 operator *(const Vector4 &vec, scalar_t scalar) { - return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar); -} - -VMATH_INLINE Vector4 operator *(scalar_t scalar, const Vector4 &vec) { - return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar); -} - -VMATH_INLINE Vector4 operator /(const Vector4 &vec, scalar_t scalar) { - return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar); -} - -VMATH_INLINE void operator +=(Vector4 &vec, scalar_t scalar) { - vec.x += scalar; - vec.y += scalar; - vec.z += scalar; - vec.w += scalar; -} - -VMATH_INLINE void operator -=(Vector4 &vec, scalar_t scalar) { - vec.x -= scalar; - vec.y -= scalar; - vec.z -= scalar; - vec.w -= scalar; -} - -VMATH_INLINE void operator *=(Vector4 &vec, scalar_t scalar) { - vec.x *= scalar; - vec.y *= scalar; - vec.z *= scalar; - vec.w *= scalar; -} - -VMATH_INLINE void operator /=(Vector4 &vec, scalar_t scalar) { - vec.x /= scalar; - vec.y /= scalar; - vec.z /= scalar; - vec.w /= scalar; -} - -VMATH_INLINE scalar_t Vector4::length() const { - return sqrt(x*x + y*y + z*z + w*w); -} -VMATH_INLINE scalar_t Vector4::length_sq() const { - return x*x + y*y + z*z + w*w; -} - -VMATH_INLINE Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t) -{ - return v0 + (v1 - v0) * t; -} - -VMATH_INLINE Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1, - const Vector4 &v2, const Vector4 &v3, scalar_t t) -{ - scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); - scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); - scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); - scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t); - scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t); - return Vector4(x, y, z, w); -} - -#endif /* __cplusplus */ diff -r dad392c710df -r 99715321ad6d libs/vmath/vmath.c --- a/libs/vmath/vmath.c Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,336 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include -#include -#include "vmath.h" - -/** Numerical calculation of integrals using simpson's rule */ -scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples) -{ - int i; - scalar_t h = (high - low) / (scalar_t)samples; - scalar_t sum = 0.0; - - for(i=0; i - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_H_ -#define VMATH_H_ - -#include -#include "vmath_types.h" - -#ifndef M_PI -#define M_PI PI -#endif - -#ifndef M_E -#define M_E 2.718281828459045 -#endif - -#define PI 3.141592653589793 -#define HALF_PI 1.570796326794897 -#define QUARTER_PI 0.785398163397448 -#define TWO_PI 6.283185307179586 - - -#define RAD_TO_DEG(a) ((((scalar_t)a) * 360.0) / TWO_PI) -#define DEG_TO_RAD(a) (((scalar_t)a) * (PI / 180.0)) - -#define SQ(x) ((x) * (x)) - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -#ifndef __GNUC__ -#define round(x) ((x) >= 0 ? (x) + 0.5 : (x) - 0.5) -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -static VMATH_INLINE scalar_t smoothstep(float a, float b, float x); - -static VMATH_INLINE scalar_t frand(scalar_t range); -static VMATH_INLINE vec3_t sphrand(scalar_t rad); - -scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples); -scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev); - -static VMATH_INLINE scalar_t lerp(scalar_t a, scalar_t b, scalar_t t); - -scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); -scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); -scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); - -scalar_t noise1(scalar_t x); -scalar_t noise2(scalar_t x, scalar_t y); -scalar_t noise3(scalar_t x, scalar_t y, scalar_t z); - -scalar_t fbm1(scalar_t x, int octaves); -scalar_t fbm2(scalar_t x, scalar_t y, int octaves); -scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves); - -scalar_t turbulence1(scalar_t x, int octaves); -scalar_t turbulence2(scalar_t x, scalar_t y, int octaves); -scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#include "vmath.inl" - -#include "vector.h" -#include "matrix.h" -#include "quat.h" -#include "sphvec.h" -#include "ray.h" -#include "geom.h" - -#endif /* VMATH_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/vmath.inl --- a/libs/vmath/vmath.inl Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#include - -static VMATH_INLINE scalar_t smoothstep(float a, float b, float x) -{ - if(x < a) return 0.0; - if(x >= b) return 1.0; - - x = (x - a) / (b - a); - return x * x * (3.0 - 2.0 * x); -} - -/** Generates a random number in [0, range) */ -static VMATH_INLINE scalar_t frand(scalar_t range) -{ - return range * (scalar_t)rand() / (scalar_t)RAND_MAX; -} - -/** Generates a random vector on the surface of a sphere */ -static VMATH_INLINE vec3_t sphrand(scalar_t rad) -{ - scalar_t u = (scalar_t)rand() / RAND_MAX; - scalar_t v = (scalar_t)rand() / RAND_MAX; - - scalar_t theta = 2.0 * M_PI * u; - scalar_t phi = acos(2.0 * v - 1.0); - - vec3_t res; - res.x = rad * cos(theta) * sin(phi); - res.y = rad * sin(theta) * sin(phi); - res.z = rad * cos(phi); - return res; -} - -/** linear interpolation */ -static VMATH_INLINE scalar_t lerp(scalar_t a, scalar_t b, scalar_t t) -{ - return a + (b - a) * t; -} diff -r dad392c710df -r 99715321ad6d libs/vmath/vmath_config.h --- a/libs/vmath/vmath_config.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#ifndef VMATH_CONFIG_H_ -#define VMATH_CONFIG_H_ - -#ifdef __cplusplus -#define VMATH_INLINE inline -#elif (__STDC_VERSION__ < 199999) -#if defined(__GNUC__) || defined(_MSC_VER) -#define VMATH_INLINE __inline -#else -#define VMATH_INLINE - -#ifdef VECTOR_H_ -#warning "compiling vector operations without inline, performance might suffer" -#endif /* VECTOR_H_ */ - -#endif /* gcc/msvc */ -#endif /* not C99 */ - -#define SINGLE_PRECISION_MATH - -#endif /* VMATH_CONFIG_H_ */ diff -r dad392c710df -r 99715321ad6d libs/vmath/vmath_types.h --- a/libs/vmath/vmath_types.h Thu Apr 17 08:50:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* -libvmath - a vector math library -Copyright (C) 2004-2011 John Tsiombikas - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see . -*/ - -#ifndef VMATH_TYPES_H_ -#define VMATH_TYPES_H_ - -#include "vmath_config.h" - -#define SMALL_NUMBER 1.e-4 -#define XSMALL_NUMBER 1.e-8 -#define ERROR_MARGIN 1.e-6 - - -#ifdef SINGLE_PRECISION_MATH -typedef float scalar_t; -#else -typedef double scalar_t; -#endif /* floating point precision */ - -/* vectors */ -typedef struct { scalar_t x, y; } vec2_t; -typedef struct { scalar_t x, y, z; } vec3_t; -typedef struct { scalar_t x, y, z, w; } vec4_t; - -/* quaternions */ -typedef vec4_t quat_t; - -/* matrices */ -typedef scalar_t mat3_t[3][3]; -typedef scalar_t mat4_t[4][4]; - - -#ifdef __cplusplus -class Vector2; -class Vector3; -class Vector4; -class Quaternion; -class Matrix3x3; -class Matrix4x4; -class SphVector; -#endif /* __cplusplus */ - -#endif /* VMATH_TYPES_H_ */ diff -r dad392c710df -r 99715321ad6d src/goat3d.cc --- a/src/goat3d.cc Thu Apr 17 08:50:36 2014 +0300 +++ b/src/goat3d.cc Thu Apr 17 08:53:42 2014 +0300 @@ -179,14 +179,14 @@ return res; } -GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const struct goat3d_node *root, const char *fname) +GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const char *fname) { FILE *fp = fopen(fname, "wb"); if(!fp) { return -1; } - int res = goat3d_save_anim_file(g, root, fp); + int res = goat3d_save_anim_file(g, fp); fclose(fp); return res; } @@ -202,7 +202,7 @@ return goat3d_load_anim_io(g, &io); } -GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, const struct goat3d_node *root, FILE *fp) +GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, FILE *fp) { goat3d_io io; io.cls = fp; @@ -210,7 +210,7 @@ io.write = write_file; io.seek = seek_file; - return goat3d_save_anim_io(g, root, &io); + return goat3d_save_anim_io(g, &io); } GOAT3DAPI int goat3d_load_anim_io(struct goat3d *g, struct goat3d_io *io) @@ -223,12 +223,12 @@ return 0; } -GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, const struct goat3d_node *root, struct goat3d_io *io) +GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, struct goat3d_io *io) { if(goat3d_getopt(g, GOAT3D_OPT_SAVEXML)) { - return g->scn->save_anim_xml(root, io) ? 0 : -1; + return g->scn->save_anim_xml(io) ? 0 : -1; } - return g->scn->save_anim(root, io) ? 0 : -1; + return g->scn->save_anim(io) ? 0 : -1; } @@ -264,6 +264,21 @@ g->scn->add_material(mtl); } +GOAT3DAPI int goat3d_get_mtl_count(struct goat3d *g) +{ + return g->scn->get_material_count(); +} + +GOAT3DAPI struct goat3d_material *goat3d_get_mtl(struct goat3d *g, int idx) +{ + return (goat3d_material*)g->scn->get_material(idx); +} + +GOAT3DAPI struct goat3d_material *goat3d_get_mtl_by_name(struct goat3d *g, const char *name) +{ + return (goat3d_material*)g->scn->get_material(name); +} + GOAT3DAPI struct goat3d_material *goat3d_create_mtl(void) { return new goat3d_material; @@ -422,6 +437,12 @@ goat3d_add_mesh_attrib4f(mesh, attrib, val, 0, 0, 1); } +GOAT3DAPI void goat3d_add_mesh_attrib2f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float x, float y) +{ + goat3d_add_mesh_attrib4f(mesh, attrib, x, y, 0, 1); +} + GOAT3DAPI void goat3d_add_mesh_attrib3f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, float x, float y, float z) { diff -r dad392c710df -r 99715321ad6d src/goat3d.h --- a/src/goat3d.h Thu Apr 17 08:50:36 2014 +0300 +++ b/src/goat3d.h Thu Apr 17 08:53:42 2014 +0300 @@ -107,13 +107,13 @@ /* load/save animation files (g must already be loaded to load animations) */ GOAT3DAPI int goat3d_load_anim(struct goat3d *g, const char *fname); -GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const struct goat3d_node *root, const char *fname); +GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const char *fname); GOAT3DAPI int goat3d_load_anim_file(struct goat3d *g, FILE *fp); -GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, const struct goat3d_node *root, FILE *fp); +GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, FILE *fp); GOAT3DAPI int goat3d_load_anim_io(struct goat3d *g, struct goat3d_io *io); -GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, const struct goat3d_node *root, struct goat3d_io *io); +GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, struct goat3d_io *io); /* misc scene properties */ GOAT3DAPI int goat3d_set_name(struct goat3d *g, const char *name); @@ -125,6 +125,9 @@ /* materials */ GOAT3DAPI void goat3d_add_mtl(struct goat3d *g, struct goat3d_material *mtl); +GOAT3DAPI int goat3d_get_mtl_count(struct goat3d *g); +GOAT3DAPI struct goat3d_material *goat3d_get_mtl(struct goat3d *g, int idx); +GOAT3DAPI struct goat3d_material *goat3d_get_mtl_by_name(struct goat3d *g, const char *name); GOAT3DAPI struct goat3d_material *goat3d_create_mtl(void); GOAT3DAPI void goat3d_destroy_mtl(struct goat3d_material *mtl); @@ -173,6 +176,8 @@ GOAT3DAPI void goat3d_set_mesh_attribs(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, const void *data, int vnum); GOAT3DAPI void goat3d_add_mesh_attrib1f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, float val); +GOAT3DAPI void goat3d_add_mesh_attrib2f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, + float x, float y); GOAT3DAPI void goat3d_add_mesh_attrib3f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, float x, float y, float z); GOAT3DAPI void goat3d_add_mesh_attrib4f(struct goat3d_mesh *mesh, enum goat3d_mesh_attrib attrib, diff -r dad392c710df -r 99715321ad6d src/goat3d_impl.h --- a/src/goat3d_impl.h Thu Apr 17 08:50:36 2014 +0300 +++ b/src/goat3d_impl.h Thu Apr 17 08:53:42 2014 +0300 @@ -98,10 +98,10 @@ bool savexml(goat3d_io *io) const; bool load_anim(goat3d_io *io); - bool save_anim(const XFormNode *node, goat3d_io *io) const; + bool save_anim(goat3d_io *io) const; bool load_anim_xml(goat3d_io *io); - bool save_anim_xml(const XFormNode *node, goat3d_io *io) const; + bool save_anim_xml(goat3d_io *io) const; }; void io_fprintf(goat3d_io *io, const char *fmt, ...); diff -r dad392c710df -r 99715321ad6d src/goat3d_write.cc --- a/src/goat3d_write.cc Thu Apr 17 08:50:36 2014 +0300 +++ b/src/goat3d_write.cc Thu Apr 17 08:53:42 2014 +0300 @@ -85,7 +85,7 @@ return false; } -bool Scene::save_anim(const XFormNode *node, goat3d_io *io) const +bool Scene::save_anim(goat3d_io *io) const { return false; } diff -r dad392c710df -r 99715321ad6d src/goat3d_writexml.cc --- a/src/goat3d_writexml.cc Thu Apr 17 08:50:36 2014 +0300 +++ b/src/goat3d_writexml.cc Thu Apr 17 08:53:42 2014 +0300 @@ -44,7 +44,7 @@ write_material(this, io, materials[i], 1); } for(size_t i=0; i *res, const XFormNode *node) -{ - if(!node) return; - - res->push_back(node); - - for(int i=0; iget_children_count(); i++) { - collect_nodes(res, node->get_child(i)); - } -} - -bool Scene::save_anim_xml(const XFormNode *node, goat3d_io *io) const +bool Scene::save_anim_xml(goat3d_io *io) const { xmlout(io, 0, "\n"); - const char *anim_name = node->get_animation_name(); - if(anim_name && *anim_name) { - xmlout(io, 1, "\n", anim_name); + if(!nodes.empty()) { + const char *anim_name = nodes[0]->get_animation_name(); + if(anim_name && *anim_name) { + xmlout(io, 1, "\n", anim_name); + } } - std::list allnodes; - collect_nodes(&allnodes, node); - - std::list::const_iterator it = allnodes.begin(); - while(it != allnodes.end()) { - const XFormNode *n = *it++; - write_node_anim(io, n, 1); + for(size_t i=0; i\n"); diff -r dad392c710df -r 99715321ad6d src/node.cc --- a/src/node.cc Thu Apr 17 08:50:36 2014 +0300 +++ b/src/node.cc Thu Apr 17 08:53:42 2014 +0300 @@ -43,6 +43,8 @@ void g3dimpl::delete_node_tree(Node *n) { + if(!n) return; + for(int i=0; iget_children_count(); i++) { delete_node_tree((Node*)n->get_child(i)); }