goat3d
changeset 27:4deb0b12fe14
wtf... corrupted heap?
line diff
1.1 --- a/exporters/maxgoat/maxgoat.vcxproj Sat Sep 28 20:36:55 2013 +0300 1.2 +++ b/exporters/maxgoat/maxgoat.vcxproj Sun Sep 29 08:20:19 2013 +0300 1.3 @@ -33,7 +33,7 @@ 1.4 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> 1.5 <ConfigurationType>DynamicLibrary</ConfigurationType> 1.6 <UseDebugLibraries>true</UseDebugLibraries> 1.7 - <PlatformToolset>v110</PlatformToolset> 1.8 + <PlatformToolset>v100</PlatformToolset> 1.9 <CharacterSet>Unicode</CharacterSet> 1.10 </PropertyGroup> 1.11 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 1.12 @@ -46,7 +46,7 @@ 1.13 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> 1.14 <ConfigurationType>DynamicLibrary</ConfigurationType> 1.15 <UseDebugLibraries>false</UseDebugLibraries> 1.16 - <PlatformToolset>v110</PlatformToolset> 1.17 + <PlatformToolset>v100</PlatformToolset> 1.18 <WholeProgramOptimization>true</WholeProgramOptimization> 1.19 <CharacterSet>Unicode</CharacterSet> 1.20 </PropertyGroup> 1.21 @@ -70,7 +70,7 @@ 1.22 <LinkIncremental>true</LinkIncremental> 1.23 </PropertyGroup> 1.24 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> 1.25 - <LinkIncremental>true</LinkIncremental> 1.26 + <LinkIncremental>false</LinkIncremental> 1.27 </PropertyGroup> 1.28 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 1.29 <LinkIncremental>false</LinkIncremental> 1.30 @@ -98,14 +98,14 @@ 1.31 </PrecompiledHeader> 1.32 <WarningLevel>Level3</WarningLevel> 1.33 <Optimization>Disabled</Optimization> 1.34 - <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MAXGOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 1.35 - <DisableSpecificWarnings>4996</DisableSpecificWarnings> 1.36 + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MAXGOAT_EXPORTS;%(PreprocessorDefinitions);BUILD_MAXPLUGIN</PreprocessorDefinitions> 1.37 + <DisableSpecificWarnings>4996;4244</DisableSpecificWarnings> 1.38 <AdditionalIncludeDirectories>$(SolutionDir)\src</AdditionalIncludeDirectories> 1.39 </ClCompile> 1.40 <Link> 1.41 <SubSystem>Windows</SubSystem> 1.42 <GenerateDebugInformation>true</GenerateDebugInformation> 1.43 - <AdditionalDependencies>goat3d-x64.lib;libvmath-x64.lib;libanim-x64.lib;%(AdditionalDependencies)</AdditionalDependencies> 1.44 + <AdditionalDependencies>goat3d-x64.lib;%(AdditionalDependencies)</AdditionalDependencies> 1.45 <AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> 1.46 </Link> 1.47 <PostBuildEvent> 1.48 @@ -139,7 +139,7 @@ 1.49 <FunctionLevelLinking>true</FunctionLevelLinking> 1.50 <IntrinsicFunctions>true</IntrinsicFunctions> 1.51 <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MAXGOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 1.52 - <DisableSpecificWarnings>4996</DisableSpecificWarnings> 1.53 + <DisableSpecificWarnings>4996;4244</DisableSpecificWarnings> 1.54 <AdditionalIncludeDirectories>$(SolutionDir)\src</AdditionalIncludeDirectories> 1.55 </ClCompile> 1.56 <Link> 1.57 @@ -147,7 +147,7 @@ 1.58 <GenerateDebugInformation>true</GenerateDebugInformation> 1.59 <EnableCOMDATFolding>true</EnableCOMDATFolding> 1.60 <OptimizeReferences>true</OptimizeReferences> 1.61 - <AdditionalDependencies>goat3d-x64.lib;libvmath-x64.lib;libanim-x64.lib;%(AdditionalDependencies)</AdditionalDependencies> 1.62 + <AdditionalDependencies>goat3d-x64.lib;%(AdditionalDependencies)</AdditionalDependencies> 1.63 <AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> 1.64 </Link> 1.65 <PostBuildEvent> 1.66 @@ -157,9 +157,6 @@ 1.67 <ItemGroup> 1.68 <ClCompile Include="src\maxgoat.cc" /> 1.69 </ItemGroup> 1.70 - <ItemGroup> 1.71 - <ClInclude Include="src\config.h" /> 1.72 - </ItemGroup> 1.73 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 1.74 <ImportGroup Label="ExtensionTargets"> 1.75 </ImportGroup>
2.1 --- a/exporters/maxgoat/maxgoat.vcxproj.filters Sat Sep 28 20:36:55 2013 +0300 2.2 +++ b/exporters/maxgoat/maxgoat.vcxproj.filters Sun Sep 29 08:20:19 2013 +0300 2.3 @@ -11,9 +11,4 @@ 2.4 <Filter>src</Filter> 2.5 </ClCompile> 2.6 </ItemGroup> 2.7 - <ItemGroup> 2.8 - <ClInclude Include="src\config.h"> 2.9 - <Filter>src</Filter> 2.10 - </ClInclude> 2.11 - </ItemGroup> 2.12 </Project> 2.13 \ No newline at end of file
3.1 --- a/exporters/maxgoat/src/maxgoat.cc Sat Sep 28 20:36:55 2013 +0300 3.2 +++ b/exporters/maxgoat/src/maxgoat.cc Sun Sep 29 08:20:19 2013 +0300 3.3 @@ -1,6 +1,8 @@ 3.4 #include <stdio.h> 3.5 #include <string.h> 3.6 +#include <stdlib.h> 3.7 #include <errno.h> 3.8 +#include <map> 3.9 #include <windows.h> 3.10 #include <shlobj.h> 3.11 #include "max.h" 3.12 @@ -33,6 +35,10 @@ 3.13 static HINSTANCE hinst; 3.14 3.15 class GoatExporter : public SceneExport { 3.16 +private: 3.17 + //std::map<IGameMaterial*, goat3d_material*> mtlmap; 3.18 + //std::map<IGameNode*, goat3d_node*> nodemap; 3.19 + 3.20 public: 3.21 IGameScene *igame; 3.22 3.23 @@ -49,9 +55,13 @@ 3.24 3.25 int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0); 3.26 3.27 - void export_materials(goat3d *goat); 3.28 - void export_meshes(goat3d *goat); 3.29 - void process_node(goat3d *goat, IGameNode *maxnode); 3.30 + void process_materials(goat3d *goat); 3.31 + 3.32 + void process_node(goat3d *goat, goat3d_node *parent, IGameNode *maxnode); 3.33 + 3.34 + void process_mesh(goat3d *goat, goat3d_mesh *mesh, IGameObject *maxobj); 3.35 + void process_light(goat3d *goat, goat3d_light *light, IGameObject *maxobj); 3.36 + void process_camera(goat3d *goat, goat3d_camera *cam, IGameObject *maxobj); 3.37 }; 3.38 3.39 3.40 @@ -62,7 +72,7 @@ 3.41 3.42 const TCHAR *GoatExporter::Ext(int n) 3.43 { 3.44 - return L"txt"; 3.45 + return L"xml"; 3.46 } 3.47 3.48 const TCHAR *GoatExporter::LongDesc() 3.49 @@ -108,6 +118,9 @@ 3.50 int GoatExporter::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, 3.51 BOOL non_interactive, DWORD opt) 3.52 { 3.53 + //mtlmap.clear(); 3.54 + //nodemap.clear(); 3.55 + 3.56 char fname[512]; 3.57 wcstombs(fname, name, sizeof fname - 1); 3.58 3.59 @@ -122,20 +135,19 @@ 3.60 3.61 goat3d *goat = goat3d_create(); 3.62 3.63 - export_materials(goat); 3.64 - export_meshes(goat); 3.65 + process_materials(goat); 3.66 + 3.67 + // process all nodes 3.68 + for(int i=0; i<igame->GetTopLevelNodeCount(); i++) { 3.69 + IGameNode *node = igame->GetTopLevelNode(i); 3.70 + process_node(goat, 0, node); 3.71 + } 3.72 3.73 if(goat3d_save(goat, fname) == -1) { 3.74 goat3d_free(goat); 3.75 return IMPEXP_FAIL; 3.76 } 3.77 3.78 - // process all nodes 3.79 - for(int i=0; i<igame->GetTopLevelNodeCount(); i++) { 3.80 - IGameNode *node = igame->GetTopLevelNode(i); 3.81 - process_node(goat, node); 3.82 - } 3.83 - 3.84 goat3d_free(goat); 3.85 return IMPEXP_SUCCESS; 3.86 } 3.87 @@ -148,7 +160,7 @@ 3.88 return str; 3.89 } 3.90 3.91 -void GoatExporter::export_materials(goat3d *goat) 3.92 +void GoatExporter::process_materials(goat3d *goat) 3.93 { 3.94 IGameProperty *prop; 3.95 3.96 @@ -231,19 +243,138 @@ 3.97 } 3.98 3.99 goat3d_add_mtl(goat, mtl); 3.100 + //mtlmap[maxmtl] = mtl; 3.101 } 3.102 } 3.103 } 3.104 3.105 -void GoatExporter::export_meshes(goat3d *goat) 3.106 +void GoatExporter::process_node(goat3d *goat, goat3d_node *parent, IGameNode *maxnode) 3.107 { 3.108 - Tab<IGameNode*> meshes = igame->GetIGameNodeByType(IGameObject::IGAME_MESH); 3.109 + goat3d_node *node = goat3d_create_node(); 3.110 + goat3d_add_node(goat, node); 3.111 3.112 - for(int i=0; i<meshes.Count(); i++) { 3.113 - const char *name = max_string(meshes[i]->GetName()); 3.114 + const char *name = max_string(maxnode->GetName()); 3.115 + if(name) { 3.116 + goat3d_set_node_name(node, name); 3.117 + } 3.118 + 3.119 + // no animation yet, just get the static PRS 3.120 + GMatrix maxmatrix = maxnode->GetObjectTM(); 3.121 + Point3 trans = maxmatrix.Translation(); 3.122 + Quat rot = maxmatrix.Rotation(); 3.123 + Point3 scale = maxmatrix.Scaling(); 3.124 + 3.125 + goat3d_set_node_position(node, trans.x, trans.y, trans.z, 0); 3.126 + goat3d_set_node_rotation(node, rot.x, rot.y, rot.z, rot.w, 0); 3.127 + goat3d_set_node_scaling(node, scale.x, scale.y, scale.z, 0); 3.128 + 3.129 + IGameObject *maxobj = maxnode->GetIGameObject(); 3.130 + IGameObject::ObjectTypes type = maxobj->GetIGameType(); 3.131 + 3.132 + switch(type) { 3.133 + case IGameObject::IGAME_MESH: 3.134 + { 3.135 + goat3d_mesh *mesh = goat3d_create_mesh(); 3.136 + if(name) goat3d_set_mesh_name(mesh, name); 3.137 + goat3d_set_node_object(node, GOAT3D_NODE_MESH, mesh); 3.138 + 3.139 + // get the node material and assign it to the mesh 3.140 + IGameMaterial *maxmtl = maxnode->GetNodeMaterial(); 3.141 + goat3d_material *mtl = 0;//mtlmap[maxmtl]; 3.142 + if(mtl) { 3.143 + goat3d_set_mesh_mtl(mesh, mtl); 3.144 + } 3.145 + 3.146 + process_mesh(goat, mesh, maxobj); 3.147 + } 3.148 + break; 3.149 + 3.150 + case IGameObject::IGAME_LIGHT: 3.151 + { 3.152 + goat3d_light *light = goat3d_create_light(); 3.153 + //if(name) goat3d_set_light_name(light, name); 3.154 + goat3d_set_node_object(node, GOAT3D_NODE_LIGHT, light); 3.155 + 3.156 + process_light(goat, light, maxobj); 3.157 + } 3.158 + break; 3.159 + 3.160 + case IGameObject::IGAME_CAMERA: 3.161 + { 3.162 + goat3d_camera *cam = goat3d_create_camera(); 3.163 + //if(name) goat3d_set_camera_name(camera, name); 3.164 + goat3d_set_node_object(node, GOAT3D_NODE_CAMERA, cam); 3.165 + 3.166 + process_camera(goat, cam, maxobj); 3.167 + } 3.168 + break; 3.169 + 3.170 + default: 3.171 + // otherwise don't assign an object, essentially treating it as a null node 3.172 + break; 3.173 + } 3.174 + 3.175 + 3.176 + for(int i=0; i<maxnode->GetChildCount(); i++) { 3.177 + process_node(goat, node, maxnode->GetNodeChild(i)); 3.178 } 3.179 } 3.180 3.181 +void GoatExporter::process_mesh(goat3d *goat, goat3d_mesh *mesh, IGameObject *maxobj) 3.182 +{ 3.183 + IGameMesh *maxmesh = (IGameMesh*)maxobj; 3.184 + 3.185 + maxmesh->SetCreateOptimizedNormalList(); // not needed any more according to docs 3.186 + maxobj->InitializeData(); 3.187 + 3.188 + int num_verts = maxmesh->GetNumberOfVerts(); 3.189 + assert(maxmesh->GetNumberOfTexVerts() == num_verts); 3.190 + 3.191 + float *vertices = new float[num_verts * 3]; 3.192 + float *normals = new float[num_verts * 3]; 3.193 + float *texcoords = new float[num_verts * 2]; 3.194 + 3.195 + for(int i=0; i<num_verts; i++) { 3.196 + Point3 v = maxmesh->GetVertex(i, true); 3.197 + vertices[i * 3] = v.x; 3.198 + vertices[i * 3 + 1] = v.y; 3.199 + vertices[i * 3 + 2] = v.z; 3.200 + } 3.201 + 3.202 + for(int i=0; i<maxmesh->GetNumberOfNormals(); i++) { 3.203 + Point3 norm = maxmesh->GetNormal(i); 3.204 + 3.205 + int vidx = maxmesh->GetNormalVertexIndex(i); 3.206 + normals[vidx * 3] = norm.x; 3.207 + normals[vidx * 3 + 1] = norm.y; 3.208 + normals[vidx * 3 + 2] = norm.z; 3.209 + } 3.210 + 3.211 + for(int i=0; i<maxmesh->GetNumberOfTexVerts(); i++) { 3.212 + Point3 tex = maxmesh->GetTexVertex(i); 3.213 + 3.214 + texcoords[i * 2] = tex.x; 3.215 + texcoords[i * 2 + 1] = tex.y; 3.216 + } 3.217 + 3.218 + goat3d_set_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX, vertices, num_verts); 3.219 + goat3d_set_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL, normals, num_verts); 3.220 + goat3d_set_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD, texcoords, num_verts); 3.221 + 3.222 + delete [] vertices; 3.223 + delete [] normals; 3.224 + delete [] texcoords; 3.225 +} 3.226 + 3.227 +void GoatExporter::process_light(goat3d *goat, goat3d_light *light, IGameObject *maxobj) 3.228 +{ 3.229 +} 3.230 + 3.231 +void GoatExporter::process_camera(goat3d *goat, goat3d_camera *cam, IGameObject *maxobj) 3.232 +{ 3.233 +} 3.234 + 3.235 + 3.236 // ------------------------------------------ 3.237 3.238 class GoatClassDesc : public ClassDesc2 {
4.1 --- a/goat3d.vcxproj Sat Sep 28 20:36:55 2013 +0300 4.2 +++ b/goat3d.vcxproj Sun Sep 29 08:20:19 2013 +0300 4.3 @@ -19,6 +19,9 @@ 4.4 </ProjectConfiguration> 4.5 </ItemGroup> 4.6 <ItemGroup> 4.7 + <ClInclude Include="libs\anim\anim.h" /> 4.8 + <ClInclude Include="libs\anim\dynarr.h" /> 4.9 + <ClInclude Include="libs\anim\track.h" /> 4.10 <ClInclude Include="libs\openctm\internal.h" /> 4.11 <ClInclude Include="libs\openctm\liblzma\Alloc.h" /> 4.12 <ClInclude Include="libs\openctm\liblzma\LzFind.h" /> 4.13 @@ -31,6 +34,16 @@ 4.14 <ClInclude Include="libs\openctm\openctm.h" /> 4.15 <ClInclude Include="libs\openctm\openctmpp.h" /> 4.16 <ClInclude Include="libs\tinyxml2\tinyxml2.h" /> 4.17 + <ClInclude Include="libs\vmath\basis.h" /> 4.18 + <ClInclude Include="libs\vmath\geom.h" /> 4.19 + <ClInclude Include="libs\vmath\matrix.h" /> 4.20 + <ClInclude Include="libs\vmath\quat.h" /> 4.21 + <ClInclude Include="libs\vmath\ray.h" /> 4.22 + <ClInclude Include="libs\vmath\sphvec.h" /> 4.23 + <ClInclude Include="libs\vmath\vector.h" /> 4.24 + <ClInclude Include="libs\vmath\vmath.h" /> 4.25 + <ClInclude Include="libs\vmath\vmath_config.h" /> 4.26 + <ClInclude Include="libs\vmath\vmath_types.h" /> 4.27 <ClInclude Include="src\camera.h" /> 4.28 <ClInclude Include="src\chunk.h" /> 4.29 <ClInclude Include="src\goat3d.h" /> 4.30 @@ -44,6 +57,9 @@ 4.31 <ClInclude Include="src\xform_node.h" /> 4.32 </ItemGroup> 4.33 <ItemGroup> 4.34 + <ClCompile Include="libs\anim\anim.c" /> 4.35 + <ClCompile Include="libs\anim\dynarr.c" /> 4.36 + <ClCompile Include="libs\anim\track.c" /> 4.37 <ClCompile Include="libs\openctm\compressMG1.c" /> 4.38 <ClCompile Include="libs\openctm\compressMG2.c" /> 4.39 <ClCompile Include="libs\openctm\compressRAW.c" /> 4.40 @@ -55,6 +71,18 @@ 4.41 <ClCompile Include="libs\openctm\openctm.c" /> 4.42 <ClCompile Include="libs\openctm\stream.c" /> 4.43 <ClCompile Include="libs\tinyxml2\tinyxml2.cpp" /> 4.44 + <ClCompile Include="libs\vmath\basis.cc" /> 4.45 + <ClCompile Include="libs\vmath\basis_c.c" /> 4.46 + <ClCompile Include="libs\vmath\geom.c" /> 4.47 + <ClCompile Include="libs\vmath\matrix.cc" /> 4.48 + <ClCompile Include="libs\vmath\matrix_c.c" /> 4.49 + <ClCompile Include="libs\vmath\quat.cc" /> 4.50 + <ClCompile Include="libs\vmath\quat_c.c" /> 4.51 + <ClCompile Include="libs\vmath\ray.cc" /> 4.52 + <ClCompile Include="libs\vmath\ray_c.c" /> 4.53 + <ClCompile Include="libs\vmath\sphvec.cc" /> 4.54 + <ClCompile Include="libs\vmath\vector.cc" /> 4.55 + <ClCompile Include="libs\vmath\vmath.c" /> 4.56 <ClCompile Include="src\camera.cc" /> 4.57 <ClCompile Include="src\chunk.cc" /> 4.58 <ClCompile Include="src\goat3d.cc" /> 4.59 @@ -69,6 +97,13 @@ 4.60 <ClCompile Include="src\scene.cc" /> 4.61 <ClCompile Include="src\xform_node.cc" /> 4.62 </ItemGroup> 4.63 + <ItemGroup> 4.64 + <None Include="libs\vmath\matrix.inl" /> 4.65 + <None Include="libs\vmath\quat.inl" /> 4.66 + <None Include="libs\vmath\ray.inl" /> 4.67 + <None Include="libs\vmath\vector.inl" /> 4.68 + <None Include="libs\vmath\vmath.inl" /> 4.69 + </ItemGroup> 4.70 <PropertyGroup Label="Globals"> 4.71 <ProjectGuid>{86BF319B-9222-4805-918D-DC1B9F77BCEF}</ProjectGuid> 4.72 <Keyword>Win32Proj</Keyword> 4.73 @@ -84,7 +119,7 @@ 4.74 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> 4.75 <ConfigurationType>StaticLibrary</ConfigurationType> 4.76 <UseDebugLibraries>true</UseDebugLibraries> 4.77 - <PlatformToolset>v110</PlatformToolset> 4.78 + <PlatformToolset>v100</PlatformToolset> 4.79 <CharacterSet>Unicode</CharacterSet> 4.80 </PropertyGroup> 4.81 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 4.82 @@ -97,7 +132,7 @@ 4.83 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> 4.84 <ConfigurationType>StaticLibrary</ConfigurationType> 4.85 <UseDebugLibraries>false</UseDebugLibraries> 4.86 - <PlatformToolset>v110</PlatformToolset> 4.87 + <PlatformToolset>v100</PlatformToolset> 4.88 <WholeProgramOptimization>true</WholeProgramOptimization> 4.89 <CharacterSet>Unicode</CharacterSet> 4.90 </PropertyGroup> 4.91 @@ -143,14 +178,18 @@ 4.92 </PrecompiledHeader> 4.93 <WarningLevel>Level3</WarningLevel> 4.94 <Optimization>Disabled</Optimization> 4.95 - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);OPENCTM_STATIC</PreprocessorDefinitions> 4.96 + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);OPENCTM_STATIC;BUILD_MAXPLUGIN</PreprocessorDefinitions> 4.97 <DisableSpecificWarnings>4244;4305;4996</DisableSpecificWarnings> 4.98 - <AdditionalIncludeDirectories>$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2</AdditionalIncludeDirectories> 4.99 + <AdditionalIncludeDirectories>$(SolutionDir)\src;$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2</AdditionalIncludeDirectories> 4.100 </ClCompile> 4.101 <Link> 4.102 <SubSystem>Windows</SubSystem> 4.103 <GenerateDebugInformation>true</GenerateDebugInformation> 4.104 </Link> 4.105 + <Lib> 4.106 + <AdditionalDependencies> 4.107 + </AdditionalDependencies> 4.108 + </Lib> 4.109 </ItemDefinitionGroup> 4.110 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 4.111 <ClCompile> 4.112 @@ -180,7 +219,7 @@ 4.113 <IntrinsicFunctions>true</IntrinsicFunctions> 4.114 <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);OPENCTM_STATIC</PreprocessorDefinitions> 4.115 <DisableSpecificWarnings>4244;4305;4996</DisableSpecificWarnings> 4.116 - <AdditionalIncludeDirectories>$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2</AdditionalIncludeDirectories> 4.117 + <AdditionalIncludeDirectories>$(SolutionDir)\src;$(SolutionDir)\libs\openctm;$(SolutionDir)\libs\openctm\liblzma;$(SolutionDir)\libs\tinyxml2</AdditionalIncludeDirectories> 4.118 </ClCompile> 4.119 <Link> 4.120 <SubSystem>Windows</SubSystem> 4.121 @@ -188,6 +227,10 @@ 4.122 <EnableCOMDATFolding>true</EnableCOMDATFolding> 4.123 <OptimizeReferences>true</OptimizeReferences> 4.124 </Link> 4.125 + <Lib> 4.126 + <AdditionalDependencies> 4.127 + </AdditionalDependencies> 4.128 + </Lib> 4.129 </ItemDefinitionGroup> 4.130 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 4.131 <ImportGroup Label="ExtensionTargets">
5.1 --- a/goat3d.vcxproj.filters Sat Sep 28 20:36:55 2013 +0300 5.2 +++ b/goat3d.vcxproj.filters Sun Sep 29 08:20:19 2013 +0300 5.3 @@ -17,6 +17,12 @@ 5.4 <Filter Include="libs\openctm\liblzma"> 5.5 <UniqueIdentifier>{18a85bea-ddb2-49a1-a7b1-bd11b23d5549}</UniqueIdentifier> 5.6 </Filter> 5.7 + <Filter Include="libs\vmath"> 5.8 + <UniqueIdentifier>{dc4ab435-af1e-4786-8011-a7a793e229eb}</UniqueIdentifier> 5.9 + </Filter> 5.10 + <Filter Include="libs\anim"> 5.11 + <UniqueIdentifier>{05d8010d-b4d9-4829-80ea-8c8d018e1e04}</UniqueIdentifier> 5.12 + </Filter> 5.13 </ItemGroup> 5.14 <ItemGroup> 5.15 <ClInclude Include="src\camera.h"> 5.16 @@ -88,6 +94,45 @@ 5.17 <ClInclude Include="libs\openctm\liblzma\Types.h"> 5.18 <Filter>libs\openctm\liblzma</Filter> 5.19 </ClInclude> 5.20 + <ClInclude Include="libs\anim\anim.h"> 5.21 + <Filter>libs\anim</Filter> 5.22 + </ClInclude> 5.23 + <ClInclude Include="libs\anim\dynarr.h"> 5.24 + <Filter>libs\anim</Filter> 5.25 + </ClInclude> 5.26 + <ClInclude Include="libs\anim\track.h"> 5.27 + <Filter>libs\anim</Filter> 5.28 + </ClInclude> 5.29 + <ClInclude Include="libs\vmath\basis.h"> 5.30 + <Filter>libs\vmath</Filter> 5.31 + </ClInclude> 5.32 + <ClInclude Include="libs\vmath\geom.h"> 5.33 + <Filter>libs\vmath</Filter> 5.34 + </ClInclude> 5.35 + <ClInclude Include="libs\vmath\matrix.h"> 5.36 + <Filter>libs\vmath</Filter> 5.37 + </ClInclude> 5.38 + <ClInclude Include="libs\vmath\quat.h"> 5.39 + <Filter>libs\vmath</Filter> 5.40 + </ClInclude> 5.41 + <ClInclude Include="libs\vmath\ray.h"> 5.42 + <Filter>libs\vmath</Filter> 5.43 + </ClInclude> 5.44 + <ClInclude Include="libs\vmath\sphvec.h"> 5.45 + <Filter>libs\vmath</Filter> 5.46 + </ClInclude> 5.47 + <ClInclude Include="libs\vmath\vector.h"> 5.48 + <Filter>libs\vmath</Filter> 5.49 + </ClInclude> 5.50 + <ClInclude Include="libs\vmath\vmath.h"> 5.51 + <Filter>libs\vmath</Filter> 5.52 + </ClInclude> 5.53 + <ClInclude Include="libs\vmath\vmath_config.h"> 5.54 + <Filter>libs\vmath</Filter> 5.55 + </ClInclude> 5.56 + <ClInclude Include="libs\vmath\vmath_types.h"> 5.57 + <Filter>libs\vmath</Filter> 5.58 + </ClInclude> 5.59 </ItemGroup> 5.60 <ItemGroup> 5.61 <ClCompile Include="src\goat3d.cc"> 5.62 @@ -162,5 +207,67 @@ 5.63 <ClCompile Include="libs\openctm\liblzma\LzmaLib.c"> 5.64 <Filter>libs\openctm\liblzma</Filter> 5.65 </ClCompile> 5.66 + <ClCompile Include="libs\anim\anim.c"> 5.67 + <Filter>libs\anim</Filter> 5.68 + </ClCompile> 5.69 + <ClCompile Include="libs\anim\dynarr.c"> 5.70 + <Filter>libs\anim</Filter> 5.71 + </ClCompile> 5.72 + <ClCompile Include="libs\anim\track.c"> 5.73 + <Filter>libs\anim</Filter> 5.74 + </ClCompile> 5.75 + <ClCompile Include="libs\vmath\basis.cc"> 5.76 + <Filter>libs\vmath</Filter> 5.77 + </ClCompile> 5.78 + <ClCompile Include="libs\vmath\basis_c.c"> 5.79 + <Filter>libs\vmath</Filter> 5.80 + </ClCompile> 5.81 + <ClCompile Include="libs\vmath\geom.c"> 5.82 + <Filter>libs\vmath</Filter> 5.83 + </ClCompile> 5.84 + <ClCompile Include="libs\vmath\matrix.cc"> 5.85 + <Filter>libs\vmath</Filter> 5.86 + </ClCompile> 5.87 + <ClCompile Include="libs\vmath\matrix_c.c"> 5.88 + <Filter>libs\vmath</Filter> 5.89 + </ClCompile> 5.90 + <ClCompile Include="libs\vmath\quat.cc"> 5.91 + <Filter>libs\vmath</Filter> 5.92 + </ClCompile> 5.93 + <ClCompile Include="libs\vmath\quat_c.c"> 5.94 + <Filter>libs\vmath</Filter> 5.95 + </ClCompile> 5.96 + <ClCompile Include="libs\vmath\ray.cc"> 5.97 + <Filter>libs\vmath</Filter> 5.98 + </ClCompile> 5.99 + <ClCompile Include="libs\vmath\ray_c.c"> 5.100 + <Filter>libs\vmath</Filter> 5.101 + </ClCompile> 5.102 + <ClCompile Include="libs\vmath\sphvec.cc"> 5.103 + <Filter>libs\vmath</Filter> 5.104 + </ClCompile> 5.105 + <ClCompile Include="libs\vmath\vector.cc"> 5.106 + <Filter>libs\vmath</Filter> 5.107 + </ClCompile> 5.108 + <ClCompile Include="libs\vmath\vmath.c"> 5.109 + <Filter>libs\vmath</Filter> 5.110 + </ClCompile> 5.111 + </ItemGroup> 5.112 + <ItemGroup> 5.113 + <None Include="libs\vmath\matrix.inl"> 5.114 + <Filter>libs\vmath</Filter> 5.115 + </None> 5.116 + <None Include="libs\vmath\quat.inl"> 5.117 + <Filter>libs\vmath</Filter> 5.118 + </None> 5.119 + <None Include="libs\vmath\ray.inl"> 5.120 + <Filter>libs\vmath</Filter> 5.121 + </None> 5.122 + <None Include="libs\vmath\vector.inl"> 5.123 + <Filter>libs\vmath</Filter> 5.124 + </None> 5.125 + <None Include="libs\vmath\vmath.inl"> 5.126 + <Filter>libs\vmath</Filter> 5.127 + </None> 5.128 </ItemGroup> 5.129 </Project> 5.130 \ No newline at end of file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/libs/anim/anim.c Sun Sep 29 08:20:19 2013 +0300 6.3 @@ -0,0 +1,455 @@ 6.4 +#include <stdlib.h> 6.5 +#include <limits.h> 6.6 +#include <assert.h> 6.7 +#include "anim.h" 6.8 +#include "dynarr.h" 6.9 + 6.10 +#define ROT_USE_SLERP 6.11 + 6.12 +static void invalidate_cache(struct anm_node *node); 6.13 + 6.14 +int anm_init_node(struct anm_node *node) 6.15 +{ 6.16 + int i, j; 6.17 + static const float defaults[] = { 6.18 + 0.0f, 0.0f, 0.0f, /* default position */ 6.19 + 0.0f, 0.0f, 0.0f, 1.0f, /* default rotation quat */ 6.20 + 1.0f, 1.0f, 1.0f /* default scale factor */ 6.21 + }; 6.22 + 6.23 + memset(node, 0, sizeof *node); 6.24 + 6.25 + for(i=0; i<ANM_NUM_TRACKS; i++) { 6.26 + if(anm_init_track(node->tracks + i) == -1) { 6.27 + for(j=0; j<i; j++) { 6.28 + anm_destroy_track(node->tracks + i); 6.29 + } 6.30 + } 6.31 + anm_set_track_default(node->tracks + i, defaults[i]); 6.32 + } 6.33 + 6.34 + node->cache.time = ANM_TIME_INVAL; 6.35 + node->cache.inv_time = ANM_TIME_INVAL; 6.36 + return 0; 6.37 +} 6.38 + 6.39 +void anm_destroy_node(struct anm_node *node) 6.40 +{ 6.41 + int i; 6.42 + free(node->name); 6.43 + 6.44 + for(i=0; i<ANM_NUM_TRACKS; i++) { 6.45 + anm_destroy_track(node->tracks + i); 6.46 + } 6.47 +} 6.48 + 6.49 +void anm_destroy_node_tree(struct anm_node *tree) 6.50 +{ 6.51 + struct anm_node *c, *tmp; 6.52 + 6.53 + if(!tree) return; 6.54 + 6.55 + c = tree->child; 6.56 + while(c) { 6.57 + tmp = c; 6.58 + c = c->next; 6.59 + 6.60 + anm_destroy_node_tree(tmp); 6.61 + } 6.62 + anm_destroy_node(tree); 6.63 +} 6.64 + 6.65 +struct anm_node *anm_create_node(void) 6.66 +{ 6.67 + struct anm_node *n; 6.68 + 6.69 + if((n = malloc(sizeof *n))) { 6.70 + if(anm_init_node(n) == -1) { 6.71 + free(n); 6.72 + return 0; 6.73 + } 6.74 + } 6.75 + return n; 6.76 +} 6.77 + 6.78 +void anm_free_node(struct anm_node *node) 6.79 +{ 6.80 + anm_destroy_node(node); 6.81 + free(node); 6.82 +} 6.83 + 6.84 +void anm_free_node_tree(struct anm_node *tree) 6.85 +{ 6.86 + struct anm_node *c, *tmp; 6.87 + 6.88 + if(!tree) return; 6.89 + 6.90 + c = tree->child; 6.91 + while(c) { 6.92 + tmp = c; 6.93 + c = c->next; 6.94 + 6.95 + anm_free_node_tree(tmp); 6.96 + } 6.97 + 6.98 + anm_free_node(tree); 6.99 +} 6.100 + 6.101 +int anm_set_node_name(struct anm_node *node, const char *name) 6.102 +{ 6.103 + char *str; 6.104 + 6.105 + if(!(str = malloc(strlen(name) + 1))) { 6.106 + return -1; 6.107 + } 6.108 + strcpy(str, name); 6.109 + free(node->name); 6.110 + node->name = str; 6.111 + return 0; 6.112 +} 6.113 + 6.114 +const char *anm_get_node_name(struct anm_node *node) 6.115 +{ 6.116 + return node->name ? node->name : ""; 6.117 +} 6.118 + 6.119 +void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in) 6.120 +{ 6.121 + int i; 6.122 + 6.123 + for(i=0; i<ANM_NUM_TRACKS; i++) { 6.124 + anm_set_track_interpolator(node->tracks + i, in); 6.125 + } 6.126 + invalidate_cache(node); 6.127 +} 6.128 + 6.129 +void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex) 6.130 +{ 6.131 + int i; 6.132 + 6.133 + for(i=0; i<ANM_NUM_TRACKS; i++) { 6.134 + anm_set_track_extrapolator(node->tracks + i, ex); 6.135 + } 6.136 + invalidate_cache(node); 6.137 +} 6.138 + 6.139 +void anm_link_node(struct anm_node *p, struct anm_node *c) 6.140 +{ 6.141 + c->next = p->child; 6.142 + p->child = c; 6.143 + 6.144 + c->parent = p; 6.145 + invalidate_cache(c); 6.146 +} 6.147 + 6.148 +int anm_unlink_node(struct anm_node *p, struct anm_node *c) 6.149 +{ 6.150 + struct anm_node *iter; 6.151 + 6.152 + if(p->child == c) { 6.153 + p->child = c->next; 6.154 + c->next = 0; 6.155 + invalidate_cache(c); 6.156 + return 0; 6.157 + } 6.158 + 6.159 + iter = p->child; 6.160 + while(iter->next) { 6.161 + if(iter->next == c) { 6.162 + iter->next = c->next; 6.163 + c->next = 0; 6.164 + invalidate_cache(c); 6.165 + return 0; 6.166 + } 6.167 + } 6.168 + return -1; 6.169 +} 6.170 + 6.171 +void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm) 6.172 +{ 6.173 + anm_set_value(node->tracks + ANM_TRACK_POS_X, tm, pos.x); 6.174 + anm_set_value(node->tracks + ANM_TRACK_POS_Y, tm, pos.y); 6.175 + anm_set_value(node->tracks + ANM_TRACK_POS_Z, tm, pos.z); 6.176 + invalidate_cache(node); 6.177 +} 6.178 + 6.179 +vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm) 6.180 +{ 6.181 + vec3_t v; 6.182 + v.x = anm_get_value(node->tracks + ANM_TRACK_POS_X, tm); 6.183 + v.y = anm_get_value(node->tracks + ANM_TRACK_POS_Y, tm); 6.184 + v.z = anm_get_value(node->tracks + ANM_TRACK_POS_Z, tm); 6.185 + return v; 6.186 +} 6.187 + 6.188 +void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm) 6.189 +{ 6.190 + anm_set_value(node->tracks + ANM_TRACK_ROT_X, tm, rot.x); 6.191 + anm_set_value(node->tracks + ANM_TRACK_ROT_Y, tm, rot.y); 6.192 + anm_set_value(node->tracks + ANM_TRACK_ROT_Z, tm, rot.z); 6.193 + anm_set_value(node->tracks + ANM_TRACK_ROT_W, tm, rot.w); 6.194 + invalidate_cache(node); 6.195 +} 6.196 + 6.197 +quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm) 6.198 +{ 6.199 +#ifndef ROT_USE_SLERP 6.200 + quat_t q; 6.201 + q.x = anm_get_value(node->tracks + ANM_TRACK_ROT_X, tm); 6.202 + q.y = anm_get_value(node->tracks + ANM_TRACK_ROT_Y, tm); 6.203 + q.z = anm_get_value(node->tracks + ANM_TRACK_ROT_Z, tm); 6.204 + q.w = anm_get_value(node->tracks + ANM_TRACK_ROT_W, tm); 6.205 + return q; 6.206 +#else 6.207 + int idx0, idx1, last_idx; 6.208 + anm_time_t tstart, tend; 6.209 + float t, dt; 6.210 + struct anm_track *track_x, *track_y, *track_z, *track_w; 6.211 + quat_t q, q1, q2; 6.212 + 6.213 + track_x = node->tracks + ANM_TRACK_ROT_X; 6.214 + track_y = node->tracks + ANM_TRACK_ROT_Y; 6.215 + track_z = node->tracks + ANM_TRACK_ROT_Z; 6.216 + track_w = node->tracks + ANM_TRACK_ROT_W; 6.217 + 6.218 + if(!track_x->count) { 6.219 + q.x = track_x->def_val; 6.220 + q.y = track_y->def_val; 6.221 + q.z = track_z->def_val; 6.222 + q.w = track_w->def_val; 6.223 + return q; 6.224 + } 6.225 + 6.226 + last_idx = track_x->count - 1; 6.227 + 6.228 + tstart = track_x->keys[0].time; 6.229 + tend = track_x->keys[last_idx].time; 6.230 + 6.231 + if(tstart == tend) { 6.232 + q.x = track_x->keys[0].val; 6.233 + q.y = track_y->keys[0].val; 6.234 + q.z = track_z->keys[0].val; 6.235 + q.w = track_w->keys[0].val; 6.236 + return q; 6.237 + } 6.238 + 6.239 + tm = anm_remap_time(track_x, tm, tstart, tend); 6.240 + 6.241 + idx0 = anm_get_key_interval(track_x, tm); 6.242 + assert(idx0 >= 0 && idx0 < track_x->count); 6.243 + idx1 = idx0 + 1; 6.244 + 6.245 + if(idx0 == last_idx) { 6.246 + q.x = track_x->keys[idx0].val; 6.247 + q.y = track_y->keys[idx0].val; 6.248 + q.z = track_z->keys[idx0].val; 6.249 + q.w = track_w->keys[idx0].val; 6.250 + return q; 6.251 + } 6.252 + 6.253 + dt = (float)(track_x->keys[idx1].time - track_x->keys[idx0].time); 6.254 + t = (float)(tm - track_x->keys[idx0].time) / dt; 6.255 + 6.256 + q1.x = track_x->keys[idx0].val; 6.257 + q1.y = track_y->keys[idx0].val; 6.258 + q1.z = track_z->keys[idx0].val; 6.259 + q1.w = track_w->keys[idx0].val; 6.260 + 6.261 + q2.x = track_x->keys[idx1].val; 6.262 + q2.y = track_y->keys[idx1].val; 6.263 + q2.z = track_z->keys[idx1].val; 6.264 + q2.w = track_w->keys[idx1].val; 6.265 + 6.266 + /*q1 = quat_normalize(q1); 6.267 + q2 = quat_normalize(q2);*/ 6.268 + 6.269 + return quat_slerp(q1, q2, t); 6.270 +#endif 6.271 +} 6.272 + 6.273 +void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm) 6.274 +{ 6.275 + anm_set_value(node->tracks + ANM_TRACK_SCL_X, tm, scl.x); 6.276 + anm_set_value(node->tracks + ANM_TRACK_SCL_Y, tm, scl.y); 6.277 + anm_set_value(node->tracks + ANM_TRACK_SCL_Z, tm, scl.z); 6.278 + invalidate_cache(node); 6.279 +} 6.280 + 6.281 +vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm) 6.282 +{ 6.283 + vec3_t v; 6.284 + v.x = anm_get_value(node->tracks + ANM_TRACK_SCL_X, tm); 6.285 + v.y = anm_get_value(node->tracks + ANM_TRACK_SCL_Y, tm); 6.286 + v.z = anm_get_value(node->tracks + ANM_TRACK_SCL_Z, tm); 6.287 + return v; 6.288 +} 6.289 + 6.290 + 6.291 +vec3_t anm_get_position(struct anm_node *node, anm_time_t tm) 6.292 +{ 6.293 + mat4_t xform; 6.294 + vec3_t pos = {0.0, 0.0, 0.0}; 6.295 + 6.296 + if(!node->parent) { 6.297 + return anm_get_node_position(node, tm); 6.298 + } 6.299 + 6.300 + anm_get_matrix(node, xform, tm); 6.301 + return v3_transform(pos, xform); 6.302 +} 6.303 + 6.304 +quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm) 6.305 +{ 6.306 + quat_t rot, prot; 6.307 + rot = anm_get_node_rotation(node, tm); 6.308 + 6.309 + if(!node->parent) { 6.310 + return rot; 6.311 + } 6.312 + 6.313 + prot = anm_get_rotation(node->parent, tm); 6.314 + return quat_mul(prot, rot); 6.315 +} 6.316 + 6.317 +vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm) 6.318 +{ 6.319 + vec3_t s, ps; 6.320 + s = anm_get_node_scaling(node, tm); 6.321 + 6.322 + if(!node->parent) { 6.323 + return s; 6.324 + } 6.325 + 6.326 + ps = anm_get_scaling(node->parent, tm); 6.327 + return v3_mul(s, ps); 6.328 +} 6.329 + 6.330 +void anm_set_pivot(struct anm_node *node, vec3_t piv) 6.331 +{ 6.332 + node->pivot = piv; 6.333 +} 6.334 + 6.335 +vec3_t anm_get_pivot(struct anm_node *node) 6.336 +{ 6.337 + return node->pivot; 6.338 +} 6.339 + 6.340 +void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) 6.341 +{ 6.342 + int i; 6.343 + mat4_t rmat; 6.344 + vec3_t pos, scale; 6.345 + quat_t rot; 6.346 + 6.347 + pos = anm_get_node_position(node, tm); 6.348 + rot = anm_get_node_rotation(node, tm); 6.349 + scale = anm_get_node_scaling(node, tm); 6.350 + 6.351 + m4_set_translation(mat, node->pivot.x, node->pivot.y, node->pivot.z); 6.352 + 6.353 + quat_to_mat4(rmat, rot); 6.354 + for(i=0; i<3; i++) { 6.355 + mat[i][0] = rmat[i][0]; 6.356 + mat[i][1] = rmat[i][1]; 6.357 + mat[i][2] = rmat[i][2]; 6.358 + } 6.359 + /* this loop is equivalent to: m4_mult(mat, mat, rmat); */ 6.360 + 6.361 + mat[0][0] *= scale.x; mat[0][1] *= scale.y; mat[0][2] *= scale.z; mat[0][3] += pos.x; 6.362 + mat[1][0] *= scale.x; mat[1][1] *= scale.y; mat[1][2] *= scale.z; mat[1][3] += pos.y; 6.363 + mat[2][0] *= scale.x; mat[2][1] *= scale.y; mat[2][2] *= scale.z; mat[2][3] += pos.z; 6.364 + 6.365 + m4_translate(mat, -node->pivot.x, -node->pivot.y, -node->pivot.z); 6.366 + 6.367 + /* that's basically: pivot * rotation * translation * scaling * -pivot */ 6.368 +} 6.369 + 6.370 +void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) 6.371 +{ 6.372 + mat4_t tmp; 6.373 + anm_get_node_matrix(node, tmp, tm); 6.374 + m4_inverse(mat, tmp); 6.375 +} 6.376 + 6.377 +void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) 6.378 +{ 6.379 + if(node->cache.time != tm) { 6.380 + anm_get_node_matrix(node, node->cache.matrix, tm); 6.381 + 6.382 + if(node->parent) { 6.383 + mat4_t parent_mat; 6.384 + 6.385 + anm_get_matrix(node->parent, parent_mat, tm); 6.386 + m4_mult(node->cache.matrix, parent_mat, node->cache.matrix); 6.387 + } 6.388 + node->cache.time = tm; 6.389 + } 6.390 + m4_copy(mat, node->cache.matrix); 6.391 +} 6.392 + 6.393 +void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) 6.394 +{ 6.395 + if(node->cache.inv_time != tm) { 6.396 + anm_get_matrix(node, mat, tm); 6.397 + m4_inverse(node->cache.inv_matrix, mat); 6.398 + node->cache.inv_time = tm; 6.399 + } 6.400 + m4_copy(mat, node->cache.inv_matrix); 6.401 +} 6.402 + 6.403 +anm_time_t anm_get_start_time(struct anm_node *node) 6.404 +{ 6.405 + int i; 6.406 + struct anm_node *c; 6.407 + anm_time_t res = LONG_MAX; 6.408 + 6.409 + for(i=0; i<ANM_NUM_TRACKS; i++) { 6.410 + if(node->tracks[i].count) { 6.411 + anm_time_t tm = node->tracks[i].keys[0].time; 6.412 + if(tm < res) { 6.413 + res = tm; 6.414 + } 6.415 + } 6.416 + } 6.417 + 6.418 + c = node->child; 6.419 + while(c) { 6.420 + anm_time_t tm = anm_get_start_time(c); 6.421 + if(tm < res) { 6.422 + res = tm; 6.423 + } 6.424 + c = c->next; 6.425 + } 6.426 + return res; 6.427 +} 6.428 + 6.429 +anm_time_t anm_get_end_time(struct anm_node *node) 6.430 +{ 6.431 + int i; 6.432 + struct anm_node *c; 6.433 + anm_time_t res = LONG_MIN; 6.434 + 6.435 + for(i=0; i<ANM_NUM_TRACKS; i++) { 6.436 + if(node->tracks[i].count) { 6.437 + anm_time_t tm = node->tracks[i].keys[node->tracks[i].count - 1].time; 6.438 + if(tm > res) { 6.439 + res = tm; 6.440 + } 6.441 + } 6.442 + } 6.443 + 6.444 + c = node->child; 6.445 + while(c) { 6.446 + anm_time_t tm = anm_get_end_time(c); 6.447 + if(tm > res) { 6.448 + res = tm; 6.449 + } 6.450 + c = c->next; 6.451 + } 6.452 + return res; 6.453 +} 6.454 + 6.455 +static void invalidate_cache(struct anm_node *node) 6.456 +{ 6.457 + node->cache.time = node->cache.inv_time = ANM_TIME_INVAL; 6.458 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/libs/anim/anim.h Sun Sep 29 08:20:19 2013 +0300 7.3 @@ -0,0 +1,112 @@ 7.4 +#ifndef LIBANIM_H_ 7.5 +#define LIBANIM_H_ 7.6 + 7.7 +#include "config.h" 7.8 + 7.9 +#include <vmath/vector.h> 7.10 +#include <vmath/quat.h> 7.11 +#include <vmath/matrix.h> 7.12 +#include "track.h" 7.13 + 7.14 +enum { 7.15 + ANM_TRACK_POS_X, 7.16 + ANM_TRACK_POS_Y, 7.17 + ANM_TRACK_POS_Z, 7.18 + 7.19 + ANM_TRACK_ROT_X, 7.20 + ANM_TRACK_ROT_Y, 7.21 + ANM_TRACK_ROT_Z, 7.22 + ANM_TRACK_ROT_W, 7.23 + 7.24 + ANM_TRACK_SCL_X, 7.25 + ANM_TRACK_SCL_Y, 7.26 + ANM_TRACK_SCL_Z, 7.27 + 7.28 + ANM_NUM_TRACKS 7.29 +}; 7.30 + 7.31 +struct anm_node { 7.32 + char *name; 7.33 + 7.34 + struct anm_track tracks[ANM_NUM_TRACKS]; 7.35 + vec3_t pivot; 7.36 + 7.37 + /* matrix cache */ 7.38 + struct mat_cache { 7.39 + mat4_t matrix, inv_matrix; 7.40 + anm_time_t time, inv_time; 7.41 + } cache; 7.42 + 7.43 + struct anm_node *parent; 7.44 + struct anm_node *child; 7.45 + struct anm_node *next; 7.46 +}; 7.47 + 7.48 +#ifdef __cplusplus 7.49 +extern "C" { 7.50 +#endif 7.51 + 7.52 +/* node constructor and destructor */ 7.53 +int anm_init_node(struct anm_node *node); 7.54 +void anm_destroy_node(struct anm_node *node); 7.55 + 7.56 +/* recursively destroy an animation node tree */ 7.57 +void anm_destroy_node_tree(struct anm_node *tree); 7.58 + 7.59 +/* helper functions to allocate/construct and destroy/free with 7.60 + * a single call. They call anm_init_node and anm_destroy_node 7.61 + * internally. 7.62 + */ 7.63 +struct anm_node *anm_create_node(void); 7.64 +void anm_free_node(struct anm_node *node); 7.65 + 7.66 +/* recursively destroy and free the nodes of a node tree */ 7.67 +void anm_free_node_tree(struct anm_node *tree); 7.68 + 7.69 +int anm_set_node_name(struct anm_node *node, const char *name); 7.70 +const char *anm_get_node_name(struct anm_node *node); 7.71 + 7.72 +void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in); 7.73 +void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex); 7.74 + 7.75 +/* link and unlink nodes with parent/child relations */ 7.76 +void anm_link_node(struct anm_node *parent, struct anm_node *child); 7.77 +int anm_unlink_node(struct anm_node *parent, struct anm_node *child); 7.78 + 7.79 +void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm); 7.80 +vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm); 7.81 + 7.82 +void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm); 7.83 +quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm); 7.84 + 7.85 +void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm); 7.86 +vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm); 7.87 + 7.88 +/* these three return the full p/r/s taking hierarchy into account */ 7.89 +vec3_t anm_get_position(struct anm_node *node, anm_time_t tm); 7.90 +quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm); 7.91 +vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm); 7.92 + 7.93 +void anm_set_pivot(struct anm_node *node, vec3_t pivot); 7.94 +vec3_t anm_get_pivot(struct anm_node *node); 7.95 + 7.96 +/* these calculate the matrix and inverse matrix of this node alone */ 7.97 +void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); 7.98 +void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); 7.99 + 7.100 +/* These calculate the matrix and inverse matrix of this node taking hierarchy 7.101 + * into account. The results are cached in thread-specific storage and returned 7.102 + * if there's no change in time or tracks from the last query... 7.103 + */ 7.104 +void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); 7.105 +void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); 7.106 + 7.107 +/* those return the start and end times of the whole tree */ 7.108 +anm_time_t anm_get_start_time(struct anm_node *node); 7.109 +anm_time_t anm_get_end_time(struct anm_node *node); 7.110 + 7.111 +#ifdef __cplusplus 7.112 +} 7.113 +#endif 7.114 + 7.115 +#endif /* LIBANIM_H_ */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/libs/anim/config.h Sun Sep 29 08:20:19 2013 +0300 8.3 @@ -0,0 +1,6 @@ 8.4 +#ifndef ANIM_CONFIG_H_ 8.5 +#define ANIM_CONFIG_H_ 8.6 + 8.7 +#undef ANIM_THREAD_SAFE 8.8 + 8.9 +#endif /* ANIM_CONFIG_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/libs/anim/dynarr.c Sun Sep 29 08:20:19 2013 +0300 9.3 @@ -0,0 +1,122 @@ 9.4 +#include <stdio.h> 9.5 +#include <stdlib.h> 9.6 +#include <string.h> 9.7 +#include "dynarr.h" 9.8 + 9.9 +/* The array descriptor keeps auxilliary information needed to manipulate 9.10 + * the dynamic array. It's allocated adjacent to the array buffer. 9.11 + */ 9.12 +struct arrdesc { 9.13 + int nelem, szelem; 9.14 + int max_elem; 9.15 + int bufsz; /* not including the descriptor */ 9.16 +}; 9.17 + 9.18 +#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc))) 9.19 + 9.20 +void *dynarr_alloc(int elem, int szelem) 9.21 +{ 9.22 + struct arrdesc *desc; 9.23 + 9.24 + if(!(desc = malloc(elem * szelem + sizeof *desc))) { 9.25 + return 0; 9.26 + } 9.27 + desc->nelem = desc->max_elem = elem; 9.28 + desc->szelem = szelem; 9.29 + desc->bufsz = elem * szelem; 9.30 + return (char*)desc + sizeof *desc; 9.31 +} 9.32 + 9.33 +void dynarr_free(void *da) 9.34 +{ 9.35 + if(da) { 9.36 + free(DESC(da)); 9.37 + } 9.38 +} 9.39 + 9.40 +void *dynarr_resize(void *da, int elem) 9.41 +{ 9.42 + int newsz; 9.43 + void *tmp; 9.44 + struct arrdesc *desc; 9.45 + 9.46 + if(!da) return 0; 9.47 + desc = DESC(da); 9.48 + 9.49 + newsz = desc->szelem * elem; 9.50 + 9.51 + if(!(tmp = realloc(desc, newsz + sizeof *desc))) { 9.52 + return 0; 9.53 + } 9.54 + desc = tmp; 9.55 + 9.56 + desc->nelem = desc->max_elem = elem; 9.57 + desc->bufsz = newsz; 9.58 + return (char*)desc + sizeof *desc; 9.59 +} 9.60 + 9.61 +int dynarr_empty(void *da) 9.62 +{ 9.63 + return DESC(da)->nelem ? 0 : 1; 9.64 +} 9.65 + 9.66 +int dynarr_size(void *da) 9.67 +{ 9.68 + return DESC(da)->nelem; 9.69 +} 9.70 + 9.71 + 9.72 +/* stack semantics */ 9.73 +void *dynarr_push(void *da, void *item) 9.74 +{ 9.75 + struct arrdesc *desc; 9.76 + int nelem; 9.77 + 9.78 + desc = DESC(da); 9.79 + nelem = desc->nelem; 9.80 + 9.81 + if(nelem >= desc->max_elem) { 9.82 + /* need to resize */ 9.83 + struct arrdesc *tmp; 9.84 + int newsz = desc->max_elem ? desc->max_elem * 2 : 1; 9.85 + 9.86 + if(!(tmp = dynarr_resize(da, newsz))) { 9.87 + fprintf(stderr, "failed to resize\n"); 9.88 + return da; 9.89 + } 9.90 + da = tmp; 9.91 + desc = DESC(da); 9.92 + desc->nelem = nelem; 9.93 + } 9.94 + 9.95 + memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem); 9.96 + return da; 9.97 +} 9.98 + 9.99 +void *dynarr_pop(void *da) 9.100 +{ 9.101 + struct arrdesc *desc; 9.102 + int nelem; 9.103 + 9.104 + desc = DESC(da); 9.105 + nelem = desc->nelem; 9.106 + 9.107 + if(!nelem) return da; 9.108 + 9.109 + if(nelem <= desc->max_elem / 3) { 9.110 + /* reclaim space */ 9.111 + struct arrdesc *tmp; 9.112 + int newsz = desc->max_elem / 2; 9.113 + 9.114 + if(!(tmp = dynarr_resize(da, newsz))) { 9.115 + fprintf(stderr, "failed to resize\n"); 9.116 + return da; 9.117 + } 9.118 + da = tmp; 9.119 + desc = DESC(da); 9.120 + desc->nelem = nelem; 9.121 + } 9.122 + desc->nelem--; 9.123 + 9.124 + return da; 9.125 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/libs/anim/dynarr.h Sun Sep 29 08:20:19 2013 +0300 10.3 @@ -0,0 +1,18 @@ 10.4 +#ifndef DYNARR_H_ 10.5 +#define DYNARR_H_ 10.6 + 10.7 +#include "config.h" 10.8 + 10.9 +void *dynarr_alloc(int elem, int szelem); 10.10 +void dynarr_free(void *da); 10.11 +void *dynarr_resize(void *da, int elem); 10.12 + 10.13 +int dynarr_empty(void *da); 10.14 +int dynarr_size(void *da); 10.15 + 10.16 +/* stack semantics */ 10.17 +void *dynarr_push(void *da, void *item); 10.18 +void *dynarr_pop(void *da); 10.19 + 10.20 + 10.21 +#endif /* DYNARR_H_ */
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/libs/anim/track.c Sun Sep 29 08:20:19 2013 +0300 11.3 @@ -0,0 +1,316 @@ 11.4 +#include <stdlib.h> 11.5 +#include <string.h> 11.6 +#include <assert.h> 11.7 +#include "track.h" 11.8 +#include "dynarr.h" 11.9 + 11.10 +static int keycmp(const void *a, const void *b); 11.11 +static int find_prev_key(struct anm_keyframe *arr, int start, int end, anm_time_t tm); 11.12 + 11.13 +static float interp_step(float v0, float v1, float v2, float v3, float t); 11.14 +static float interp_linear(float v0, float v1, float v2, float v3, float t); 11.15 +static float interp_cubic(float v0, float v1, float v2, float v3, float t); 11.16 + 11.17 +static anm_time_t remap_extend(anm_time_t tm, anm_time_t start, anm_time_t end); 11.18 +static anm_time_t remap_clamp(anm_time_t tm, anm_time_t start, anm_time_t end); 11.19 +static anm_time_t remap_repeat(anm_time_t tm, anm_time_t start, anm_time_t end); 11.20 +static anm_time_t remap_pingpong(anm_time_t tm, anm_time_t start, anm_time_t end); 11.21 + 11.22 +/* XXX keep this in sync with enum anm_interpolator at track.h */ 11.23 +static float (*interp[])(float, float, float, float, float) = { 11.24 + interp_step, 11.25 + interp_linear, 11.26 + interp_cubic, 11.27 + 0 11.28 +}; 11.29 + 11.30 +/* XXX keep this in sync with enum anm_extrapolator at track.h */ 11.31 +static anm_time_t (*remap_time[])(anm_time_t, anm_time_t, anm_time_t) = { 11.32 + remap_extend, 11.33 + remap_clamp, 11.34 + remap_repeat, 11.35 + remap_pingpong, 11.36 + 0 11.37 +}; 11.38 + 11.39 +int anm_init_track(struct anm_track *track) 11.40 +{ 11.41 + memset(track, 0, sizeof *track); 11.42 + 11.43 + if(!(track->keys = dynarr_alloc(0, sizeof *track->keys))) { 11.44 + return -1; 11.45 + } 11.46 + track->interp = ANM_INTERP_LINEAR; 11.47 + track->extrap = ANM_EXTRAP_CLAMP; 11.48 + return 0; 11.49 +} 11.50 + 11.51 +void anm_destroy_track(struct anm_track *track) 11.52 +{ 11.53 + dynarr_free(track->keys); 11.54 +} 11.55 + 11.56 +struct anm_track *anm_create_track(void) 11.57 +{ 11.58 + struct anm_track *track; 11.59 + 11.60 + if((track = malloc(sizeof *track))) { 11.61 + if(anm_init_track(track) == -1) { 11.62 + free(track); 11.63 + return 0; 11.64 + } 11.65 + } 11.66 + return track; 11.67 +} 11.68 + 11.69 +void anm_free_track(struct anm_track *track) 11.70 +{ 11.71 + anm_destroy_track(track); 11.72 + free(track); 11.73 +} 11.74 + 11.75 +void anm_copy_track(struct anm_track *dest, struct anm_track *src) 11.76 +{ 11.77 + free(dest->name); 11.78 + if(dest->keys) { 11.79 + dynarr_free(dest->keys); 11.80 + } 11.81 + 11.82 + if(src->name) { 11.83 + dest->name = malloc(strlen(src->name) + 1); 11.84 + strcpy(dest->name, src->name); 11.85 + } 11.86 + 11.87 + dest->count = src->count; 11.88 + dest->keys = dynarr_alloc(src->count, sizeof *dest->keys); 11.89 + memcpy(dest->keys, src->keys, src->count * sizeof *dest->keys); 11.90 + 11.91 + dest->def_val = src->def_val; 11.92 + dest->interp = src->interp; 11.93 + dest->extrap = src->extrap; 11.94 +} 11.95 + 11.96 +int anm_set_track_name(struct anm_track *track, const char *name) 11.97 +{ 11.98 + char *tmp; 11.99 + 11.100 + if(!(tmp = malloc(strlen(name) + 1))) { 11.101 + return -1; 11.102 + } 11.103 + free(track->name); 11.104 + track->name = tmp; 11.105 + return 0; 11.106 +} 11.107 + 11.108 +const char *anm_get_track_name(struct anm_track *track) 11.109 +{ 11.110 + return track->name; 11.111 +} 11.112 + 11.113 +void anm_set_track_interpolator(struct anm_track *track, enum anm_interpolator in) 11.114 +{ 11.115 + track->interp = in; 11.116 +} 11.117 + 11.118 +void anm_set_track_extrapolator(struct anm_track *track, enum anm_extrapolator ex) 11.119 +{ 11.120 + track->extrap = ex; 11.121 +} 11.122 + 11.123 +anm_time_t anm_remap_time(struct anm_track *track, anm_time_t tm, anm_time_t start, anm_time_t end) 11.124 +{ 11.125 + return remap_time[track->extrap](tm, start, end); 11.126 +} 11.127 + 11.128 +void anm_set_track_default(struct anm_track *track, float def) 11.129 +{ 11.130 + track->def_val = def; 11.131 +} 11.132 + 11.133 +int anm_set_keyframe(struct anm_track *track, struct anm_keyframe *key) 11.134 +{ 11.135 + int idx = anm_get_key_interval(track, key->time); 11.136 + 11.137 + /* if we got a valid keyframe index, compare them... */ 11.138 + if(idx >= 0 && idx < track->count && keycmp(key, track->keys + idx) == 0) { 11.139 + /* ... it's the same key, just update the value */ 11.140 + track->keys[idx].val = key->val; 11.141 + } else { 11.142 + /* ... it's a new key, add it and re-sort them */ 11.143 + void *tmp; 11.144 + if(!(tmp = dynarr_push(track->keys, key))) { 11.145 + return -1; 11.146 + } 11.147 + track->keys = tmp; 11.148 + /* TODO lazy qsort */ 11.149 + qsort(track->keys, ++track->count, sizeof *track->keys, keycmp); 11.150 + } 11.151 + return 0; 11.152 +} 11.153 + 11.154 +static int keycmp(const void *a, const void *b) 11.155 +{ 11.156 + return ((struct anm_keyframe*)a)->time - ((struct anm_keyframe*)b)->time; 11.157 +} 11.158 + 11.159 +struct anm_keyframe *anm_get_keyframe(struct anm_track *track, int idx) 11.160 +{ 11.161 + if(idx < 0 || idx >= track->count) { 11.162 + return 0; 11.163 + } 11.164 + return track->keys + idx; 11.165 +} 11.166 + 11.167 +int anm_get_key_interval(struct anm_track *track, anm_time_t tm) 11.168 +{ 11.169 + int last; 11.170 + 11.171 + if(!track->count || tm < track->keys[0].time) { 11.172 + return -1; 11.173 + } 11.174 + 11.175 + last = track->count - 1; 11.176 + if(tm > track->keys[last].time) { 11.177 + return last; 11.178 + } 11.179 + 11.180 + return find_prev_key(track->keys, 0, last, tm); 11.181 +} 11.182 + 11.183 +static int find_prev_key(struct anm_keyframe *arr, int start, int end, anm_time_t tm) 11.184 +{ 11.185 + int mid; 11.186 + 11.187 + if(end - start <= 1) { 11.188 + return start; 11.189 + } 11.190 + 11.191 + mid = (start + end) / 2; 11.192 + if(tm < arr[mid].time) { 11.193 + return find_prev_key(arr, start, mid, tm); 11.194 + } 11.195 + if(tm > arr[mid].time) { 11.196 + return find_prev_key(arr, mid, end, tm); 11.197 + } 11.198 + return mid; 11.199 +} 11.200 + 11.201 +int anm_set_value(struct anm_track *track, anm_time_t tm, float val) 11.202 +{ 11.203 + struct anm_keyframe key; 11.204 + key.time = tm; 11.205 + key.val = val; 11.206 + 11.207 + return anm_set_keyframe(track, &key); 11.208 +} 11.209 + 11.210 +float anm_get_value(struct anm_track *track, anm_time_t tm) 11.211 +{ 11.212 + int idx0, idx1, last_idx; 11.213 + anm_time_t tstart, tend; 11.214 + float t, dt; 11.215 + float v0, v1, v2, v3; 11.216 + 11.217 + if(!track->count) { 11.218 + return track->def_val; 11.219 + } 11.220 + 11.221 + last_idx = track->count - 1; 11.222 + 11.223 + tstart = track->keys[0].time; 11.224 + tend = track->keys[last_idx].time; 11.225 + 11.226 + if(tstart == tend) { 11.227 + return track->keys[0].val; 11.228 + } 11.229 + 11.230 + tm = remap_time[track->extrap](tm, tstart, tend); 11.231 + 11.232 + idx0 = anm_get_key_interval(track, tm); 11.233 + assert(idx0 >= 0 && idx0 < track->count); 11.234 + idx1 = idx0 + 1; 11.235 + 11.236 + if(idx0 == last_idx) { 11.237 + return track->keys[idx0].val; 11.238 + } 11.239 + 11.240 + dt = (float)(track->keys[idx1].time - track->keys[idx0].time); 11.241 + t = (float)(tm - track->keys[idx0].time) / dt; 11.242 + 11.243 + v1 = track->keys[idx0].val; 11.244 + v2 = track->keys[idx1].val; 11.245 + 11.246 + /* get the neigboring values to allow for cubic interpolation */ 11.247 + v0 = idx0 > 0 ? track->keys[idx0 - 1].val : v1; 11.248 + v3 = idx1 < last_idx ? track->keys[idx1 + 1].val : v2; 11.249 + 11.250 + return interp[track->interp](v0, v1, v2, v3, t); 11.251 +} 11.252 + 11.253 + 11.254 +static float interp_step(float v0, float v1, float v2, float v3, float t) 11.255 +{ 11.256 + return v1; 11.257 +} 11.258 + 11.259 +static float interp_linear(float v0, float v1, float v2, float v3, float t) 11.260 +{ 11.261 + return v1 + (v2 - v1) * t; 11.262 +} 11.263 + 11.264 +static float interp_cubic(float a, float b, float c, float d, float t) 11.265 +{ 11.266 + float x, y, z, w; 11.267 + float tsq = t * t; 11.268 + 11.269 + x = -a + 3.0 * b - 3.0 * c + d; 11.270 + y = 2.0 * a - 5.0 * b + 4.0 * c - d; 11.271 + z = c - a; 11.272 + w = 2.0 * b; 11.273 + 11.274 + return 0.5 * (x * tsq * t + y * tsq + z * t + w); 11.275 +} 11.276 + 11.277 +static anm_time_t remap_extend(anm_time_t tm, anm_time_t start, anm_time_t end) 11.278 +{ 11.279 + return remap_repeat(tm, start, end); 11.280 +} 11.281 + 11.282 +static anm_time_t remap_clamp(anm_time_t tm, anm_time_t start, anm_time_t end) 11.283 +{ 11.284 + if(start == end) { 11.285 + return start; 11.286 + } 11.287 + return tm < start ? start : (tm >= end ? end - 1 : tm); 11.288 +} 11.289 + 11.290 +static anm_time_t remap_repeat(anm_time_t tm, anm_time_t start, anm_time_t end) 11.291 +{ 11.292 + anm_time_t x, interv = end - start; 11.293 + 11.294 + if(interv == 0) { 11.295 + return start; 11.296 + } 11.297 + 11.298 + x = (tm - start) % interv; 11.299 + if(x < 0) { 11.300 + x += interv; 11.301 + } 11.302 + return x + start; 11.303 + 11.304 + /*if(tm < start) { 11.305 + while(tm < start) { 11.306 + tm += interv; 11.307 + } 11.308 + return tm; 11.309 + } 11.310 + return (tm - start) % interv + start;*/ 11.311 +} 11.312 + 11.313 +static anm_time_t remap_pingpong(anm_time_t tm, anm_time_t start, anm_time_t end) 11.314 +{ 11.315 + anm_time_t interv = end - start; 11.316 + anm_time_t x = remap_repeat(tm, start, end + interv); 11.317 + 11.318 + return x > end ? end + interv - x : x; 11.319 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/libs/anim/track.h Sun Sep 29 08:20:19 2013 +0300 12.3 @@ -0,0 +1,101 @@ 12.4 +/* An animation track defines the values of a single scalar over time 12.5 + * and supports various interpolation and extrapolation modes. 12.6 + */ 12.7 +#ifndef LIBANIM_TRACK_H_ 12.8 +#define LIBANIM_TRACK_H_ 12.9 + 12.10 +#include <limits.h> 12.11 +#include "config.h" 12.12 + 12.13 +enum anm_interpolator { 12.14 + ANM_INTERP_STEP, 12.15 + ANM_INTERP_LINEAR, 12.16 + ANM_INTERP_CUBIC 12.17 +}; 12.18 + 12.19 +enum anm_extrapolator { 12.20 + ANM_EXTRAP_EXTEND, /* extend to infinity */ 12.21 + ANM_EXTRAP_CLAMP, /* clamp to last value */ 12.22 + ANM_EXTRAP_REPEAT, /* repeat motion */ 12.23 + ANM_EXTRAP_PINGPONG /* repeat with mirroring */ 12.24 +}; 12.25 + 12.26 +typedef long anm_time_t; 12.27 +#define ANM_TIME_INVAL LONG_MIN 12.28 + 12.29 +#define ANM_SEC2TM(x) ((anm_time_t)((x) * 1000)) 12.30 +#define ANM_MSEC2TM(x) ((anm_time_t)(x)) 12.31 +#define ANM_TM2SEC(x) ((x) / 1000.0) 12.32 +#define ANM_TM2MSEC(x) (x) 12.33 + 12.34 +struct anm_keyframe { 12.35 + anm_time_t time; 12.36 + float val; 12.37 +}; 12.38 + 12.39 +struct anm_track { 12.40 + char *name; 12.41 + int count; 12.42 + struct anm_keyframe *keys; 12.43 + 12.44 + float def_val; 12.45 + 12.46 + enum anm_interpolator interp; 12.47 + enum anm_extrapolator extrap; 12.48 +}; 12.49 + 12.50 +#ifdef __cplusplus 12.51 +extern "C" { 12.52 +#endif 12.53 + 12.54 +/* track constructor and destructor */ 12.55 +int anm_init_track(struct anm_track *track); 12.56 +void anm_destroy_track(struct anm_track *track); 12.57 + 12.58 +/* helper functions that use anm_init_track and anm_destroy_track internally */ 12.59 +struct anm_track *anm_create_track(void); 12.60 +void anm_free_track(struct anm_track *track); 12.61 + 12.62 +/* copies track src to dest 12.63 + * XXX: dest must have been initialized first 12.64 + */ 12.65 +void anm_copy_track(struct anm_track *dest, struct anm_track *src); 12.66 + 12.67 +int anm_set_track_name(struct anm_track *track, const char *name); 12.68 +const char *anm_get_track_name(struct anm_track *track); 12.69 + 12.70 +void anm_set_track_interpolator(struct anm_track *track, enum anm_interpolator in); 12.71 +void anm_set_track_extrapolator(struct anm_track *track, enum anm_extrapolator ex); 12.72 + 12.73 +anm_time_t anm_remap_time(struct anm_track *track, anm_time_t tm, anm_time_t start, anm_time_t end); 12.74 + 12.75 +void anm_set_track_default(struct anm_track *track, float def); 12.76 + 12.77 +/* set or update a keyframe */ 12.78 +int anm_set_keyframe(struct anm_track *track, struct anm_keyframe *key); 12.79 + 12.80 +/* get the idx-th keyframe, returns null if it doesn't exist */ 12.81 +struct anm_keyframe *anm_get_keyframe(struct anm_track *track, int idx); 12.82 + 12.83 +/* Finds the 0-based index of the intra-keyframe interval which corresponds 12.84 + * to the specified time. If the time falls exactly onto the N-th keyframe 12.85 + * the function returns N. 12.86 + * 12.87 + * Special cases: 12.88 + * - if the time is before the first keyframe -1 is returned. 12.89 + * - if the time is after the last keyframe, the index of the last keyframe 12.90 + * is returned. 12.91 + */ 12.92 +int anm_get_key_interval(struct anm_track *track, anm_time_t tm); 12.93 + 12.94 +int anm_set_value(struct anm_track *track, anm_time_t tm, float val); 12.95 + 12.96 +/* evaluates and returns the value of the track for a particular time */ 12.97 +float anm_get_value(struct anm_track *track, anm_time_t tm); 12.98 + 12.99 +#ifdef __cplusplus 12.100 +} 12.101 +#endif 12.102 + 12.103 + 12.104 +#endif /* LIBANIM_TRACK_H_ */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/libs/vmath/basis.cc Sun Sep 29 08:20:19 2013 +0300 13.3 @@ -0,0 +1,63 @@ 13.4 +#include "basis.h" 13.5 +#include "vmath.h" 13.6 + 13.7 +Basis::Basis() 13.8 +{ 13.9 + i = Vector3(1, 0, 0); 13.10 + j = Vector3(0, 1, 0); 13.11 + k = Vector3(0, 0, 1); 13.12 +} 13.13 + 13.14 +Basis::Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k) 13.15 +{ 13.16 + this->i = i; 13.17 + this->j = j; 13.18 + this->k = k; 13.19 +} 13.20 + 13.21 +Basis::Basis(const Vector3 &dir, bool left_handed) 13.22 +{ 13.23 + k = dir; 13.24 + j = Vector3(0, 1, 0); 13.25 + i = cross_product(j, k); 13.26 + j = cross_product(k, i); 13.27 +} 13.28 + 13.29 +/** Rotate with euler angles */ 13.30 +void Basis::rotate(scalar_t x, scalar_t y, scalar_t z) { 13.31 + Matrix4x4 RotMat; 13.32 + RotMat.set_rotation(Vector3(x, y, z)); 13.33 + i.transform(RotMat); 13.34 + j.transform(RotMat); 13.35 + k.transform(RotMat); 13.36 +} 13.37 + 13.38 +/** Rotate by axis-angle specification */ 13.39 +void Basis::rotate(const Vector3 &axis, scalar_t angle) { 13.40 + Quaternion q; 13.41 + q.set_rotation(axis, angle); 13.42 + i.transform(q); 13.43 + j.transform(q); 13.44 + k.transform(q); 13.45 +} 13.46 + 13.47 +/** Rotate with a 4x4 matrix */ 13.48 +void Basis::rotate(const Matrix4x4 &mat) { 13.49 + i.transform(mat); 13.50 + j.transform(mat); 13.51 + k.transform(mat); 13.52 +} 13.53 + 13.54 +/** Rotate with a quaternion */ 13.55 +void Basis::rotate(const Quaternion &quat) { 13.56 + i.transform(quat); 13.57 + j.transform(quat); 13.58 + k.transform(quat); 13.59 +} 13.60 + 13.61 +/** Extract a rotation matrix from the orthogonal basis */ 13.62 +Matrix3x3 Basis::create_rotation_matrix() const { 13.63 + return Matrix3x3( i.x, j.x, k.x, 13.64 + i.y, j.y, k.y, 13.65 + i.z, j.z, k.z); 13.66 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/libs/vmath/basis.h Sun Sep 29 08:20:19 2013 +0300 14.3 @@ -0,0 +1,57 @@ 14.4 +/* 14.5 +libvmath - a vector math library 14.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 14.7 + 14.8 +This program is free software: you can redistribute it and/or modify 14.9 +it under the terms of the GNU Lesser General Public License as published 14.10 +by the Free Software Foundation, either version 3 of the License, or 14.11 +(at your option) any later version. 14.12 + 14.13 +This program is distributed in the hope that it will be useful, 14.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 14.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.16 +GNU Lesser General Public License for more details. 14.17 + 14.18 +You should have received a copy of the GNU Lesser General Public License 14.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 14.20 +*/ 14.21 + 14.22 +#ifndef VMATH_BASIS_H_ 14.23 +#define VMATH_BASIS_H_ 14.24 + 14.25 +#include "vector.h" 14.26 +#include "matrix.h" 14.27 + 14.28 +enum { 14.29 + LEFT_HANDED, 14.30 + RIGHT_HANDED 14.31 +}; 14.32 + 14.33 +#ifdef __cplusplus 14.34 +extern "C" { 14.35 +#endif /* __cplusplus */ 14.36 + 14.37 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k); 14.38 +void basis_matrix_dir(mat4_t res, vec3_t dir); 14.39 + 14.40 +#ifdef __cplusplus 14.41 +} /* extern "C" */ 14.42 + 14.43 +class Basis { 14.44 +public: 14.45 + Vector3 i, j, k; 14.46 + 14.47 + Basis(); 14.48 + Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k); 14.49 + Basis(const Vector3 &dir, bool left_handed = true); 14.50 + 14.51 + void rotate(scalar_t x, scalar_t y, scalar_t z); 14.52 + void rotate(const Vector3 &axis, scalar_t angle); 14.53 + void rotate(const Matrix4x4 &mat); 14.54 + void rotate(const Quaternion &quat); 14.55 + 14.56 + Matrix3x3 create_rotation_matrix() const; 14.57 +}; 14.58 +#endif /* __cplusplus */ 14.59 + 14.60 +#endif /* VMATH_BASIS_H_ */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/libs/vmath/basis_c.c Sun Sep 29 08:20:19 2013 +0300 15.3 @@ -0,0 +1,37 @@ 15.4 +/* 15.5 +libvmath - a vector math library 15.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 15.7 + 15.8 +This program is free software: you can redistribute it and/or modify 15.9 +it under the terms of the GNU Lesser General Public License as published 15.10 +by the Free Software Foundation, either version 3 of the License, or 15.11 +(at your option) any later version. 15.12 + 15.13 +This program is distributed in the hope that it will be useful, 15.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 15.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15.16 +GNU Lesser General Public License for more details. 15.17 + 15.18 +You should have received a copy of the GNU Lesser General Public License 15.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 15.20 +*/ 15.21 + 15.22 +#include "basis.h" 15.23 +#include "matrix.h" 15.24 + 15.25 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k) 15.26 +{ 15.27 + m4_identity(res); 15.28 + m4_set_column(res, v4_cons(i.x, i.y, i.z, 1.0), 0); 15.29 + m4_set_column(res, v4_cons(j.x, j.y, j.z, 1.0), 1); 15.30 + m4_set_column(res, v4_cons(k.x, k.y, k.z, 1.0), 2); 15.31 +} 15.32 + 15.33 +void basis_matrix_dir(mat4_t res, vec3_t dir) 15.34 +{ 15.35 + vec3_t k = v3_normalize(dir); 15.36 + vec3_t j = {0, 1, 0}; 15.37 + vec3_t i = v3_cross(j, k); 15.38 + j = v3_cross(k, i); 15.39 + basis_matrix(res, i, j, k); 15.40 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/libs/vmath/geom.c Sun Sep 29 08:20:19 2013 +0300 16.3 @@ -0,0 +1,150 @@ 16.4 +/* 16.5 +libvmath - a vector math library 16.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 16.7 + 16.8 +This program is free software: you can redistribute it and/or modify 16.9 +it under the terms of the GNU Lesser General Public License as published 16.10 +by the Free Software Foundation, either version 3 of the License, or 16.11 +(at your option) any later version. 16.12 + 16.13 +This program is distributed in the hope that it will be useful, 16.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 16.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16.16 +GNU Lesser General Public License for more details. 16.17 + 16.18 +You should have received a copy of the GNU Lesser General Public License 16.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 16.20 +*/ 16.21 + 16.22 + 16.23 +#include <math.h> 16.24 +#include "geom.h" 16.25 +#include "vector.h" 16.26 + 16.27 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d) 16.28 +{ 16.29 + plane_t p; 16.30 + p.norm.x = nx; 16.31 + p.norm.y = ny; 16.32 + p.norm.z = nz; 16.33 + p.d = d; 16.34 + return p; 16.35 +} 16.36 + 16.37 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2) 16.38 +{ 16.39 + vec3_t a, b, norm; 16.40 + 16.41 + a = v3_sub(v1, v0); 16.42 + b = v3_sub(v2, v0); 16.43 + norm = v3_cross(a, b); 16.44 + norm = v3_normalize(norm); 16.45 + 16.46 + return plane_ptnorm(v0, norm); 16.47 +} 16.48 + 16.49 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal) 16.50 +{ 16.51 + plane_t plane; 16.52 + 16.53 + plane.norm = normal; 16.54 + plane.d = v3_dot(pt, normal); 16.55 + 16.56 + return plane; 16.57 +} 16.58 + 16.59 +plane_t plane_invert(plane_t p) 16.60 +{ 16.61 + p.norm = v3_neg(p.norm); 16.62 + p.d = -p.d; 16.63 + return p; 16.64 +} 16.65 + 16.66 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt) 16.67 +{ 16.68 + vec3_t pp = plane_point(plane); 16.69 + vec3_t pptopt = v3_sub(pt, pp); 16.70 + return v3_dot(pptopt, plane.norm); 16.71 +} 16.72 + 16.73 +scalar_t plane_dist(plane_t plane, vec3_t pt) 16.74 +{ 16.75 + return fabs(plane_signed_dist(plane, pt)); 16.76 +} 16.77 + 16.78 +vec3_t plane_point(plane_t plane) 16.79 +{ 16.80 + return v3_scale(plane.norm, plane.d); 16.81 +} 16.82 + 16.83 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos) 16.84 +{ 16.85 + vec3_t pt, orig_to_pt; 16.86 + scalar_t ndotdir; 16.87 + 16.88 + pt = plane_point(plane); 16.89 + ndotdir = v3_dot(plane.norm, ray.dir); 16.90 + 16.91 + if(fabs(ndotdir) < 1e-7) { 16.92 + return 0; 16.93 + } 16.94 + 16.95 + if(pos) { 16.96 + orig_to_pt = v3_sub(pt, ray.origin); 16.97 + *pos = v3_dot(plane.norm, orig_to_pt) / ndotdir; 16.98 + } 16.99 + return 1; 16.100 +} 16.101 + 16.102 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad) 16.103 +{ 16.104 + sphere_t sph; 16.105 + sph.pos.x = x; 16.106 + sph.pos.y = y; 16.107 + sph.pos.z = z; 16.108 + sph.rad = rad; 16.109 + return sph; 16.110 +} 16.111 + 16.112 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos) 16.113 +{ 16.114 + scalar_t a, b, c, d, sqrt_d, t1, t2, t; 16.115 + 16.116 + a = v3_dot(ray.dir, ray.dir); 16.117 + b = 2.0 * ray.dir.x * (ray.origin.x - sph.pos.x) + 16.118 + 2.0 * ray.dir.y * (ray.origin.y - sph.pos.y) + 16.119 + 2.0 * ray.dir.z * (ray.origin.z - sph.pos.z); 16.120 + c = v3_dot(sph.pos, sph.pos) + v3_dot(ray.origin, ray.origin) + 16.121 + 2.0 * v3_dot(v3_neg(sph.pos), ray.origin) - sph.rad * sph.rad; 16.122 + 16.123 + d = b * b - 4.0 * a * c; 16.124 + if(d < 0.0) { 16.125 + return 0; 16.126 + } 16.127 + 16.128 + sqrt_d = sqrt(d); 16.129 + t1 = (-b + sqrt_d) / (2.0 * a); 16.130 + t2 = (-b - sqrt_d) / (2.0 * a); 16.131 + 16.132 + if(t1 < 1e-7 || t1 > 1.0) { 16.133 + t1 = t2; 16.134 + } 16.135 + if(t2 < 1e-7 || t2 > 1.0) { 16.136 + t2 = t1; 16.137 + } 16.138 + t = t1 < t2 ? t1 : t2; 16.139 + 16.140 + if(t < 1e-7 || t > 1.0) { 16.141 + return 0; 16.142 + } 16.143 + 16.144 + if(pos) { 16.145 + *pos = t; 16.146 + } 16.147 + return 1; 16.148 +} 16.149 + 16.150 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad) 16.151 +{ 16.152 + return -1; 16.153 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/libs/vmath/geom.h Sun Sep 29 08:20:19 2013 +0300 17.3 @@ -0,0 +1,72 @@ 17.4 +/* 17.5 +libvmath - a vector math library 17.6 +Copyright (C) 2004-2012 John Tsiombikas <nuclear@member.fsf.org> 17.7 + 17.8 +This program is free software: you can redistribute it and/or modify 17.9 +it under the terms of the GNU Lesser General Public License as published 17.10 +by the Free Software Foundation, either version 3 of the License, or 17.11 +(at your option) any later version. 17.12 + 17.13 +This program is distributed in the hope that it will be useful, 17.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 17.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.16 +GNU Lesser General Public License for more details. 17.17 + 17.18 +You should have received a copy of the GNU Lesser General Public License 17.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 17.20 +*/ 17.21 +#ifndef LIBVMATH_GEOM_H_ 17.22 +#define LIBVMATH_GEOM_H_ 17.23 + 17.24 +#include "vector.h" 17.25 +#include "ray.h" 17.26 + 17.27 +typedef struct { 17.28 + vec3_t norm; 17.29 + scalar_t d; 17.30 +} plane_t; 17.31 + 17.32 +typedef struct { 17.33 + vec3_t pos; 17.34 + scalar_t rad; 17.35 +} sphere_t; 17.36 + 17.37 +typedef struct { 17.38 + vec3_t min, max; 17.39 +} aabox_t; 17.40 + 17.41 +#ifdef __cplusplus 17.42 +extern "C" { 17.43 +#endif 17.44 + 17.45 +/* planes are good... you need planes, yes you do */ 17.46 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d); 17.47 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2); 17.48 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal); 17.49 + 17.50 +plane_t plane_invert(plane_t p); 17.51 + 17.52 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt); 17.53 +scalar_t plane_dist(plane_t plane, vec3_t pt); 17.54 +vec3_t plane_point(plane_t plane); 17.55 + 17.56 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos); 17.57 + 17.58 +/* spheres always come in handy */ 17.59 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad); 17.60 + 17.61 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos); 17.62 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad); 17.63 + 17.64 +#ifdef __cplusplus 17.65 +} 17.66 + 17.67 +/* TODO 17.68 +class Plane : public plane_t { 17.69 +public: 17.70 +}; 17.71 +*/ 17.72 + 17.73 +#endif 17.74 + 17.75 +#endif /* LIBVMATH_GEOM_H_ */
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/libs/vmath/matrix.cc Sun Sep 29 08:20:19 2013 +0300 18.3 @@ -0,0 +1,821 @@ 18.4 +#include <cstdio> 18.5 +#include <cmath> 18.6 +#include "matrix.h" 18.7 +#include "vector.h" 18.8 +#include "quat.h" 18.9 + 18.10 +using namespace std; 18.11 + 18.12 +// ----------- Matrix3x3 -------------- 18.13 + 18.14 +Matrix3x3 Matrix3x3::identity = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); 18.15 + 18.16 +Matrix3x3::Matrix3x3() 18.17 +{ 18.18 + *this = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); 18.19 +} 18.20 + 18.21 +Matrix3x3::Matrix3x3( scalar_t m11, scalar_t m12, scalar_t m13, 18.22 + scalar_t m21, scalar_t m22, scalar_t m23, 18.23 + scalar_t m31, scalar_t m32, scalar_t m33) 18.24 +{ 18.25 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; 18.26 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; 18.27 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; 18.28 +} 18.29 + 18.30 +Matrix3x3::Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec) 18.31 +{ 18.32 + set_row_vector(ivec, 0); 18.33 + set_row_vector(jvec, 1); 18.34 + set_row_vector(kvec, 2); 18.35 +} 18.36 + 18.37 +Matrix3x3::Matrix3x3(const mat3_t cmat) 18.38 +{ 18.39 + memcpy(m, cmat, sizeof(mat3_t)); 18.40 +} 18.41 + 18.42 +Matrix3x3::Matrix3x3(const Matrix4x4 &mat4x4) 18.43 +{ 18.44 + for(int i=0; i<3; i++) { 18.45 + for(int j=0; j<3; j++) { 18.46 + m[i][j] = mat4x4[i][j]; 18.47 + } 18.48 + } 18.49 +} 18.50 + 18.51 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2) 18.52 +{ 18.53 + Matrix3x3 res; 18.54 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 18.55 + scalar_t *dest = res.m[0]; 18.56 + 18.57 + for(int i=0; i<9; i++) { 18.58 + *dest++ = *op1++ + *op2++; 18.59 + } 18.60 + return res; 18.61 +} 18.62 + 18.63 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2) 18.64 +{ 18.65 + Matrix3x3 res; 18.66 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 18.67 + scalar_t *dest = res.m[0]; 18.68 + 18.69 + for(int i=0; i<9; i++) { 18.70 + *dest++ = *op1++ - *op2++; 18.71 + } 18.72 + return res; 18.73 +} 18.74 + 18.75 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2) 18.76 +{ 18.77 + Matrix3x3 res; 18.78 + for(int i=0; i<3; i++) { 18.79 + for(int j=0; j<3; j++) { 18.80 + 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]; 18.81 + } 18.82 + } 18.83 + return res; 18.84 +} 18.85 + 18.86 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2) 18.87 +{ 18.88 + scalar_t *op1 = m1.m[0]; 18.89 + const scalar_t *op2 = m2.m[0]; 18.90 + 18.91 + for(int i=0; i<9; i++) { 18.92 + *op1++ += *op2++; 18.93 + } 18.94 +} 18.95 + 18.96 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2) 18.97 +{ 18.98 + scalar_t *op1 = m1.m[0]; 18.99 + const scalar_t *op2 = m2.m[0]; 18.100 + 18.101 + for(int i=0; i<9; i++) { 18.102 + *op1++ -= *op2++; 18.103 + } 18.104 +} 18.105 + 18.106 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2) 18.107 +{ 18.108 + Matrix3x3 res; 18.109 + for(int i=0; i<3; i++) { 18.110 + for(int j=0; j<3; j++) { 18.111 + 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]; 18.112 + } 18.113 + } 18.114 + memcpy(m1.m, res.m, 9 * sizeof(scalar_t)); 18.115 +} 18.116 + 18.117 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar) 18.118 +{ 18.119 + Matrix3x3 res; 18.120 + const scalar_t *mptr = mat.m[0]; 18.121 + scalar_t *dptr = res.m[0]; 18.122 + 18.123 + for(int i=0; i<9; i++) { 18.124 + *dptr++ = *mptr++ * scalar; 18.125 + } 18.126 + return res; 18.127 +} 18.128 + 18.129 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat) 18.130 +{ 18.131 + Matrix3x3 res; 18.132 + const scalar_t *mptr = mat.m[0]; 18.133 + scalar_t *dptr = res.m[0]; 18.134 + 18.135 + for(int i=0; i<9; i++) { 18.136 + *dptr++ = *mptr++ * scalar; 18.137 + } 18.138 + return res; 18.139 +} 18.140 + 18.141 +void operator *=(Matrix3x3 &mat, scalar_t scalar) 18.142 +{ 18.143 + scalar_t *mptr = mat.m[0]; 18.144 + 18.145 + for(int i=0; i<9; i++) { 18.146 + *mptr++ *= scalar; 18.147 + } 18.148 +} 18.149 + 18.150 +void Matrix3x3::translate(const Vector2 &trans) 18.151 +{ 18.152 + Matrix3x3 tmat(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1); 18.153 + *this *= tmat; 18.154 +} 18.155 + 18.156 +void Matrix3x3::set_translation(const Vector2 &trans) 18.157 +{ 18.158 + *this = Matrix3x3(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1); 18.159 +} 18.160 + 18.161 +void Matrix3x3::rotate(scalar_t angle) 18.162 +{ 18.163 + scalar_t cos_a = cos(angle); 18.164 + scalar_t sin_a = sin(angle); 18.165 + Matrix3x3 rmat( cos_a, -sin_a, 0, 18.166 + sin_a, cos_a, 0, 18.167 + 0, 0, 1); 18.168 + *this *= rmat; 18.169 +} 18.170 + 18.171 +void Matrix3x3::set_rotation(scalar_t angle) 18.172 +{ 18.173 + scalar_t cos_a = cos(angle); 18.174 + scalar_t sin_a = sin(angle); 18.175 + *this = Matrix3x3(cos_a, -sin_a, 0, sin_a, cos_a, 0, 0, 0, 1); 18.176 +} 18.177 + 18.178 +void Matrix3x3::rotate(const Vector3 &euler_angles) 18.179 +{ 18.180 + Matrix3x3 xrot, yrot, zrot; 18.181 + 18.182 + xrot = Matrix3x3( 1, 0, 0, 18.183 + 0, cos(euler_angles.x), -sin(euler_angles.x), 18.184 + 0, sin(euler_angles.x), cos(euler_angles.x)); 18.185 + 18.186 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 18.187 + 0, 1, 0, 18.188 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 18.189 + 18.190 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 18.191 + sin(euler_angles.z), cos(euler_angles.z), 0, 18.192 + 0, 0, 1); 18.193 + 18.194 + *this *= xrot * yrot * zrot; 18.195 +} 18.196 + 18.197 +void Matrix3x3::set_rotation(const Vector3 &euler_angles) 18.198 +{ 18.199 + Matrix3x3 xrot, yrot, zrot; 18.200 + 18.201 + xrot = Matrix3x3( 1, 0, 0, 18.202 + 0, cos(euler_angles.x), -sin(euler_angles.x), 18.203 + 0, sin(euler_angles.x), cos(euler_angles.x)); 18.204 + 18.205 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 18.206 + 0, 1, 0, 18.207 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 18.208 + 18.209 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 18.210 + sin(euler_angles.z), cos(euler_angles.z), 0, 18.211 + 0, 0, 1); 18.212 + 18.213 + *this = xrot * yrot * zrot; 18.214 +} 18.215 + 18.216 +void Matrix3x3::rotate(const Vector3 &axis, scalar_t angle) 18.217 +{ 18.218 + scalar_t sina = (scalar_t)sin(angle); 18.219 + scalar_t cosa = (scalar_t)cos(angle); 18.220 + scalar_t invcosa = 1-cosa; 18.221 + scalar_t nxsq = axis.x * axis.x; 18.222 + scalar_t nysq = axis.y * axis.y; 18.223 + scalar_t nzsq = axis.z * axis.z; 18.224 + 18.225 + Matrix3x3 xform; 18.226 + xform.m[0][0] = nxsq + (1-nxsq) * cosa; 18.227 + xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 18.228 + xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 18.229 + 18.230 + xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 18.231 + xform.m[1][1] = nysq + (1-nysq) * cosa; 18.232 + xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 18.233 + 18.234 + xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 18.235 + xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 18.236 + xform.m[2][2] = nzsq + (1-nzsq) * cosa; 18.237 + 18.238 + *this *= xform; 18.239 +} 18.240 + 18.241 +void Matrix3x3::set_rotation(const Vector3 &axis, scalar_t angle) 18.242 +{ 18.243 + scalar_t sina = (scalar_t)sin(angle); 18.244 + scalar_t cosa = (scalar_t)cos(angle); 18.245 + scalar_t invcosa = 1-cosa; 18.246 + scalar_t nxsq = axis.x * axis.x; 18.247 + scalar_t nysq = axis.y * axis.y; 18.248 + scalar_t nzsq = axis.z * axis.z; 18.249 + 18.250 + reset_identity(); 18.251 + m[0][0] = nxsq + (1-nxsq) * cosa; 18.252 + m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 18.253 + m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 18.254 + m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 18.255 + m[1][1] = nysq + (1-nysq) * cosa; 18.256 + m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 18.257 + m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 18.258 + m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 18.259 + m[2][2] = nzsq + (1-nzsq) * cosa; 18.260 +} 18.261 + 18.262 +// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes 18.263 +// article "Quaternion Calculus and Fast Animation". 18.264 +// adapted from: http://www.geometrictools.com/LibMathematics/Algebra/Wm5Quaternion.inl 18.265 +Quaternion Matrix3x3::get_rotation_quat() const 18.266 +{ 18.267 + static const int next[3] = {1, 2, 0}; 18.268 + 18.269 + float quat[4]; 18.270 + 18.271 + scalar_t trace = m[0][0] + m[1][1] + m[2][2]; 18.272 + scalar_t root; 18.273 + 18.274 + if(trace > 0.0f) { 18.275 + // |w| > 1/2 18.276 + root = sqrt(trace + 1.0f); // 2w 18.277 + quat[0] = 0.5f * root; 18.278 + root = 0.5f / root; // 1 / 4w 18.279 + quat[1] = (m[2][1] - m[1][2]) * root; 18.280 + quat[2] = (m[0][2] - m[2][0]) * root; 18.281 + quat[3] = (m[1][0] - m[0][1]) * root; 18.282 + } else { 18.283 + // |w| <= 1/2 18.284 + int i = 0; 18.285 + if(m[1][1] > m[0][0]) { 18.286 + i = 1; 18.287 + } 18.288 + if(m[2][2] > m[i][i]) { 18.289 + i = 2; 18.290 + } 18.291 + int j = next[i]; 18.292 + int k = next[j]; 18.293 + 18.294 + root = sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0f); 18.295 + quat[i + 1] = 0.5f * root; 18.296 + root = 0.5f / root; 18.297 + quat[0] = (m[k][j] - m[j][k]) * root; 18.298 + quat[j + 1] = (m[j][i] - m[i][j]) * root; 18.299 + quat[k + 1] = (m[k][i] - m[i][k]) * root; 18.300 + } 18.301 + return Quaternion(quat[0], quat[1], quat[2], quat[3]); 18.302 +} 18.303 + 18.304 +void Matrix3x3::scale(const Vector3 &scale_vec) 18.305 +{ 18.306 + Matrix3x3 smat( scale_vec.x, 0, 0, 18.307 + 0, scale_vec.y, 0, 18.308 + 0, 0, scale_vec.z); 18.309 + *this *= smat; 18.310 +} 18.311 + 18.312 +void Matrix3x3::set_scaling(const Vector3 &scale_vec) 18.313 +{ 18.314 + *this = Matrix3x3( scale_vec.x, 0, 0, 18.315 + 0, scale_vec.y, 0, 18.316 + 0, 0, scale_vec.z); 18.317 +} 18.318 + 18.319 +void Matrix3x3::set_column_vector(const Vector3 &vec, unsigned int col_index) 18.320 +{ 18.321 + m[0][col_index] = vec.x; 18.322 + m[1][col_index] = vec.y; 18.323 + m[2][col_index] = vec.z; 18.324 +} 18.325 + 18.326 +void Matrix3x3::set_row_vector(const Vector3 &vec, unsigned int row_index) 18.327 +{ 18.328 + m[row_index][0] = vec.x; 18.329 + m[row_index][1] = vec.y; 18.330 + m[row_index][2] = vec.z; 18.331 +} 18.332 + 18.333 +Vector3 Matrix3x3::get_column_vector(unsigned int col_index) const 18.334 +{ 18.335 + return Vector3(m[0][col_index], m[1][col_index], m[2][col_index]); 18.336 +} 18.337 + 18.338 +Vector3 Matrix3x3::get_row_vector(unsigned int row_index) const 18.339 +{ 18.340 + return Vector3(m[row_index][0], m[row_index][1], m[row_index][2]); 18.341 +} 18.342 + 18.343 +void Matrix3x3::transpose() 18.344 +{ 18.345 + Matrix3x3 tmp = *this; 18.346 + for(int i=0; i<3; i++) { 18.347 + for(int j=0; j<3; j++) { 18.348 + m[i][j] = tmp[j][i]; 18.349 + } 18.350 + } 18.351 +} 18.352 + 18.353 +Matrix3x3 Matrix3x3::transposed() const 18.354 +{ 18.355 + Matrix3x3 res; 18.356 + for(int i=0; i<3; i++) { 18.357 + for(int j=0; j<3; j++) { 18.358 + res[i][j] = m[j][i]; 18.359 + } 18.360 + } 18.361 + return res; 18.362 +} 18.363 + 18.364 +scalar_t Matrix3x3::determinant() const 18.365 +{ 18.366 + return m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) - 18.367 + m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) + 18.368 + m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0]); 18.369 +} 18.370 + 18.371 +Matrix3x3 Matrix3x3::inverse() const 18.372 +{ 18.373 + // TODO: implement 3x3 inverse 18.374 + return *this; 18.375 +} 18.376 + 18.377 +ostream &operator <<(ostream &out, const Matrix3x3 &mat) 18.378 +{ 18.379 + for(int i=0; i<3; i++) { 18.380 + char str[100]; 18.381 + sprintf(str, "[ %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2]); 18.382 + out << str; 18.383 + } 18.384 + return out; 18.385 +} 18.386 + 18.387 + 18.388 + 18.389 +/* ----------------- Matrix4x4 implementation --------------- */ 18.390 + 18.391 +Matrix4x4 Matrix4x4::identity = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 18.392 + 18.393 +Matrix4x4::Matrix4x4() 18.394 +{ 18.395 + *this = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 18.396 +} 18.397 + 18.398 +Matrix4x4::Matrix4x4( scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 18.399 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 18.400 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 18.401 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44) 18.402 +{ 18.403 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14; 18.404 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24; 18.405 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34; 18.406 + m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44; 18.407 +} 18.408 + 18.409 +Matrix4x4::Matrix4x4(const mat4_t cmat) 18.410 +{ 18.411 + memcpy(m, cmat, sizeof(mat4_t)); 18.412 +} 18.413 + 18.414 +Matrix4x4::Matrix4x4(const Matrix3x3 &mat3x3) 18.415 +{ 18.416 + reset_identity(); 18.417 + for(int i=0; i<3; i++) { 18.418 + for(int j=0; j<3; j++) { 18.419 + m[i][j] = mat3x3[i][j]; 18.420 + } 18.421 + } 18.422 +} 18.423 + 18.424 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2) 18.425 +{ 18.426 + Matrix4x4 res; 18.427 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 18.428 + scalar_t *dest = res.m[0]; 18.429 + 18.430 + for(int i=0; i<16; i++) { 18.431 + *dest++ = *op1++ + *op2++; 18.432 + } 18.433 + return res; 18.434 +} 18.435 + 18.436 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2) 18.437 +{ 18.438 + Matrix4x4 res; 18.439 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 18.440 + scalar_t *dest = res.m[0]; 18.441 + 18.442 + for(int i=0; i<16; i++) { 18.443 + *dest++ = *op1++ - *op2++; 18.444 + } 18.445 + return res; 18.446 +} 18.447 + 18.448 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2) 18.449 +{ 18.450 + scalar_t *op1 = m1.m[0]; 18.451 + const scalar_t *op2 = m2.m[0]; 18.452 + 18.453 + for(int i=0; i<16; i++) { 18.454 + *op1++ += *op2++; 18.455 + } 18.456 +} 18.457 + 18.458 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2) 18.459 +{ 18.460 + scalar_t *op1 = m1.m[0]; 18.461 + const scalar_t *op2 = m2.m[0]; 18.462 + 18.463 + for(int i=0; i<16; i++) { 18.464 + *op1++ -= *op2++; 18.465 + } 18.466 +} 18.467 + 18.468 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar) 18.469 +{ 18.470 + Matrix4x4 res; 18.471 + const scalar_t *mptr = mat.m[0]; 18.472 + scalar_t *dptr = res.m[0]; 18.473 + 18.474 + for(int i=0; i<16; i++) { 18.475 + *dptr++ = *mptr++ * scalar; 18.476 + } 18.477 + return res; 18.478 +} 18.479 + 18.480 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat) 18.481 +{ 18.482 + Matrix4x4 res; 18.483 + const scalar_t *mptr = mat.m[0]; 18.484 + scalar_t *dptr = res.m[0]; 18.485 + 18.486 + for(int i=0; i<16; i++) { 18.487 + *dptr++ = *mptr++ * scalar; 18.488 + } 18.489 + return res; 18.490 +} 18.491 + 18.492 +void operator *=(Matrix4x4 &mat, scalar_t scalar) 18.493 +{ 18.494 + scalar_t *mptr = mat.m[0]; 18.495 + 18.496 + for(int i=0; i<16; i++) { 18.497 + *mptr++ *= scalar; 18.498 + } 18.499 +} 18.500 + 18.501 +void Matrix4x4::translate(const Vector3 &trans) 18.502 +{ 18.503 + Matrix4x4 tmat(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1); 18.504 + *this *= tmat; 18.505 +} 18.506 + 18.507 +void Matrix4x4::set_translation(const Vector3 &trans) 18.508 +{ 18.509 + *this = Matrix4x4(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1); 18.510 +} 18.511 + 18.512 +Vector3 Matrix4x4::get_translation() const 18.513 +{ 18.514 + return Vector3(m[0][3], m[1][3], m[2][3]); 18.515 +} 18.516 + 18.517 +void Matrix4x4::rotate(const Vector3 &euler_angles) 18.518 +{ 18.519 + Matrix3x3 xrot, yrot, zrot; 18.520 + 18.521 + xrot = Matrix3x3( 1, 0, 0, 18.522 + 0, cos(euler_angles.x), -sin(euler_angles.x), 18.523 + 0, sin(euler_angles.x), cos(euler_angles.x)); 18.524 + 18.525 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 18.526 + 0, 1, 0, 18.527 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 18.528 + 18.529 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 18.530 + sin(euler_angles.z), cos(euler_angles.z), 0, 18.531 + 0, 0, 1); 18.532 + 18.533 + *this *= Matrix4x4(xrot * yrot * zrot); 18.534 +} 18.535 + 18.536 +void Matrix4x4::set_rotation(const Vector3 &euler_angles) 18.537 +{ 18.538 + Matrix3x3 xrot, yrot, zrot; 18.539 + 18.540 + xrot = Matrix3x3( 1, 0, 0, 18.541 + 0, cos(euler_angles.x), -sin(euler_angles.x), 18.542 + 0, sin(euler_angles.x), cos(euler_angles.x)); 18.543 + 18.544 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 18.545 + 0, 1, 0, 18.546 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 18.547 + 18.548 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 18.549 + sin(euler_angles.z), cos(euler_angles.z), 0, 18.550 + 0, 0, 1); 18.551 + 18.552 + *this = Matrix4x4(xrot * yrot * zrot); 18.553 +} 18.554 + 18.555 +void Matrix4x4::rotate(const Vector3 &axis, scalar_t angle) 18.556 +{ 18.557 + scalar_t sina = (scalar_t)sin(angle); 18.558 + scalar_t cosa = (scalar_t)cos(angle); 18.559 + scalar_t invcosa = 1-cosa; 18.560 + scalar_t nxsq = axis.x * axis.x; 18.561 + scalar_t nysq = axis.y * axis.y; 18.562 + scalar_t nzsq = axis.z * axis.z; 18.563 + 18.564 + Matrix4x4 xform; 18.565 + xform[0][0] = nxsq + (1-nxsq) * cosa; 18.566 + xform[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 18.567 + xform[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 18.568 + xform[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 18.569 + xform[1][1] = nysq + (1-nysq) * cosa; 18.570 + xform[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 18.571 + xform[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 18.572 + xform[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 18.573 + xform[2][2] = nzsq + (1-nzsq) * cosa; 18.574 + 18.575 + *this *= xform; 18.576 +} 18.577 + 18.578 +void Matrix4x4::set_rotation(const Vector3 &axis, scalar_t angle) 18.579 +{ 18.580 + scalar_t sina = (scalar_t)sin(angle); 18.581 + scalar_t cosa = (scalar_t)cos(angle); 18.582 + scalar_t invcosa = 1-cosa; 18.583 + scalar_t nxsq = axis.x * axis.x; 18.584 + scalar_t nysq = axis.y * axis.y; 18.585 + scalar_t nzsq = axis.z * axis.z; 18.586 + 18.587 + reset_identity(); 18.588 + m[0][0] = nxsq + (1-nxsq) * cosa; 18.589 + m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 18.590 + m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 18.591 + m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 18.592 + m[1][1] = nysq + (1-nysq) * cosa; 18.593 + m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 18.594 + m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 18.595 + m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 18.596 + m[2][2] = nzsq + (1-nzsq) * cosa; 18.597 +} 18.598 + 18.599 +void Matrix4x4::rotate(const Quaternion &quat) 18.600 +{ 18.601 + *this *= quat.get_rotation_matrix(); 18.602 +} 18.603 + 18.604 +void Matrix4x4::set_rotation(const Quaternion &quat) 18.605 +{ 18.606 + *this = quat.get_rotation_matrix(); 18.607 +} 18.608 + 18.609 +Quaternion Matrix4x4::get_rotation_quat() const 18.610 +{ 18.611 + Matrix3x3 mat3 = *this; 18.612 + return mat3.get_rotation_quat(); 18.613 +} 18.614 + 18.615 +void Matrix4x4::scale(const Vector4 &scale_vec) 18.616 +{ 18.617 + Matrix4x4 smat( scale_vec.x, 0, 0, 0, 18.618 + 0, scale_vec.y, 0, 0, 18.619 + 0, 0, scale_vec.z, 0, 18.620 + 0, 0, 0, scale_vec.w); 18.621 + *this *= smat; 18.622 +} 18.623 + 18.624 +void Matrix4x4::set_scaling(const Vector4 &scale_vec) 18.625 +{ 18.626 + *this = Matrix4x4( scale_vec.x, 0, 0, 0, 18.627 + 0, scale_vec.y, 0, 0, 18.628 + 0, 0, scale_vec.z, 0, 18.629 + 0, 0, 0, scale_vec.w); 18.630 +} 18.631 + 18.632 +Vector3 Matrix4x4::get_scaling() const 18.633 +{ 18.634 + Vector3 vi = get_row_vector(0); 18.635 + Vector3 vj = get_row_vector(1); 18.636 + Vector3 vk = get_row_vector(2); 18.637 + 18.638 + return Vector3(vi.length(), vj.length(), vk.length()); 18.639 +} 18.640 + 18.641 +void Matrix4x4::set_perspective(float vfov, float aspect, float znear, float zfar) 18.642 +{ 18.643 + float f = 1.0f / tan(vfov * 0.5f); 18.644 + float dz = znear - zfar; 18.645 + 18.646 + reset_identity(); 18.647 + 18.648 + m[0][0] = f / aspect; 18.649 + m[1][1] = f; 18.650 + m[2][2] = (zfar + znear) / dz; 18.651 + m[3][2] = -1.0f; 18.652 + m[2][3] = 2.0f * zfar * znear / dz; 18.653 + m[3][3] = 0.0f; 18.654 +} 18.655 + 18.656 +void Matrix4x4::set_orthographic(float left, float right, float bottom, float top, float znear, float zfar) 18.657 +{ 18.658 + float dx = right - left; 18.659 + float dy = top - bottom; 18.660 + float dz = zfar - znear; 18.661 + 18.662 + reset_identity(); 18.663 + 18.664 + m[0][0] = 2.0 / dx; 18.665 + m[1][1] = 2.0 / dy; 18.666 + m[2][2] = -2.0 / dz; 18.667 + m[0][3] = -(right + left) / dx; 18.668 + m[1][3] = -(top + bottom) / dy; 18.669 + m[2][3] = -(zfar + znear) / dz; 18.670 +} 18.671 + 18.672 +void Matrix4x4::set_column_vector(const Vector4 &vec, unsigned int col_index) 18.673 +{ 18.674 + m[0][col_index] = vec.x; 18.675 + m[1][col_index] = vec.y; 18.676 + m[2][col_index] = vec.z; 18.677 + m[3][col_index] = vec.w; 18.678 +} 18.679 + 18.680 +void Matrix4x4::set_row_vector(const Vector4 &vec, unsigned int row_index) 18.681 +{ 18.682 + m[row_index][0] = vec.x; 18.683 + m[row_index][1] = vec.y; 18.684 + m[row_index][2] = vec.z; 18.685 + m[row_index][3] = vec.w; 18.686 +} 18.687 + 18.688 +Vector4 Matrix4x4::get_column_vector(unsigned int col_index) const 18.689 +{ 18.690 + return Vector4(m[0][col_index], m[1][col_index], m[2][col_index], m[3][col_index]); 18.691 +} 18.692 + 18.693 +Vector4 Matrix4x4::get_row_vector(unsigned int row_index) const 18.694 +{ 18.695 + return Vector4(m[row_index][0], m[row_index][1], m[row_index][2], m[row_index][3]); 18.696 +} 18.697 + 18.698 +void Matrix4x4::transpose() 18.699 +{ 18.700 + Matrix4x4 tmp = *this; 18.701 + for(int i=0; i<4; i++) { 18.702 + for(int j=0; j<4; j++) { 18.703 + m[i][j] = tmp[j][i]; 18.704 + } 18.705 + } 18.706 +} 18.707 + 18.708 +Matrix4x4 Matrix4x4::transposed() const 18.709 +{ 18.710 + Matrix4x4 res; 18.711 + for(int i=0; i<4; i++) { 18.712 + for(int j=0; j<4; j++) { 18.713 + res[i][j] = m[j][i]; 18.714 + } 18.715 + } 18.716 + return res; 18.717 +} 18.718 + 18.719 +scalar_t Matrix4x4::determinant() const 18.720 +{ 18.721 + scalar_t det11 = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 18.722 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 18.723 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 18.724 + 18.725 + scalar_t det12 = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 18.726 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 18.727 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 18.728 + 18.729 + scalar_t det13 = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 18.730 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 18.731 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 18.732 + 18.733 + scalar_t det14 = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 18.734 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 18.735 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 18.736 + 18.737 + return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14; 18.738 +} 18.739 + 18.740 + 18.741 +Matrix4x4 Matrix4x4::adjoint() const 18.742 +{ 18.743 + Matrix4x4 coef; 18.744 + 18.745 + coef.m[0][0] = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 18.746 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 18.747 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 18.748 + coef.m[0][1] = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 18.749 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 18.750 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 18.751 + coef.m[0][2] = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 18.752 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 18.753 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 18.754 + coef.m[0][3] = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 18.755 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 18.756 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 18.757 + 18.758 + coef.m[1][0] = (m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 18.759 + (m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 18.760 + (m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 18.761 + coef.m[1][1] = (m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 18.762 + (m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 18.763 + (m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 18.764 + coef.m[1][2] = (m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 18.765 + (m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 18.766 + (m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 18.767 + coef.m[1][3] = (m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 18.768 + (m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 18.769 + (m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 18.770 + 18.771 + coef.m[2][0] = (m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 18.772 + (m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) + 18.773 + (m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])); 18.774 + coef.m[2][1] = (m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 18.775 + (m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 18.776 + (m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])); 18.777 + coef.m[2][2] = (m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) - 18.778 + (m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 18.779 + (m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 18.780 + coef.m[2][3] = (m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) - 18.781 + (m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) + 18.782 + (m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 18.783 + 18.784 + coef.m[3][0] = (m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 18.785 + (m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) + 18.786 + (m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])); 18.787 + coef.m[3][1] = (m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 18.788 + (m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 18.789 + (m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])); 18.790 + coef.m[3][2] = (m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) - 18.791 + (m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 18.792 + (m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 18.793 + coef.m[3][3] = (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) - 18.794 + (m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) + 18.795 + (m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 18.796 + 18.797 + coef.transpose(); 18.798 + 18.799 + for(int i=0; i<4; i++) { 18.800 + for(int j=0; j<4; j++) { 18.801 + coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j]; 18.802 + if(i%2) coef.m[i][j] = -coef.m[i][j]; 18.803 + } 18.804 + } 18.805 + 18.806 + return coef; 18.807 +} 18.808 + 18.809 +Matrix4x4 Matrix4x4::inverse() const 18.810 +{ 18.811 + Matrix4x4 adj = adjoint(); 18.812 + 18.813 + return adj * (1.0f / determinant()); 18.814 +} 18.815 + 18.816 +ostream &operator <<(ostream &out, const Matrix4x4 &mat) 18.817 +{ 18.818 + for(int i=0; i<4; i++) { 18.819 + char str[100]; 18.820 + 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]); 18.821 + out << str; 18.822 + } 18.823 + return out; 18.824 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/libs/vmath/matrix.h Sun Sep 29 08:20:19 2013 +0300 19.3 @@ -0,0 +1,260 @@ 19.4 +/* 19.5 +libvmath - a vector math library 19.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 19.7 + 19.8 +This program is free software: you can redistribute it and/or modify 19.9 +it under the terms of the GNU Lesser General Public License as published 19.10 +by the Free Software Foundation, either version 3 of the License, or 19.11 +(at your option) any later version. 19.12 + 19.13 +This program is distributed in the hope that it will be useful, 19.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 19.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19.16 +GNU Lesser General Public License for more details. 19.17 + 19.18 +You should have received a copy of the GNU Lesser General Public License 19.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 19.20 +*/ 19.21 + 19.22 +#ifndef VMATH_MATRIX_H_ 19.23 +#define VMATH_MATRIX_H_ 19.24 + 19.25 +#include <stdio.h> 19.26 +#include "vmath_types.h" 19.27 + 19.28 +#ifdef __cplusplus 19.29 +extern "C" { 19.30 +#endif /* __cplusplus */ 19.31 + 19.32 +/* C matrix 3x3 functions */ 19.33 +static inline void m3_identity(mat3_t m); 19.34 +static inline void m3_cons(mat3_t m, 19.35 + scalar_t m11, scalar_t m12, scalar_t m13, 19.36 + scalar_t m21, scalar_t m22, scalar_t m23, 19.37 + scalar_t m31, scalar_t m32, scalar_t m33); 19.38 +static inline void m3_copy(mat3_t dest, mat3_t src); 19.39 +void m3_to_m4(mat4_t dest, mat3_t src); 19.40 + 19.41 +void m3_print(FILE *fp, mat3_t m); 19.42 + 19.43 +/* C matrix 4x4 functions */ 19.44 +static inline void m4_identity(mat4_t m); 19.45 +static inline void m4_cons(mat4_t m, 19.46 + scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 19.47 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 19.48 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 19.49 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44); 19.50 +static inline void m4_copy(mat4_t dest, mat4_t src); 19.51 +void m4_to_m3(mat3_t dest, mat4_t src); 19.52 + 19.53 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2); 19.54 + 19.55 +void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 19.56 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 19.57 + 19.58 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 19.59 + 19.60 +void m4_set_rotation_x(mat4_t m, scalar_t angle); 19.61 +void m4_rotate_x(mat4_t m, scalar_t angle); 19.62 +void m4_set_rotation_y(mat4_t m, scalar_t angle); 19.63 +void m4_rotate_y(mat4_t m, scalar_t angle); 19.64 +void m4_set_rotation_z(mat4_t m, scalar_t angle); 19.65 +void m4_rotate_z(mat4_t m, scalar_t angle); 19.66 +/* axis-angle rotation */ 19.67 +void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 19.68 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 19.69 +/* concatentate a rotation quaternion */ 19.70 +void m4_rotate_quat(mat4_t m, quat_t q); 19.71 + 19.72 +void m4_set_scaling(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 19.73 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 19.74 + 19.75 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx); 19.76 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx); 19.77 + 19.78 +void m4_transpose(mat4_t res, mat4_t m); 19.79 +scalar_t m4_determinant(mat4_t m); 19.80 +void m4_adjoint(mat4_t res, mat4_t m); 19.81 +void m4_inverse(mat4_t res, mat4_t m); 19.82 + 19.83 +void m4_print(FILE *fp, mat4_t m); 19.84 + 19.85 +#ifdef __cplusplus 19.86 +} 19.87 + 19.88 +/* when included from C++ source files, also define the matrix classes */ 19.89 +#include <iostream> 19.90 + 19.91 +/** 3x3 matrix */ 19.92 +class Matrix3x3 { 19.93 +public: 19.94 + scalar_t m[3][3]; 19.95 + 19.96 + static Matrix3x3 identity; 19.97 + 19.98 + Matrix3x3(); 19.99 + Matrix3x3( scalar_t m11, scalar_t m12, scalar_t m13, 19.100 + scalar_t m21, scalar_t m22, scalar_t m23, 19.101 + scalar_t m31, scalar_t m32, scalar_t m33); 19.102 + Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec); 19.103 + Matrix3x3(const mat3_t cmat); 19.104 + 19.105 + Matrix3x3(const Matrix4x4 &mat4x4); 19.106 + 19.107 + /* binary operations matrix (op) matrix */ 19.108 + friend Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2); 19.109 + friend Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2); 19.110 + friend Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2); 19.111 + 19.112 + friend void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2); 19.113 + friend void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2); 19.114 + friend void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2); 19.115 + 19.116 + /* binary operations matrix (op) scalar and scalar (op) matrix */ 19.117 + friend Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar); 19.118 + friend Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat); 19.119 + 19.120 + friend void operator *=(Matrix3x3 &mat, scalar_t scalar); 19.121 + 19.122 + inline scalar_t *operator [](int index); 19.123 + inline const scalar_t *operator [](int index) const; 19.124 + 19.125 + inline void reset_identity(); 19.126 + 19.127 + void translate(const Vector2 &trans); 19.128 + void set_translation(const Vector2 &trans); 19.129 + 19.130 + void rotate(scalar_t angle); /* 2d rotation */ 19.131 + void rotate(const Vector3 &euler_angles); /* 3d rotation with euler angles */ 19.132 + void rotate(const Vector3 &axis, scalar_t angle); /* 3d axis/angle rotation */ 19.133 + void set_rotation(scalar_t angle); 19.134 + void set_rotation(const Vector3 &euler_angles); 19.135 + void set_rotation(const Vector3 &axis, scalar_t angle); 19.136 + Quaternion get_rotation_quat() const; 19.137 + 19.138 + void scale(const Vector3 &scale_vec); 19.139 + void set_scaling(const Vector3 &scale_vec); 19.140 + 19.141 + void set_column_vector(const Vector3 &vec, unsigned int col_index); 19.142 + void set_row_vector(const Vector3 &vec, unsigned int row_index); 19.143 + Vector3 get_column_vector(unsigned int col_index) const; 19.144 + Vector3 get_row_vector(unsigned int row_index) const; 19.145 + 19.146 + void transpose(); 19.147 + Matrix3x3 transposed() const; 19.148 + scalar_t determinant() const; 19.149 + Matrix3x3 inverse() const; 19.150 + 19.151 + friend std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat); 19.152 +}; 19.153 + 19.154 +/* binary operations matrix (op) matrix */ 19.155 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2); 19.156 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2); 19.157 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2); 19.158 + 19.159 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2); 19.160 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2); 19.161 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2); 19.162 + 19.163 +/* binary operations matrix (op) scalar and scalar (op) matrix */ 19.164 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar); 19.165 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat); 19.166 + 19.167 +void operator *=(Matrix3x3 &mat, scalar_t scalar); 19.168 + 19.169 +std::ostream &operator <<(std::ostream &out, const Matrix3x3 &mat); 19.170 + 19.171 + 19.172 + 19.173 +/** 4x4 matrix */ 19.174 +class Matrix4x4 { 19.175 +public: 19.176 + scalar_t m[4][4]; 19.177 + 19.178 + static Matrix4x4 identity; 19.179 + 19.180 + Matrix4x4(); 19.181 + Matrix4x4( scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 19.182 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 19.183 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 19.184 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44); 19.185 + Matrix4x4(const mat4_t cmat); 19.186 + 19.187 + Matrix4x4(const Matrix3x3 &mat3x3); 19.188 + 19.189 + /* binary operations matrix (op) matrix */ 19.190 + friend Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2); 19.191 + friend Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2); 19.192 + friend Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2); 19.193 + 19.194 + friend void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2); 19.195 + friend void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2); 19.196 + friend inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2); 19.197 + 19.198 + /* binary operations matrix (op) scalar and scalar (op) matrix */ 19.199 + friend Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar); 19.200 + friend Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat); 19.201 + 19.202 + friend void operator *=(Matrix4x4 &mat, scalar_t scalar); 19.203 + 19.204 + inline scalar_t *operator [](int index); 19.205 + inline const scalar_t *operator [](int index) const; 19.206 + 19.207 + inline void reset_identity(); 19.208 + 19.209 + void translate(const Vector3 &trans); 19.210 + void set_translation(const Vector3 &trans); 19.211 + Vector3 get_translation() const; /* extract translation */ 19.212 + 19.213 + void rotate(const Vector3 &euler_angles); /* 3d rotation with euler angles */ 19.214 + void rotate(const Vector3 &axis, scalar_t angle); /* 3d axis/angle rotation */ 19.215 + void rotate(const Quaternion &quat); 19.216 + void set_rotation(const Vector3 &euler_angles); 19.217 + void set_rotation(const Vector3 &axis, scalar_t angle); 19.218 + void set_rotation(const Quaternion &quat); 19.219 + Quaternion get_rotation_quat() const; /* extract rotation */ 19.220 + 19.221 + void scale(const Vector4 &scale_vec); 19.222 + void set_scaling(const Vector4 &scale_vec); 19.223 + Vector3 get_scaling() const; /* extract scaling */ 19.224 + 19.225 + void set_perspective(float vfov, float aspect, float znear, float zfar); 19.226 + void set_orthographic(float left, float right, float bottom, float top, float znear = -1.0, float zfar = 1.0); 19.227 + 19.228 + void set_column_vector(const Vector4 &vec, unsigned int col_index); 19.229 + void set_row_vector(const Vector4 &vec, unsigned int row_index); 19.230 + Vector4 get_column_vector(unsigned int col_index) const; 19.231 + Vector4 get_row_vector(unsigned int row_index) const; 19.232 + 19.233 + void transpose(); 19.234 + Matrix4x4 transposed() const; 19.235 + scalar_t determinant() const; 19.236 + Matrix4x4 adjoint() const; 19.237 + Matrix4x4 inverse() const; 19.238 + 19.239 + friend std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat); 19.240 +}; 19.241 + 19.242 +/* binary operations matrix (op) matrix */ 19.243 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2); 19.244 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2); 19.245 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2); 19.246 + 19.247 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2); 19.248 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2); 19.249 +inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2); 19.250 + 19.251 +/* binary operations matrix (op) scalar and scalar (op) matrix */ 19.252 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar); 19.253 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat); 19.254 + 19.255 +void operator *=(Matrix4x4 &mat, scalar_t scalar); 19.256 + 19.257 +std::ostream &operator <<(std::ostream &out, const Matrix4x4 &mat); 19.258 + 19.259 +#endif /* __cplusplus */ 19.260 + 19.261 +#include "matrix.inl" 19.262 + 19.263 +#endif /* VMATH_MATRIX_H_ */
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/libs/vmath/matrix.inl Sun Sep 29 08:20:19 2013 +0300 20.3 @@ -0,0 +1,200 @@ 20.4 +/* 20.5 +libvmath - a vector math library 20.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 20.7 + 20.8 +This program is free software: you can redistribute it and/or modify 20.9 +it under the terms of the GNU Lesser General Public License as published 20.10 +by the Free Software Foundation, either version 3 of the License, or 20.11 +(at your option) any later version. 20.12 + 20.13 +This program is distributed in the hope that it will be useful, 20.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 20.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20.16 +GNU Lesser General Public License for more details. 20.17 + 20.18 +You should have received a copy of the GNU Lesser General Public License 20.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 20.20 +*/ 20.21 + 20.22 +#include <string.h> 20.23 + 20.24 +#ifdef __cplusplus 20.25 +extern "C" { 20.26 +#endif /* __cplusplus */ 20.27 + 20.28 +/* C matrix 3x3 functions */ 20.29 +static inline void m3_identity(mat3_t m) 20.30 +{ 20.31 + static const mat3_t id = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; 20.32 + memcpy(m, id, sizeof id); 20.33 +} 20.34 + 20.35 +static inline void m3_cons(mat3_t m, 20.36 + scalar_t m11, scalar_t m12, scalar_t m13, 20.37 + scalar_t m21, scalar_t m22, scalar_t m23, 20.38 + scalar_t m31, scalar_t m32, scalar_t m33) 20.39 +{ 20.40 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; 20.41 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; 20.42 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; 20.43 +} 20.44 + 20.45 +static inline void m3_copy(mat3_t dest, mat3_t src) 20.46 +{ 20.47 + memcpy(dest, src, sizeof(mat3_t)); 20.48 +} 20.49 + 20.50 + 20.51 +/* C matrix 4x4 functions */ 20.52 +static inline void m4_identity(mat4_t m) 20.53 +{ 20.54 + static const mat4_t id = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; 20.55 + memcpy(m, id, sizeof id); 20.56 +} 20.57 + 20.58 +static inline void m4_cons(mat4_t m, 20.59 + scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 20.60 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 20.61 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 20.62 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44) 20.63 +{ 20.64 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14; 20.65 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24; 20.66 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34; 20.67 + m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44; 20.68 +} 20.69 + 20.70 +static inline void m4_copy(mat4_t dest, mat4_t src) 20.71 +{ 20.72 + memcpy(dest, src, sizeof(mat4_t)); 20.73 +} 20.74 + 20.75 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2) 20.76 +{ 20.77 + mat4_t tmp; 20.78 + 20.79 + /* 20.80 + int i, j; 20.81 + for(i=0; i<4; i++) { 20.82 + for(j=0; j<4; j++) { 20.83 + 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]; 20.84 + } 20.85 + } 20.86 + */ 20.87 + 20.88 + 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]; 20.89 + 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]; 20.90 + 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]; 20.91 + 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]; 20.92 + 20.93 + 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]; 20.94 + 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]; 20.95 + 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]; 20.96 + 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]; 20.97 + 20.98 + 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]; 20.99 + 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]; 20.100 + 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]; 20.101 + 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]; 20.102 + 20.103 + 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]; 20.104 + 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]; 20.105 + 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]; 20.106 + 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]; 20.107 + 20.108 + m4_copy(res, tmp); 20.109 +} 20.110 + 20.111 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx) 20.112 +{ 20.113 + m[0][idx] = v.x; 20.114 + m[1][idx] = v.y; 20.115 + m[2][idx] = v.z; 20.116 + m[3][idx] = v.w; 20.117 +} 20.118 + 20.119 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx) 20.120 +{ 20.121 + m[idx][0] = v.x; 20.122 + m[idx][1] = v.y; 20.123 + m[idx][2] = v.z; 20.124 + m[idx][3] = v.w; 20.125 +} 20.126 + 20.127 +#ifdef __cplusplus 20.128 +} /* extern "C" */ 20.129 + 20.130 + 20.131 +/* unrolled to hell and inline */ 20.132 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2) 20.133 +{ 20.134 + Matrix4x4 res; 20.135 + 20.136 + /* 20.137 + for(i=0; i<4; i++) { 20.138 + for(j=0; j<4; j++) { 20.139 + 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]; 20.140 + } 20.141 + } 20.142 + */ 20.143 + 20.144 + 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]; 20.145 + 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]; 20.146 + 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]; 20.147 + 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]; 20.148 + 20.149 + 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]; 20.150 + 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]; 20.151 + 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]; 20.152 + 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]; 20.153 + 20.154 + 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]; 20.155 + 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]; 20.156 + 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]; 20.157 + 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]; 20.158 + 20.159 + 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]; 20.160 + 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]; 20.161 + 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]; 20.162 + 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]; 20.163 + 20.164 + return res; 20.165 +} 20.166 + 20.167 +inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2) 20.168 +{ 20.169 + Matrix4x4 res = m1 * m2; 20.170 + m1 = res; 20.171 +} 20.172 + 20.173 + 20.174 +inline scalar_t *Matrix3x3::operator [](int index) 20.175 +{ 20.176 + return m[index]; 20.177 +} 20.178 + 20.179 +inline const scalar_t *Matrix3x3::operator [](int index) const 20.180 +{ 20.181 + return m[index]; 20.182 +} 20.183 + 20.184 +inline void Matrix3x3::reset_identity() 20.185 +{ 20.186 + *this = identity; 20.187 +} 20.188 + 20.189 +inline scalar_t *Matrix4x4::operator [](int index) 20.190 +{ 20.191 + return m[index]; 20.192 +} 20.193 + 20.194 +inline const scalar_t *Matrix4x4::operator [](int index) const 20.195 +{ 20.196 + return m[index]; 20.197 +} 20.198 + 20.199 +inline void Matrix4x4::reset_identity() 20.200 +{ 20.201 + *this = identity; 20.202 +} 20.203 +#endif /* __cplusplus */
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/libs/vmath/matrix_c.c Sun Sep 29 08:20:19 2013 +0300 21.3 @@ -0,0 +1,292 @@ 21.4 +/* 21.5 +libvmath - a vector math library 21.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 21.7 + 21.8 +This program is free software: you can redistribute it and/or modify 21.9 +it under the terms of the GNU Lesser General Public License as published 21.10 +by the Free Software Foundation, either version 3 of the License, or 21.11 +(at your option) any later version. 21.12 + 21.13 +This program is distributed in the hope that it will be useful, 21.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 21.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.16 +GNU Lesser General Public License for more details. 21.17 + 21.18 +You should have received a copy of the GNU Lesser General Public License 21.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 21.20 +*/ 21.21 + 21.22 + 21.23 +#include <stdio.h> 21.24 +#include "matrix.h" 21.25 +#include "vector.h" 21.26 +#include "quat.h" 21.27 + 21.28 +void m3_to_m4(mat4_t dest, mat3_t src) 21.29 +{ 21.30 + int i, j; 21.31 + 21.32 + memset(dest, 0, sizeof(mat4_t)); 21.33 + for(i=0; i<3; i++) { 21.34 + for(j=0; j<3; j++) { 21.35 + dest[i][j] = src[i][j]; 21.36 + } 21.37 + } 21.38 + dest[3][3] = 1.0; 21.39 +} 21.40 + 21.41 +void m3_print(FILE *fp, mat3_t m) 21.42 +{ 21.43 + int i; 21.44 + for(i=0; i<3; i++) { 21.45 + fprintf(fp, "[ %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2]); 21.46 + } 21.47 +} 21.48 + 21.49 +/* C matrix 4x4 functions */ 21.50 +void m4_to_m3(mat3_t dest, mat4_t src) 21.51 +{ 21.52 + int i, j; 21.53 + for(i=0; i<3; i++) { 21.54 + for(j=0; j<3; j++) { 21.55 + dest[i][j] = src[i][j]; 21.56 + } 21.57 + } 21.58 +} 21.59 + 21.60 +void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 21.61 +{ 21.62 + m4_identity(m); 21.63 + m[0][3] = x; 21.64 + m[1][3] = y; 21.65 + m[2][3] = z; 21.66 +} 21.67 + 21.68 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 21.69 +{ 21.70 + mat4_t tm; 21.71 + m4_set_translation(tm, x, y, z); 21.72 + m4_mult(m, m, tm); 21.73 +} 21.74 + 21.75 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 21.76 +{ 21.77 + m4_rotate_x(m, x); 21.78 + m4_rotate_y(m, y); 21.79 + m4_rotate_z(m, z); 21.80 +} 21.81 + 21.82 +void m4_set_rotation_x(mat4_t m, scalar_t angle) 21.83 +{ 21.84 + m4_identity(m); 21.85 + m[1][1] = cos(angle); m[1][2] = -sin(angle); 21.86 + m[2][1] = sin(angle); m[2][2] = cos(angle); 21.87 +} 21.88 + 21.89 +void m4_rotate_x(mat4_t m, scalar_t angle) 21.90 +{ 21.91 + mat4_t rm; 21.92 + m4_set_rotation_x(m, angle); 21.93 + m4_mult(m, m, rm); 21.94 +} 21.95 + 21.96 +void m4_set_rotation_y(mat4_t m, scalar_t angle) 21.97 +{ 21.98 + m4_identity(m); 21.99 + m[0][0] = cos(angle); m[0][2] = sin(angle); 21.100 + m[2][0] = -sin(angle); m[2][2] = cos(angle); 21.101 +} 21.102 + 21.103 +void m4_rotate_y(mat4_t m, scalar_t angle) 21.104 +{ 21.105 + mat4_t rm; 21.106 + m4_set_rotation_y(rm, angle); 21.107 + m4_mult(m, m, rm); 21.108 +} 21.109 + 21.110 +void m4_set_rotation_z(mat4_t m, scalar_t angle) 21.111 +{ 21.112 + m4_identity(m); 21.113 + m[0][0] = cos(angle); m[0][1] = -sin(angle); 21.114 + m[1][0] = sin(angle); m[1][1] = cos(angle); 21.115 +} 21.116 + 21.117 +void m4_rotate_z(mat4_t m, scalar_t angle) 21.118 +{ 21.119 + mat4_t rm; 21.120 + m4_set_rotation_z(rm, angle); 21.121 + m4_mult(m, m, rm); 21.122 +} 21.123 + 21.124 +void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 21.125 +{ 21.126 + scalar_t sina = sin(angle); 21.127 + scalar_t cosa = cos(angle); 21.128 + scalar_t one_minus_cosa = 1.0 - cosa; 21.129 + scalar_t nxsq = x * x; 21.130 + scalar_t nysq = y * y; 21.131 + scalar_t nzsq = z * z; 21.132 + 21.133 + m[0][0] = nxsq + (1.0 - nxsq) * cosa; 21.134 + m[0][1] = x * y * one_minus_cosa - z * sina; 21.135 + m[0][2] = x * z * one_minus_cosa + y * sina; 21.136 + m[1][0] = x * y * one_minus_cosa + z * sina; 21.137 + m[1][1] = nysq + (1.0 - nysq) * cosa; 21.138 + m[1][2] = y * z * one_minus_cosa - x * sina; 21.139 + m[2][0] = x * z * one_minus_cosa - y * sina; 21.140 + m[2][1] = y * z * one_minus_cosa + x * sina; 21.141 + m[2][2] = nzsq + (1.0 - nzsq) * cosa; 21.142 + 21.143 + /* the rest are identity */ 21.144 + m[3][0] = m[3][1] = m[3][2] = m[0][3] = m[1][3] = m[2][3] = 0.0; 21.145 + m[3][3] = 1.0; 21.146 +} 21.147 + 21.148 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 21.149 +{ 21.150 + mat4_t xform; 21.151 + m4_set_rotation_axis(xform, angle, x, y, z); 21.152 + m4_mult(m, m, xform); 21.153 +} 21.154 + 21.155 +void m4_rotate_quat(mat4_t m, quat_t q) 21.156 +{ 21.157 + mat4_t rm; 21.158 + quat_to_mat4(rm, q); 21.159 + m4_mult(m, m, rm); 21.160 +} 21.161 + 21.162 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 21.163 +{ 21.164 + mat4_t sm; 21.165 + m4_identity(sm); 21.166 + sm[0][0] = x; 21.167 + sm[1][1] = y; 21.168 + sm[2][2] = z; 21.169 + m4_mult(m, m, sm); 21.170 +} 21.171 + 21.172 +void m4_transpose(mat4_t res, mat4_t m) 21.173 +{ 21.174 + int i, j; 21.175 + mat4_t tmp; 21.176 + m4_copy(tmp, m); 21.177 + 21.178 + for(i=0; i<4; i++) { 21.179 + for(j=0; j<4; j++) { 21.180 + res[i][j] = tmp[j][i]; 21.181 + } 21.182 + } 21.183 +} 21.184 + 21.185 +scalar_t m4_determinant(mat4_t m) 21.186 +{ 21.187 + scalar_t det11 = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 21.188 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 21.189 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 21.190 + 21.191 + scalar_t det12 = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 21.192 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 21.193 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 21.194 + 21.195 + scalar_t det13 = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 21.196 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 21.197 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 21.198 + 21.199 + scalar_t det14 = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 21.200 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 21.201 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 21.202 + 21.203 + return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14; 21.204 +} 21.205 + 21.206 +void m4_adjoint(mat4_t res, mat4_t m) 21.207 +{ 21.208 + int i, j; 21.209 + mat4_t coef; 21.210 + 21.211 + coef[0][0] = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 21.212 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 21.213 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 21.214 + coef[0][1] = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 21.215 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 21.216 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 21.217 + coef[0][2] = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 21.218 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 21.219 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 21.220 + coef[0][3] = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 21.221 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 21.222 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 21.223 + 21.224 + coef[1][0] = (m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 21.225 + (m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 21.226 + (m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 21.227 + coef[1][1] = (m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 21.228 + (m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 21.229 + (m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 21.230 + coef[1][2] = (m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 21.231 + (m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 21.232 + (m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 21.233 + coef[1][3] = (m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 21.234 + (m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 21.235 + (m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 21.236 + 21.237 + coef[2][0] = (m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 21.238 + (m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) + 21.239 + (m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])); 21.240 + coef[2][1] = (m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 21.241 + (m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 21.242 + (m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])); 21.243 + coef[2][2] = (m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) - 21.244 + (m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 21.245 + (m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 21.246 + coef[2][3] = (m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) - 21.247 + (m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) + 21.248 + (m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 21.249 + 21.250 + coef[3][0] = (m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 21.251 + (m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) + 21.252 + (m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])); 21.253 + coef[3][1] = (m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 21.254 + (m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 21.255 + (m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])); 21.256 + coef[3][2] = (m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) - 21.257 + (m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 21.258 + (m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 21.259 + coef[3][3] = (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) - 21.260 + (m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) + 21.261 + (m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 21.262 + 21.263 + m4_transpose(res, coef); 21.264 + 21.265 + for(i=0; i<4; i++) { 21.266 + for(j=0; j<4; j++) { 21.267 + res[i][j] = j % 2 ? -res[i][j] : res[i][j]; 21.268 + if(i % 2) res[i][j] = -res[i][j]; 21.269 + } 21.270 + } 21.271 +} 21.272 + 21.273 +void m4_inverse(mat4_t res, mat4_t m) 21.274 +{ 21.275 + int i, j; 21.276 + mat4_t adj; 21.277 + scalar_t det; 21.278 + 21.279 + m4_adjoint(adj, m); 21.280 + det = m4_determinant(m); 21.281 + 21.282 + for(i=0; i<4; i++) { 21.283 + for(j=0; j<4; j++) { 21.284 + res[i][j] = adj[i][j] / det; 21.285 + } 21.286 + } 21.287 +} 21.288 + 21.289 +void m4_print(FILE *fp, mat4_t m) 21.290 +{ 21.291 + int i; 21.292 + for(i=0; i<4; i++) { 21.293 + 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]); 21.294 + } 21.295 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/libs/vmath/quat.cc Sun Sep 29 08:20:19 2013 +0300 22.3 @@ -0,0 +1,212 @@ 22.4 +#include "quat.h" 22.5 +#include "vmath.h" 22.6 + 22.7 +Quaternion::Quaternion() 22.8 +{ 22.9 + s = 1.0; 22.10 + v.x = v.y = v.z = 0.0; 22.11 +} 22.12 + 22.13 +Quaternion::Quaternion(scalar_t s, const Vector3 &v) 22.14 +{ 22.15 + this->s = s; 22.16 + this->v = v; 22.17 +} 22.18 + 22.19 +Quaternion::Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z) 22.20 +{ 22.21 + v.x = x; 22.22 + v.y = y; 22.23 + v.z = z; 22.24 + this->s = s; 22.25 +} 22.26 + 22.27 +Quaternion::Quaternion(const Vector3 &axis, scalar_t angle) 22.28 +{ 22.29 + set_rotation(axis, angle); 22.30 +} 22.31 + 22.32 +Quaternion::Quaternion(const quat_t &quat) 22.33 +{ 22.34 + v.x = quat.x; 22.35 + v.y = quat.y; 22.36 + v.z = quat.z; 22.37 + s = quat.w; 22.38 +} 22.39 + 22.40 +Quaternion Quaternion::operator +(const Quaternion &quat) const 22.41 +{ 22.42 + return Quaternion(s + quat.s, v + quat.v); 22.43 +} 22.44 + 22.45 +Quaternion Quaternion::operator -(const Quaternion &quat) const 22.46 +{ 22.47 + return Quaternion(s - quat.s, v - quat.v); 22.48 +} 22.49 + 22.50 +Quaternion Quaternion::operator -() const 22.51 +{ 22.52 + return Quaternion(-s, -v); 22.53 +} 22.54 + 22.55 +/** Quaternion Multiplication: 22.56 + * Q1*Q2 = [s1*s2 - v1.v2, s1*v2 + s2*v1 + v1(x)v2] 22.57 + */ 22.58 +Quaternion Quaternion::operator *(const Quaternion &quat) const 22.59 +{ 22.60 + Quaternion newq; 22.61 + newq.s = s * quat.s - dot_product(v, quat.v); 22.62 + newq.v = quat.v * s + v * quat.s + cross_product(v, quat.v); 22.63 + return newq; 22.64 +} 22.65 + 22.66 +void Quaternion::operator +=(const Quaternion &quat) 22.67 +{ 22.68 + *this = Quaternion(s + quat.s, v + quat.v); 22.69 +} 22.70 + 22.71 +void Quaternion::operator -=(const Quaternion &quat) 22.72 +{ 22.73 + *this = Quaternion(s - quat.s, v - quat.v); 22.74 +} 22.75 + 22.76 +void Quaternion::operator *=(const Quaternion &quat) 22.77 +{ 22.78 + *this = *this * quat; 22.79 +} 22.80 + 22.81 +void Quaternion::reset_identity() 22.82 +{ 22.83 + s = 1.0; 22.84 + v.x = v.y = v.z = 0.0; 22.85 +} 22.86 + 22.87 +Quaternion Quaternion::conjugate() const 22.88 +{ 22.89 + return Quaternion(s, -v); 22.90 +} 22.91 + 22.92 +scalar_t Quaternion::length() const 22.93 +{ 22.94 + return (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); 22.95 +} 22.96 + 22.97 +/** Q * ~Q = ||Q||^2 */ 22.98 +scalar_t Quaternion::length_sq() const 22.99 +{ 22.100 + return v.x*v.x + v.y*v.y + v.z*v.z + s*s; 22.101 +} 22.102 + 22.103 +void Quaternion::normalize() 22.104 +{ 22.105 + scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); 22.106 + v.x /= len; 22.107 + v.y /= len; 22.108 + v.z /= len; 22.109 + s /= len; 22.110 +} 22.111 + 22.112 +Quaternion Quaternion::normalized() const 22.113 +{ 22.114 + Quaternion nq = *this; 22.115 + scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); 22.116 + nq.v.x /= len; 22.117 + nq.v.y /= len; 22.118 + nq.v.z /= len; 22.119 + nq.s /= len; 22.120 + return nq; 22.121 +} 22.122 + 22.123 +/** Quaternion Inversion: Q^-1 = ~Q / ||Q||^2 */ 22.124 +Quaternion Quaternion::inverse() const 22.125 +{ 22.126 + Quaternion inv = conjugate(); 22.127 + scalar_t lensq = length_sq(); 22.128 + inv.v /= lensq; 22.129 + inv.s /= lensq; 22.130 + 22.131 + return inv; 22.132 +} 22.133 + 22.134 + 22.135 +void Quaternion::set_rotation(const Vector3 &axis, scalar_t angle) 22.136 +{ 22.137 + scalar_t half_angle = angle / 2.0; 22.138 + s = cos(half_angle); 22.139 + v = axis * sin(half_angle); 22.140 +} 22.141 + 22.142 +void Quaternion::rotate(const Vector3 &axis, scalar_t angle) 22.143 +{ 22.144 + Quaternion q; 22.145 + scalar_t half_angle = angle / 2.0; 22.146 + q.s = cos(half_angle); 22.147 + q.v = axis * sin(half_angle); 22.148 + 22.149 + *this *= q; 22.150 +} 22.151 + 22.152 +void Quaternion::rotate(const Quaternion &q) 22.153 +{ 22.154 + *this = q * *this * q.conjugate(); 22.155 +} 22.156 + 22.157 +Matrix3x3 Quaternion::get_rotation_matrix() const 22.158 +{ 22.159 + return Matrix3x3( 22.160 + 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, 22.161 + 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, 22.162 + 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); 22.163 +} 22.164 + 22.165 + 22.166 +/** Spherical linear interpolation (slerp) */ 22.167 +Quaternion slerp(const Quaternion &quat1, const Quaternion &q2, scalar_t t) 22.168 +{ 22.169 + Quaternion q1; 22.170 + 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; 22.171 + 22.172 + if(dot < 0.0) { 22.173 + /* make sure we interpolate across the shortest arc */ 22.174 + q1 = -quat1; 22.175 + dot = -dot; 22.176 + } else { 22.177 + q1 = quat1; 22.178 + } 22.179 + 22.180 + /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to 22.181 + * floating point imprecisions 22.182 + */ 22.183 + if(dot < -1.0) dot = -1.0; 22.184 + if(dot > 1.0) dot = 1.0; 22.185 + 22.186 + scalar_t angle = acos(dot); 22.187 + scalar_t a, b; 22.188 + 22.189 + scalar_t sin_angle = sin(angle); 22.190 + if(fabs(sin_angle) < SMALL_NUMBER) { 22.191 + /* for very small angles or completely opposite orientations 22.192 + * use linear interpolation to avoid div/zero (in the first case it makes sense, 22.193 + * the second case is pretty much undefined anyway I guess ... 22.194 + */ 22.195 + a = 1.0f - t; 22.196 + b = t; 22.197 + } else { 22.198 + a = sin((1.0f - t) * angle) / sin_angle; 22.199 + b = sin(t * angle) / sin_angle; 22.200 + } 22.201 + 22.202 + scalar_t x = q1.v.x * a + q2.v.x * b; 22.203 + scalar_t y = q1.v.y * a + q2.v.y * b; 22.204 + scalar_t z = q1.v.z * a + q2.v.z * b; 22.205 + scalar_t s = q1.s * a + q2.s * b; 22.206 + 22.207 + return Quaternion(s, Vector3(x, y, z)); 22.208 +} 22.209 + 22.210 + 22.211 +std::ostream &operator <<(std::ostream &out, const Quaternion &q) 22.212 +{ 22.213 + out << "(" << q.s << ", " << q.v << ")"; 22.214 + return out; 22.215 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/libs/vmath/quat.h Sun Sep 29 08:20:19 2013 +0300 23.3 @@ -0,0 +1,118 @@ 23.4 +/* 23.5 +libvmath - a vector math library 23.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 23.7 + 23.8 +This program is free software: you can redistribute it and/or modify 23.9 +it under the terms of the GNU Lesser General Public License as published 23.10 +by the Free Software Foundation, either version 3 of the License, or 23.11 +(at your option) any later version. 23.12 + 23.13 +This program is distributed in the hope that it will be useful, 23.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 23.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.16 +GNU Lesser General Public License for more details. 23.17 + 23.18 +You should have received a copy of the GNU Lesser General Public License 23.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 23.20 +*/ 23.21 + 23.22 +#ifndef VMATH_QUATERNION_H_ 23.23 +#define VMATH_QUATERNION_H_ 23.24 + 23.25 +#include <stdio.h> 23.26 +#include "vmath_types.h" 23.27 +#include "vector.h" 23.28 + 23.29 +#ifdef __cplusplus 23.30 +extern "C" { 23.31 +#endif /* __cplusplus */ 23.32 + 23.33 +#define quat_cons(s, x, y, z) v4_cons(x, y, z, s) 23.34 +#define quat_vec(q) v3_cons((q).x, (q).y, (q).z) 23.35 +#define quat_s(q) ((q).w) 23.36 +#define quat_identity() quat_cons(1.0, 0.0, 0.0, 0.0) 23.37 +void quat_print(FILE *fp, quat_t q); 23.38 + 23.39 +#define quat_add v4_add 23.40 +#define quat_sub v4_sub 23.41 +#define quat_neg v4_neg 23.42 + 23.43 +static inline quat_t quat_mul(quat_t q1, quat_t q2); 23.44 + 23.45 +static inline quat_t quat_conjugate(quat_t q); 23.46 + 23.47 +#define quat_length v4_length 23.48 +#define quat_length_sq v4_length_sq 23.49 + 23.50 +#define quat_normalize v4_normalize 23.51 +static inline quat_t quat_inverse(quat_t q); 23.52 + 23.53 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 23.54 +quat_t quat_rotate_quat(quat_t q, quat_t rotq); 23.55 + 23.56 +static inline void quat_to_mat3(mat3_t res, quat_t q); 23.57 +static inline void quat_to_mat4(mat4_t res, quat_t q); 23.58 + 23.59 +#define quat_lerp quat_slerp 23.60 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t); 23.61 + 23.62 + 23.63 +#ifdef __cplusplus 23.64 +} /* extern "C" */ 23.65 + 23.66 +#include <iostream> 23.67 + 23.68 +/* Quaternion */ 23.69 +class Quaternion { 23.70 +public: 23.71 + scalar_t s; 23.72 + Vector3 v; 23.73 + 23.74 + Quaternion(); 23.75 + Quaternion(scalar_t s, const Vector3 &v); 23.76 + Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z); 23.77 + Quaternion(const Vector3 &axis, scalar_t angle); 23.78 + Quaternion(const quat_t &quat); 23.79 + 23.80 + Quaternion operator +(const Quaternion &quat) const; 23.81 + Quaternion operator -(const Quaternion &quat) const; 23.82 + Quaternion operator -() const; 23.83 + Quaternion operator *(const Quaternion &quat) const; 23.84 + 23.85 + void operator +=(const Quaternion &quat); 23.86 + void operator -=(const Quaternion &quat); 23.87 + void operator *=(const Quaternion &quat); 23.88 + 23.89 + void reset_identity(); 23.90 + 23.91 + Quaternion conjugate() const; 23.92 + 23.93 + scalar_t length() const; 23.94 + scalar_t length_sq() const; 23.95 + 23.96 + void normalize(); 23.97 + Quaternion normalized() const; 23.98 + 23.99 + Quaternion inverse() const; 23.100 + 23.101 + void set_rotation(const Vector3 &axis, scalar_t angle); 23.102 + void rotate(const Vector3 &axis, scalar_t angle); 23.103 + /* note: this is a totally different operation from the above 23.104 + * this treats the quaternion as signifying direction and rotates 23.105 + * it by a rotation quaternion by rot * q * rot' 23.106 + */ 23.107 + void rotate(const Quaternion &q); 23.108 + 23.109 + Matrix3x3 get_rotation_matrix() const; 23.110 +}; 23.111 + 23.112 +Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t); 23.113 +inline Quaternion lerp(const Quaternion &q1, const Quaternion &q2, scalar_t t); 23.114 + 23.115 +std::ostream &operator <<(std::ostream &out, const Quaternion &q); 23.116 + 23.117 +#endif /* __cplusplus */ 23.118 + 23.119 +#include "quat.inl" 23.120 + 23.121 +#endif /* VMATH_QUATERNION_H_ */
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/libs/vmath/quat.inl Sun Sep 29 08:20:19 2013 +0300 24.3 @@ -0,0 +1,81 @@ 24.4 +/* 24.5 +libvmath - a vector math library 24.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 24.7 + 24.8 +This program is free software: you can redistribute it and/or modify 24.9 +it under the terms of the GNU Lesser General Public License as published 24.10 +by the Free Software Foundation, either version 3 of the License, or 24.11 +(at your option) any later version. 24.12 + 24.13 +This program is distributed in the hope that it will be useful, 24.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 24.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.16 +GNU Lesser General Public License for more details. 24.17 + 24.18 +You should have received a copy of the GNU Lesser General Public License 24.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 24.20 +*/ 24.21 + 24.22 +#include "vector.h" 24.23 +#include "matrix.h" 24.24 + 24.25 +#ifdef __cplusplus 24.26 +extern "C" { 24.27 +#endif /* __cplusplus */ 24.28 + 24.29 +static inline quat_t quat_mul(quat_t q1, quat_t q2) 24.30 +{ 24.31 + quat_t res; 24.32 + vec3_t v1 = quat_vec(q1); 24.33 + vec3_t v2 = quat_vec(q2); 24.34 + 24.35 + res.w = q1.w * q2.w - v3_dot(v1, v2); 24.36 + /* resvec = v2 * q1 + v1 * q2 + cross(v1, v2) */ 24.37 + res.x = v2.x * q1.w + v1.x * q2.w + (v1.y * v2.z - v1.z * v2.y); 24.38 + res.y = v2.y * q1.w + v1.y * q2.w + (v1.z * v2.x - v1.x * v2.z); 24.39 + res.z = v2.z * q1.w + v1.z * q2.w + (v1.x * v2.y - v1.y * v2.x); 24.40 + return res; 24.41 +} 24.42 + 24.43 +static inline quat_t quat_conjugate(quat_t q) 24.44 +{ 24.45 + q.x = -q.x; 24.46 + q.y = -q.y; 24.47 + q.z = -q.z; 24.48 + return q; 24.49 +} 24.50 + 24.51 +static inline quat_t quat_inverse(quat_t q) 24.52 +{ 24.53 + scalar_t lensq = quat_length_sq(q); 24.54 + q = quat_conjugate(q); 24.55 + q.x /= lensq; 24.56 + q.y /= lensq; 24.57 + q.z /= lensq; 24.58 + q.w /= lensq; 24.59 + return q; 24.60 +} 24.61 + 24.62 +static inline void quat_to_mat3(mat3_t res, quat_t q) 24.63 +{ 24.64 + 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, 24.65 + 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, 24.66 + 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); 24.67 +} 24.68 + 24.69 +static inline void quat_to_mat4(mat4_t res, quat_t q) 24.70 +{ 24.71 + 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, 24.72 + 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, 24.73 + 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, 24.74 + 0, 0, 0, 1); 24.75 +} 24.76 + 24.77 +#ifdef __cplusplus 24.78 +} /* extern "C" */ 24.79 + 24.80 +inline Quaternion lerp(const Quaternion &a, const Quaternion &b, scalar_t t) 24.81 +{ 24.82 + return slerp(a, b, t); 24.83 +} 24.84 +#endif /* __cplusplus */
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/libs/vmath/quat_c.c Sun Sep 29 08:20:19 2013 +0300 25.3 @@ -0,0 +1,89 @@ 25.4 +/* 25.5 +libvmath - a vector math library 25.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 25.7 + 25.8 +This program is free software: you can redistribute it and/or modify 25.9 +it under the terms of the GNU Lesser General Public License as published 25.10 +by the Free Software Foundation, either version 3 of the License, or 25.11 +(at your option) any later version. 25.12 + 25.13 +This program is distributed in the hope that it will be useful, 25.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 25.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.16 +GNU Lesser General Public License for more details. 25.17 + 25.18 +You should have received a copy of the GNU Lesser General Public License 25.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 25.20 +*/ 25.21 + 25.22 + 25.23 +#include <stdio.h> 25.24 +#include <math.h> 25.25 +#include "quat.h" 25.26 + 25.27 +void quat_print(FILE *fp, quat_t q) 25.28 +{ 25.29 + fprintf(fp, "([ %.4f %.4f %.4f ] %.4f)", q.x, q.y, q.z, q.w); 25.30 +} 25.31 + 25.32 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 25.33 +{ 25.34 + quat_t rq; 25.35 + scalar_t half_angle = angle * 0.5; 25.36 + scalar_t sin_half = sin(half_angle); 25.37 + 25.38 + rq.w = cos(half_angle); 25.39 + rq.x = x * sin_half; 25.40 + rq.y = y * sin_half; 25.41 + rq.z = z * sin_half; 25.42 + 25.43 + return quat_mul(q, rq); 25.44 +} 25.45 + 25.46 +quat_t quat_rotate_quat(quat_t q, quat_t rotq) 25.47 +{ 25.48 + return quat_mul(quat_mul(rotq, q), quat_conjugate(rotq)); 25.49 +} 25.50 + 25.51 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t) 25.52 +{ 25.53 + quat_t res; 25.54 + scalar_t a, b, angle, sin_angle, dot; 25.55 + 25.56 + dot = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; 25.57 + if(dot < 0.0) { 25.58 + /* make sure we interpolate across the shortest arc */ 25.59 + q1.x = -q1.x; 25.60 + q1.y = -q1.y; 25.61 + q1.z = -q1.z; 25.62 + q1.w = -q1.w; 25.63 + dot = -dot; 25.64 + } 25.65 + 25.66 + /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to 25.67 + * floating point imprecisions 25.68 + */ 25.69 + if(dot < -1.0) dot = -1.0; 25.70 + if(dot > 1.0) dot = 1.0; 25.71 + 25.72 + angle = acos(dot); 25.73 + sin_angle = sin(angle); 25.74 + 25.75 + if(fabs(sin_angle) < SMALL_NUMBER) { 25.76 + /* for very small angles or completely opposite orientations 25.77 + * use linear interpolation to avoid div/zero (in the first case it makes sense, 25.78 + * the second case is pretty much undefined anyway I guess ... 25.79 + */ 25.80 + a = 1.0f - t; 25.81 + b = t; 25.82 + } else { 25.83 + a = sin((1.0f - t) * angle) / sin_angle; 25.84 + b = sin(t * angle) / sin_angle; 25.85 + } 25.86 + 25.87 + res.x = q1.x * a + q2.x * b; 25.88 + res.y = q1.y * a + q2.y * b; 25.89 + res.z = q1.z * a + q2.z * b; 25.90 + res.w = q1.w * a + q2.w * b; 25.91 + return res; 25.92 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/libs/vmath/ray.cc Sun Sep 29 08:20:19 2013 +0300 26.3 @@ -0,0 +1,39 @@ 26.4 +#include "ray.h" 26.5 +#include "vector.h" 26.6 + 26.7 +scalar_t Ray::env_ior = 1.0; 26.8 + 26.9 +Ray::Ray() 26.10 +{ 26.11 + ior = env_ior; 26.12 + energy = 1.0; 26.13 + time = 0; 26.14 + iter = 0; 26.15 +} 26.16 + 26.17 +Ray::Ray(const Vector3 &origin, const Vector3 &dir) 26.18 +{ 26.19 + this->origin = origin; 26.20 + this->dir = dir; 26.21 + ior = env_ior; 26.22 + energy = 1.0; 26.23 + time = 0; 26.24 + iter = 0; 26.25 +} 26.26 + 26.27 +void Ray::transform(const Matrix4x4 &xform) 26.28 +{ 26.29 + Matrix4x4 upper = xform; 26.30 + upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; 26.31 + upper[3][3] = 1.0; 26.32 + 26.33 + dir.transform(upper); 26.34 + origin.transform(xform); 26.35 +} 26.36 + 26.37 +Ray Ray::transformed(const Matrix4x4 &xform) const 26.38 +{ 26.39 + Ray foo = *this; 26.40 + foo.transform(xform); 26.41 + return foo; 26.42 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/libs/vmath/ray.h Sun Sep 29 08:20:19 2013 +0300 27.3 @@ -0,0 +1,64 @@ 27.4 +/* 27.5 +libvmath - a vector math library 27.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 27.7 + 27.8 +This program is free software: you can redistribute it and/or modify 27.9 +it under the terms of the GNU Lesser General Public License as published 27.10 +by the Free Software Foundation, either version 3 of the License, or 27.11 +(at your option) any later version. 27.12 + 27.13 +This program is distributed in the hope that it will be useful, 27.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 27.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27.16 +GNU Lesser General Public License for more details. 27.17 + 27.18 +You should have received a copy of the GNU Lesser General Public License 27.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 27.20 +*/ 27.21 + 27.22 +#ifndef VMATH_RAY_H_ 27.23 +#define VMATH_RAY_H_ 27.24 + 27.25 +#include "matrix.h" 27.26 +#include "vector.h" 27.27 + 27.28 +typedef struct { 27.29 + vec3_t origin, dir; 27.30 +} ray_t; 27.31 + 27.32 +#ifdef __cplusplus 27.33 +extern "C" { 27.34 +#endif /* __cplusplus */ 27.35 + 27.36 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir); 27.37 +ray_t ray_transform(ray_t r, mat4_t m); 27.38 + 27.39 +#ifdef __cplusplus 27.40 +} /* __cplusplus */ 27.41 + 27.42 +#include <stack> 27.43 + 27.44 +class Ray { 27.45 +public: 27.46 + static scalar_t env_ior; 27.47 + 27.48 + Vector3 origin, dir; 27.49 + scalar_t energy; 27.50 + int iter; 27.51 + scalar_t ior; 27.52 + long time; 27.53 + 27.54 + Ray(); 27.55 + Ray(const Vector3 &origin, const Vector3 &dir); 27.56 + 27.57 + void transform(const Matrix4x4 &xform); 27.58 + Ray transformed(const Matrix4x4 &xform) const; 27.59 +}; 27.60 + 27.61 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm); 27.62 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t from_ior, scalar_t to_ior); 27.63 +#endif /* __cplusplus */ 27.64 + 27.65 +#include "ray.inl" 27.66 + 27.67 +#endif /* VMATH_RAY_H_ */
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/libs/vmath/ray.inl Sun Sep 29 08:20:19 2013 +0300 28.3 @@ -0,0 +1,52 @@ 28.4 +/* 28.5 +libvmath - a vector math library 28.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 28.7 + 28.8 +This program is free software: you can redistribute it and/or modify 28.9 +it under the terms of the GNU Lesser General Public License as published 28.10 +by the Free Software Foundation, either version 3 of the License, or 28.11 +(at your option) any later version. 28.12 + 28.13 +This program is distributed in the hope that it will be useful, 28.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 28.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28.16 +GNU Lesser General Public License for more details. 28.17 + 28.18 +You should have received a copy of the GNU Lesser General Public License 28.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 28.20 +*/ 28.21 + 28.22 +#ifdef __cplusplus 28.23 +extern "C" { 28.24 +#endif /* __cplusplus */ 28.25 + 28.26 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir) 28.27 +{ 28.28 + ray_t r; 28.29 + r.origin = origin; 28.30 + r.dir = dir; 28.31 + return r; 28.32 +} 28.33 + 28.34 +#ifdef __cplusplus 28.35 +} 28.36 + 28.37 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm) 28.38 +{ 28.39 + Ray ray = inray; 28.40 + ray.dir = ray.dir.reflection(norm); 28.41 + return ray; 28.42 +} 28.43 + 28.44 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t from_ior, scalar_t to_ior) 28.45 +{ 28.46 + Ray ray = inray; 28.47 + ray.dir = ray.dir.refraction(norm, from_ior, to_ior); 28.48 + 28.49 + /* check TIR */ 28.50 + if(dot_product(ray.dir, norm) > 0.0) { 28.51 + return reflect_ray(inray, norm); 28.52 + } 28.53 + return ray; 28.54 +} 28.55 +#endif /* __cplusplus */
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/libs/vmath/ray_c.c Sun Sep 29 08:20:19 2013 +0300 29.3 @@ -0,0 +1,36 @@ 29.4 +/* 29.5 +libvmath - a vector math library 29.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 29.7 + 29.8 +This program is free software: you can redistribute it and/or modify 29.9 +it under the terms of the GNU Lesser General Public License as published 29.10 +by the Free Software Foundation, either version 3 of the License, or 29.11 +(at your option) any later version. 29.12 + 29.13 +This program is distributed in the hope that it will be useful, 29.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 29.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29.16 +GNU Lesser General Public License for more details. 29.17 + 29.18 +You should have received a copy of the GNU Lesser General Public License 29.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 29.20 +*/ 29.21 + 29.22 +#include "ray.h" 29.23 +#include "vector.h" 29.24 + 29.25 +ray_t ray_transform(ray_t r, mat4_t xform) 29.26 +{ 29.27 + mat4_t upper; 29.28 + vec3_t dir; 29.29 + 29.30 + m4_copy(upper, xform); 29.31 + upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; 29.32 + upper[3][3] = 1.0; 29.33 + 29.34 + dir = v3_sub(r.dir, r.origin); 29.35 + dir = v3_transform(dir, upper); 29.36 + r.origin = v3_transform(r.origin, xform); 29.37 + r.dir = v3_add(dir, r.origin); 29.38 + return r; 29.39 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/libs/vmath/sphvec.cc Sun Sep 29 08:20:19 2013 +0300 30.3 @@ -0,0 +1,27 @@ 30.4 +#include "sphvec.h" 30.5 +#include "vector.h" 30.6 + 30.7 +/* theta: 0 <= theta <= 2pi, the angle around Y axis. 30.8 + * phi: 0 <= phi <= pi, the angle from Y axis. 30.9 + * r: radius. 30.10 + */ 30.11 +SphVector::SphVector(scalar_t theta, scalar_t phi, scalar_t r) { 30.12 + this->theta = theta; 30.13 + this->phi = phi; 30.14 + this->r = r; 30.15 +} 30.16 + 30.17 +/* Constructs a spherical coordinate vector from a cartesian vector */ 30.18 +SphVector::SphVector(const Vector3 &cvec) { 30.19 + *this = cvec; 30.20 +} 30.21 + 30.22 +/* Assignment operator that converts cartesian to spherical coords */ 30.23 +SphVector &SphVector::operator =(const Vector3 &cvec) { 30.24 + r = cvec.length(); 30.25 + //theta = atan2(cvec.y, cvec.x); 30.26 + theta = atan2(cvec.z, cvec.x); 30.27 + //phi = acos(cvec.z / r); 30.28 + phi = acos(cvec.y / r); 30.29 + return *this; 30.30 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/libs/vmath/sphvec.h Sun Sep 29 08:20:19 2013 +0300 31.3 @@ -0,0 +1,36 @@ 31.4 +/* 31.5 +libvmath - a vector math library 31.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 31.7 + 31.8 +This program is free software: you can redistribute it and/or modify 31.9 +it under the terms of the GNU Lesser General Public License as published 31.10 +by the Free Software Foundation, either version 3 of the License, or 31.11 +(at your option) any later version. 31.12 + 31.13 +This program is distributed in the hope that it will be useful, 31.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 31.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31.16 +GNU Lesser General Public License for more details. 31.17 + 31.18 +You should have received a copy of the GNU Lesser General Public License 31.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 31.20 +*/ 31.21 + 31.22 +#ifndef VMATH_SPHVEC_H_ 31.23 +#define VMATH_SPHVEC_H_ 31.24 + 31.25 +#include "vmath_types.h" 31.26 + 31.27 +#ifdef __cplusplus 31.28 +/* Vector in spherical coordinates */ 31.29 +class SphVector { 31.30 +public: 31.31 + scalar_t theta, phi, r; 31.32 + 31.33 + SphVector(scalar_t theta = 0.0, scalar_t phi = 0.0, scalar_t r = 1.0); 31.34 + SphVector(const Vector3 &cvec); 31.35 + SphVector &operator =(const Vector3 &cvec); 31.36 +}; 31.37 +#endif /* __cplusplus */ 31.38 + 31.39 +#endif /* VMATH_SPHVEC_H_ */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/libs/vmath/vector.cc Sun Sep 29 08:20:19 2013 +0300 32.3 @@ -0,0 +1,326 @@ 32.4 +#include "vector.h" 32.5 +#include "vmath.h" 32.6 + 32.7 +// ---------- Vector2 ----------- 32.8 + 32.9 +Vector2::Vector2(scalar_t x, scalar_t y) 32.10 +{ 32.11 + this->x = x; 32.12 + this->y = y; 32.13 +} 32.14 + 32.15 +Vector2::Vector2(const vec2_t &vec) 32.16 +{ 32.17 + x = vec.x; 32.18 + y = vec.y; 32.19 +} 32.20 + 32.21 +Vector2::Vector2(const Vector3 &vec) 32.22 +{ 32.23 + x = vec.x; 32.24 + y = vec.y; 32.25 +} 32.26 + 32.27 +Vector2::Vector2(const Vector4 &vec) 32.28 +{ 32.29 + x = vec.x; 32.30 + y = vec.y; 32.31 +} 32.32 + 32.33 +void Vector2::normalize() 32.34 +{ 32.35 + scalar_t len = length(); 32.36 + x /= len; 32.37 + y /= len; 32.38 +} 32.39 + 32.40 +Vector2 Vector2::normalized() const 32.41 +{ 32.42 + scalar_t len = length(); 32.43 + return Vector2(x / len, y / len); 32.44 +} 32.45 + 32.46 +void Vector2::transform(const Matrix3x3 &mat) 32.47 +{ 32.48 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2]; 32.49 + y = mat[1][0] * x + mat[1][1] * y + mat[1][2]; 32.50 + x = nx; 32.51 +} 32.52 + 32.53 +Vector2 Vector2::transformed(const Matrix3x3 &mat) const 32.54 +{ 32.55 + Vector2 vec; 32.56 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2]; 32.57 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2]; 32.58 + return vec; 32.59 +} 32.60 + 32.61 +void Vector2::rotate(scalar_t angle) 32.62 +{ 32.63 + *this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y); 32.64 +} 32.65 + 32.66 +Vector2 Vector2::rotated(scalar_t angle) const 32.67 +{ 32.68 + return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y); 32.69 +} 32.70 + 32.71 +Vector2 Vector2::reflection(const Vector2 &normal) const 32.72 +{ 32.73 + return 2.0 * dot_product(*this, normal) * normal - *this; 32.74 +} 32.75 + 32.76 +Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const 32.77 +{ 32.78 + // quick and dirty implementation :) 32.79 + Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior); 32.80 + return Vector2(v3refr.x, v3refr.y); 32.81 +} 32.82 + 32.83 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec) 32.84 +{ 32.85 + out << "[" << vec.x << " " << vec.y << "]"; 32.86 + return out; 32.87 +} 32.88 + 32.89 + 32.90 + 32.91 +// --------- Vector3 ---------- 32.92 + 32.93 +Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z) 32.94 +{ 32.95 + this->x = x; 32.96 + this->y = y; 32.97 + this->z = z; 32.98 +} 32.99 + 32.100 +Vector3::Vector3(const vec3_t &vec) 32.101 +{ 32.102 + x = vec.x; 32.103 + y = vec.y; 32.104 + z = vec.z; 32.105 +} 32.106 + 32.107 +Vector3::Vector3(const Vector2 &vec) 32.108 +{ 32.109 + x = vec.x; 32.110 + y = vec.y; 32.111 + z = 1; 32.112 +} 32.113 + 32.114 +Vector3::Vector3(const Vector4 &vec) 32.115 +{ 32.116 + x = vec.x; 32.117 + y = vec.y; 32.118 + z = vec.z; 32.119 +} 32.120 + 32.121 +Vector3::Vector3(const SphVector &sph) 32.122 +{ 32.123 + *this = sph; 32.124 +} 32.125 + 32.126 +Vector3 &Vector3::operator =(const SphVector &sph) 32.127 +{ 32.128 + x = sph.r * cos(sph.theta) * sin(sph.phi); 32.129 + z = sph.r * sin(sph.theta) * sin(sph.phi); 32.130 + y = sph.r * cos(sph.phi); 32.131 + return *this; 32.132 +} 32.133 + 32.134 +void Vector3::normalize() 32.135 +{ 32.136 + scalar_t len = length(); 32.137 + x /= len; 32.138 + y /= len; 32.139 + z /= len; 32.140 +} 32.141 + 32.142 +Vector3 Vector3::normalized() const 32.143 +{ 32.144 + scalar_t len = length(); 32.145 + return Vector3(x / len, y / len, z / len); 32.146 +} 32.147 + 32.148 +Vector3 Vector3::reflection(const Vector3 &normal) const 32.149 +{ 32.150 + return 2.0 * dot_product(*this, normal) * normal - *this; 32.151 +} 32.152 + 32.153 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const 32.154 +{ 32.155 + return refraction(normal, src_ior / dst_ior); 32.156 +} 32.157 + 32.158 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const 32.159 +{ 32.160 + scalar_t cos_inc = dot_product(*this, -normal); 32.161 + 32.162 + scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0); 32.163 + 32.164 + if(radical < 0.0) { // total internal reflection 32.165 + return -reflection(normal); 32.166 + } 32.167 + 32.168 + scalar_t beta = ior * cos_inc - sqrt(radical); 32.169 + 32.170 + return *this * ior + normal * beta; 32.171 +} 32.172 + 32.173 +void Vector3::transform(const Matrix3x3 &mat) 32.174 +{ 32.175 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z; 32.176 + scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z; 32.177 + z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z; 32.178 + x = nx; 32.179 + y = ny; 32.180 +} 32.181 + 32.182 +Vector3 Vector3::transformed(const Matrix3x3 &mat) const 32.183 +{ 32.184 + Vector3 vec; 32.185 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z; 32.186 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z; 32.187 + vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z; 32.188 + return vec; 32.189 +} 32.190 + 32.191 +void Vector3::transform(const Matrix4x4 &mat) 32.192 +{ 32.193 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; 32.194 + scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; 32.195 + z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; 32.196 + x = nx; 32.197 + y = ny; 32.198 +} 32.199 + 32.200 +Vector3 Vector3::transformed(const Matrix4x4 &mat) const 32.201 +{ 32.202 + Vector3 vec; 32.203 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; 32.204 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; 32.205 + vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; 32.206 + return vec; 32.207 +} 32.208 + 32.209 +void Vector3::transform(const Quaternion &quat) 32.210 +{ 32.211 + Quaternion vq(0.0f, *this); 32.212 + vq = quat * vq * quat.inverse(); 32.213 + *this = vq.v; 32.214 +} 32.215 + 32.216 +Vector3 Vector3::transformed(const Quaternion &quat) const 32.217 +{ 32.218 + Quaternion vq(0.0f, *this); 32.219 + vq = quat * vq * quat.inverse(); 32.220 + return vq.v; 32.221 +} 32.222 + 32.223 +void Vector3::rotate(const Vector3 &euler) 32.224 +{ 32.225 + Matrix4x4 rot; 32.226 + rot.set_rotation(euler); 32.227 + transform(rot); 32.228 +} 32.229 + 32.230 +Vector3 Vector3::rotated(const Vector3 &euler) const 32.231 +{ 32.232 + Matrix4x4 rot; 32.233 + rot.set_rotation(euler); 32.234 + return transformed(rot); 32.235 +} 32.236 + 32.237 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec) 32.238 +{ 32.239 + out << "[" << vec.x << " " << vec.y << " " << vec.z << "]"; 32.240 + return out; 32.241 +} 32.242 + 32.243 + 32.244 +// -------------- Vector4 -------------- 32.245 +Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w) 32.246 +{ 32.247 + this->x = x; 32.248 + this->y = y; 32.249 + this->z = z; 32.250 + this->w = w; 32.251 +} 32.252 + 32.253 +Vector4::Vector4(const vec4_t &vec) 32.254 +{ 32.255 + x = vec.x; 32.256 + y = vec.y; 32.257 + z = vec.z; 32.258 + w = vec.w; 32.259 +} 32.260 + 32.261 +Vector4::Vector4(const Vector2 &vec) 32.262 +{ 32.263 + x = vec.x; 32.264 + y = vec.y; 32.265 + z = 1; 32.266 + w = 1; 32.267 +} 32.268 + 32.269 +Vector4::Vector4(const Vector3 &vec) 32.270 +{ 32.271 + x = vec.x; 32.272 + y = vec.y; 32.273 + z = vec.z; 32.274 + w = 1; 32.275 +} 32.276 + 32.277 +void Vector4::normalize() 32.278 +{ 32.279 + scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w); 32.280 + x /= len; 32.281 + y /= len; 32.282 + z /= len; 32.283 + w /= len; 32.284 +} 32.285 + 32.286 +Vector4 Vector4::normalized() const 32.287 +{ 32.288 + scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w); 32.289 + return Vector4(x / len, y / len, z / len, w / len); 32.290 +} 32.291 + 32.292 +void Vector4::transform(const Matrix4x4 &mat) 32.293 +{ 32.294 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w; 32.295 + scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w; 32.296 + scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w; 32.297 + w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w; 32.298 + x = nx; 32.299 + y = ny; 32.300 + z = nz; 32.301 +} 32.302 + 32.303 +Vector4 Vector4::transformed(const Matrix4x4 &mat) const 32.304 +{ 32.305 + Vector4 vec; 32.306 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w; 32.307 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w; 32.308 + vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w; 32.309 + vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w; 32.310 + return vec; 32.311 +} 32.312 + 32.313 +// TODO: implement 4D vector reflection 32.314 +Vector4 Vector4::reflection(const Vector4 &normal) const 32.315 +{ 32.316 + return *this; 32.317 +} 32.318 + 32.319 +// TODO: implement 4D vector refraction 32.320 +Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const 32.321 +{ 32.322 + return *this; 32.323 +} 32.324 + 32.325 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec) 32.326 +{ 32.327 + out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]"; 32.328 + return out; 32.329 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/libs/vmath/vector.h Sun Sep 29 08:20:19 2013 +0300 33.3 @@ -0,0 +1,292 @@ 33.4 +/* 33.5 +libvmath - a vector math library 33.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 33.7 + 33.8 +This program is free software: you can redistribute it and/or modify 33.9 +it under the terms of the GNU Lesser General Public License as published 33.10 +by the Free Software Foundation, either version 3 of the License, or 33.11 +(at your option) any later version. 33.12 + 33.13 +This program is distributed in the hope that it will be useful, 33.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 33.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33.16 +GNU Lesser General Public License for more details. 33.17 + 33.18 +You should have received a copy of the GNU Lesser General Public License 33.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 33.20 +*/ 33.21 + 33.22 +#ifndef VMATH_VECTOR_H_ 33.23 +#define VMATH_VECTOR_H_ 33.24 + 33.25 +#include <stdio.h> 33.26 +#include "vmath_types.h" 33.27 + 33.28 +#ifdef __cplusplus 33.29 +extern "C" { 33.30 +#endif /* __cplusplus */ 33.31 + 33.32 +/* C 2D vector functions */ 33.33 +static inline vec2_t v2_cons(scalar_t x, scalar_t y); 33.34 +static inline void v2_print(FILE *fp, vec2_t v); 33.35 + 33.36 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2); 33.37 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2); 33.38 +static inline vec2_t v2_scale(vec2_t v, scalar_t s); 33.39 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2); 33.40 +static inline scalar_t v2_length(vec2_t v); 33.41 +static inline scalar_t v2_length_sq(vec2_t v); 33.42 +static inline vec2_t v2_normalize(vec2_t v); 33.43 + 33.44 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t); 33.45 + 33.46 +/* C 3D vector functions */ 33.47 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z); 33.48 +static inline void v3_print(FILE *fp, vec3_t v); 33.49 + 33.50 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2); 33.51 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2); 33.52 +static inline vec3_t v3_neg(vec3_t v); 33.53 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2); 33.54 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s); 33.55 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2); 33.56 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2); 33.57 +static inline scalar_t v3_length(vec3_t v); 33.58 +static inline scalar_t v3_length_sq(vec3_t v); 33.59 +static inline vec3_t v3_normalize(vec3_t v); 33.60 +static inline vec3_t v3_transform(vec3_t v, mat4_t m); 33.61 + 33.62 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z); 33.63 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 33.64 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q); 33.65 + 33.66 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n); 33.67 + 33.68 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t); 33.69 + 33.70 +/* C 4D vector functions */ 33.71 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w); 33.72 +static inline void v4_print(FILE *fp, vec4_t v); 33.73 + 33.74 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2); 33.75 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2); 33.76 +static inline vec4_t v4_neg(vec4_t v); 33.77 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2); 33.78 +static inline vec4_t v4_scale(vec4_t v, scalar_t s); 33.79 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2); 33.80 +static inline scalar_t v4_length(vec4_t v); 33.81 +static inline scalar_t v4_length_sq(vec4_t v); 33.82 +static inline vec4_t v4_normalize(vec4_t v); 33.83 +static inline vec4_t v4_transform(vec4_t v, mat4_t m); 33.84 + 33.85 +#ifdef __cplusplus 33.86 +} /* extern "C" */ 33.87 + 33.88 +/* when included from C++ source files, also define the vector classes */ 33.89 +#include <iostream> 33.90 + 33.91 +/** 2D Vector */ 33.92 +class Vector2 { 33.93 +public: 33.94 + scalar_t x, y; 33.95 + 33.96 + Vector2(scalar_t x = 0.0, scalar_t y = 0.0); 33.97 + Vector2(const vec2_t &vec); 33.98 + Vector2(const Vector3 &vec); 33.99 + Vector2(const Vector4 &vec); 33.100 + 33.101 + inline scalar_t &operator [](int elem); 33.102 + inline const scalar_t &operator [](int elem) const; 33.103 + 33.104 + inline scalar_t length() const; 33.105 + inline scalar_t length_sq() const; 33.106 + void normalize(); 33.107 + Vector2 normalized() const; 33.108 + 33.109 + void transform(const Matrix3x3 &mat); 33.110 + Vector2 transformed(const Matrix3x3 &mat) const; 33.111 + 33.112 + void rotate(scalar_t angle); 33.113 + Vector2 rotated(scalar_t angle) const; 33.114 + 33.115 + Vector2 reflection(const Vector2 &normal) const; 33.116 + Vector2 refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const; 33.117 +}; 33.118 + 33.119 +/* unary operations */ 33.120 +inline Vector2 operator -(const Vector2 &vec); 33.121 + 33.122 +/* binary vector (op) vector operations */ 33.123 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2); 33.124 + 33.125 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2); 33.126 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2); 33.127 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2); 33.128 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2); 33.129 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2); 33.130 + 33.131 +inline void operator +=(Vector2 &v1, const Vector2 &v2); 33.132 +inline void operator -=(Vector2 &v1, const Vector2 &v2); 33.133 +inline void operator *=(Vector2 &v1, const Vector2 &v2); 33.134 +inline void operator /=(Vector2 &v1, const Vector2 &v2); 33.135 + 33.136 +/* binary vector (op) scalar and scalar (op) vector operations */ 33.137 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar); 33.138 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec); 33.139 +inline Vector2 operator -(const Vector2 &vec, scalar_t scalar); 33.140 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar); 33.141 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec); 33.142 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar); 33.143 + 33.144 +inline void operator +=(Vector2 &vec, scalar_t scalar); 33.145 +inline void operator -=(Vector2 &vec, scalar_t scalar); 33.146 +inline void operator *=(Vector2 &vec, scalar_t scalar); 33.147 +inline void operator /=(Vector2 &vec, scalar_t scalar); 33.148 + 33.149 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec); 33.150 + 33.151 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t); 33.152 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1, 33.153 + const Vector2 &v2, const Vector2 &v3, scalar_t t); 33.154 + 33.155 +/* 3D Vector */ 33.156 +class Vector3 { 33.157 +public: 33.158 + scalar_t x, y, z; 33.159 + 33.160 + Vector3(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0); 33.161 + Vector3(const vec3_t &vec); 33.162 + Vector3(const Vector2 &vec); 33.163 + Vector3(const Vector4 &vec); 33.164 + Vector3(const SphVector &sph); 33.165 + 33.166 + Vector3 &operator =(const SphVector &sph); 33.167 + 33.168 + inline scalar_t &operator [](int elem); 33.169 + inline const scalar_t &operator [](int elem) const; 33.170 + 33.171 + inline scalar_t length() const; 33.172 + inline scalar_t length_sq() const; 33.173 + void normalize(); 33.174 + Vector3 normalized() const; 33.175 + 33.176 + void transform(const Matrix3x3 &mat); 33.177 + Vector3 transformed(const Matrix3x3 &mat) const; 33.178 + void transform(const Matrix4x4 &mat); 33.179 + Vector3 transformed(const Matrix4x4 &mat) const; 33.180 + void transform(const Quaternion &quat); 33.181 + Vector3 transformed(const Quaternion &quat) const; 33.182 + 33.183 + void rotate(const Vector3 &euler); 33.184 + Vector3 rotated(const Vector3 &euler) const; 33.185 + 33.186 + Vector3 reflection(const Vector3 &normal) const; 33.187 + Vector3 refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const; 33.188 + Vector3 refraction(const Vector3 &normal, scalar_t ior) const; 33.189 +}; 33.190 + 33.191 +/* unary operations */ 33.192 +inline Vector3 operator -(const Vector3 &vec); 33.193 + 33.194 +/* binary vector (op) vector operations */ 33.195 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2); 33.196 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2); 33.197 + 33.198 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2); 33.199 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2); 33.200 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2); 33.201 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2); 33.202 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2); 33.203 + 33.204 +inline void operator +=(Vector3 &v1, const Vector3 &v2); 33.205 +inline void operator -=(Vector3 &v1, const Vector3 &v2); 33.206 +inline void operator *=(Vector3 &v1, const Vector3 &v2); 33.207 +inline void operator /=(Vector3 &v1, const Vector3 &v2); 33.208 + 33.209 +/* binary vector (op) scalar and scalar (op) vector operations */ 33.210 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar); 33.211 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec); 33.212 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar); 33.213 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar); 33.214 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec); 33.215 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar); 33.216 + 33.217 +inline void operator +=(Vector3 &vec, scalar_t scalar); 33.218 +inline void operator -=(Vector3 &vec, scalar_t scalar); 33.219 +inline void operator *=(Vector3 &vec, scalar_t scalar); 33.220 +inline void operator /=(Vector3 &vec, scalar_t scalar); 33.221 + 33.222 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec); 33.223 + 33.224 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t); 33.225 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1, 33.226 + const Vector3 &v2, const Vector3 &v3, scalar_t t); 33.227 + 33.228 +/* 4D Vector */ 33.229 +class Vector4 { 33.230 +public: 33.231 + scalar_t x, y, z, w; 33.232 + 33.233 + Vector4(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0, scalar_t w = 0.0); 33.234 + Vector4(const vec4_t &vec); 33.235 + Vector4(const Vector2 &vec); 33.236 + Vector4(const Vector3 &vec); 33.237 + 33.238 + inline scalar_t &operator [](int elem); 33.239 + inline const scalar_t &operator [](int elem) const; 33.240 + 33.241 + inline scalar_t length() const; 33.242 + inline scalar_t length_sq() const; 33.243 + void normalize(); 33.244 + Vector4 normalized() const; 33.245 + 33.246 + void transform(const Matrix4x4 &mat); 33.247 + Vector4 transformed(const Matrix4x4 &mat) const; 33.248 + 33.249 + Vector4 reflection(const Vector4 &normal) const; 33.250 + Vector4 refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const; 33.251 +}; 33.252 + 33.253 + 33.254 +/* unary operations */ 33.255 +inline Vector4 operator -(const Vector4 &vec); 33.256 + 33.257 +/* binary vector (op) vector operations */ 33.258 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2); 33.259 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3); 33.260 + 33.261 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2); 33.262 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2); 33.263 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2); 33.264 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2); 33.265 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2); 33.266 + 33.267 +inline void operator +=(Vector4 &v1, const Vector4 &v2); 33.268 +inline void operator -=(Vector4 &v1, const Vector4 &v2); 33.269 +inline void operator *=(Vector4 &v1, const Vector4 &v2); 33.270 +inline void operator /=(Vector4 &v1, const Vector4 &v2); 33.271 + 33.272 +/* binary vector (op) scalar and scalar (op) vector operations */ 33.273 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar); 33.274 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec); 33.275 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar); 33.276 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar); 33.277 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec); 33.278 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar); 33.279 + 33.280 +inline void operator +=(Vector4 &vec, scalar_t scalar); 33.281 +inline void operator -=(Vector4 &vec, scalar_t scalar); 33.282 +inline void operator *=(Vector4 &vec, scalar_t scalar); 33.283 +inline void operator /=(Vector4 &vec, scalar_t scalar); 33.284 + 33.285 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec); 33.286 + 33.287 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t); 33.288 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1, 33.289 + const Vector4 &v2, const Vector4 &v3, scalar_t t); 33.290 + 33.291 +#endif /* __cplusplus */ 33.292 + 33.293 +#include "vector.inl" 33.294 + 33.295 +#endif /* VMATH_VECTOR_H_ */
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/libs/vmath/vector.inl Sun Sep 29 08:20:19 2013 +0300 34.3 @@ -0,0 +1,761 @@ 34.4 +/* 34.5 +libvmath - a vector math library 34.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 34.7 + 34.8 +This program is free software: you can redistribute it and/or modify 34.9 +it under the terms of the GNU Lesser General Public License as published 34.10 +by the Free Software Foundation, either version 3 of the License, or 34.11 +(at your option) any later version. 34.12 + 34.13 +This program is distributed in the hope that it will be useful, 34.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 34.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34.16 +GNU Lesser General Public License for more details. 34.17 + 34.18 +You should have received a copy of the GNU Lesser General Public License 34.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 34.20 +*/ 34.21 + 34.22 +#include <math.h> 34.23 + 34.24 +#ifdef __cplusplus 34.25 +extern "C" { 34.26 +#endif /* __cplusplus */ 34.27 + 34.28 +/* C 2D vector functions */ 34.29 +static inline vec2_t v2_cons(scalar_t x, scalar_t y) 34.30 +{ 34.31 + vec2_t v; 34.32 + v.x = x; 34.33 + v.y = y; 34.34 + return v; 34.35 +} 34.36 + 34.37 +static inline void v2_print(FILE *fp, vec2_t v) 34.38 +{ 34.39 + fprintf(fp, "[ %.4f %.4f ]", v.x, v.y); 34.40 +} 34.41 + 34.42 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2) 34.43 +{ 34.44 + vec2_t res; 34.45 + res.x = v1.x + v2.x; 34.46 + res.y = v1.y + v2.y; 34.47 + return res; 34.48 +} 34.49 + 34.50 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2) 34.51 +{ 34.52 + vec2_t res; 34.53 + res.x = v1.x - v2.x; 34.54 + res.y = v1.y - v2.y; 34.55 + return res; 34.56 +} 34.57 + 34.58 +static inline vec2_t v2_scale(vec2_t v, scalar_t s) 34.59 +{ 34.60 + vec2_t res; 34.61 + res.x = v.x * s; 34.62 + res.y = v.y * s; 34.63 + return res; 34.64 +} 34.65 + 34.66 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2) 34.67 +{ 34.68 + return v1.x * v2.x + v1.y * v2.y; 34.69 +} 34.70 + 34.71 +static inline scalar_t v2_length(vec2_t v) 34.72 +{ 34.73 + return sqrt(v.x * v.x + v.y * v.y); 34.74 +} 34.75 + 34.76 +static inline scalar_t v2_length_sq(vec2_t v) 34.77 +{ 34.78 + return v.x * v.x + v.y * v.y; 34.79 +} 34.80 + 34.81 +static inline vec2_t v2_normalize(vec2_t v) 34.82 +{ 34.83 + scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y); 34.84 + v.x /= len; 34.85 + v.y /= len; 34.86 + return v; 34.87 +} 34.88 + 34.89 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t) 34.90 +{ 34.91 + vec2_t res; 34.92 + res.x = v1.x + (v2.x - v1.x) * t; 34.93 + res.y = v1.y + (v2.y - v1.y) * t; 34.94 + return res; 34.95 +} 34.96 + 34.97 + 34.98 +/* C 3D vector functions */ 34.99 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z) 34.100 +{ 34.101 + vec3_t v; 34.102 + v.x = x; 34.103 + v.y = y; 34.104 + v.z = z; 34.105 + return v; 34.106 +} 34.107 + 34.108 +static inline void v3_print(FILE *fp, vec3_t v) 34.109 +{ 34.110 + fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z); 34.111 +} 34.112 + 34.113 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2) 34.114 +{ 34.115 + v1.x += v2.x; 34.116 + v1.y += v2.y; 34.117 + v1.z += v2.z; 34.118 + return v1; 34.119 +} 34.120 + 34.121 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2) 34.122 +{ 34.123 + v1.x -= v2.x; 34.124 + v1.y -= v2.y; 34.125 + v1.z -= v2.z; 34.126 + return v1; 34.127 +} 34.128 + 34.129 +static inline vec3_t v3_neg(vec3_t v) 34.130 +{ 34.131 + v.x = -v.x; 34.132 + v.y = -v.y; 34.133 + v.z = -v.z; 34.134 + return v; 34.135 +} 34.136 + 34.137 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2) 34.138 +{ 34.139 + v1.x *= v2.x; 34.140 + v1.y *= v2.y; 34.141 + v1.z *= v2.z; 34.142 + return v1; 34.143 +} 34.144 + 34.145 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s) 34.146 +{ 34.147 + v1.x *= s; 34.148 + v1.y *= s; 34.149 + v1.z *= s; 34.150 + return v1; 34.151 +} 34.152 + 34.153 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2) 34.154 +{ 34.155 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 34.156 +} 34.157 + 34.158 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2) 34.159 +{ 34.160 + vec3_t v; 34.161 + v.x = v1.y * v2.z - v1.z * v2.y; 34.162 + v.y = v1.z * v2.x - v1.x * v2.z; 34.163 + v.z = v1.x * v2.y - v1.y * v2.x; 34.164 + return v; 34.165 +} 34.166 + 34.167 +static inline scalar_t v3_length(vec3_t v) 34.168 +{ 34.169 + return sqrt(v.x * v.x + v.y * v.y + v.z * v.z); 34.170 +} 34.171 + 34.172 +static inline scalar_t v3_length_sq(vec3_t v) 34.173 +{ 34.174 + return v.x * v.x + v.y * v.y + v.z * v.z; 34.175 +} 34.176 + 34.177 +static inline vec3_t v3_normalize(vec3_t v) 34.178 +{ 34.179 + scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); 34.180 + v.x /= len; 34.181 + v.y /= len; 34.182 + v.z /= len; 34.183 + return v; 34.184 +} 34.185 + 34.186 +static inline vec3_t v3_transform(vec3_t v, mat4_t m) 34.187 +{ 34.188 + vec3_t res; 34.189 + res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3]; 34.190 + res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3]; 34.191 + res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]; 34.192 + return res; 34.193 +} 34.194 + 34.195 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z) 34.196 +{ 34.197 + void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t); 34.198 + 34.199 + mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; 34.200 + m4_rotate(m, x, y, z); 34.201 + return v3_transform(v, m); 34.202 +} 34.203 + 34.204 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 34.205 +{ 34.206 + void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t); 34.207 + 34.208 + mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; 34.209 + m4_rotate_axis(m, angle, x, y, z); 34.210 + return v3_transform(v, m); 34.211 +} 34.212 + 34.213 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q) 34.214 +{ 34.215 + quat_t quat_rotate_quat(quat_t, quat_t); 34.216 + 34.217 + quat_t vq = v4_cons(v.x, v.y, v.z, 0.0); 34.218 + quat_t res = quat_rotate_quat(vq, q); 34.219 + return v3_cons(res.x, res.y, res.z); 34.220 +} 34.221 + 34.222 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n) 34.223 +{ 34.224 + scalar_t dot = v3_dot(v, n); 34.225 + return v3_sub(v3_scale(n, dot * 2.0), v); 34.226 +} 34.227 + 34.228 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t) 34.229 +{ 34.230 + v1.x += (v2.x - v1.x) * t; 34.231 + v1.y += (v2.y - v1.y) * t; 34.232 + v1.z += (v2.z - v1.z) * t; 34.233 + return v1; 34.234 +} 34.235 + 34.236 +/* C 4D vector functions */ 34.237 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w) 34.238 +{ 34.239 + vec4_t v; 34.240 + v.x = x; 34.241 + v.y = y; 34.242 + v.z = z; 34.243 + v.w = w; 34.244 + return v; 34.245 +} 34.246 + 34.247 +static inline void v4_print(FILE *fp, vec4_t v) 34.248 +{ 34.249 + fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w); 34.250 +} 34.251 + 34.252 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2) 34.253 +{ 34.254 + v1.x += v2.x; 34.255 + v1.y += v2.y; 34.256 + v1.z += v2.z; 34.257 + v1.w += v2.w; 34.258 + return v1; 34.259 +} 34.260 + 34.261 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2) 34.262 +{ 34.263 + v1.x -= v2.x; 34.264 + v1.y -= v2.y; 34.265 + v1.z -= v2.z; 34.266 + v1.w -= v2.w; 34.267 + return v1; 34.268 +} 34.269 + 34.270 +static inline vec4_t v4_neg(vec4_t v) 34.271 +{ 34.272 + v.x = -v.x; 34.273 + v.y = -v.y; 34.274 + v.z = -v.z; 34.275 + v.w = -v.w; 34.276 + return v; 34.277 +} 34.278 + 34.279 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2) 34.280 +{ 34.281 + v1.x *= v2.x; 34.282 + v1.y *= v2.y; 34.283 + v1.z *= v2.z; 34.284 + v1.w *= v2.w; 34.285 + return v1; 34.286 +} 34.287 + 34.288 +static inline vec4_t v4_scale(vec4_t v, scalar_t s) 34.289 +{ 34.290 + v.x *= s; 34.291 + v.y *= s; 34.292 + v.z *= s; 34.293 + v.w *= s; 34.294 + return v; 34.295 +} 34.296 + 34.297 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2) 34.298 +{ 34.299 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; 34.300 +} 34.301 + 34.302 +static inline scalar_t v4_length(vec4_t v) 34.303 +{ 34.304 + return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); 34.305 +} 34.306 + 34.307 +static inline scalar_t v4_length_sq(vec4_t v) 34.308 +{ 34.309 + return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; 34.310 +} 34.311 + 34.312 +static inline vec4_t v4_normalize(vec4_t v) 34.313 +{ 34.314 + scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); 34.315 + v.x /= len; 34.316 + v.y /= len; 34.317 + v.z /= len; 34.318 + v.w /= len; 34.319 + return v; 34.320 +} 34.321 + 34.322 +static inline vec4_t v4_transform(vec4_t v, mat4_t m) 34.323 +{ 34.324 + vec4_t res; 34.325 + res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w; 34.326 + res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w; 34.327 + res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w; 34.328 + res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w; 34.329 + return res; 34.330 +} 34.331 + 34.332 +#ifdef __cplusplus 34.333 +} /* extern "C" */ 34.334 + 34.335 + 34.336 +/* --------------- C++ part -------------- */ 34.337 + 34.338 +inline scalar_t &Vector2::operator [](int elem) { 34.339 + return elem ? y : x; 34.340 +} 34.341 + 34.342 +inline const scalar_t &Vector2::operator [](int elem) const { 34.343 + return elem ? y : x; 34.344 +} 34.345 + 34.346 +inline Vector2 operator -(const Vector2 &vec) { 34.347 + return Vector2(-vec.x, -vec.y); 34.348 +} 34.349 + 34.350 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2) { 34.351 + return v1.x * v2.x + v1.y * v2.y; 34.352 +} 34.353 + 34.354 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2) { 34.355 + return Vector2(v1.x + v2.x, v1.y + v2.y); 34.356 +} 34.357 + 34.358 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2) { 34.359 + return Vector2(v1.x - v2.x, v1.y - v2.y); 34.360 +} 34.361 + 34.362 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2) { 34.363 + return Vector2(v1.x * v2.x, v1.y * v2.y); 34.364 +} 34.365 + 34.366 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2) { 34.367 + return Vector2(v1.x / v2.x, v1.y / v2.y); 34.368 +} 34.369 + 34.370 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2) { 34.371 + return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER); 34.372 +} 34.373 + 34.374 +inline void operator +=(Vector2 &v1, const Vector2 &v2) { 34.375 + v1.x += v2.x; 34.376 + v1.y += v2.y; 34.377 +} 34.378 + 34.379 +inline void operator -=(Vector2 &v1, const Vector2 &v2) { 34.380 + v1.x -= v2.x; 34.381 + v1.y -= v2.y; 34.382 +} 34.383 + 34.384 +inline void operator *=(Vector2 &v1, const Vector2 &v2) { 34.385 + v1.x *= v2.x; 34.386 + v1.y *= v2.y; 34.387 +} 34.388 + 34.389 +inline void operator /=(Vector2 &v1, const Vector2 &v2) { 34.390 + v1.x /= v2.x; 34.391 + v1.y /= v2.y; 34.392 +} 34.393 + 34.394 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar) { 34.395 + return Vector2(vec.x + scalar, vec.y + scalar); 34.396 +} 34.397 + 34.398 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec) { 34.399 + return Vector2(vec.x + scalar, vec.y + scalar); 34.400 +} 34.401 + 34.402 +inline Vector2 operator -(scalar_t scalar, const Vector2 &vec) { 34.403 + return Vector2(vec.x - scalar, vec.y - scalar); 34.404 +} 34.405 + 34.406 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar) { 34.407 + return Vector2(vec.x * scalar, vec.y * scalar); 34.408 +} 34.409 + 34.410 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec) { 34.411 + return Vector2(vec.x * scalar, vec.y * scalar); 34.412 +} 34.413 + 34.414 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar) { 34.415 + return Vector2(vec.x / scalar, vec.y / scalar); 34.416 +} 34.417 + 34.418 +inline void operator +=(Vector2 &vec, scalar_t scalar) { 34.419 + vec.x += scalar; 34.420 + vec.y += scalar; 34.421 +} 34.422 + 34.423 +inline void operator -=(Vector2 &vec, scalar_t scalar) { 34.424 + vec.x -= scalar; 34.425 + vec.y -= scalar; 34.426 +} 34.427 + 34.428 +inline void operator *=(Vector2 &vec, scalar_t scalar) { 34.429 + vec.x *= scalar; 34.430 + vec.y *= scalar; 34.431 +} 34.432 + 34.433 +inline void operator /=(Vector2 &vec, scalar_t scalar) { 34.434 + vec.x /= scalar; 34.435 + vec.y /= scalar; 34.436 +} 34.437 + 34.438 +inline scalar_t Vector2::length() const { 34.439 + return sqrt(x*x + y*y); 34.440 +} 34.441 + 34.442 +inline scalar_t Vector2::length_sq() const { 34.443 + return x*x + y*y; 34.444 +} 34.445 + 34.446 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t) 34.447 +{ 34.448 + return a + (b - a) * t; 34.449 +} 34.450 + 34.451 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1, 34.452 + const Vector2 &v2, const Vector2 &v3, scalar_t t) 34.453 +{ 34.454 + scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); 34.455 + scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); 34.456 + scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); 34.457 + return Vector2(x, y); 34.458 +} 34.459 + 34.460 + 34.461 +/* ------------- Vector3 -------------- */ 34.462 + 34.463 +inline scalar_t &Vector3::operator [](int elem) { 34.464 + return elem ? (elem == 1 ? y : z) : x; 34.465 +} 34.466 + 34.467 +inline const scalar_t &Vector3::operator [](int elem) const { 34.468 + return elem ? (elem == 1 ? y : z) : x; 34.469 +} 34.470 + 34.471 +/* unary operations */ 34.472 +inline Vector3 operator -(const Vector3 &vec) { 34.473 + return Vector3(-vec.x, -vec.y, -vec.z); 34.474 +} 34.475 + 34.476 +/* binary vector (op) vector operations */ 34.477 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) { 34.478 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 34.479 +} 34.480 + 34.481 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) { 34.482 + 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); 34.483 +} 34.484 + 34.485 + 34.486 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2) { 34.487 + return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); 34.488 +} 34.489 + 34.490 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2) { 34.491 + return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); 34.492 +} 34.493 + 34.494 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2) { 34.495 + return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); 34.496 +} 34.497 + 34.498 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2) { 34.499 + return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); 34.500 +} 34.501 + 34.502 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2) { 34.503 + return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER); 34.504 +} 34.505 + 34.506 +inline void operator +=(Vector3 &v1, const Vector3 &v2) { 34.507 + v1.x += v2.x; 34.508 + v1.y += v2.y; 34.509 + v1.z += v2.z; 34.510 +} 34.511 + 34.512 +inline void operator -=(Vector3 &v1, const Vector3 &v2) { 34.513 + v1.x -= v2.x; 34.514 + v1.y -= v2.y; 34.515 + v1.z -= v2.z; 34.516 +} 34.517 + 34.518 +inline void operator *=(Vector3 &v1, const Vector3 &v2) { 34.519 + v1.x *= v2.x; 34.520 + v1.y *= v2.y; 34.521 + v1.z *= v2.z; 34.522 +} 34.523 + 34.524 +inline void operator /=(Vector3 &v1, const Vector3 &v2) { 34.525 + v1.x /= v2.x; 34.526 + v1.y /= v2.y; 34.527 + v1.z /= v2.z; 34.528 +} 34.529 +/* binary vector (op) scalar and scalar (op) vector operations */ 34.530 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar) { 34.531 + return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar); 34.532 +} 34.533 + 34.534 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec) { 34.535 + return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar); 34.536 +} 34.537 + 34.538 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar) { 34.539 + return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar); 34.540 +} 34.541 + 34.542 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar) { 34.543 + return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar); 34.544 +} 34.545 + 34.546 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec) { 34.547 + return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar); 34.548 +} 34.549 + 34.550 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar) { 34.551 + return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar); 34.552 +} 34.553 + 34.554 +inline void operator +=(Vector3 &vec, scalar_t scalar) { 34.555 + vec.x += scalar; 34.556 + vec.y += scalar; 34.557 + vec.z += scalar; 34.558 +} 34.559 + 34.560 +inline void operator -=(Vector3 &vec, scalar_t scalar) { 34.561 + vec.x -= scalar; 34.562 + vec.y -= scalar; 34.563 + vec.z -= scalar; 34.564 +} 34.565 + 34.566 +inline void operator *=(Vector3 &vec, scalar_t scalar) { 34.567 + vec.x *= scalar; 34.568 + vec.y *= scalar; 34.569 + vec.z *= scalar; 34.570 +} 34.571 + 34.572 +inline void operator /=(Vector3 &vec, scalar_t scalar) { 34.573 + vec.x /= scalar; 34.574 + vec.y /= scalar; 34.575 + vec.z /= scalar; 34.576 +} 34.577 + 34.578 +inline scalar_t Vector3::length() const { 34.579 + return sqrt(x*x + y*y + z*z); 34.580 +} 34.581 +inline scalar_t Vector3::length_sq() const { 34.582 + return x*x + y*y + z*z; 34.583 +} 34.584 + 34.585 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) { 34.586 + return a + (b - a) * t; 34.587 +} 34.588 + 34.589 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1, 34.590 + const Vector3 &v2, const Vector3 &v3, scalar_t t) 34.591 +{ 34.592 + scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); 34.593 + scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); 34.594 + scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); 34.595 + scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t); 34.596 + return Vector3(x, y, z); 34.597 +} 34.598 + 34.599 +/* ----------- Vector4 ----------------- */ 34.600 + 34.601 +inline scalar_t &Vector4::operator [](int elem) { 34.602 + return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x; 34.603 +} 34.604 + 34.605 +inline const scalar_t &Vector4::operator [](int elem) const { 34.606 + return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x; 34.607 +} 34.608 + 34.609 +inline Vector4 operator -(const Vector4 &vec) { 34.610 + return Vector4(-vec.x, -vec.y, -vec.z, -vec.w); 34.611 +} 34.612 + 34.613 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) { 34.614 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; 34.615 +} 34.616 + 34.617 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) { 34.618 + scalar_t a, b, c, d, e, f; /* Intermediate Values */ 34.619 + Vector4 result; 34.620 + 34.621 + /* Calculate intermediate values. */ 34.622 + a = (v2.x * v3.y) - (v2.y * v3.x); 34.623 + b = (v2.x * v3.z) - (v2.z * v3.x); 34.624 + c = (v2.x * v3.w) - (v2.w * v3.x); 34.625 + d = (v2.y * v3.z) - (v2.z * v3.y); 34.626 + e = (v2.y * v3.w) - (v2.w * v3.y); 34.627 + f = (v2.z * v3.w) - (v2.w * v3.z); 34.628 + 34.629 + /* Calculate the result-vector components. */ 34.630 + result.x = (v1.y * f) - (v1.z * e) + (v1.w * d); 34.631 + result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b); 34.632 + result.z = (v1.x * e) - (v1.y * c) + (v1.w * a); 34.633 + result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a); 34.634 + return result; 34.635 +} 34.636 + 34.637 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2) { 34.638 + return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); 34.639 +} 34.640 + 34.641 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2) { 34.642 + return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); 34.643 +} 34.644 + 34.645 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2) { 34.646 + return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w); 34.647 +} 34.648 + 34.649 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2) { 34.650 + return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w); 34.651 +} 34.652 + 34.653 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2) { 34.654 + return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && 34.655 + (fabs(v1.y - v2.y) < XSMALL_NUMBER) && 34.656 + (fabs(v1.z - v2.z) < XSMALL_NUMBER) && 34.657 + (fabs(v1.w - v2.w) < XSMALL_NUMBER); 34.658 +} 34.659 + 34.660 +inline void operator +=(Vector4 &v1, const Vector4 &v2) { 34.661 + v1.x += v2.x; 34.662 + v1.y += v2.y; 34.663 + v1.z += v2.z; 34.664 + v1.w += v2.w; 34.665 +} 34.666 + 34.667 +inline void operator -=(Vector4 &v1, const Vector4 &v2) { 34.668 + v1.x -= v2.x; 34.669 + v1.y -= v2.y; 34.670 + v1.z -= v2.z; 34.671 + v1.w -= v2.w; 34.672 +} 34.673 + 34.674 +inline void operator *=(Vector4 &v1, const Vector4 &v2) { 34.675 + v1.x *= v2.x; 34.676 + v1.y *= v2.y; 34.677 + v1.z *= v2.z; 34.678 + v1.w *= v2.w; 34.679 +} 34.680 + 34.681 +inline void operator /=(Vector4 &v1, const Vector4 &v2) { 34.682 + v1.x /= v2.x; 34.683 + v1.y /= v2.y; 34.684 + v1.z /= v2.z; 34.685 + v1.w /= v2.w; 34.686 +} 34.687 + 34.688 +/* binary vector (op) scalar and scalar (op) vector operations */ 34.689 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar) { 34.690 + return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar); 34.691 +} 34.692 + 34.693 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec) { 34.694 + return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar); 34.695 +} 34.696 + 34.697 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar) { 34.698 + return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar); 34.699 +} 34.700 + 34.701 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar) { 34.702 + return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar); 34.703 +} 34.704 + 34.705 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec) { 34.706 + return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar); 34.707 +} 34.708 + 34.709 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar) { 34.710 + return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar); 34.711 +} 34.712 + 34.713 +inline void operator +=(Vector4 &vec, scalar_t scalar) { 34.714 + vec.x += scalar; 34.715 + vec.y += scalar; 34.716 + vec.z += scalar; 34.717 + vec.w += scalar; 34.718 +} 34.719 + 34.720 +inline void operator -=(Vector4 &vec, scalar_t scalar) { 34.721 + vec.x -= scalar; 34.722 + vec.y -= scalar; 34.723 + vec.z -= scalar; 34.724 + vec.w -= scalar; 34.725 +} 34.726 + 34.727 +inline void operator *=(Vector4 &vec, scalar_t scalar) { 34.728 + vec.x *= scalar; 34.729 + vec.y *= scalar; 34.730 + vec.z *= scalar; 34.731 + vec.w *= scalar; 34.732 +} 34.733 + 34.734 +inline void operator /=(Vector4 &vec, scalar_t scalar) { 34.735 + vec.x /= scalar; 34.736 + vec.y /= scalar; 34.737 + vec.z /= scalar; 34.738 + vec.w /= scalar; 34.739 +} 34.740 + 34.741 +inline scalar_t Vector4::length() const { 34.742 + return sqrt(x*x + y*y + z*z + w*w); 34.743 +} 34.744 +inline scalar_t Vector4::length_sq() const { 34.745 + return x*x + y*y + z*z + w*w; 34.746 +} 34.747 + 34.748 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t) 34.749 +{ 34.750 + return v0 + (v1 - v0) * t; 34.751 +} 34.752 + 34.753 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1, 34.754 + const Vector4 &v2, const Vector4 &v3, scalar_t t) 34.755 +{ 34.756 + scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); 34.757 + scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); 34.758 + scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); 34.759 + scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t); 34.760 + scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t); 34.761 + return Vector4(x, y, z, w); 34.762 +} 34.763 + 34.764 +#endif /* __cplusplus */
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/libs/vmath/vmath.c Sun Sep 29 08:20:19 2013 +0300 35.3 @@ -0,0 +1,336 @@ 35.4 +/* 35.5 +libvmath - a vector math library 35.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 35.7 + 35.8 +This program is free software: you can redistribute it and/or modify 35.9 +it under the terms of the GNU Lesser General Public License as published 35.10 +by the Free Software Foundation, either version 3 of the License, or 35.11 +(at your option) any later version. 35.12 + 35.13 +This program is distributed in the hope that it will be useful, 35.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 35.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35.16 +GNU Lesser General Public License for more details. 35.17 + 35.18 +You should have received a copy of the GNU Lesser General Public License 35.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 35.20 +*/ 35.21 + 35.22 +#include <stdlib.h> 35.23 +#include <math.h> 35.24 +#include "vmath.h" 35.25 + 35.26 +/** Numerical calculation of integrals using simpson's rule */ 35.27 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples) 35.28 +{ 35.29 + int i; 35.30 + scalar_t h = (high - low) / (scalar_t)samples; 35.31 + scalar_t sum = 0.0; 35.32 + 35.33 + for(i=0; i<samples+1; i++) { 35.34 + scalar_t y = f((scalar_t)i * h + low); 35.35 + sum += ((!i || i == samples) ? y : ((i % 2) ? 4.0 * y : 2.0 * y)) * (h / 3.0); 35.36 + } 35.37 + return sum; 35.38 +} 35.39 + 35.40 +/** Gaussuan function */ 35.41 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev) 35.42 +{ 35.43 + scalar_t exponent = -SQ(x - mean) / (2.0 * SQ(sdev)); 35.44 + return 1.0 - -pow(M_E, exponent) / (sdev * sqrt(TWO_PI)); 35.45 +} 35.46 + 35.47 + 35.48 +/** b-spline approximation */ 35.49 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) 35.50 +{ 35.51 + vec4_t tmp; 35.52 + scalar_t tsq = t * t; 35.53 + 35.54 + static mat4_t bspline_mat = { 35.55 + {-1, 3, -3, 1}, 35.56 + {3, -6, 3, 0}, 35.57 + {-3, 0, 3, 0}, 35.58 + {1, 4, 1, 0} 35.59 + }; 35.60 + 35.61 + tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), bspline_mat), 1.0 / 6.0); 35.62 + return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp); 35.63 +} 35.64 + 35.65 +/** Catmull-rom spline interpolation */ 35.66 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) 35.67 +{ 35.68 + vec4_t tmp; 35.69 + scalar_t tsq = t * t; 35.70 + 35.71 + static mat4_t crspline_mat = { 35.72 + {-1, 3, -3, 1}, 35.73 + {2, -5, 4, -1}, 35.74 + {-1, 0, 1, 0}, 35.75 + {0, 2, 0, 0} 35.76 + }; 35.77 + 35.78 + tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), crspline_mat), 0.5); 35.79 + return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp); 35.80 +} 35.81 + 35.82 +/** Bezier interpolation */ 35.83 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) 35.84 +{ 35.85 + scalar_t omt, omt3, t3, f; 35.86 + t3 = t * t * t; 35.87 + omt = 1.0f - t; 35.88 + omt3 = omt * omt * omt; 35.89 + f = 3 * t * omt; 35.90 + 35.91 + return (a * omt3) + (b * f * omt) + (c * f * t) + (d * t3); 35.92 +} 35.93 + 35.94 +/* ---- Ken Perlin's implementation of noise ---- */ 35.95 + 35.96 +#define B 0x100 35.97 +#define BM 0xff 35.98 +#define N 0x1000 35.99 +#define NP 12 /* 2^N */ 35.100 +#define NM 0xfff 35.101 + 35.102 +#define s_curve(t) (t * t * (3.0f - 2.0f * t)) 35.103 + 35.104 +#define setup(elem, b0, b1, r0, r1) \ 35.105 + do { \ 35.106 + scalar_t t = elem + N; \ 35.107 + b0 = ((int)t) & BM; \ 35.108 + b1 = (b0 + 1) & BM; \ 35.109 + r0 = t - (int)t; \ 35.110 + r1 = r0 - 1.0f; \ 35.111 + } while(0) 35.112 + 35.113 + 35.114 +static int perm[B + B + 2]; /* permuted index from g_n onto themselves */ 35.115 +static vec3_t grad3[B + B + 2]; /* 3D random gradients */ 35.116 +static vec2_t grad2[B + B + 2]; /* 2D random gradients */ 35.117 +static scalar_t grad1[B + B + 2]; /* 1D random ... slopes */ 35.118 +static int tables_valid; 35.119 + 35.120 +static void init_noise() 35.121 +{ 35.122 + int i; 35.123 + 35.124 + /* calculate random gradients */ 35.125 + for(i=0; i<B; i++) { 35.126 + perm[i] = i; /* .. and initialize permutation mapping to identity */ 35.127 + 35.128 + grad1[i] = (scalar_t)((rand() % (B + B)) - B) / B; 35.129 + 35.130 + grad2[i].x = (scalar_t)((rand() % (B + B)) - B) / B; 35.131 + grad2[i].y = (scalar_t)((rand() % (B + B)) - B) / B; 35.132 + grad2[i] = v2_normalize(grad2[i]); 35.133 + 35.134 + grad3[i].x = (scalar_t)((rand() % (B + B)) - B) / B; 35.135 + grad3[i].y = (scalar_t)((rand() % (B + B)) - B) / B; 35.136 + grad3[i].z = (scalar_t)((rand() % (B + B)) - B) / B; 35.137 + grad3[i] = v3_normalize(grad3[i]); 35.138 + } 35.139 + 35.140 + /* permute indices by swapping them randomly */ 35.141 + for(i=0; i<B; i++) { 35.142 + int rand_idx = rand() % B; 35.143 + 35.144 + int tmp = perm[i]; 35.145 + perm[i] = perm[rand_idx]; 35.146 + perm[rand_idx] = tmp; 35.147 + } 35.148 + 35.149 + /* fill up the rest of the arrays by duplicating the existing gradients */ 35.150 + /* and permutations */ 35.151 + for(i=0; i<B+2; i++) { 35.152 + perm[B + i] = perm[i]; 35.153 + grad1[B + i] = grad1[i]; 35.154 + grad2[B + i] = grad2[i]; 35.155 + grad3[B + i] = grad3[i]; 35.156 + } 35.157 +} 35.158 + 35.159 +scalar_t noise1(scalar_t x) 35.160 +{ 35.161 + int bx0, bx1; 35.162 + scalar_t rx0, rx1, sx, u, v; 35.163 + 35.164 + if(!tables_valid) { 35.165 + init_noise(); 35.166 + tables_valid = 1; 35.167 + } 35.168 + 35.169 + setup(x, bx0, bx1, rx0, rx1); 35.170 + sx = s_curve(rx0); 35.171 + u = rx0 * grad1[perm[bx0]]; 35.172 + v = rx1 * grad1[perm[bx1]]; 35.173 + 35.174 + return lerp(u, v, sx); 35.175 +} 35.176 + 35.177 +scalar_t noise2(scalar_t x, scalar_t y) 35.178 +{ 35.179 + int i, j, b00, b10, b01, b11; 35.180 + int bx0, bx1, by0, by1; 35.181 + scalar_t rx0, rx1, ry0, ry1; 35.182 + scalar_t sx, sy, u, v, a, b; 35.183 + 35.184 + if(!tables_valid) { 35.185 + init_noise(); 35.186 + tables_valid = 1; 35.187 + } 35.188 + 35.189 + setup(x, bx0, bx1, rx0, rx1); 35.190 + setup(y, by0, by1, ry0, ry1); 35.191 + 35.192 + i = perm[bx0]; 35.193 + j = perm[bx1]; 35.194 + 35.195 + b00 = perm[i + by0]; 35.196 + b10 = perm[j + by0]; 35.197 + b01 = perm[i + by1]; 35.198 + b11 = perm[j + by1]; 35.199 + 35.200 + /* calculate hermite inteprolating factors */ 35.201 + sx = s_curve(rx0); 35.202 + sy = s_curve(ry0); 35.203 + 35.204 + /* interpolate along the left edge */ 35.205 + u = v2_dot(grad2[b00], v2_cons(rx0, ry0)); 35.206 + v = v2_dot(grad2[b10], v2_cons(rx1, ry0)); 35.207 + a = lerp(u, v, sx); 35.208 + 35.209 + /* interpolate along the right edge */ 35.210 + u = v2_dot(grad2[b01], v2_cons(rx0, ry1)); 35.211 + v = v2_dot(grad2[b11], v2_cons(rx1, ry1)); 35.212 + b = lerp(u, v, sx); 35.213 + 35.214 + /* interpolate between them */ 35.215 + return lerp(a, b, sy); 35.216 +} 35.217 + 35.218 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z) 35.219 +{ 35.220 + int i, j; 35.221 + int bx0, bx1, by0, by1, bz0, bz1; 35.222 + int b00, b10, b01, b11; 35.223 + scalar_t rx0, rx1, ry0, ry1, rz0, rz1; 35.224 + scalar_t sx, sy, sz; 35.225 + scalar_t u, v, a, b, c, d; 35.226 + 35.227 + if(!tables_valid) { 35.228 + init_noise(); 35.229 + tables_valid = 1; 35.230 + } 35.231 + 35.232 + setup(x, bx0, bx1, rx0, rx1); 35.233 + setup(y, by0, by1, ry0, ry1); 35.234 + setup(z, bz0, bz1, rz0, rz1); 35.235 + 35.236 + i = perm[bx0]; 35.237 + j = perm[bx1]; 35.238 + 35.239 + b00 = perm[i + by0]; 35.240 + b10 = perm[j + by0]; 35.241 + b01 = perm[i + by1]; 35.242 + b11 = perm[j + by1]; 35.243 + 35.244 + /* calculate hermite interpolating factors */ 35.245 + sx = s_curve(rx0); 35.246 + sy = s_curve(ry0); 35.247 + sz = s_curve(rz0); 35.248 + 35.249 + /* interpolate along the top slice of the cell */ 35.250 + u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz0)); 35.251 + v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz0)); 35.252 + a = lerp(u, v, sx); 35.253 + 35.254 + u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz0)); 35.255 + v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz0)); 35.256 + b = lerp(u, v, sx); 35.257 + 35.258 + c = lerp(a, b, sy); 35.259 + 35.260 + /* interpolate along the bottom slice of the cell */ 35.261 + u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz1)); 35.262 + v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz1)); 35.263 + a = lerp(u, v, sx); 35.264 + 35.265 + u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz1)); 35.266 + v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz1)); 35.267 + b = lerp(u, v, sx); 35.268 + 35.269 + d = lerp(a, b, sy); 35.270 + 35.271 + /* interpolate between slices */ 35.272 + return lerp(c, d, sz); 35.273 +} 35.274 + 35.275 +scalar_t fbm1(scalar_t x, int octaves) 35.276 +{ 35.277 + int i; 35.278 + scalar_t res = 0.0f, freq = 1.0f; 35.279 + for(i=0; i<octaves; i++) { 35.280 + res += noise1(x * freq) / freq; 35.281 + freq *= 2.0f; 35.282 + } 35.283 + return res; 35.284 +} 35.285 + 35.286 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves) 35.287 +{ 35.288 + int i; 35.289 + scalar_t res = 0.0f, freq = 1.0f; 35.290 + for(i=0; i<octaves; i++) { 35.291 + res += noise2(x * freq, y * freq) / freq; 35.292 + freq *= 2.0f; 35.293 + } 35.294 + return res; 35.295 +} 35.296 + 35.297 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves) 35.298 +{ 35.299 + int i; 35.300 + scalar_t res = 0.0f, freq = 1.0f; 35.301 + for(i=0; i<octaves; i++) { 35.302 + res += noise3(x * freq, y * freq, z * freq) / freq; 35.303 + freq *= 2.0f; 35.304 + } 35.305 + return res; 35.306 +} 35.307 + 35.308 +scalar_t turbulence1(scalar_t x, int octaves) 35.309 +{ 35.310 + int i; 35.311 + scalar_t res = 0.0f, freq = 1.0f; 35.312 + for(i=0; i<octaves; i++) { 35.313 + res += fabs(noise1(x * freq) / freq); 35.314 + freq *= 2.0f; 35.315 + } 35.316 + return res; 35.317 +} 35.318 + 35.319 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves) 35.320 +{ 35.321 + int i; 35.322 + scalar_t res = 0.0f, freq = 1.0f; 35.323 + for(i=0; i<octaves; i++) { 35.324 + res += fabs(noise2(x * freq, y * freq) / freq); 35.325 + freq *= 2.0f; 35.326 + } 35.327 + return res; 35.328 +} 35.329 + 35.330 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves) 35.331 +{ 35.332 + int i; 35.333 + scalar_t res = 0.0f, freq = 1.0f; 35.334 + for(i=0; i<octaves; i++) { 35.335 + res += fabs(noise3(x * freq, y * freq, z * freq) / freq); 35.336 + freq *= 2.0f; 35.337 + } 35.338 + return res; 35.339 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/libs/vmath/vmath.h Sun Sep 29 08:20:19 2013 +0300 36.3 @@ -0,0 +1,94 @@ 36.4 +/* 36.5 +libvmath - a vector math library 36.6 +Copyright (C) 2004-2013 John Tsiombikas <nuclear@member.fsf.org> 36.7 + 36.8 +This program is free software: you can redistribute it and/or modify 36.9 +it under the terms of the GNU Lesser General Public License as published 36.10 +by the Free Software Foundation, either version 3 of the License, or 36.11 +(at your option) any later version. 36.12 + 36.13 +This program is distributed in the hope that it will be useful, 36.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 36.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36.16 +GNU Lesser General Public License for more details. 36.17 + 36.18 +You should have received a copy of the GNU Lesser General Public License 36.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 36.20 +*/ 36.21 + 36.22 +#ifndef VMATH_H_ 36.23 +#define VMATH_H_ 36.24 + 36.25 +#include <math.h> 36.26 +#include "vmath_types.h" 36.27 + 36.28 +#ifndef M_PI 36.29 +#define M_PI PI 36.30 +#endif 36.31 + 36.32 +#ifndef M_E 36.33 +#define M_E 2.718281828459045 36.34 +#endif 36.35 + 36.36 +#define PI 3.141592653589793 36.37 +#define HALF_PI 1.570796326794897 36.38 +#define QUARTER_PI 0.785398163397448 36.39 +#define TWO_PI 6.283185307179586 36.40 + 36.41 + 36.42 +#define RAD_TO_DEG(a) ((((scalar_t)a) * 360.0) / TWO_PI) 36.43 +#define DEG_TO_RAD(a) (((scalar_t)a) * (PI / 180.0)) 36.44 + 36.45 +#define SQ(x) ((x) * (x)) 36.46 + 36.47 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) 36.48 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) 36.49 + 36.50 +#ifndef __GNUC__ 36.51 +#define round(x) ((x) >= 0 ? (x) + 0.5 : (x) - 0.5) 36.52 +#endif 36.53 + 36.54 +#ifdef __cplusplus 36.55 +extern "C" { 36.56 +#endif /* __cplusplus */ 36.57 + 36.58 +static inline scalar_t smoothstep(float a, float b, float x); 36.59 + 36.60 +static inline scalar_t frand(scalar_t range); 36.61 +static inline vec3_t sphrand(scalar_t rad); 36.62 + 36.63 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples); 36.64 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev); 36.65 + 36.66 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t); 36.67 + 36.68 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); 36.69 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); 36.70 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); 36.71 + 36.72 +scalar_t noise1(scalar_t x); 36.73 +scalar_t noise2(scalar_t x, scalar_t y); 36.74 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z); 36.75 + 36.76 +scalar_t fbm1(scalar_t x, int octaves); 36.77 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves); 36.78 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves); 36.79 + 36.80 +scalar_t turbulence1(scalar_t x, int octaves); 36.81 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves); 36.82 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves); 36.83 + 36.84 +#ifdef __cplusplus 36.85 +} 36.86 +#endif /* __cplusplus */ 36.87 + 36.88 +#include "vmath.inl" 36.89 + 36.90 +#include "vector.h" 36.91 +#include "matrix.h" 36.92 +#include "quat.h" 36.93 +#include "sphvec.h" 36.94 +#include "ray.h" 36.95 +#include "geom.h" 36.96 + 36.97 +#endif /* VMATH_H_ */
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/libs/vmath/vmath.inl Sun Sep 29 08:20:19 2013 +0300 37.3 @@ -0,0 +1,56 @@ 37.4 +/* 37.5 +libvmath - a vector math library 37.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 37.7 + 37.8 +This program is free software: you can redistribute it and/or modify 37.9 +it under the terms of the GNU Lesser General Public License as published 37.10 +by the Free Software Foundation, either version 3 of the License, or 37.11 +(at your option) any later version. 37.12 + 37.13 +This program is distributed in the hope that it will be useful, 37.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 37.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37.16 +GNU Lesser General Public License for more details. 37.17 + 37.18 +You should have received a copy of the GNU Lesser General Public License 37.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 37.20 +*/ 37.21 + 37.22 +#include <stdlib.h> 37.23 + 37.24 +static inline scalar_t smoothstep(float a, float b, float x) 37.25 +{ 37.26 + if(x < a) return 0.0; 37.27 + if(x >= b) return 1.0; 37.28 + 37.29 + x = (x - a) / (b - a); 37.30 + return x * x * (3.0 - 2.0 * x); 37.31 +} 37.32 + 37.33 +/** Generates a random number in [0, range) */ 37.34 +static inline scalar_t frand(scalar_t range) 37.35 +{ 37.36 + return range * (scalar_t)rand() / (scalar_t)RAND_MAX; 37.37 +} 37.38 + 37.39 +/** Generates a random vector on the surface of a sphere */ 37.40 +static inline vec3_t sphrand(scalar_t rad) 37.41 +{ 37.42 + scalar_t u = (scalar_t)rand() / RAND_MAX; 37.43 + scalar_t v = (scalar_t)rand() / RAND_MAX; 37.44 + 37.45 + scalar_t theta = 2.0 * M_PI * u; 37.46 + scalar_t phi = acos(2.0 * v - 1.0); 37.47 + 37.48 + vec3_t res; 37.49 + res.x = rad * cos(theta) * sin(phi); 37.50 + res.y = rad * sin(theta) * sin(phi); 37.51 + res.z = rad * cos(phi); 37.52 + return res; 37.53 +} 37.54 + 37.55 +/** linear interpolation */ 37.56 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t) 37.57 +{ 37.58 + return a + (b - a) * t; 37.59 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/libs/vmath/vmath_config.h Sun Sep 29 08:20:19 2013 +0300 38.3 @@ -0,0 +1,19 @@ 38.4 +#ifndef VMATH_CONFIG_H_ 38.5 +#define VMATH_CONFIG_H_ 38.6 + 38.7 +#if (__STDC_VERSION__ < 199999) 38.8 +#if defined(__GNUC__) || defined(_MSC_VER) 38.9 +#define inline __inline 38.10 +#else 38.11 +#define inline 38.12 + 38.13 +#ifdef VECTOR_H_ 38.14 +#warning "compiling vector operations without inline, performance might suffer" 38.15 +#endif /* VECTOR_H_ */ 38.16 + 38.17 +#endif /* gcc/msvc */ 38.18 +#endif /* not C99 */ 38.19 + 38.20 +#define SINGLE_PRECISION_MATH 38.21 + 38.22 +#endif /* VMATH_CONFIG_H_ */
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/libs/vmath/vmath_types.h Sun Sep 29 08:20:19 2013 +0300 39.3 @@ -0,0 +1,58 @@ 39.4 +/* 39.5 +libvmath - a vector math library 39.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 39.7 + 39.8 +This program is free software: you can redistribute it and/or modify 39.9 +it under the terms of the GNU Lesser General Public License as published 39.10 +by the Free Software Foundation, either version 3 of the License, or 39.11 +(at your option) any later version. 39.12 + 39.13 +This program is distributed in the hope that it will be useful, 39.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 39.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 39.16 +GNU Lesser General Public License for more details. 39.17 + 39.18 +You should have received a copy of the GNU Lesser General Public License 39.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 39.20 +*/ 39.21 + 39.22 +#ifndef VMATH_TYPES_H_ 39.23 +#define VMATH_TYPES_H_ 39.24 + 39.25 +#include "vmath_config.h" 39.26 + 39.27 +#define SMALL_NUMBER 1.e-4 39.28 +#define XSMALL_NUMBER 1.e-8 39.29 +#define ERROR_MARGIN 1.e-6 39.30 + 39.31 + 39.32 +#ifdef SINGLE_PRECISION_MATH 39.33 +typedef float scalar_t; 39.34 +#else 39.35 +typedef double scalar_t; 39.36 +#endif /* floating point precision */ 39.37 + 39.38 +/* vectors */ 39.39 +typedef struct { scalar_t x, y; } vec2_t; 39.40 +typedef struct { scalar_t x, y, z; } vec3_t; 39.41 +typedef struct { scalar_t x, y, z, w; } vec4_t; 39.42 + 39.43 +/* quaternions */ 39.44 +typedef vec4_t quat_t; 39.45 + 39.46 +/* matrices */ 39.47 +typedef scalar_t mat3_t[3][3]; 39.48 +typedef scalar_t mat4_t[4][4]; 39.49 + 39.50 + 39.51 +#ifdef __cplusplus 39.52 +class Vector2; 39.53 +class Vector3; 39.54 +class Vector4; 39.55 +class Quaternion; 39.56 +class Matrix3x3; 39.57 +class Matrix4x4; 39.58 +class SphVector; 39.59 +#endif /* __cplusplus */ 39.60 + 39.61 +#endif /* VMATH_TYPES_H_ */
40.1 --- a/src/goat3d.cc Sat Sep 28 20:36:55 2013 +0300 40.2 +++ b/src/goat3d.cc Sun Sep 29 08:20:19 2013 +0300 40.3 @@ -25,6 +25,7 @@ 40.4 struct goat3d *goat3d_create(void) 40.5 { 40.6 goat3d *goat = new goat3d; 40.7 + goat->flags = 0; 40.8 goat->scn = new Scene; 40.9 return goat; 40.10 } 40.11 @@ -142,6 +143,11 @@ 40.12 } 40.13 40.14 // ---- materials ---- 40.15 +void goat3d_add_mtl(struct goat3d *g, struct goat3d_material *mtl) 40.16 +{ 40.17 + g->scn->add_material(mtl); 40.18 +} 40.19 + 40.20 struct goat3d_material *goat3d_create_mtl(void) 40.21 { 40.22 return new goat3d_material; 40.23 @@ -197,12 +203,27 @@ 40.24 return (*mtl)[attrib].map.c_str(); 40.25 } 40.26 40.27 -void goat3d_add_mtl(struct goat3d *g, struct goat3d_material *mtl) 40.28 +// ---- meshes ---- 40.29 +void goat3d_add_mesh(struct goat3d *g, struct goat3d_mesh *mesh) 40.30 { 40.31 - g->scn->add_material(mtl); 40.32 + g->scn->add_mesh(mesh); 40.33 } 40.34 40.35 -// ---- meshes ---- 40.36 +int goat3d_get_mesh_count(struct goat3d *g) 40.37 +{ 40.38 + return g->scn->get_mesh_count(); 40.39 +} 40.40 + 40.41 +struct goat3d_mesh *goat3d_get_mesh(struct goat3d *g, int idx) 40.42 +{ 40.43 + return (goat3d_mesh*)g->scn->get_mesh(idx); 40.44 +} 40.45 + 40.46 +struct goat3d_mesh *goat3d_get_mesh_by_name(struct goat3d *g, const char *name) 40.47 +{ 40.48 + return (goat3d_mesh*)g->scn->get_mesh(name); 40.49 +} 40.50 + 40.51 struct goat3d_mesh *goat3d_create_mesh(void) 40.52 { 40.53 return new goat3d_mesh; 40.54 @@ -459,23 +480,92 @@ 40.55 im_use[GOAT3D_MESH_ATTR_COLOR] = true; 40.56 } 40.57 40.58 -void goat3d_add_mesh(struct goat3d *g, struct goat3d_mesh *mesh) 40.59 +/* lights */ 40.60 +void goat3d_add_light(struct goat3d *g, struct goat3d_light *lt) 40.61 { 40.62 - g->scn->add_mesh(mesh); 40.63 + g->scn->add_light(lt); 40.64 } 40.65 40.66 -int goat3d_get_mesh_count(struct goat3d *g) 40.67 +int goat3d_get_light_count(struct goat3d *g) 40.68 { 40.69 - return g->scn->get_mesh_count(); 40.70 + return g->scn->get_light_count(); 40.71 } 40.72 40.73 -struct goat3d_mesh *goat3d_get_mesh(struct goat3d *g, int idx) 40.74 +struct goat3d_light *goat3d_get_light(struct goat3d *g, int idx) 40.75 { 40.76 - return (goat3d_mesh*)g->scn->get_mesh(idx); 40.77 + return (goat3d_light*)g->scn->get_light(idx); 40.78 } 40.79 40.80 +struct goat3d_light *goat3d_get_light_by_name(struct goat3d *g, const char *name) 40.81 +{ 40.82 + return (goat3d_light*)g->scn->get_light(name); 40.83 +} 40.84 + 40.85 + 40.86 +struct goat3d_light *goat3d_create_light(void) 40.87 +{ 40.88 + return new goat3d_light; 40.89 +} 40.90 + 40.91 +void goat3d_destroy_light(struct goat3d_light *lt) 40.92 +{ 40.93 + delete lt; 40.94 +} 40.95 + 40.96 + 40.97 +/* cameras */ 40.98 +void goat3d_add_camera(struct goat3d *g, struct goat3d_camera *cam) 40.99 +{ 40.100 + g->scn->add_camera(cam); 40.101 +} 40.102 + 40.103 +int goat3d_get_camera_count(struct goat3d *g) 40.104 +{ 40.105 + return g->scn->get_camera_count(); 40.106 +} 40.107 + 40.108 +struct goat3d_camera *goat3d_get_camera(struct goat3d *g, int idx) 40.109 +{ 40.110 + return (goat3d_camera*)g->scn->get_camera(idx); 40.111 +} 40.112 + 40.113 +struct goat3d_camera *goat3d_get_camera_by_name(struct goat3d *g, const char *name) 40.114 +{ 40.115 + return (goat3d_camera*)g->scn->get_camera(name); 40.116 +} 40.117 + 40.118 +struct goat3d_camera *goat3d_create_camera(void) 40.119 +{ 40.120 + return new goat3d_camera; 40.121 +} 40.122 + 40.123 +void goat3d_destroy_camera(struct goat3d_camera *cam) 40.124 +{ 40.125 + delete cam; 40.126 +} 40.127 + 40.128 + 40.129 40.130 // node 40.131 +void goat3d_add_node(struct goat3d *g, struct goat3d_node *node) 40.132 +{ 40.133 + g->scn->add_node(node); 40.134 +} 40.135 + 40.136 +int goat3d_get_node_count(struct goat3d *g) 40.137 +{ 40.138 + return g->scn->get_node_count(); 40.139 +} 40.140 + 40.141 +struct goat3d_node *goat3d_get_node(struct goat3d *g, int idx) 40.142 +{ 40.143 + return (goat3d_node*)g->scn->get_node(idx); 40.144 +} 40.145 + 40.146 +struct goat3d_node *goat3d_get_node_by_name(struct goat3d *g, const char *name) 40.147 +{ 40.148 + return (goat3d_node*)g->scn->get_node(name); 40.149 +} 40.150 40.151 struct goat3d_node *goat3d_create_node(void) 40.152 {
41.1 --- a/src/goat3d.h Sat Sep 28 20:36:55 2013 +0300 41.2 +++ b/src/goat3d.h Sun Sep 29 08:20:19 2013 +0300 41.3 @@ -90,6 +90,8 @@ 41.4 const float *goat3d_get_ambient(const struct goat3d *g); 41.5 41.6 /* materials */ 41.7 +void goat3d_add_mtl(struct goat3d *g, struct goat3d_material *mtl); 41.8 + 41.9 struct goat3d_material *goat3d_create_mtl(void); 41.10 void goat3d_destroy_mtl(struct goat3d_material *mtl); 41.11 41.12 @@ -105,9 +107,12 @@ 41.13 void goat3d_set_mtl_attrib_map(struct goat3d_material *mtl, const char *attrib, const char *mapname); 41.14 const char *goat3d_get_mtl_attrib_map(struct goat3d_material *mtl, const char *attrib); 41.15 41.16 -void goat3d_add_mtl(struct goat3d *g, struct goat3d_material *mtl); 41.17 +/* meshes */ 41.18 +void goat3d_add_mesh(struct goat3d *g, struct goat3d_mesh *mesh); 41.19 +int goat3d_get_mesh_count(struct goat3d *g); 41.20 +struct goat3d_mesh *goat3d_get_mesh(struct goat3d *g, int idx); 41.21 +struct goat3d_mesh *goat3d_get_mesh_by_name(struct goat3d *g, const char *name); 41.22 41.23 -/* meshes */ 41.24 struct goat3d_mesh *goat3d_create_mesh(void); 41.25 void goat3d_destroy_mesh(struct goat3d_mesh *mesh); 41.26 41.27 @@ -160,13 +165,32 @@ 41.28 void goat3d_color3f(float x, float y, float z); 41.29 void goat3d_color4f(float x, float y, float z, float w); 41.30 41.31 -void goat3d_add_mesh(struct goat3d *g, struct goat3d_mesh *mesh); 41.32 +/* lights */ 41.33 +void goat3d_add_light(struct goat3d *g, struct goat3d_light *lt); 41.34 +int goat3d_get_light_count(struct goat3d *g); 41.35 +struct goat3d_light *goat3d_get_light(struct goat3d *g, int idx); 41.36 +struct goat3d_light *goat3d_get_light_by_name(struct goat3d *g, const char *name); 41.37 41.38 -int goat3d_get_mesh_count(struct goat3d *g); 41.39 -struct goat3d_mesh *goat3d_get_mesh(struct goat3d *g, int idx); 41.40 +struct goat3d_light *goat3d_create_light(void); 41.41 +void goat3d_destroy_light(struct goat3d_light *lt); 41.42 + 41.43 +/* cameras */ 41.44 +void goat3d_add_camera(struct goat3d *g, struct goat3d_camera *cam); 41.45 +int goat3d_get_camera_count(struct goat3d *g); 41.46 +struct goat3d_camera *goat3d_get_camera(struct goat3d *g, int idx); 41.47 +struct goat3d_camera *goat3d_get_camera_by_name(struct goat3d *g, const char *name); 41.48 + 41.49 +struct goat3d_camera *goat3d_create_camera(void); 41.50 +void goat3d_destroy_camera(struct goat3d_camera *cam); 41.51 41.52 /* nodes */ 41.53 +void goat3d_add_node(struct goat3d *g, struct goat3d_node *node); 41.54 +int goat3d_get_node_count(struct goat3d *g); 41.55 +struct goat3d_node *goat3d_get_node(struct goat3d *g, int idx); 41.56 +struct goat3d_node *goat3d_get_node_by_name(struct goat3d *g, const char *name); 41.57 + 41.58 struct goat3d_node *goat3d_create_node(void); 41.59 +void goat3d_destroy_node(struct goat3d_node *node); 41.60 41.61 void goat3d_set_node_name(struct goat3d_node *node, const char *name); 41.62 const char *goat3d_get_node_name(const struct goat3d_node *node);