From ccfd8410e494593009335b50a181fd2a9227e000 Mon Sep 17 00:00:00 2001 From: Johannes Riecken Date: Sat, 27 Aug 2022 11:37:41 +0200 Subject: [PATCH] Remove trailing whitespace Command: gsed -i 's/\s\+$//' **/*.{cpp,h,mak,txt} --- 2D Collision/code/FATE/ENGINE.h | 176 +- 2D Collision/code/FATE/FATE.cpp | 298 +- 2D Collision/code/FATE/FATE.h | 76 +- 2D Collision/code/FATE/Fate.mak | 850 ++--- 2D Collision/code/FATE/Mainfrm.cpp | 2732 ++++++++--------- 2D Collision/code/FATE/Mainfrm.h | 218 +- 2D Collision/code/FATE/MathDefs.h | 110 +- 2D Collision/code/FATE/RESOURCE.h | 72 +- 2D Collision/code/FATE/Readme.txt | 114 +- 2D Collision/code/FATE/STDAFX.cpp | 12 +- 2D Collision/code/FATE/STDAFX.h | 32 +- 2D Water Effects/Code/OGL/Agua/Agua.cpp | 112 +- 2D Water Effects/Code/OGL/Agua/Agua.h | 98 +- 2D Water Effects/Code/OGL/Agua/AguaDlg.cpp | 966 +++--- 2D Water Effects/Code/OGL/Agua/AguaDlg.h | 146 +- 2D Water Effects/Code/OGL/Agua/LoadTGA.cpp | 208 +- 2D Water Effects/Code/OGL/Agua/LoadTGA.h | 68 +- 2D Water Effects/Code/OGL/Agua/ReadMe.txt | 100 +- 2D Water Effects/Code/OGL/Agua/Resource.h | 58 +- 2D Water Effects/Code/OGL/Agua/StdAfx.cpp | 16 +- 2D Water Effects/Code/OGL/Agua/StdAfx.h | 52 +- 3D Morphing/Code/OGL/Morphy/Bitmap.cpp | 1246 ++++---- 3D Morphing/Code/OGL/Morphy/Bitmap.h | 104 +- 3D Morphing/Code/OGL/Morphy/LoadDlg.cpp | 144 +- 3D Morphing/Code/OGL/Morphy/LoadOBJ.cpp | 646 ++-- 3D Morphing/Code/OGL/Morphy/LoadOBJ.h | 64 +- 3D Morphing/Code/OGL/Morphy/MainFrm.cpp | 424 +-- 3D Morphing/Code/OGL/Morphy/MainFrm.h | 176 +- 3D Morphing/Code/OGL/Morphy/MathDefs.h | 176 +- 3D Morphing/Code/OGL/Morphy/Morphy.cpp | 308 +- 3D Morphing/Code/OGL/Morphy/Morphy.h | 130 +- 3D Morphing/Code/OGL/Morphy/Morphy.mak | 812 ++--- 3D Morphing/Code/OGL/Morphy/OGLView.cpp | 1378 ++++----- 3D Morphing/Code/OGL/Morphy/OGLView.h | 204 +- 3D Morphing/Code/OGL/Morphy/ReadMe.txt | 78 +- 3D Morphing/Code/OGL/Morphy/Skeleton.cpp | 312 +- 3D Morphing/Code/OGL/Morphy/Skeleton.h | 292 +- 3D Morphing/Code/OGL/Morphy/Slider.cpp | 164 +- 3D Morphing/Code/OGL/Morphy/Slider.h | 104 +- 3D Morphing/Code/OGL/Morphy/StdAfx.cpp | 12 +- 3D Morphing/Code/OGL/Morphy/StdAfx.h | 52 +- 3D Morphing/Code/OGL/Morphy/loaddlg.h | 96 +- 3D Morphing/Code/OGL/Morphy/resource.h | 92 +- Blob Modeling/Code/OGL/Blobby/Blobby.cpp | 308 +- Blob Modeling/Code/OGL/Blobby/Blobby.h | 130 +- Blob Modeling/Code/OGL/Blobby/EditBlob.cpp | 92 +- Blob Modeling/Code/OGL/Blobby/EditBlob.h | 94 +- Blob Modeling/Code/OGL/Blobby/EditSys.cpp | 94 +- Blob Modeling/Code/OGL/Blobby/EditSys.h | 94 +- Blob Modeling/Code/OGL/Blobby/MainFrm.cpp | 508 +-- Blob Modeling/Code/OGL/Blobby/MainFrm.h | 176 +- Blob Modeling/Code/OGL/Blobby/MathDefs.cpp | 210 +- Blob Modeling/Code/OGL/Blobby/MathDefs.h | 226 +- Blob Modeling/Code/OGL/Blobby/MetaGoop.cpp | 752 ++--- Blob Modeling/Code/OGL/Blobby/MetaGoop.h | 112 +- Blob Modeling/Code/OGL/Blobby/OGLView.cpp | 1534 ++++----- Blob Modeling/Code/OGL/Blobby/OGLView.h | 228 +- Blob Modeling/Code/OGL/Blobby/ReadMe.txt | 118 +- Blob Modeling/Code/OGL/Blobby/StdAfx.cpp | 12 +- Blob Modeling/Code/OGL/Blobby/StdAfx.h | 52 +- Blob Modeling/Code/OGL/Blobby/resource.h | 124 +- CCD3D.cpp | 20 +- Cartoon Rendering/Code/OGL/Loony/LoadOBJ.cpp | 704 ++--- Cartoon Rendering/Code/OGL/Loony/LoadOBJ.h | 78 +- Cartoon Rendering/Code/OGL/Loony/Loony.cpp | 316 +- Cartoon Rendering/Code/OGL/Loony/Loony.h | 134 +- Cartoon Rendering/Code/OGL/Loony/MainFrm.cpp | 556 ++-- Cartoon Rendering/Code/OGL/Loony/MainFrm.h | 180 +- Cartoon Rendering/Code/OGL/Loony/MathDefs.cpp | 572 ++-- Cartoon Rendering/Code/OGL/Loony/MathDefs.h | 236 +- Cartoon Rendering/Code/OGL/Loony/OGLView.cpp | 1500 ++++----- Cartoon Rendering/Code/OGL/Loony/OGLView.h | 214 +- Cartoon Rendering/Code/OGL/Loony/Skeleton.cpp | 514 ++-- Cartoon Rendering/Code/OGL/Loony/Skeleton.h | 416 +-- Cartoon Rendering/Code/OGL/Loony/StdAfx.cpp | 12 +- Cartoon Rendering/Code/OGL/Loony/StdAfx.h | 52 +- Cartoon Rendering/Code/OGL/Loony/ToonSet.cpp | 118 +- Cartoon Rendering/Code/OGL/Loony/ToonSet.h | 104 +- Cartoon Rendering/Code/OGL/Loony/readme.txt | 156 +- Cartoon Rendering/Code/OGL/Loony/resource.h | 186 +- .../Code/OGL/Clothy/AddSpher.cpp | 100 +- .../Code/OGL/Clothy/AddSpher.h | 98 +- .../Code/OGL/Clothy/Clothy.cpp | 308 +- .../Code/OGL/Clothy/Clothy.h | 134 +- .../Code/OGL/Clothy/Clothy.mak | 788 ++--- .../Code/OGL/Clothy/LoadOBJ.cpp | 750 ++--- .../Code/OGL/Clothy/LoadOBJ.h | 92 +- .../Code/OGL/Clothy/MainFrm.cpp | 876 +++--- .../Code/OGL/Clothy/MainFrm.h | 238 +- .../Code/OGL/Clothy/MathDefs.cpp | 224 +- .../Code/OGL/Clothy/MathDefs.h | 230 +- .../Code/OGL/Clothy/NewCloth.cpp | 146 +- .../Code/OGL/Clothy/NewCloth.h | 114 +- .../Code/OGL/Clothy/OGLView.cpp | 2022 ++++++------ .../Code/OGL/Clothy/OGLView.h | 244 +- .../Code/OGL/Clothy/PhysEnv.cpp | 2364 +++++++------- .../Code/OGL/Clothy/PhysEnv.h | 316 +- .../Code/OGL/Clothy/ReadMe.txt | 136 +- .../Code/OGL/Clothy/SetVert.cpp | 86 +- .../Code/OGL/Clothy/SetVert.h | 92 +- .../Code/OGL/Clothy/SimProps.cpp | 112 +- .../Code/OGL/Clothy/SimProps.h | 104 +- .../Code/OGL/Clothy/Skeleton.cpp | 330 +- .../Code/OGL/Clothy/Skeleton.h | 308 +- .../Code/OGL/Clothy/StdAfx.cpp | 12 +- .../Code/OGL/Clothy/StdAfx.h | 52 +- .../Code/OGL/Clothy/TimeProps.cpp | 96 +- .../Code/OGL/Clothy/TimeProps.h | 96 +- .../Code/OGL/Clothy/resource.h | 208 +- .../Code/OGL/ToonTown/EXTERNS.h | 406 +-- .../Code/OGL/ToonTown/LoadOBJ.h | 64 +- .../Code/OGL/ToonTown/LoadTGA.h | 54 +- .../Code/OGL/ToonTown/MathDefs.h | 244 +- .../Code/OGL/ToonTown/Readme.txt | 124 +- .../Code/OGL/ToonTown/ToonTown.mak | 938 +++--- .../Code/OGL/ToonTown/resource.h | 78 +- More Kine/Code/OGL/KineChain/Bitmap.cpp | 394 +-- More Kine/Code/OGL/KineChain/Bitmap.h | 48 +- More Kine/Code/OGL/KineChain/KineChain.cpp | 308 +- More Kine/Code/OGL/KineChain/KineChain.h | 130 +- More Kine/Code/OGL/KineChain/KineChain.mak | 916 +++--- More Kine/Code/OGL/KineChain/MainFrm.cpp | 444 +-- More Kine/Code/OGL/KineChain/MainFrm.h | 176 +- More Kine/Code/OGL/KineChain/MathDefs.cpp | 182 +- More Kine/Code/OGL/KineChain/MathDefs.h | 180 +- More Kine/Code/OGL/KineChain/Matrix.h | 78 +- More Kine/Code/OGL/KineChain/Model.h | 286 +- More Kine/Code/OGL/KineChain/OGLView.cpp | 1964 ++++++------ More Kine/Code/OGL/KineChain/OGLView.h | 212 +- More Kine/Code/OGL/KineChain/Quatern.cpp | 732 ++--- More Kine/Code/OGL/KineChain/Quatern.h | 118 +- More Kine/Code/OGL/KineChain/ReadMe.txt | 72 +- More Kine/Code/OGL/KineChain/Restrict.cpp | 152 +- More Kine/Code/OGL/KineChain/Restrict.h | 120 +- More Kine/Code/OGL/KineChain/Skeleton.cpp | 304 +- More Kine/Code/OGL/KineChain/Skeleton.h | 268 +- More Kine/Code/OGL/KineChain/StdAfx.cpp | 12 +- More Kine/Code/OGL/KineChain/StdAfx.h | 52 +- More Kine/Code/OGL/KineChain/resource.h | 104 +- .../Code/OGL/Kine/Kine.cpp | 308 +- .../Code/OGL/Kine/Kine.h | 130 +- .../Code/OGL/Kine/Kine.mak | 718 ++--- .../Code/OGL/Kine/MainFrm.cpp | 382 +-- .../Code/OGL/Kine/MainFrm.h | 164 +- .../Code/OGL/Kine/Model.h | 620 ++-- .../Code/OGL/Kine/OGLView.cpp | 1294 ++++---- .../Code/OGL/Kine/OGLView.h | 194 +- .../Code/OGL/Kine/Quatern.cpp | 730 ++--- .../Code/OGL/Kine/Quatern.h | 136 +- .../Code/OGL/Kine/RESOURCE.h | 62 +- .../Code/OGL/Kine/ReadMe.txt | 242 +- .../Code/OGL/Kine/Skeleton.cpp | 302 +- .../Code/OGL/Kine/Skeleton.h | 276 +- .../Code/OGL/Kine/StdAfx.cpp | 12 +- .../Code/OGL/Kine/StdAfx.h | 52 +- .../Code/OGL/Squashy/LoadOBJ.cpp | 750 ++--- .../Code/OGL/Squashy/LoadOBJ.h | 92 +- .../Code/OGL/Squashy/MainFrm.cpp | 738 ++--- .../Code/OGL/Squashy/MainFrm.h | 218 +- .../Code/OGL/Squashy/MathDefs.cpp | 308 +- .../Code/OGL/Squashy/MathDefs.h | 234 +- .../Code/OGL/Squashy/OGLView.cpp | 1714 +++++------ .../Code/OGL/Squashy/OGLView.h | 248 +- .../Code/OGL/Squashy/PhysEnv.cpp | 2210 ++++++------- .../Code/OGL/Squashy/PhysEnv.h | 272 +- .../Code/OGL/Squashy/ReadMe.txt | 254 +- .../Code/OGL/Squashy/SimProps.cpp | 116 +- .../Code/OGL/Squashy/SimProps.h | 106 +- .../Code/OGL/Squashy/Skeleton.cpp | 330 +- .../Code/OGL/Squashy/Skeleton.h | 308 +- .../Code/OGL/Squashy/Squashy.cpp | 308 +- .../Code/OGL/Squashy/Squashy.h | 130 +- .../Code/OGL/Squashy/Squashy.mak | 684 ++--- .../Code/OGL/Squashy/StdAfx.cpp | 12 +- .../Code/OGL/Squashy/StdAfx.h | 52 +- .../Code/OGL/Squashy/TimeProps.cpp | 96 +- .../Code/OGL/Squashy/TimeProps.h | 96 +- .../Code/OGL/Squashy/VertMass.cpp | 86 +- .../Code/OGL/Squashy/VertMass.h | 92 +- .../Code/OGL/Squashy/resource.h | 160 +- .../code/OGL/Squashy/LoadOBJ.cpp | 750 ++--- Particle Dynamics/code/OGL/Squashy/LoadOBJ.h | 92 +- .../code/OGL/Squashy/MainFrm.cpp | 674 ++-- Particle Dynamics/code/OGL/Squashy/MainFrm.h | 206 +- .../code/OGL/Squashy/MathDefs.cpp | 308 +- Particle Dynamics/code/OGL/Squashy/MathDefs.h | 234 +- .../code/OGL/Squashy/OGLView.cpp | 1664 +++++----- Particle Dynamics/code/OGL/Squashy/OGLView.h | 246 +- .../code/OGL/Squashy/PhysEnv.cpp | 1648 +++++----- Particle Dynamics/code/OGL/Squashy/PhysEnv.h | 238 +- Particle Dynamics/code/OGL/Squashy/ReadMe.txt | 164 +- .../code/OGL/Squashy/SimProps.cpp | 116 +- Particle Dynamics/code/OGL/Squashy/SimProps.h | 106 +- .../code/OGL/Squashy/Skeleton.cpp | 330 +- Particle Dynamics/code/OGL/Squashy/Skeleton.h | 308 +- .../code/OGL/Squashy/Squashy.cpp | 308 +- Particle Dynamics/code/OGL/Squashy/Squashy.h | 130 +- .../code/OGL/Squashy/Squashy.mak | 684 ++--- Particle Dynamics/code/OGL/Squashy/StdAfx.cpp | 12 +- Particle Dynamics/code/OGL/Squashy/StdAfx.h | 52 +- .../code/OGL/Squashy/TimeProps.cpp | 96 +- .../code/OGL/Squashy/TimeProps.h | 96 +- .../code/OGL/Squashy/VertMass.cpp | 86 +- Particle Dynamics/code/OGL/Squashy/VertMass.h | 92 +- Particle Dynamics/code/OGL/Squashy/resource.h | 154 +- Particle Systems/Code/OGL/Spray/EditEmit.cpp | 226 +- Particle Systems/Code/OGL/Spray/EditEmit.h | 144 +- Particle Systems/Code/OGL/Spray/MainFrm.cpp | 548 ++-- Particle Systems/Code/OGL/Spray/MainFrm.h | 180 +- Particle Systems/Code/OGL/Spray/MathStuff.h | 144 +- Particle Systems/Code/OGL/Spray/Matrix.cpp | 90 +- Particle Systems/Code/OGL/Spray/Matrix.h | 78 +- Particle Systems/Code/OGL/Spray/OGLView.cpp | 1238 ++++---- Particle Systems/Code/OGL/Spray/OGLView.h | 214 +- Particle Systems/Code/OGL/Spray/Particle.cpp | 764 ++--- Particle Systems/Code/OGL/Spray/Particle.h | 174 +- Particle Systems/Code/OGL/Spray/ReadMe.txt | 24 +- Particle Systems/Code/OGL/Spray/Spray.cpp | 318 +- Particle Systems/Code/OGL/Spray/Spray.h | 132 +- Particle Systems/Code/OGL/Spray/StdAfx.cpp | 12 +- Particle Systems/Code/OGL/Spray/StdAfx.h | 50 +- Particle Systems/Code/OGL/Spray/resource.h | 118 +- Pool Table Physics/Code/OGL/Pool/EXTERNS.h | 220 +- Pool Table Physics/Code/OGL/Pool/GameSim.cpp | 1034 +++---- Pool Table Physics/Code/OGL/Pool/LoadTGA.cpp | 186 +- Pool Table Physics/Code/OGL/Pool/LoadTGA.h | 54 +- Pool Table Physics/Code/OGL/Pool/MathDefs.cpp | 1178 +++---- Pool Table Physics/Code/OGL/Pool/MathDefs.h | 358 +-- Pool Table Physics/Code/OGL/Pool/Pool.cpp | 912 +++--- .../Code/OGL/Pool/RENDERWORLD.cpp | 828 ++--- Pool Table Physics/Code/OGL/Pool/Readme.txt | 154 +- Pool Table Physics/Code/OGL/Pool/VIEWWND.cpp | 664 ++-- Pool Table Physics/Code/OGL/Pool/models.h | 1672 +++++----- Pool Table Physics/Code/OGL/Pool/resource.h | 68 +- .../Code/OGL/SkinApp/MainFrm.cpp | 762 ++--- .../Code/OGL/SkinApp/MainFrm.h | 192 +- .../Code/OGL/SkinApp/Math.h | 132 +- .../Code/OGL/SkinApp/Matrix.cpp | 90 +- .../Code/OGL/SkinApp/Matrix.h | 78 +- .../Code/OGL/SkinApp/OGLView.cpp | 2132 ++++++------- .../Code/OGL/SkinApp/OGLView.h | 232 +- .../Code/OGL/SkinApp/Quatern.cpp | 826 ++--- .../Code/OGL/SkinApp/Quatern.h | 122 +- .../Code/OGL/SkinApp/ReadMe.txt | 226 +- .../Code/OGL/SkinApp/SetRot.cpp | 94 +- .../Code/OGL/SkinApp/SetRot.h | 96 +- .../Code/OGL/SkinApp/Skeleton.cpp | 326 +- .../Code/OGL/SkinApp/Skeleton.h | 330 +- .../Code/OGL/SkinApp/SkinApp.cpp | 316 +- .../Code/OGL/SkinApp/SkinApp.h | 130 +- .../Code/OGL/SkinApp/StdAfx.cpp | 12 +- .../Code/OGL/SkinApp/StdAfx.h | 52 +- .../Code/OGL/SkinApp/Weight.cpp | 136 +- .../Code/OGL/SkinApp/Weight.h | 102 +- .../Code/OGL/SkinApp/resource.h | 80 +- .../Code/OGL/Skully/HierWin.cpp | 606 ++-- .../Code/OGL/Skully/Hierwin.h | 248 +- .../Code/OGL/Skully/LoadOBJ.cpp | 714 ++--- .../Code/OGL/Skully/LoadOBJ.h | 78 +- .../Code/OGL/Skully/LoadSkel.cpp | 338 +- .../Code/OGL/Skully/LoadSkel.h | 56 +- .../Code/OGL/Skully/MainFrm.cpp | 742 ++--- .../Code/OGL/Skully/MainFrm.h | 204 +- .../Code/OGL/Skully/MathDefs.cpp | 526 ++-- .../Code/OGL/Skully/MathDefs.h | 234 +- .../Code/OGL/Skully/OGLView.cpp | 2536 +++++++-------- .../Code/OGL/Skully/OGLView.h | 236 +- .../Code/OGL/Skully/Skeleton.cpp | 514 ++-- .../Code/OGL/Skully/Skeleton.h | 412 +-- .../Code/OGL/Skully/Skully.cpp | 316 +- Skeletal Deformation/Code/OGL/Skully/Skully.h | 134 +- .../Code/OGL/Skully/StdAfx.cpp | 12 +- Skeletal Deformation/Code/OGL/Skully/StdAfx.h | 52 +- .../Code/OGL/Skully/readme.txt | 282 +- .../Code/OGL/Skully/resource.h | 162 +- .../Code/OGL/Friction/Friction.cpp | 308 +- .../Code/OGL/Friction/Friction.h | 128 +- .../Code/OGL/Friction/Friction.mak | 684 ++--- .../Code/OGL/Friction/LoadOBJ.cpp | 750 ++--- .../Code/OGL/Friction/LoadOBJ.h | 92 +- .../Code/OGL/Friction/MainFrm.cpp | 764 ++--- .../Code/OGL/Friction/MainFrm.h | 222 +- .../Code/OGL/Friction/MathDefs.cpp | 308 +- .../Code/OGL/Friction/MathDefs.h | 234 +- .../Code/OGL/Friction/OGLView.cpp | 1712 +++++------ .../Code/OGL/Friction/OGLView.h | 248 +- .../Code/OGL/Friction/PhysEnv.cpp | 2302 +++++++------- .../Code/OGL/Friction/PhysEnv.h | 276 +- .../Code/OGL/Friction/ReadMe.txt | 216 +- .../Code/OGL/Friction/SimProps.cpp | 124 +- .../Code/OGL/Friction/SimProps.h | 110 +- .../Code/OGL/Friction/Skeleton.cpp | 330 +- .../Code/OGL/Friction/Skeleton.h | 308 +- .../Code/OGL/Friction/StdAfx.cpp | 12 +- .../Code/OGL/Friction/StdAfx.h | 52 +- .../Code/OGL/Friction/TimeProps.cpp | 96 +- .../Code/OGL/Friction/TimeProps.h | 96 +- .../Code/OGL/Friction/VertMass.cpp | 86 +- .../Code/OGL/Friction/VertMass.h | 92 +- .../Code/OGL/Friction/resource.h | 166 +- .../Code/OGL/SlashHarder/MainFrm.cpp | 698 ++--- .../Code/OGL/SlashHarder/MainFrm.h | 184 +- .../Code/OGL/SlashHarder/OGLView.cpp | 1120 +++---- .../Code/OGL/SlashHarder/OGLView.h | 200 +- .../Code/OGL/SlashHarder/Quatern.cpp | 826 ++--- .../Code/OGL/SlashHarder/Quatern.h | 130 +- .../Code/OGL/SlashHarder/ReadMe.txt | 206 +- .../Code/OGL/SlashHarder/SetRot.cpp | 94 +- .../Code/OGL/SlashHarder/SetRot.h | 96 +- .../Code/OGL/SlashHarder/Skeleton.cpp | 322 +- .../Code/OGL/SlashHarder/Skeleton.h | 346 +-- .../Code/OGL/SlashHarder/Slash.cpp | 308 +- .../Code/OGL/SlashHarder/Slash.h | 130 +- .../Code/OGL/SlashHarder/Slider.cpp | 164 +- .../Code/OGL/SlashHarder/Slider.h | 104 +- .../Code/OGL/SlashHarder/StdAfx.cpp | 12 +- .../Code/OGL/SlashHarder/StdAfx.h | 52 +- .../Code/OGL/SlashHarder/resource.h | 70 +- .../Code/OGL/Slash/MainFrm.cpp | 492 +-- .../Code/OGL/Slash/MainFrm.h | 172 +- .../Code/OGL/Slash/Model.h | 142 +- .../Code/OGL/Slash/OGLView.cpp | 1060 +++---- .../Code/OGL/Slash/OGLView.h | 188 +- .../Code/OGL/Slash/Quatern.cpp | 892 +++--- .../Code/OGL/Slash/Quatern.h | 136 +- .../Code/OGL/Slash/ReadMe.txt | 108 +- .../Code/OGL/Slash/SetRot.cpp | 94 +- .../Code/OGL/Slash/SetRot.h | 96 +- .../Code/OGL/Slash/Skeleton.cpp | 302 +- .../Code/OGL/Slash/Skeleton.h | 276 +- .../Code/OGL/Slash/Slash.cpp | 308 +- .../Code/OGL/Slash/Slash.h | 130 +- .../Code/OGL/Slash/Slash.mak | 862 +++--- .../Code/OGL/Slash/StdAfx.cpp | 12 +- .../Code/OGL/Slash/StdAfx.h | 52 +- .../Code/OGL/Slash/resource.h | 60 +- .../Code/OGL/Dagger/Dagger.cpp | 316 +- .../Code/OGL/Dagger/Dagger.h | 130 +- .../Code/OGL/Dagger/HierWin.cpp | 536 ++-- .../Code/OGL/Dagger/LoadAnim.cpp | 1420 ++++----- .../Code/OGL/Dagger/LoadAnim.h | 60 +- .../Code/OGL/Dagger/MainFrm.cpp | 964 +++--- .../Code/OGL/Dagger/MainFrm.h | 306 +- .../Code/OGL/Dagger/OGLView.cpp | 1178 +++---- .../Code/OGL/Dagger/OGLView.h | 188 +- .../Code/OGL/Dagger/ReadMe.txt | 196 +- .../Code/OGL/Dagger/Skeleton.cpp | 400 +-- .../Code/OGL/Dagger/Skeleton.h | 286 +- .../Code/OGL/Dagger/StdAfx.cpp | 12 +- .../Code/OGL/Dagger/StdAfx.h | 52 +- .../Code/OGL/Dagger/hierwin.h | 232 +- .../Code/OGL/Dagger/resource.h | 84 +- quat2eul.cpp | 4 +- 353 files changed, 60750 insertions(+), 60750 deletions(-) diff --git a/2D Collision/code/FATE/ENGINE.h b/2D Collision/code/FATE/ENGINE.h index f7a10b7..c556d95 100644 --- a/2D Collision/code/FATE/ENGINE.h +++ b/2D Collision/code/FATE/ENGINE.h @@ -1,89 +1,89 @@ -/***************************************************************** - - Engine.H - Game Engine Structures -*****************************************************************/ - -#ifndef ENGINE_H -#define ENGINE_H - -#define MAX_FRAMES 100 /* MAXIMUM FRAMES PER DESC */ - -typedef long fixed28; - -typedef unsigned char uchar; - -// STRUCTURE DEFINITIONS... -// 2D POINT TYPE FOR SECTORS...FIXED POINT X AND Y -typedef struct POINT2D -{ - long x, y; -} tPoint2D; - -typedef struct POINT3D -{ - long x, y, z; -} tPoint3D; - -/***************************************** - INSIDE SECTOR STRUCTURE: -*****************************************/ - - /* quadrant id's, incremental angles, accumulated angle values */ -typedef short quadrant_type; - - /* result value from point in polygon test */ -typedef enum pt_poly_relation {INSIDE, OUTSIDE} pt_poly_relation; - - /* determine the quadrant of a polygon point - relative to the test point */ -#define quadrant(vertex, x, y) \ - ( (vertex.x > x) ? ((vertex.y > y) ? 0 : 3) : ( (vertex.y > y) ? 1 : 2) ) - - /* determine x intercept of a polygon edge - with a horizontal line at the y value of the test point */ -#define x_intercept(pt1, pt2, yy) \ - (pt2.x - ( ((pt2.y - yy) * (pt1.x - pt2.x)) / (pt1.y - pt2.y) ) ) - - /* adjust delta */ -#define adjust_delta(delta, vertex, next_vertex, xx, yy) \ - switch (delta) { \ - /* make quadrant deltas wrap around */ \ - case 3: delta = -1; break; \ - case -3: delta = 1; break; \ - /* check if went around point cw or ccw */ \ - case 2: case -2: if (x_intercept(vertex, next_vertex, yy) > xx) \ - delta = - (delta); \ - break; \ - } - - -/* 2D EDGE STRUCTURE */ -typedef struct { - tPoint2D pos; /* Coords of Start */ - short nextedge,prevedge,backedge; - short sector,backsector; - short tex1,tex2; - uchar Uoff,Voff,Uscale,Vscale; - long shade; - long flags; - long pad1,pad2,pad3; -} tEdge; - -#define SECTOR_FLAGS_CLOSED 1 -#define SECTOR_FLAGS_VISITED 2 - -/* 2D SECTOR STRUCTURE */ -typedef struct { - short edge,edgecnt; /* FIRST EDGE # and COUNT */ - long ceil_height,floor_height; - short floor_flags,floor_tex; - uchar floor_Uoff,floor_Voff,floor_Uscale,floor_Vscale; - long floor_shade; - short ceil_flags,ceil_tex; - uchar ceil_Uoff,ceil_Voff,ceil_Uscale,ceil_Vscale; - long ceil_shade; - long flags,pad2,pad3; // FOR LATER EXPANSION -} tSector; - +/***************************************************************** + + Engine.H + Game Engine Structures +*****************************************************************/ + +#ifndef ENGINE_H +#define ENGINE_H + +#define MAX_FRAMES 100 /* MAXIMUM FRAMES PER DESC */ + +typedef long fixed28; + +typedef unsigned char uchar; + +// STRUCTURE DEFINITIONS... +// 2D POINT TYPE FOR SECTORS...FIXED POINT X AND Y +typedef struct POINT2D +{ + long x, y; +} tPoint2D; + +typedef struct POINT3D +{ + long x, y, z; +} tPoint3D; + +/***************************************** + INSIDE SECTOR STRUCTURE: +*****************************************/ + + /* quadrant id's, incremental angles, accumulated angle values */ +typedef short quadrant_type; + + /* result value from point in polygon test */ +typedef enum pt_poly_relation {INSIDE, OUTSIDE} pt_poly_relation; + + /* determine the quadrant of a polygon point + relative to the test point */ +#define quadrant(vertex, x, y) \ + ( (vertex.x > x) ? ((vertex.y > y) ? 0 : 3) : ( (vertex.y > y) ? 1 : 2) ) + + /* determine x intercept of a polygon edge + with a horizontal line at the y value of the test point */ +#define x_intercept(pt1, pt2, yy) \ + (pt2.x - ( ((pt2.y - yy) * (pt1.x - pt2.x)) / (pt1.y - pt2.y) ) ) + + /* adjust delta */ +#define adjust_delta(delta, vertex, next_vertex, xx, yy) \ + switch (delta) { \ + /* make quadrant deltas wrap around */ \ + case 3: delta = -1; break; \ + case -3: delta = 1; break; \ + /* check if went around point cw or ccw */ \ + case 2: case -2: if (x_intercept(vertex, next_vertex, yy) > xx) \ + delta = - (delta); \ + break; \ + } + + +/* 2D EDGE STRUCTURE */ +typedef struct { + tPoint2D pos; /* Coords of Start */ + short nextedge,prevedge,backedge; + short sector,backsector; + short tex1,tex2; + uchar Uoff,Voff,Uscale,Vscale; + long shade; + long flags; + long pad1,pad2,pad3; +} tEdge; + +#define SECTOR_FLAGS_CLOSED 1 +#define SECTOR_FLAGS_VISITED 2 + +/* 2D SECTOR STRUCTURE */ +typedef struct { + short edge,edgecnt; /* FIRST EDGE # and COUNT */ + long ceil_height,floor_height; + short floor_flags,floor_tex; + uchar floor_Uoff,floor_Voff,floor_Uscale,floor_Vscale; + long floor_shade; + short ceil_flags,ceil_tex; + uchar ceil_Uoff,ceil_Voff,ceil_Uscale,ceil_Vscale; + long ceil_shade; + long flags,pad2,pad3; // FOR LATER EXPANSION +} tSector; + #endif \ No newline at end of file diff --git a/2D Collision/code/FATE/FATE.cpp b/2D Collision/code/FATE/FATE.cpp index f1cfbf4..f910735 100644 --- a/2D Collision/code/FATE/FATE.cpp +++ b/2D Collision/code/FATE/FATE.cpp @@ -1,149 +1,149 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Fate.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of 2D Collision System -// -// Created: -// JL 11/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Fate.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CFateApp - -BEGIN_MESSAGE_MAP(CFateApp, CWinApp) - //{{AFX_MSG_MAP(CFateApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CFateApp construction - -CFateApp::CFateApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CFateApp object - -CFateApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CFateApp initialization - -BOOL CFateApp::InitInstance() -{ - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - public: - virtual BOOL DestroyWindow(); - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CFateApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CFateApp commands - -BOOL CAboutDlg::DestroyWindow() -{ - // TODO: Add your specialized code here and/or call the base class - - return CDialog::DestroyWindow(); -} +/////////////////////////////////////////////////////////////////////////////// +// +// Fate.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of 2D Collision System +// +// Created: +// JL 11/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Fate.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CFateApp + +BEGIN_MESSAGE_MAP(CFateApp, CWinApp) + //{{AFX_MSG_MAP(CFateApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CFateApp construction + +CFateApp::CFateApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CFateApp object + +CFateApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CFateApp initialization + +BOOL CFateApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + public: + virtual BOOL DestroyWindow(); + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CFateApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CFateApp commands + +BOOL CAboutDlg::DestroyWindow() +{ + // TODO: Add your specialized code here and/or call the base class + + return CDialog::DestroyWindow(); +} diff --git a/2D Collision/code/FATE/FATE.h b/2D Collision/code/FATE/FATE.h index 0b91882..3fb604b 100644 --- a/2D Collision/code/FATE/FATE.h +++ b/2D Collision/code/FATE/FATE.h @@ -1,38 +1,38 @@ -// Fate.h : main header file for the FATE application -// - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CFateApp: -// See Fate.cpp for the implementation of this class -// - -class CFateApp : public CWinApp -{ -public: - CFateApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CFateApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CFateApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// +// Fate.h : main header file for the FATE application +// + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CFateApp: +// See Fate.cpp for the implementation of this class +// + +class CFateApp : public CWinApp +{ +public: + CFateApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CFateApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CFateApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// diff --git a/2D Collision/code/FATE/Fate.mak b/2D Collision/code/FATE/Fate.mak index e38cace..f9b9755 100644 --- a/2D Collision/code/FATE/Fate.mak +++ b/2D Collision/code/FATE/Fate.mak @@ -1,425 +1,425 @@ -# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -!IF "$(CFG)" == "" -CFG=Fate - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Fate - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Fate - Win32 Release" && "$(CFG)" != "Fate - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE on this makefile -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Fate.mak" CFG="Fate - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Fate - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Fate - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF -################################################################################ -# Begin Project -# PROP Target_Last_Scanned "Fate - Win32 Debug" -RSC=rc.exe -MTL=mktyplib.exe -CPP=cl.exe - -!IF "$(CFG)" == "Fate - Win32 Release" - -# PROP BASE Use_MFC 6 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 5 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "$(OUTDIR)\Fate.exe" "$(OUTDIR)\Fate.hlp" - -CLEAN : - -@erase "$(INTDIR)\Fate.hlp" - -@erase "$(INTDIR)\Fate.obj" - -@erase "$(INTDIR)\Fate.pch" - -@erase "$(INTDIR)\Fate.res" - -@erase "$(INTDIR)\FateDoc.obj" - -@erase "$(INTDIR)\FateView.obj" - -@erase "$(INTDIR)\Loadpcx.obj" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\SecAttr.obj" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(OUTDIR)\Fate.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /c -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ - "_MBCS" /Fp"$(INTDIR)/Fate.pch" /Yu"stdafx.h" /Fo"$(INTDIR)/" /c -CPP_OBJS=.\Release/ -CPP_SBRS=.\. -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /win32 -MTL_PROJ=/nologo /D "NDEBUG" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" -# ADD RSC /l 0x409 /d "NDEBUG" -RSC_PROJ=/l 0x409 /fo"$(INTDIR)/Fate.res" /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/Fate.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 -# ADD LINK32 winmm.lib /nologo /subsystem:windows /machine:I386 -LINK32_FLAGS=winmm.lib /nologo /subsystem:windows /incremental:no\ - /pdb:"$(OUTDIR)/Fate.pdb" /machine:I386 /out:"$(OUTDIR)/Fate.exe" -LINK32_OBJS= \ - "$(INTDIR)\Fate.obj" \ - "$(INTDIR)\Fate.res" \ - "$(INTDIR)\FateDoc.obj" \ - "$(INTDIR)\FateView.obj" \ - "$(INTDIR)\Loadpcx.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\SecAttr.obj" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\Fate.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Fate - Win32 Debug" - -# PROP BASE Use_MFC 6 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 6 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -OUTDIR=.\Debug -INTDIR=.\Debug - -ALL : "$(OUTDIR)\Fate.exe" "$(OUTDIR)\Fate.hlp" - -CLEAN : - -@erase "$(INTDIR)\Fate.hlp" - -@erase "$(INTDIR)\Fate.obj" - -@erase "$(INTDIR)\Fate.pch" - -@erase "$(INTDIR)\Fate.res" - -@erase "$(INTDIR)\FateDoc.obj" - -@erase "$(INTDIR)\FateView.obj" - -@erase "$(INTDIR)\Loadpcx.obj" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\SecAttr.obj" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc40.idb" - -@erase "$(INTDIR)\vc40.pdb" - -@erase "$(OUTDIR)\Fate.exe" - -@erase "$(OUTDIR)\Fate.ilk" - -@erase "$(OUTDIR)\Fate.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c -CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Fate.pch" /Yu"stdafx.h" /Fo"$(INTDIR)/"\ - /Fd"$(INTDIR)/" /c -CPP_OBJS=.\Debug/ -CPP_SBRS=.\. -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /win32 -MTL_PROJ=/nologo /D "_DEBUG" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" -# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" -RSC_PROJ=/l 0x409 /fo"$(INTDIR)/Fate.res" /d "_DEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/Fate.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 winmm.lib /nologo /subsystem:windows /debug /machine:I386 -LINK32_FLAGS=winmm.lib /nologo /subsystem:windows /incremental:yes\ - /pdb:"$(OUTDIR)/Fate.pdb" /debug /machine:I386 /out:"$(OUTDIR)/Fate.exe" -LINK32_OBJS= \ - "$(INTDIR)\Fate.obj" \ - "$(INTDIR)\Fate.res" \ - "$(INTDIR)\FateDoc.obj" \ - "$(INTDIR)\FateView.obj" \ - "$(INTDIR)\Loadpcx.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\SecAttr.obj" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\Fate.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -################################################################################ -# Begin Target - -# Name "Fate - Win32 Release" -# Name "Fate - Win32 Debug" - -!IF "$(CFG)" == "Fate - Win32 Release" - -!ELSEIF "$(CFG)" == "Fate - Win32 Debug" - -!ENDIF - -################################################################################ -# Begin Source File - -SOURCE=.\ReadMe.txt - -!IF "$(CFG)" == "Fate - Win32 Release" - -!ELSEIF "$(CFG)" == "Fate - Win32 Debug" - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\Fate.cpp -DEP_CPP_FATE_=\ - ".\AmpDefs.h"\ - ".\engine.h"\ - ".\Fate.h"\ - ".\FateDoc.h"\ - ".\FateView.h"\ - ".\loadpcx.h"\ - ".\MainFrm.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\Fate.obj" : $(SOURCE) $(DEP_CPP_FATE_) "$(INTDIR)"\ - "$(INTDIR)\Fate.pch" - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\StdAfx.cpp -DEP_CPP_STDAF=\ - ".\StdAfx.h"\ - - -!IF "$(CFG)" == "Fate - Win32 Release" - -# ADD CPP /Yc"stdafx.h" - -BuildCmds= \ - $(CPP) /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS"\ - /Fp"$(INTDIR)/Fate.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/" /c $(SOURCE) \ - - -"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" - $(BuildCmds) - -"$(INTDIR)\Fate.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" - $(BuildCmds) - -!ELSEIF "$(CFG)" == "Fate - Win32 Debug" - -# ADD CPP /Yc"stdafx.h" - -BuildCmds= \ - $(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Fate.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/"\ - /Fd"$(INTDIR)/" /c $(SOURCE) \ - - -"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" - $(BuildCmds) - -"$(INTDIR)\Fate.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" - $(BuildCmds) - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\MainFrm.cpp -DEP_CPP_MAINF=\ - ".\Fate.h"\ - ".\MainFrm.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ - "$(INTDIR)\Fate.pch" - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\FateDoc.cpp -DEP_CPP_FATED=\ - ".\Fate.h"\ - ".\FateDoc.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\FateDoc.obj" : $(SOURCE) $(DEP_CPP_FATED) "$(INTDIR)"\ - "$(INTDIR)\Fate.pch" - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\FateView.cpp -DEP_CPP_FATEV=\ - ".\AmpDefs.h"\ - ".\engine.h"\ - ".\Fate.h"\ - ".\FateDoc.h"\ - ".\FateView.h"\ - ".\loadpcx.h"\ - ".\MainFrm.h"\ - ".\SecAttr.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\FateView.obj" : $(SOURCE) $(DEP_CPP_FATEV) "$(INTDIR)"\ - "$(INTDIR)\Fate.pch" - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\Fate.rc -DEP_RSC_FATE_R=\ - ".\res\Fate.ico"\ - ".\res\Fate.rc2"\ - ".\res\FateDoc.ico"\ - ".\res\Toolbar.bmp"\ - - -"$(INTDIR)\Fate.res" : $(SOURCE) $(DEP_RSC_FATE_R) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\hlp\Fate.hpj - -!IF "$(CFG)" == "Fate - Win32 Release" - -# Begin Custom Build - Making help file... -OutDir=.\Release -ProjDir=. -TargetName=Fate -InputPath=.\hlp\Fate.hpj - -"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - "$(ProjDir)\makehelp.bat" - -# End Custom Build - -!ELSEIF "$(CFG)" == "Fate - Win32 Debug" - -# Begin Custom Build - Making help file... -OutDir=.\Debug -ProjDir=. -TargetName=Fate -InputPath=.\hlp\Fate.hpj - -"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - "$(ProjDir)\makehelp.bat" - -# End Custom Build - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\SecAttr.cpp -DEP_CPP_SECAT=\ - ".\engine.h"\ - ".\Fate.h"\ - ".\loadpcx.h"\ - ".\SecAttr.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\SecAttr.obj" : $(SOURCE) $(DEP_CPP_SECAT) "$(INTDIR)"\ - "$(INTDIR)\Fate.pch" - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\Loadpcx.cpp -DEP_CPP_LOADP=\ - ".\loadpcx.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\Loadpcx.obj" : $(SOURCE) $(DEP_CPP_LOADP) "$(INTDIR)"\ - "$(INTDIR)\Fate.pch" - - -# End Source File -# End Target -# End Project -################################################################################ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Fate - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Fate - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Fate - Win32 Release" && "$(CFG)" != "Fate - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Fate.mak" CFG="Fate - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Fate - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Fate - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Fate - Win32 Debug" +RSC=rc.exe +MTL=mktyplib.exe +CPP=cl.exe + +!IF "$(CFG)" == "Fate - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 5 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\Fate.exe" "$(OUTDIR)\Fate.hlp" + +CLEAN : + -@erase "$(INTDIR)\Fate.hlp" + -@erase "$(INTDIR)\Fate.obj" + -@erase "$(INTDIR)\Fate.pch" + -@erase "$(INTDIR)\Fate.res" + -@erase "$(INTDIR)\FateDoc.obj" + -@erase "$(INTDIR)\FateView.obj" + -@erase "$(INTDIR)\Loadpcx.obj" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\SecAttr.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(OUTDIR)\Fate.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\ + "_MBCS" /Fp"$(INTDIR)/Fate.pch" /Yu"stdafx.h" /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/Fate.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Fate.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 winmm.lib /nologo /subsystem:windows /machine:I386 +LINK32_FLAGS=winmm.lib /nologo /subsystem:windows /incremental:no\ + /pdb:"$(OUTDIR)/Fate.pdb" /machine:I386 /out:"$(OUTDIR)/Fate.exe" +LINK32_OBJS= \ + "$(INTDIR)\Fate.obj" \ + "$(INTDIR)\Fate.res" \ + "$(INTDIR)\FateDoc.obj" \ + "$(INTDIR)\FateView.obj" \ + "$(INTDIR)\Loadpcx.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\SecAttr.obj" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\Fate.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Fate - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Fate.exe" "$(OUTDIR)\Fate.hlp" + +CLEAN : + -@erase "$(INTDIR)\Fate.hlp" + -@erase "$(INTDIR)\Fate.obj" + -@erase "$(INTDIR)\Fate.pch" + -@erase "$(INTDIR)\Fate.res" + -@erase "$(INTDIR)\FateDoc.obj" + -@erase "$(INTDIR)\FateView.obj" + -@erase "$(INTDIR)\Loadpcx.obj" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\SecAttr.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\Fate.exe" + -@erase "$(OUTDIR)\Fate.ilk" + -@erase "$(OUTDIR)\Fate.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Fate.pch" /Yu"stdafx.h" /Fo"$(INTDIR)/"\ + /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/Fate.res" /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Fate.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 winmm.lib /nologo /subsystem:windows /debug /machine:I386 +LINK32_FLAGS=winmm.lib /nologo /subsystem:windows /incremental:yes\ + /pdb:"$(OUTDIR)/Fate.pdb" /debug /machine:I386 /out:"$(OUTDIR)/Fate.exe" +LINK32_OBJS= \ + "$(INTDIR)\Fate.obj" \ + "$(INTDIR)\Fate.res" \ + "$(INTDIR)\FateDoc.obj" \ + "$(INTDIR)\FateView.obj" \ + "$(INTDIR)\Loadpcx.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\SecAttr.obj" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\Fate.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "Fate - Win32 Release" +# Name "Fate - Win32 Debug" + +!IF "$(CFG)" == "Fate - Win32 Release" + +!ELSEIF "$(CFG)" == "Fate - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\ReadMe.txt + +!IF "$(CFG)" == "Fate - Win32 Release" + +!ELSEIF "$(CFG)" == "Fate - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Fate.cpp +DEP_CPP_FATE_=\ + ".\AmpDefs.h"\ + ".\engine.h"\ + ".\Fate.h"\ + ".\FateDoc.h"\ + ".\FateView.h"\ + ".\loadpcx.h"\ + ".\MainFrm.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\Fate.obj" : $(SOURCE) $(DEP_CPP_FATE_) "$(INTDIR)"\ + "$(INTDIR)\Fate.pch" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\StdAfx.cpp +DEP_CPP_STDAF=\ + ".\StdAfx.h"\ + + +!IF "$(CFG)" == "Fate - Win32 Release" + +# ADD CPP /Yc"stdafx.h" + +BuildCmds= \ + $(CPP) /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS"\ + /Fp"$(INTDIR)/Fate.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\Fate.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "Fate - Win32 Debug" + +# ADD CPP /Yc"stdafx.h" + +BuildCmds= \ + $(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Fate.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/"\ + /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\Fate.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\MainFrm.cpp +DEP_CPP_MAINF=\ + ".\Fate.h"\ + ".\MainFrm.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ + "$(INTDIR)\Fate.pch" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FateDoc.cpp +DEP_CPP_FATED=\ + ".\Fate.h"\ + ".\FateDoc.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\FateDoc.obj" : $(SOURCE) $(DEP_CPP_FATED) "$(INTDIR)"\ + "$(INTDIR)\Fate.pch" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FateView.cpp +DEP_CPP_FATEV=\ + ".\AmpDefs.h"\ + ".\engine.h"\ + ".\Fate.h"\ + ".\FateDoc.h"\ + ".\FateView.h"\ + ".\loadpcx.h"\ + ".\MainFrm.h"\ + ".\SecAttr.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\FateView.obj" : $(SOURCE) $(DEP_CPP_FATEV) "$(INTDIR)"\ + "$(INTDIR)\Fate.pch" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Fate.rc +DEP_RSC_FATE_R=\ + ".\res\Fate.ico"\ + ".\res\Fate.rc2"\ + ".\res\FateDoc.ico"\ + ".\res\Toolbar.bmp"\ + + +"$(INTDIR)\Fate.res" : $(SOURCE) $(DEP_RSC_FATE_R) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hlp\Fate.hpj + +!IF "$(CFG)" == "Fate - Win32 Release" + +# Begin Custom Build - Making help file... +OutDir=.\Release +ProjDir=. +TargetName=Fate +InputPath=.\hlp\Fate.hpj + +"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + "$(ProjDir)\makehelp.bat" + +# End Custom Build + +!ELSEIF "$(CFG)" == "Fate - Win32 Debug" + +# Begin Custom Build - Making help file... +OutDir=.\Debug +ProjDir=. +TargetName=Fate +InputPath=.\hlp\Fate.hpj + +"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + "$(ProjDir)\makehelp.bat" + +# End Custom Build + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SecAttr.cpp +DEP_CPP_SECAT=\ + ".\engine.h"\ + ".\Fate.h"\ + ".\loadpcx.h"\ + ".\SecAttr.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\SecAttr.obj" : $(SOURCE) $(DEP_CPP_SECAT) "$(INTDIR)"\ + "$(INTDIR)\Fate.pch" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Loadpcx.cpp +DEP_CPP_LOADP=\ + ".\loadpcx.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\Loadpcx.obj" : $(SOURCE) $(DEP_CPP_LOADP) "$(INTDIR)"\ + "$(INTDIR)\Fate.pch" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/2D Collision/code/FATE/Mainfrm.cpp b/2D Collision/code/FATE/Mainfrm.cpp index 503141b..364a8ac 100644 --- a/2D Collision/code/FATE/Mainfrm.cpp +++ b/2D Collision/code/FATE/Mainfrm.cpp @@ -1,1366 +1,1366 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of 2D Collision System -// -// Created: -// JL 11/1/98 -// -// Notes: THIS CONTAINS SOME USEFUL COMPUTATIONAL GEOMETRY ROUTINES AT THE -// END OF THIS FILE. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include -#include "Fate.h" - -#include "MainFrm.h" - -//IGNORE THE DOUBLE TO FLOAT CONVERSION WARNING -#pragma warning ( disable : 4244 ) - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_COMMAND(ID_OPTIONS_GRID_DOWN, OnOptionsGridDown) - ON_COMMAND(ID_OPTIONS_GRIDUP, OnOptionsGridup) - ON_WM_KEYDOWN() - ON_COMMAND(ID_OPTIONS_ZOOMIN, OnOptionsZoomin) - ON_COMMAND(ID_OPTIONS_ZOOMOUT, OnOptionsZoomout) - ON_WM_LBUTTONDOWN() - ON_WM_LBUTTONUP() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_RBUTTONUP() - ON_WM_PAINT() - ON_COMMAND(ID_FILE_NEW, OnFileNew) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - //}}AFX_MSG_MAP - // Global help commands -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_INFO, // status line INFO - ID_INDICATOR_SNAP, // status line SNAP - ID_INDICATOR_GRID, // status line GRIDSIZE - ID_INDICATOR_SC2, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_offX = 0; - m_offY = 0; - m_scale = 0.4; - m_gridsize = 64; - m_snap = TRUE; - m_point = NULL; - // SET UP THE WORLD VARIABLES - m_cursector = NULL; - m_curedge = NULL; - m_firstedge = NULL; // FIRST EDGE IN A SECTOR - m_edgecnt = 0; - m_sectorcnt = 0; - m_nearest_edge = -1; - m_nearest_pnt.x = 0; - m_nearest_pnt.y = 0; - m_old_pnt.x = -2; - m_old_pnt.y = -2; - - m_cam_pos.x = 0; - m_cam_pos.y = 0; - m_cam_pos.z = 0; - m_cam_yaw = 0; - m_cam_pitch = 0; - m_cam_sector = -1; - - InitTrig(); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - char str[80]; - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - GetWindowRect(&m_window_rect); - - sprintf(str,"Zoom = %2.1f",m_scale); - SetStatusText(4,str); - sprintf(str,"Grid = %3d",m_gridsize); - SetStatusText(3,str); - SetStatusText(2,"Snap On"); - sprintf(str,"Sectors = %3d Edges = %3d",m_sectorcnt,m_edgecnt); - SetStatusText(1,str); - - return 0; -} - -void CMainFrame::SetStatusText(short id,char *string ) -{ - m_wndStatusBar.SetPaneText(id,string); -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - // TODO: Modify the Window class or styles here by modifying - // the CREATESTRUCT cs - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// Scale the Grid Size Up -void CMainFrame::OnOptionsGridup() -{ - char str[80]; - if (m_gridsize <= 1024) m_gridsize *= 2; - sprintf(str,"Grid = %4d",m_gridsize); - SetStatusText(3,str); - Invalidate (TRUE); -} - -///////////////////////////////////////////////////////////////////////////// -// Scale the Grid Size Down -void CMainFrame::OnOptionsGridDown() -{ - char str[80]; - if (m_gridsize > 2) - { - m_gridsize /= 2; - sprintf(str,"Grid = %4d",m_gridsize); - } - else - { - m_gridsize = 1; - sprintf(str,"Grid OFF"); - } - SetStatusText(3,str); - Invalidate (TRUE); -} - -void CMainFrame::OnOptionsZoomin() -{ - char str[80]; - if (m_scale <= 10.0) m_scale += .1; - sprintf(str,"Zoom = %2.1f",m_scale); - SetStatusText(4,str); - Invalidate (TRUE); -} - -void CMainFrame::OnOptionsZoomout() -{ - char str[80]; - if (m_scale > 0.2) - { - m_scale -= 0.1; - } - sprintf(str,"Zoom = %2.1f",m_scale); - SetStatusText(4,str); - Invalidate (TRUE); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - tPoint3D temp; - tPoint2D temp2D; - int cx, cy; - CRect rect; - cx = (GetSystemMetrics(SM_CXFULLSCREEN) - (640 + 8)) / 2; - cy = (GetSystemMetrics(SM_CYFULLSCREEN) - (480 + 94)) / 2; - - switch (nChar) - { - case VK_INSERT: - InsertPoint(); - Invalidate(TRUE); - break; - case VK_DELETE: - DeleteSector(); - Invalidate(TRUE); - break; - case VK_RETURN: - CloseSector(); - Invalidate(TRUE); - break; - case VK_ADD: - OnOptionsGridup(); - break; - case VK_SUBTRACT: - OnOptionsGridDown(); - break; - case 'A': - OnOptionsZoomin(); - break; - case 'M': - break; - case 'Z': - OnOptionsZoomout(); - break; - case 'S': - m_snap = TRUE - m_snap; - if (m_snap) - SetStatusText(2,"Snap On"); - else - SetStatusText(2,"Snap Off"); - break; - case VK_UP: - temp.x = m_cam_pos.x + (m_sin[m_cam_yaw]>>13); - temp.z = m_cam_pos.z + (m_cos[m_cam_yaw]>>13); - if (m_cam_sector == -1) - { - m_cam_pos.x = temp.x; - m_cam_pos.z = temp.z; - temp2D.x = temp.x; - temp2D.y = temp.z; - m_cam_sector = InsideSector(&temp2D); - } - else - { - if (CheckCollision(m_cam_sector,&temp)) - { - m_cam_pos.x = temp.x; - m_cam_pos.z = temp.z; - } - } - Invalidate(TRUE); - break; - case VK_DOWN: - temp.x = m_cam_pos.x - (m_sin[m_cam_yaw]>>13); - temp.z = m_cam_pos.z - (m_cos[m_cam_yaw]>>13); - if (m_cam_sector == -1) - { - m_cam_pos.x = temp.x; - m_cam_pos.z = temp.z; - temp2D.x = temp.x; - temp2D.y = temp.z; - m_cam_sector = InsideSector(&temp2D); - } - else - { - if (CheckCollision(m_cam_sector,&temp)) - { - m_cam_pos.x = temp.x; - m_cam_pos.z = temp.z; - } - } - Invalidate(TRUE); - break; - case VK_LEFT: - m_cam_yaw += (4096 - 128); - m_cam_yaw %= 4096; - Invalidate(TRUE); - break; - case VK_RIGHT: - m_cam_yaw += 128; - m_cam_yaw %= 4096; - Invalidate(TRUE); - break; - } - - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonUp -// Purpose: Right Mouse Button Handler -////////////////////////////////////////////////////////////////// -void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) -{ - tPoint2D temp; - // MOVE THE CAMERA POSITION TO WHERE THE USER CLICKS - m_cam_pos.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); - m_cam_pos.z = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale); - temp.x = m_cam_pos.x; - temp.y = m_cam_pos.z; - m_cam_sector = InsideSector(&temp); - Invalidate(TRUE); - CFrameWnd::OnRButtonUp(nFlags, point); -} - -#define VERTEX_SNAP_PROXIMITY 100 - -void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) -{ - short loop,t_sector,t_edge; - tPoint2D temp; - long dist; - char message[80]; - - temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); - temp.y = (long)-((point.y + m_offY - (m_sizeY / 2)) / m_scale); - if ((nFlags & MK_CONTROL) > 0) - { - t_sector = -1; - for (loop = 0; loop < m_edgecnt; loop++) - { - dist = (temp.x - m_edgelist[loop].pos.x) * // SQUARED DISTANCE - (temp.x - m_edgelist[loop].pos.x) + - (temp.y - m_edgelist[loop].pos.y) * - (temp.y - m_edgelist[loop].pos.y); - if (dist < VERTEX_SNAP_PROXIMITY) - { - temp.x = m_edgelist[loop].pos.x; - temp.y = m_edgelist[loop].pos.y; - t_sector = m_edgelist[loop].sector; - t_edge = loop; - } - } - if (t_sector == -1) // IF I DIDN'T CLICK ON AN EXISTING POINT, SNAP IT - { - SnapPoint(&temp); - // CHECK ALL POINTS AGAIN ONCE I HAVE SNAPPED - for (loop = 0; loop < m_edgecnt; loop++) - { - dist = (temp.x - m_edgelist[loop].pos.x) * // SQUARED DISTANCE - (temp.x - m_edgelist[loop].pos.x) + - (temp.y - m_edgelist[loop].pos.y) * - (temp.y - m_edgelist[loop].pos.y); - if (dist < VERTEX_SNAP_PROXIMITY) - { - temp.x = m_edgelist[loop].pos.x; - temp.y = m_edgelist[loop].pos.y; - t_sector = m_edgelist[loop].sector; - t_edge = loop; - } - } - } - if (m_cursector == NULL) // haven't created a sector - { - m_cursector = &m_sectorlist[m_sectorcnt]; - m_cursector->edge = m_edgecnt; - m_cursector->edgecnt = 1; - m_cursector->flags = 0; - m_curedge = &m_edgelist[m_edgecnt]; - m_curedge->pos.x = temp.x; - m_curedge->pos.y = temp.y; - m_curedge->sector = m_sectorcnt; - m_curedge->backsector = -1; - m_curedge->backedge = -1; - m_curedge->nextedge = -1; - m_curedge->prevedge = -1; - m_firstedge = m_curedge; - m_sectorcnt++; - m_edgecnt++; - Invalidate(TRUE); - } - else - { - if (&m_sectorlist[t_sector] == m_cursector) - { - if (t_edge == m_cursector->edge) // CLOSED THE SECTOR - { - m_curedge->nextedge = m_cursector->edge; - m_firstedge->prevedge = m_edgecnt - 1; // LINK BACK THE START TO THE END - m_cursector->flags = SECTOR_FLAGS_CLOSED; - m_cursector->ceil_tex = 0; - m_cursector->floor_tex = 0; - m_cursector->floor_height = 0; - m_cursector->ceil_height = 2048; - m_cursector = NULL; - CheckDoubleSided(); - } - } - else - { - m_curedge->nextedge = m_edgecnt; - m_cursector->edgecnt++; - m_curedge = &m_edgelist[m_edgecnt]; - m_curedge->pos.x = temp.x; - m_curedge->pos.y = temp.y; - m_curedge->sector = m_sectorcnt - 1; - m_curedge->backsector = -1; - m_curedge->backedge = -1; - m_curedge->nextedge = -1; - m_curedge->prevedge = m_edgecnt - 1; - m_edgecnt++; - } - Invalidate(TRUE); - } - m_point = NULL; - sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); - SetStatusText(1,message); - } - else if ((nFlags & MK_SHIFT) > 0) - { - m_clickpoint = point; - } - else // MOVE A SET POINT - { - m_point = NULL; - for (loop = 0; loop < m_edgecnt; loop++) - { - dist = (temp.x - m_edgelist[loop].pos.x) * - (temp.x - m_edgelist[loop].pos.x) + - (temp.y - m_edgelist[loop].pos.y) * - (temp.y - m_edgelist[loop].pos.y); - if (dist < 100) - { - m_temppoint.x = m_edgelist[loop].pos.x; - m_temppoint.y = m_edgelist[loop].pos.y; - m_point = &m_edgelist[loop].pos; - Invalidate(TRUE); - break; - } - } - } - CFrameWnd::OnLButtonDown(nFlags, point); -} - -void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point) -{ - short loop; - char message[80]; - short t_edge,next; - if (m_point != NULL) - { - SnapPoint(m_point); - // Check if I need to delete similar edges - CheckDeleteEdges(&m_temppoint,m_point); - // MOVE ALL POINTS THAT WERE AT THE SAME LOCATION - for (loop = 0; loop < m_edgecnt; loop++) - { - if (m_temppoint.x == m_edgelist[loop].pos.x && - m_temppoint.y == m_edgelist[loop].pos.y) - { - m_edgelist[loop].pos.x = m_point->x; - m_edgelist[loop].pos.y = m_point->y; - } - // STORE OFF THE MOVED POINT - if (m_point == &m_edgelist[loop].pos) - t_edge = loop; - } - // CHECK IF I NEED TO DELETE THIS EDGE - next = m_edgelist[t_edge].nextedge; - if (m_point->x == m_edgelist[next].pos.x && - m_point->y == m_edgelist[next].pos.y) - { - DeleteEdge(t_edge); - } - - CheckDoubleSided(); - - sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); - SetStatusText(1,message); - Invalidate(TRUE); - } - CFrameWnd::OnLButtonUp(nFlags, point); -} - -void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - tPoint2D temp; - char message[80]; - short sec; - - temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); - temp.y = (long)-((point.y + m_offY - (m_sizeY / 2)) / m_scale); - - sec = InsideSector(&temp); - - if (sec == -1) - { - MessageBox("Not inside any..","Inside Sector Test",MB_OK); - } - else - { - sprintf(message,"Inside Sector %d",sec); - MessageBox(message,"Inside Sector Test",MB_OK); - } - CFrameWnd::OnLButtonDblClk(nFlags, point); -} - -void CMainFrame::OnMouseMove(UINT nFlags, CPoint point) -{ - long startX,startY; - short nearest; - CClientDC dc(this); // device context for painting - if ((nFlags & MK_LBUTTON) == MK_LBUTTON) - { - - if ((nFlags & MK_SHIFT) > 0) - { - m_offY += m_clickpoint.y - point.y; - m_offX += m_clickpoint.x - point.x; - Invalidate(TRUE); - m_clickpoint = point; - } - else if (m_point != NULL) - { - dc.SetROP2(R2_NOT); - // ERASE OLD POINT - startX = (m_point->x * m_scale) - m_offX + (m_sizeX / 2); - startY = (-m_point->y * m_scale) - m_offY + (m_sizeY / 2); - dc.MoveTo(startX-2,startY-2); - dc.LineTo(startX+2,startY-2); - dc.LineTo(startX+2,startY+2); - dc.LineTo(startX-2,startY+2); - dc.LineTo(startX-2,startY-2); - - m_point->x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); - m_point->y = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale); - - startX = (m_point->x * m_scale) - m_offX + (m_sizeX / 2); - startY = (-m_point->y * m_scale) - m_offY + (m_sizeY / 2); - dc.MoveTo(startX-2,startY-2); - dc.LineTo(startX+2,startY-2); - dc.LineTo(startX+2,startY+2); - dc.LineTo(startX-2,startY+2); - dc.LineTo(startX-2,startY-2); - } - } - else - { - dc.SetROP2(R2_NOT); - nearest = GetNearestEdge(point); - if (nearest >= 0) - { - m_nearest_edge = nearest; - // TODO: m_old_pnt is not defined at start - dc.MoveTo(m_old_pnt.x-1,m_old_pnt.y-1); - dc.LineTo(m_old_pnt.x+1,m_old_pnt.y-1); - dc.LineTo(m_old_pnt.x+1,m_old_pnt.y+1); - dc.LineTo(m_old_pnt.x-1,m_old_pnt.y+1); - dc.LineTo(m_old_pnt.x-1,m_old_pnt.y-1); - startX = (m_nearest_pnt.x * m_scale) - m_offX + (m_sizeX / 2); - startY = (-m_nearest_pnt.y * m_scale) - m_offY + (m_sizeY / 2); - dc.MoveTo(startX-1,startY-1); - dc.LineTo(startX+1,startY-1); - dc.LineTo(startX+1,startY+1); - dc.LineTo(startX-1,startY+1); - dc.LineTo(startX-1,startY-1); - m_old_pnt.x = startX; - m_old_pnt.y = startY; - } - } - CFrameWnd::OnMouseMove(nFlags, point); -} - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - Draw2DView(&dc); - // Do not call CFrameWnd::OnPaint() for painting messages -} - - - -void CMainFrame::OnFileNew() -{ - // RESET THE WORLD TO NOTHING - char message[80]; - m_sectorcnt = 0; - m_edgecnt = 0; - sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); - SetStatusText(1,message); - Invalidate(TRUE); -} - -// LOAD A SET OF SECTORS FROM A FILE -void CMainFrame::OnFileOpen() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Fate Files (*.fte)|*.FTE|All Files (*.*)|*.*||"; - char directory[80]; - CFileDialog *dialog; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY - _getcwd(directory,80); - dialog = new CFileDialog(TRUE,"FTE",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - fp = fopen(dialog->GetPathName(),"rb"); - if (fp != NULL) - { - fread(&m_sectorcnt,sizeof(short),1,fp); - fread(m_sectorlist,sizeof(tSector),m_sectorcnt,fp); - fread(&m_edgecnt,sizeof(short),1,fp); - fread(m_edgelist,sizeof(tEdge),m_edgecnt,fp); - fread(&m_cam_pos,sizeof(tPoint3D),1,fp); - fclose(fp); - } - } - // RESET THE MAIN DIRECTORY - _chdir(directory); - Invalidate(TRUE); -} - -// SAVE THE CURRENT SETUP TO A FILE -void CMainFrame::OnFileSave() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Fate Files (*.fte)|*.FTE|All Files (*.*)|*.*||"; - char directory[80]; - CFileDialog *dialog; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY - _getcwd(directory,80); - dialog = new CFileDialog(FALSE,"PFTE",NULL,OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - fp = fopen(dialog->GetPathName(),"wb"); - if (fp != NULL) - { - fwrite(&m_sectorcnt,sizeof(short),1,fp); - fwrite(m_sectorlist,sizeof(tSector),m_sectorcnt,fp); - fwrite(&m_edgecnt,sizeof(short),1,fp); - fwrite(m_edgelist,sizeof(tEdge), m_edgecnt,fp); - fwrite(&m_cam_pos,sizeof(tPoint3D),1,fp); - fclose(fp); - } - } - // RESET THE MAIN DIRECTORY - _chdir(directory); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame Implementation Functions - -// CREATE A FIXED POINT TRIG TABLE -void CMainFrame::InitTrig() -{ - int angle; - float f_angle; - - for(angle = 0; angle < MAX_ANGLE; angle++) - { - f_angle = ((float)angle * M_PI) / (MAX_ANGLE / 2); // Convert degrees to radians - m_sin[angle] = (long)(sin(f_angle) * (1 << PRECISION)); // Get fixed point sine 2^16 - m_cos[angle] = (long)(cos(f_angle) * (1 << PRECISION)); // Get fixed point cosine 2^16 - } -} - -///////////////////////////////////////////////////////////////////////////// -// Procedure: DrawCurPos -// Purpose: Draw the current POV Position on the Map -void CMainFrame::DrawCurPos(CDC* pDC) -{ - CPen penPOV; - long startX,startY,endX,endY; - double lenX,lenY; - short left,right; - - penPOV.CreatePen(PS_SOLID,1,0x00005000); - pDC->SelectObject(&penPOV); - - lenX = (double)((10 * m_sin[m_cam_yaw])/PRECMULT); - lenY = (double)((15 * m_cos[m_cam_yaw])/PRECMULT); - - startX = (m_cam_pos.x * m_scale) - m_offX + (m_sizeX / 2); - startY = (-m_cam_pos.z * m_scale) - m_offY + (m_sizeY / 2); - - endX = startX + lenX; - endY = startY - lenY; - - pDC->MoveTo(startX,startY); - pDC->LineTo(endX,endY); - - // DO THE ARROWHEAD PART - - startX = endX; - startY = endY; - - left = m_cam_yaw + 4096 - 512; - left %= 4096; - - lenX = (m_sin[left]>>13); - lenY = (m_cos[left]>>13); - - endX = startX - lenX; - endY = startY + lenY; - - pDC->MoveTo(startX,startY); - pDC->LineTo(endX,endY); - - right = m_cam_yaw + 512; - right %= 4096; - - lenX = (m_sin[right]>>13); - lenY = (m_cos[right]>>13); - - endX = startX - lenX; - endY = startY + lenY; - - pDC->MoveTo(startX,startY); - pDC->LineTo(endX,endY); - -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame drawing -void CMainFrame::Draw2DView(CDC* pDC) -{ - long startX,startY,tempX,tempY; - long loop,loop2,pos; - tPoint2D *pnt; - CPen pengrid,penclosedline,pendoublesided,penblue,penltblue,*curpen; - CRect aRect; - pDC->SetROP2(R2_COPYPEN); - - pengrid.CreatePen(PS_SOLID,1,0x00c0c0c0); - penclosedline.CreatePen(PS_SOLID,1,0x00505050); - pendoublesided.CreatePen(PS_SOLID,1,0x000000FF); - penblue.CreatePen(PS_SOLID,1,0x00FF0000); - penltblue.CreatePen(PS_SOLID,1,0x00FF4040); - pDC->SelectObject(&pengrid); - - - GetWindowRect(&aRect); - m_sizeX = aRect.right - aRect.left; - m_sizeY = aRect.bottom - aRect.top; - - - if (m_gridsize > 1) - { - startX = -65536; - startY = -65536; - // DO ALL THE COLUMNS - for (loop = startX; loop < 65536; loop += m_gridsize) - { - pos = (long)((double)loop * m_scale); - pos = pos - m_offX + (m_sizeX / 2); - if (pos >=0 && pos < m_sizeX) - { - pDC->MoveTo(pos,0); - pDC->LineTo(pos,m_sizeY); - } - } - // DO ALL THE COLUMNS - for (loop = startY; loop < 65536; loop += m_gridsize) - { - pos = (long)((double)loop * m_scale); - pos = pos - m_offY + (m_sizeY / 2); - if (pos >=0 && pos < m_sizeY) - { - pDC->MoveTo(0,pos); - pDC->LineTo(m_sizeX,pos); - } - } - } - - // DRAW ALL THE LINES - for (loop = 0; loop < m_sectorcnt; loop++) // FOR ALL THE SECTORS - { - if ((m_sectorlist[loop].flags & SECTOR_FLAGS_CLOSED) == 0) - { - curpen = &penltblue; - } - else - { - curpen = &penclosedline; - } - pos = m_sectorlist[loop].edge; - for (loop2 = 0; loop2 < m_sectorlist[loop].edgecnt; loop2++) - { - pnt = &m_edgelist[pos].pos; - tempX = (pnt->x * m_scale) - m_offX + (m_sizeX / 2); - tempY = (-pnt->y * m_scale) - m_offY + (m_sizeY / 2); - if (loop2 == 0) // FIRST EDGE SAVE POINT - { - pDC->MoveTo(tempX,tempY); - startX = tempX; - startY = tempY; - } - else - { - pDC->LineTo(tempX,tempY); - } - if (m_edgelist[pos].backedge > -1) - { - pDC->SelectObject(&pendoublesided); - } - else - { - pDC->SelectObject(curpen); - } - pos = m_edgelist[pos].nextedge; - } - if ((m_sectorlist[loop].flags & SECTOR_FLAGS_CLOSED) > 0) - { - pDC->LineTo(startX,startY); - } - } - - // DRAW THE POINTS - for (loop = 0; loop < m_sectorcnt; loop++) // FOR ALL THE SECTORS - { - pDC->SelectObject(&penblue); - pos = m_sectorlist[loop].edge; - for (loop2 = 0; loop2 < m_sectorlist[loop].edgecnt; loop2++) - { - pnt = &m_edgelist[pos].pos; - startX = (pnt->x * m_scale) - m_offX + (m_sizeX / 2); - startY = (-pnt->y * m_scale) - m_offY + (m_sizeY / 2); - pDC->MoveTo(startX-2,startY-2); - pDC->LineTo(startX+2,startY-2); - pDC->LineTo(startX+2,startY+2); - pDC->LineTo(startX-2,startY+2); - pDC->LineTo(startX-2,startY-2); - pos = m_edgelist[pos].nextedge; - } - } - - if (m_nearest_edge > -1) - { - pDC->SelectObject(&penltblue); - startX = (m_nearest_pnt.x * m_scale) - m_offX + (m_sizeX / 2); - startY = (-m_nearest_pnt.y * m_scale) - m_offY + (m_sizeY / 2); - pDC->MoveTo(startX-1,startY-1); - pDC->LineTo(startX+1,startY-1); - pDC->LineTo(startX+1,startY+1); - pDC->LineTo(startX-1,startY+1); - pDC->LineTo(startX-1,startY-1); - } - - DrawCurPos(pDC); -/* - sprintf(message,"Nearest #%d",m_nearest_edge); - m_MainFrame->SetStatusText(0,message);*/ -} - -void CMainFrame::TransformPoint(long world_x, long world_z, long *camera_x, long *camera_z) -{ - long move_x, move_z; - - /* DO POSITION. TRANSLATE ABOUT LOOK AT POINT.. */ - move_x = world_x - m_cam_pos.x; - move_z = world_z - m_cam_pos.z; - - /* DO YAW... */ - *camera_x = (FixMult(m_cos[m_cam_yaw],move_x)) - - (FixMult(m_sin[m_cam_yaw],move_z)); - - *camera_z = (FixMult(m_cos[m_cam_yaw],move_z)) + - (FixMult(m_sin[m_cam_yaw],move_x)); - -} - -BOOL CMainFrame::OnSamePos(short pos1,short pos2) -{ - if (m_edgelist[pos1].pos.x == m_edgelist[pos2].pos.x && - m_edgelist[pos1].pos.y == m_edgelist[pos2].pos.y) - return TRUE; - else - return FALSE; -} - -// CHECK FOR DOUBLE SIDED EDGES -void CMainFrame::CheckDoubleSided() -{ - short inner,outer; - for (outer = 0; outer < m_edgecnt; outer++) - { - for (inner = 0; inner < m_edgecnt; inner++) - { - // THEY SHARE AN EDGE IF - if (OnSamePos(outer,m_edgelist[inner].nextedge) && - OnSamePos(inner,m_edgelist[outer].nextedge)) - { - m_edgelist[inner].backedge = outer; - m_edgelist[inner].backsector = m_edgelist[outer].sector; - m_edgelist[outer].backedge = inner; - m_edgelist[outer].backsector = m_edgelist[inner].sector; - } - } - } -} - -void CMainFrame::InsertPoint() -{ - tEdge *this_edge,*new_edge; - tPoint2D t_pnt; - if (m_nearest_edge >= 0) - { - t_pnt.x = m_nearest_pnt.x; - t_pnt.y = m_nearest_pnt.y; - SnapPoint(&t_pnt); - this_edge = &m_edgelist[m_nearest_edge]; - new_edge = &m_edgelist[m_edgecnt]; - new_edge->pos.x = t_pnt.x; - new_edge->pos.y = t_pnt.y; - new_edge->sector = this_edge->sector; - new_edge->backsector = -1; - new_edge->backedge = -1; - new_edge->prevedge = m_nearest_edge; - m_edgelist[this_edge->nextedge].prevedge = m_edgecnt; - new_edge->nextedge = this_edge->nextedge; - this_edge->nextedge = m_edgecnt; - m_edgecnt++; - m_sectorlist[this_edge->sector].edgecnt++; - } -} - -void CMainFrame::DeleteEdge(short which) -{ - short loop; - tEdge *t_edge; - t_edge = &m_edgelist[which]; - char message[80]; - sprintf(message,"Delete # %d",which); - MessageBox(message,"Delete Edge",MB_OK); - // FIX THE POINTERS TO THIS EDGE - // DO IT FOR THE SECTORS - for (loop = 0; loop < m_sectorcnt; loop ++) - { - if (m_sectorlist[loop].edge == which) - { - m_sectorlist[loop].edge = t_edge->nextedge; - m_edgelist[m_edgelist[loop].nextedge].prevedge = - m_edgelist[m_sectorlist[loop].edge].prevedge; - } - } - // DO IT FOR THE EDGES - for (loop = 0; loop < m_edgecnt; loop++) - { - if (m_edgelist[loop].nextedge == which) - { - m_edgelist[loop].nextedge = t_edge->nextedge; - m_edgelist[m_edgelist[loop].nextedge].prevedge = - m_edgelist[loop].prevedge; - } - } - - // RESET THE MEMORY AND THE POINTERS - for (loop = which; loop < m_edgecnt; loop++) - { - memcpy( &m_edgelist[loop],&m_edgelist[loop+1],sizeof(tEdge) ); - } - m_edgecnt--; // DECREMENT THE EDGECNT - // RESET THE POINTERS IN THE SECTORS - for (loop = 0; loop < m_sectorcnt; loop ++) - { - if (m_sectorlist[loop].edge >= which) - m_sectorlist[loop].edge--; - } - // RESET THE POINTERS IN THE EDGES - for (loop = 0; loop < m_edgecnt; loop ++) - { - if (m_edgelist[loop].nextedge >= which) - m_edgelist[loop].nextedge--; - if (m_edgelist[loop].prevedge>= which) - m_edgelist[loop].prevedge--; - } -} - -void CMainFrame::DeleteSector() -{ - char message[80]; - short loop, t_sector; - if (m_nearest_edge > -1) - { - t_sector = m_edgelist[m_nearest_edge].sector; - if (m_cursector == &m_sectorlist[t_sector]) - { - m_cursector = NULL; - } - // DELETE IN THE EDGES - for (loop = 0; loop < m_edgecnt; loop ++) - { - if (m_edgelist[loop].sector == t_sector) - { - DeleteEdge(loop); - loop --; - } - } - // DELETE THE ACTUAL SECTOR - for (loop = t_sector; loop < m_sectorcnt; loop ++) - { - memcpy( &m_sectorlist[loop],&m_sectorlist[loop+1],sizeof(tSector) ); - } - m_sectorcnt--; - } - sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); - SetStatusText(1,message); -} - -// CLOSES AN EDITING SECTOR IF IT IS OPEN -void CMainFrame::CloseSector() -{ - char message[80]; - sprintf(message,"Close Sector %d?",m_sectorcnt); - if (MessageBox(message,"Delete Edge",MB_YESNO)) - { - if (m_cursector != NULL) // I AM WORKING ON ONE - { - m_curedge->nextedge = m_cursector->edge; - m_firstedge->prevedge = m_edgecnt - 1; // LINK BACK THE START TO THE END - m_cursector->flags = SECTOR_FLAGS_CLOSED; - m_cursector->ceil_tex = 0; - m_cursector->floor_tex = 0; - m_cursector->floor_height = 0; - m_cursector->ceil_height = 2048; - m_cursector = NULL; - CheckDoubleSided(); - } - } -} - -void CMainFrame::SnapPoint(tPoint2D *point) -{ - if (m_snap && m_gridsize > 1) - { - if (point->x > 0) point->x += (m_gridsize / 2); - else point->x -= (m_gridsize / 2); - point->x = (point->x / m_gridsize) * m_gridsize; - if (point->y > 0) point->y += (m_gridsize / 2); - else point->y -= (m_gridsize / 2); - point->y = (point->y / m_gridsize) * m_gridsize; - } -} - -////////////////////////////////////////////////////////////////// -// CheckDeleteEdges -// Purpose: To find if moving a point caused an edge to be deleted -////////////////////////////////////////////////////////////////// -void CMainFrame::CheckDeleteEdges(tPoint2D *a,tPoint2D *b) -{ - short loop,next; - for (loop = 0; loop < m_edgecnt; loop++) - { - next = m_edgelist[loop].nextedge; - if (next > -1) - { - if (a->x == m_edgelist[loop].pos.x && a->y == m_edgelist[loop].pos.y && - b->x == m_edgelist[next].pos.x && - b->y == m_edgelist[next].pos.y) - { - DeleteEdge(loop); - loop--; - } - if (b->x == m_edgelist[loop].pos.x && b->y == m_edgelist[loop].pos.y && - a->x == m_edgelist[next].pos.x && - a->y == m_edgelist[next].pos.y) - { - DeleteEdge(loop); - loop--; - } - // IF IT IS A SINGLE POINT, DELETE IT - if (m_edgelist[loop].pos.x == - m_edgelist[next].pos.x && - m_edgelist[loop].pos.y == - m_edgelist[next].pos.y ) - { - DeleteEdge(loop); - loop--; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: GetNearestPoint -// Purpose: Find the nearest point on a line segment -// Arguments: Two endpoints to a line segment a and b, -// and a test point c -// Returns: Sets the nearest point on the segment in nearest -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::GetNearestPoint(tPoint2D *a,tPoint2D *b,tPoint2D *c,tPoint2D *nearest) -{ -/// Local Variables /////////////////////////////////////////////////////////// - long dot_ta,dot_tb; -/////////////////////////////////////////////////////////////////////////////// - // SEE IF a IS THE NEAREST POINT - ANGLE IS OBTUSE - dot_ta = (c->x - a->x)*(b->x - a->x) + (c->y - a->y)*(b->y - a->y); - if (dot_ta <= 0) // It is off the a vertex - { - nearest->x = a->x; - nearest->y = a->y; - return; - } - dot_tb = (c->x - b->x)*(a->x - b->x) + (c->y - b->y)*(a->y - b->y); - // SEE IF b IS THE NEAREST POINT - ANGLE IS OBTUSE - if (dot_tb <= 0) - { - nearest->x = b->x; - nearest->y = b->y; - return; - } - // FIND THE REAL NEAREST POINT ON THE LINE SEGMENT - BASED ON RATIO - nearest->x = a->x + ((b->x - a->x) * dot_ta)/(dot_ta + dot_tb); - nearest->y = a->y + ((b->y - a->y) * dot_ta)/(dot_ta + dot_tb); -} - -short CMainFrame::GetNearestEdge(CPoint point) -{ - short loop,winner = -1,next; - long distance = 20000,tempdist; - tPoint2D *a,*b,temp,nearest; - temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); - temp.y = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale); - // CHECK ALL POINTS - for (loop = 0; loop < m_edgecnt; loop++) - { - a = &m_edgelist[loop].pos; - next = m_edgelist[loop].nextedge; - if (next >= 0) - { - b = &m_edgelist[next].pos; - GetNearestPoint(a,b,&temp,&nearest); - tempdist = (nearest.x - temp.x) * (nearest.x - temp.x) + - (nearest.y - temp.y) * (nearest.y - temp.y); - if (tempdist < distance) - { - distance = tempdist; - winner = loop; - m_nearest_pnt.x = nearest.x; - m_nearest_pnt.y = nearest.y; - } - } - } - return winner; -} - -// DISTANCE THRESHOLD TO WALLS - SORT OF ARBITRARY - ABOUT A FOOT -#define DISTANCE_THRESH 256 - -////////////////////////////////////////////////////////////////// -// Procedure: CheckCollision -// Purpose: Make Sure view is not too close to wall -// Returns: TRUE if Valid Position, else FALSE -////////////////////////////////////////////////////////////////// -BOOL CMainFrame::CheckCollision(short sector, tPoint3D *test) -{ - short loop,next,cur; - long tempdist,temp2; - tPoint2D *a,*b,temp,nearest; - // CHECK ALL POINTS - - temp.x = test->x; - temp.y = test->z; - - // IF MY TEST POINT IS OUTSIDE THE CURRENT SECTOR, GET A NEW ONE - // TODO: COULD BE OPTIMISED BASED ON WHEN YOU CROSS A DOUBLE SIDED EDGE - // NO NEED NOW IT IS FAST ENOUGH - if (!PointInPoly(&m_sectorlist[sector], &temp)) - { - // GET THE SECTOR THAT THE TEST POINT IS IN - sector = m_cam_sector = InsideSector(&temp); - } - - if (sector > -1) - { - cur = m_sectorlist[sector].edge; - - for (loop = 0; loop < m_sectorlist[sector].edgecnt; loop++) - { - a = &m_edgelist[cur].pos; - next = m_edgelist[cur].nextedge; - if (next >= 0) // IF THERE IS A NEXT - { - b = &m_edgelist[next].pos; - // IF THE EDGE IS DOUBLE SIDED JUST CHECK ENDPOINTS - if (m_edgelist[cur].backedge > -1) - { - // CHECK ONLY THE SQUARED DISTANCE - NO NEED FOR A SQRT - tempdist = (a->x - test->x) * (a->x - test->x) + - (a->y - test->z) * (a->y - test->z); - temp2 = (b->x - test->x) * (b->x - test->x) + - (b->y - test->z) * (b->y - test->z); - // WHICH IS THE CLOSEST - if (temp2 < tempdist) - tempdist = temp2; - } - else // EDGE IS NOT DOUBLE SIDED SO FIND NEAREST POINT ON LINE - { - GetNearestPoint(a,b,&temp,&nearest); - // CHECK ONLY THE SQUARED DISTANCE - NO NEED FOR A SQRT - tempdist = (nearest.x - test->x) * (nearest.x - test->x) + - (nearest.y - test->z) * (nearest.y - test->z); - } - if (tempdist < DISTANCE_THRESH) - { - return FALSE; // TOO CLOSE - } - } - cur = next; - } - - return TRUE; // VALID POSITION - } - else - return FALSE; // OUTSIDE SECTOR - -} - -#ifdef USE_VERSION2 -// FIGURE OUT WHICH QUADRANT THE VERTEX IS RELATIVE TO THE HIT POINT -#define WHICH_QUAD(vertex, hitPos) \ - ( (vertex.x > hitPos->x) ? ((vertex.y > hitPos->y) ? 1 : 4) : ( (vertex.y > hitPos->y) ? 2 : 3) ) -// GET THE X INTERCEPT OF THE LINE FROM THE CURRENT VERTEX TO THE NEXT -#define X_INTERCEPT(point1, point2, hitY) \ - (point2.x - ( ((point2.y - hitY) * (point1.x - point2.x)) / (point1.y - point2.y) ) ) - -////////////////////////////////////////////////////////////////// -// Procedure: PointInPoly (SUM OF ANGLES CROSSING VERSION) -// Purpose: Check if a point is inside a polygon -// Returns: TRUE if Point is inside polygon, else FALSE -////////////////////////////////////////////////////////////////// -BOOL CMainFrame::PointInPoly(tSector *sector, tPoint2D *hitPos) -{ - short edge, first, next; - short quad, next_quad, delta, total; - - edge = first = sector->edge; - quad = WHICH_QUAD(m_edgelist[edge].pos, hitPos); - total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED - /* LOOP THROUGH THE VERTICES IN A SECTOR */ - do { - next = m_edgelist[edge].nextedge; - next_quad = WHICH_QUAD(m_edgelist[next].pos, hitPos); - delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED - // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE QUAD - switch (delta) { - case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT WAS CLOCKWISE OR COUNTER - case -2: - // US THE X POSITION AT THE HIT POINT TO DETERMINE WHICH WAY AROUND - if (X_INTERCEPT(m_edgelist[edge].pos, m_edgelist[next].pos, hitPos->y) > hitPos->x) - delta = - (delta); - break; - case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 - delta = -1; - break; - case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 - delta = 1; - break; - } - /* ADD IN THE DELTA */ - total += delta; - quad = next_quad; // RESET FOR NEXT STEP - edge = next; - } while (edge != first); - - /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ - if ((total == +4) || (total == -4)) return TRUE; else return FALSE; -} - -#else -////////////////////////////////////////////////////////////////// -// Procedure: PointInPoly (EDGE CROSSING VERSION) -// Purpose: Check if a point is inside a polygon -// Returns: TRUE if Point is inside polygon, else FALSE -////////////////////////////////////////////////////////////////// -BOOL CMainFrame::PointInPoly(tSector *sector, tPoint2D *hitPos) -{ - short edge, first, next; - tPoint2D *pnt1,*pnt2; - BOOL inside = FALSE; // INITIAL TEST CONDITION - BOOL flag1,flag2; - - edge = first = sector->edge; // SET UP INITIAL CONDITIONS - pnt1 = &m_edgelist[edge].pos; - flag1 = ( hitPos->y >= pnt1->y ) ; // IS THE FIRST VERTEX OVER OR UNDER THE LINE - /* LOOP THROUGH THE VERTICES IN A SECTOR */ - do { - next = m_edgelist[edge].nextedge; // CHECK THE NEXT VERTEX - pnt2 = &m_edgelist[next].pos; - flag2 = ( hitPos->y >= pnt2->y ); // IS IT OVER OR UNDER - - if (flag1 != flag2) // MAKE SURE THE EDGE ACTUALLY CROSSES THE TEST X AXIS - { - // CALCULATE WHETHER THE SEGMENT ACTUALLY CROSSES THE X TEST AXIS - // A TRICK FROM GRAPHIC GEMS IV TO GET RID OF THE X INTERCEPT DIVIDE - if (((pnt2->y - hitPos->y) * (pnt1->x - pnt2->x) >= - (pnt2->x - hitPos->x) * (pnt1->y - pnt2->y)) == flag2 ) - inside = !inside; // IF IT CROSSES TOGGLE THE INSIDE FLAG (ODD IS IN, EVEN OUT) - } - pnt1 = pnt2; // RESET FOR NEXT STEP - edge = next; - flag1 = flag2; - } while (edge != first); - return inside; -} -#endif - -////////////////////////////////////////////////////////////////// -// Procedure: InsideSector -// Purpose: Find What sector a Point is in -// Returns: Number of Sector that point is in or -1 -// Notes: Could be optimized based on adjacent sectors -////////////////////////////////////////////////////////////////// -short CMainFrame::InsideSector(tPoint2D *hitPos) -{ - unsigned short loop; - short ret = -1; - char message[80]; - for (loop = 0; loop < m_sectorcnt; loop++) // FOR ALL THE SECTORS - { - if ((m_sectorlist[loop].flags & SECTOR_FLAGS_CLOSED) == 1) - { - if (PointInPoly(&m_sectorlist[loop],hitPos)) - { - ret = loop; - break; - } - } - } - - sprintf(message,"Cam in Sector = %d",ret); - SetStatusText(1,message); - return ret; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of 2D Collision System +// +// Created: +// JL 11/1/98 +// +// Notes: THIS CONTAINS SOME USEFUL COMPUTATIONAL GEOMETRY ROUTINES AT THE +// END OF THIS FILE. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include "Fate.h" + +#include "MainFrm.h" + +//IGNORE THE DOUBLE TO FLOAT CONVERSION WARNING +#pragma warning ( disable : 4244 ) + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_COMMAND(ID_OPTIONS_GRID_DOWN, OnOptionsGridDown) + ON_COMMAND(ID_OPTIONS_GRIDUP, OnOptionsGridup) + ON_WM_KEYDOWN() + ON_COMMAND(ID_OPTIONS_ZOOMIN, OnOptionsZoomin) + ON_COMMAND(ID_OPTIONS_ZOOMOUT, OnOptionsZoomout) + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONUP() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_RBUTTONUP() + ON_WM_PAINT() + ON_COMMAND(ID_FILE_NEW, OnFileNew) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + //}}AFX_MSG_MAP + // Global help commands +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_INFO, // status line INFO + ID_INDICATOR_SNAP, // status line SNAP + ID_INDICATOR_GRID, // status line GRIDSIZE + ID_INDICATOR_SC2, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_offX = 0; + m_offY = 0; + m_scale = 0.4; + m_gridsize = 64; + m_snap = TRUE; + m_point = NULL; + // SET UP THE WORLD VARIABLES + m_cursector = NULL; + m_curedge = NULL; + m_firstedge = NULL; // FIRST EDGE IN A SECTOR + m_edgecnt = 0; + m_sectorcnt = 0; + m_nearest_edge = -1; + m_nearest_pnt.x = 0; + m_nearest_pnt.y = 0; + m_old_pnt.x = -2; + m_old_pnt.y = -2; + + m_cam_pos.x = 0; + m_cam_pos.y = 0; + m_cam_pos.z = 0; + m_cam_yaw = 0; + m_cam_pitch = 0; + m_cam_sector = -1; + + InitTrig(); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + char str[80]; + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + GetWindowRect(&m_window_rect); + + sprintf(str,"Zoom = %2.1f",m_scale); + SetStatusText(4,str); + sprintf(str,"Grid = %3d",m_gridsize); + SetStatusText(3,str); + SetStatusText(2,"Snap On"); + sprintf(str,"Sectors = %3d Edges = %3d",m_sectorcnt,m_edgecnt); + SetStatusText(1,str); + + return 0; +} + +void CMainFrame::SetStatusText(short id,char *string ) +{ + m_wndStatusBar.SetPaneText(id,string); +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Scale the Grid Size Up +void CMainFrame::OnOptionsGridup() +{ + char str[80]; + if (m_gridsize <= 1024) m_gridsize *= 2; + sprintf(str,"Grid = %4d",m_gridsize); + SetStatusText(3,str); + Invalidate (TRUE); +} + +///////////////////////////////////////////////////////////////////////////// +// Scale the Grid Size Down +void CMainFrame::OnOptionsGridDown() +{ + char str[80]; + if (m_gridsize > 2) + { + m_gridsize /= 2; + sprintf(str,"Grid = %4d",m_gridsize); + } + else + { + m_gridsize = 1; + sprintf(str,"Grid OFF"); + } + SetStatusText(3,str); + Invalidate (TRUE); +} + +void CMainFrame::OnOptionsZoomin() +{ + char str[80]; + if (m_scale <= 10.0) m_scale += .1; + sprintf(str,"Zoom = %2.1f",m_scale); + SetStatusText(4,str); + Invalidate (TRUE); +} + +void CMainFrame::OnOptionsZoomout() +{ + char str[80]; + if (m_scale > 0.2) + { + m_scale -= 0.1; + } + sprintf(str,"Zoom = %2.1f",m_scale); + SetStatusText(4,str); + Invalidate (TRUE); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + tPoint3D temp; + tPoint2D temp2D; + int cx, cy; + CRect rect; + cx = (GetSystemMetrics(SM_CXFULLSCREEN) - (640 + 8)) / 2; + cy = (GetSystemMetrics(SM_CYFULLSCREEN) - (480 + 94)) / 2; + + switch (nChar) + { + case VK_INSERT: + InsertPoint(); + Invalidate(TRUE); + break; + case VK_DELETE: + DeleteSector(); + Invalidate(TRUE); + break; + case VK_RETURN: + CloseSector(); + Invalidate(TRUE); + break; + case VK_ADD: + OnOptionsGridup(); + break; + case VK_SUBTRACT: + OnOptionsGridDown(); + break; + case 'A': + OnOptionsZoomin(); + break; + case 'M': + break; + case 'Z': + OnOptionsZoomout(); + break; + case 'S': + m_snap = TRUE - m_snap; + if (m_snap) + SetStatusText(2,"Snap On"); + else + SetStatusText(2,"Snap Off"); + break; + case VK_UP: + temp.x = m_cam_pos.x + (m_sin[m_cam_yaw]>>13); + temp.z = m_cam_pos.z + (m_cos[m_cam_yaw]>>13); + if (m_cam_sector == -1) + { + m_cam_pos.x = temp.x; + m_cam_pos.z = temp.z; + temp2D.x = temp.x; + temp2D.y = temp.z; + m_cam_sector = InsideSector(&temp2D); + } + else + { + if (CheckCollision(m_cam_sector,&temp)) + { + m_cam_pos.x = temp.x; + m_cam_pos.z = temp.z; + } + } + Invalidate(TRUE); + break; + case VK_DOWN: + temp.x = m_cam_pos.x - (m_sin[m_cam_yaw]>>13); + temp.z = m_cam_pos.z - (m_cos[m_cam_yaw]>>13); + if (m_cam_sector == -1) + { + m_cam_pos.x = temp.x; + m_cam_pos.z = temp.z; + temp2D.x = temp.x; + temp2D.y = temp.z; + m_cam_sector = InsideSector(&temp2D); + } + else + { + if (CheckCollision(m_cam_sector,&temp)) + { + m_cam_pos.x = temp.x; + m_cam_pos.z = temp.z; + } + } + Invalidate(TRUE); + break; + case VK_LEFT: + m_cam_yaw += (4096 - 128); + m_cam_yaw %= 4096; + Invalidate(TRUE); + break; + case VK_RIGHT: + m_cam_yaw += 128; + m_cam_yaw %= 4096; + Invalidate(TRUE); + break; + } + + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonUp +// Purpose: Right Mouse Button Handler +////////////////////////////////////////////////////////////////// +void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) +{ + tPoint2D temp; + // MOVE THE CAMERA POSITION TO WHERE THE USER CLICKS + m_cam_pos.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); + m_cam_pos.z = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale); + temp.x = m_cam_pos.x; + temp.y = m_cam_pos.z; + m_cam_sector = InsideSector(&temp); + Invalidate(TRUE); + CFrameWnd::OnRButtonUp(nFlags, point); +} + +#define VERTEX_SNAP_PROXIMITY 100 + +void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) +{ + short loop,t_sector,t_edge; + tPoint2D temp; + long dist; + char message[80]; + + temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); + temp.y = (long)-((point.y + m_offY - (m_sizeY / 2)) / m_scale); + if ((nFlags & MK_CONTROL) > 0) + { + t_sector = -1; + for (loop = 0; loop < m_edgecnt; loop++) + { + dist = (temp.x - m_edgelist[loop].pos.x) * // SQUARED DISTANCE + (temp.x - m_edgelist[loop].pos.x) + + (temp.y - m_edgelist[loop].pos.y) * + (temp.y - m_edgelist[loop].pos.y); + if (dist < VERTEX_SNAP_PROXIMITY) + { + temp.x = m_edgelist[loop].pos.x; + temp.y = m_edgelist[loop].pos.y; + t_sector = m_edgelist[loop].sector; + t_edge = loop; + } + } + if (t_sector == -1) // IF I DIDN'T CLICK ON AN EXISTING POINT, SNAP IT + { + SnapPoint(&temp); + // CHECK ALL POINTS AGAIN ONCE I HAVE SNAPPED + for (loop = 0; loop < m_edgecnt; loop++) + { + dist = (temp.x - m_edgelist[loop].pos.x) * // SQUARED DISTANCE + (temp.x - m_edgelist[loop].pos.x) + + (temp.y - m_edgelist[loop].pos.y) * + (temp.y - m_edgelist[loop].pos.y); + if (dist < VERTEX_SNAP_PROXIMITY) + { + temp.x = m_edgelist[loop].pos.x; + temp.y = m_edgelist[loop].pos.y; + t_sector = m_edgelist[loop].sector; + t_edge = loop; + } + } + } + if (m_cursector == NULL) // haven't created a sector + { + m_cursector = &m_sectorlist[m_sectorcnt]; + m_cursector->edge = m_edgecnt; + m_cursector->edgecnt = 1; + m_cursector->flags = 0; + m_curedge = &m_edgelist[m_edgecnt]; + m_curedge->pos.x = temp.x; + m_curedge->pos.y = temp.y; + m_curedge->sector = m_sectorcnt; + m_curedge->backsector = -1; + m_curedge->backedge = -1; + m_curedge->nextedge = -1; + m_curedge->prevedge = -1; + m_firstedge = m_curedge; + m_sectorcnt++; + m_edgecnt++; + Invalidate(TRUE); + } + else + { + if (&m_sectorlist[t_sector] == m_cursector) + { + if (t_edge == m_cursector->edge) // CLOSED THE SECTOR + { + m_curedge->nextedge = m_cursector->edge; + m_firstedge->prevedge = m_edgecnt - 1; // LINK BACK THE START TO THE END + m_cursector->flags = SECTOR_FLAGS_CLOSED; + m_cursector->ceil_tex = 0; + m_cursector->floor_tex = 0; + m_cursector->floor_height = 0; + m_cursector->ceil_height = 2048; + m_cursector = NULL; + CheckDoubleSided(); + } + } + else + { + m_curedge->nextedge = m_edgecnt; + m_cursector->edgecnt++; + m_curedge = &m_edgelist[m_edgecnt]; + m_curedge->pos.x = temp.x; + m_curedge->pos.y = temp.y; + m_curedge->sector = m_sectorcnt - 1; + m_curedge->backsector = -1; + m_curedge->backedge = -1; + m_curedge->nextedge = -1; + m_curedge->prevedge = m_edgecnt - 1; + m_edgecnt++; + } + Invalidate(TRUE); + } + m_point = NULL; + sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); + SetStatusText(1,message); + } + else if ((nFlags & MK_SHIFT) > 0) + { + m_clickpoint = point; + } + else // MOVE A SET POINT + { + m_point = NULL; + for (loop = 0; loop < m_edgecnt; loop++) + { + dist = (temp.x - m_edgelist[loop].pos.x) * + (temp.x - m_edgelist[loop].pos.x) + + (temp.y - m_edgelist[loop].pos.y) * + (temp.y - m_edgelist[loop].pos.y); + if (dist < 100) + { + m_temppoint.x = m_edgelist[loop].pos.x; + m_temppoint.y = m_edgelist[loop].pos.y; + m_point = &m_edgelist[loop].pos; + Invalidate(TRUE); + break; + } + } + } + CFrameWnd::OnLButtonDown(nFlags, point); +} + +void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point) +{ + short loop; + char message[80]; + short t_edge,next; + if (m_point != NULL) + { + SnapPoint(m_point); + // Check if I need to delete similar edges + CheckDeleteEdges(&m_temppoint,m_point); + // MOVE ALL POINTS THAT WERE AT THE SAME LOCATION + for (loop = 0; loop < m_edgecnt; loop++) + { + if (m_temppoint.x == m_edgelist[loop].pos.x && + m_temppoint.y == m_edgelist[loop].pos.y) + { + m_edgelist[loop].pos.x = m_point->x; + m_edgelist[loop].pos.y = m_point->y; + } + // STORE OFF THE MOVED POINT + if (m_point == &m_edgelist[loop].pos) + t_edge = loop; + } + // CHECK IF I NEED TO DELETE THIS EDGE + next = m_edgelist[t_edge].nextedge; + if (m_point->x == m_edgelist[next].pos.x && + m_point->y == m_edgelist[next].pos.y) + { + DeleteEdge(t_edge); + } + + CheckDoubleSided(); + + sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); + SetStatusText(1,message); + Invalidate(TRUE); + } + CFrameWnd::OnLButtonUp(nFlags, point); +} + +void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + tPoint2D temp; + char message[80]; + short sec; + + temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); + temp.y = (long)-((point.y + m_offY - (m_sizeY / 2)) / m_scale); + + sec = InsideSector(&temp); + + if (sec == -1) + { + MessageBox("Not inside any..","Inside Sector Test",MB_OK); + } + else + { + sprintf(message,"Inside Sector %d",sec); + MessageBox(message,"Inside Sector Test",MB_OK); + } + CFrameWnd::OnLButtonDblClk(nFlags, point); +} + +void CMainFrame::OnMouseMove(UINT nFlags, CPoint point) +{ + long startX,startY; + short nearest; + CClientDC dc(this); // device context for painting + if ((nFlags & MK_LBUTTON) == MK_LBUTTON) + { + + if ((nFlags & MK_SHIFT) > 0) + { + m_offY += m_clickpoint.y - point.y; + m_offX += m_clickpoint.x - point.x; + Invalidate(TRUE); + m_clickpoint = point; + } + else if (m_point != NULL) + { + dc.SetROP2(R2_NOT); + // ERASE OLD POINT + startX = (m_point->x * m_scale) - m_offX + (m_sizeX / 2); + startY = (-m_point->y * m_scale) - m_offY + (m_sizeY / 2); + dc.MoveTo(startX-2,startY-2); + dc.LineTo(startX+2,startY-2); + dc.LineTo(startX+2,startY+2); + dc.LineTo(startX-2,startY+2); + dc.LineTo(startX-2,startY-2); + + m_point->x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); + m_point->y = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale); + + startX = (m_point->x * m_scale) - m_offX + (m_sizeX / 2); + startY = (-m_point->y * m_scale) - m_offY + (m_sizeY / 2); + dc.MoveTo(startX-2,startY-2); + dc.LineTo(startX+2,startY-2); + dc.LineTo(startX+2,startY+2); + dc.LineTo(startX-2,startY+2); + dc.LineTo(startX-2,startY-2); + } + } + else + { + dc.SetROP2(R2_NOT); + nearest = GetNearestEdge(point); + if (nearest >= 0) + { + m_nearest_edge = nearest; + // TODO: m_old_pnt is not defined at start + dc.MoveTo(m_old_pnt.x-1,m_old_pnt.y-1); + dc.LineTo(m_old_pnt.x+1,m_old_pnt.y-1); + dc.LineTo(m_old_pnt.x+1,m_old_pnt.y+1); + dc.LineTo(m_old_pnt.x-1,m_old_pnt.y+1); + dc.LineTo(m_old_pnt.x-1,m_old_pnt.y-1); + startX = (m_nearest_pnt.x * m_scale) - m_offX + (m_sizeX / 2); + startY = (-m_nearest_pnt.y * m_scale) - m_offY + (m_sizeY / 2); + dc.MoveTo(startX-1,startY-1); + dc.LineTo(startX+1,startY-1); + dc.LineTo(startX+1,startY+1); + dc.LineTo(startX-1,startY+1); + dc.LineTo(startX-1,startY-1); + m_old_pnt.x = startX; + m_old_pnt.y = startY; + } + } + CFrameWnd::OnMouseMove(nFlags, point); +} + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + Draw2DView(&dc); + // Do not call CFrameWnd::OnPaint() for painting messages +} + + + +void CMainFrame::OnFileNew() +{ + // RESET THE WORLD TO NOTHING + char message[80]; + m_sectorcnt = 0; + m_edgecnt = 0; + sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); + SetStatusText(1,message); + Invalidate(TRUE); +} + +// LOAD A SET OF SECTORS FROM A FILE +void CMainFrame::OnFileOpen() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Fate Files (*.fte)|*.FTE|All Files (*.*)|*.*||"; + char directory[80]; + CFileDialog *dialog; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY + _getcwd(directory,80); + dialog = new CFileDialog(TRUE,"FTE",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + fp = fopen(dialog->GetPathName(),"rb"); + if (fp != NULL) + { + fread(&m_sectorcnt,sizeof(short),1,fp); + fread(m_sectorlist,sizeof(tSector),m_sectorcnt,fp); + fread(&m_edgecnt,sizeof(short),1,fp); + fread(m_edgelist,sizeof(tEdge),m_edgecnt,fp); + fread(&m_cam_pos,sizeof(tPoint3D),1,fp); + fclose(fp); + } + } + // RESET THE MAIN DIRECTORY + _chdir(directory); + Invalidate(TRUE); +} + +// SAVE THE CURRENT SETUP TO A FILE +void CMainFrame::OnFileSave() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Fate Files (*.fte)|*.FTE|All Files (*.*)|*.*||"; + char directory[80]; + CFileDialog *dialog; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY + _getcwd(directory,80); + dialog = new CFileDialog(FALSE,"PFTE",NULL,OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + fp = fopen(dialog->GetPathName(),"wb"); + if (fp != NULL) + { + fwrite(&m_sectorcnt,sizeof(short),1,fp); + fwrite(m_sectorlist,sizeof(tSector),m_sectorcnt,fp); + fwrite(&m_edgecnt,sizeof(short),1,fp); + fwrite(m_edgelist,sizeof(tEdge), m_edgecnt,fp); + fwrite(&m_cam_pos,sizeof(tPoint3D),1,fp); + fclose(fp); + } + } + // RESET THE MAIN DIRECTORY + _chdir(directory); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame Implementation Functions + +// CREATE A FIXED POINT TRIG TABLE +void CMainFrame::InitTrig() +{ + int angle; + float f_angle; + + for(angle = 0; angle < MAX_ANGLE; angle++) + { + f_angle = ((float)angle * M_PI) / (MAX_ANGLE / 2); // Convert degrees to radians + m_sin[angle] = (long)(sin(f_angle) * (1 << PRECISION)); // Get fixed point sine 2^16 + m_cos[angle] = (long)(cos(f_angle) * (1 << PRECISION)); // Get fixed point cosine 2^16 + } +} + +///////////////////////////////////////////////////////////////////////////// +// Procedure: DrawCurPos +// Purpose: Draw the current POV Position on the Map +void CMainFrame::DrawCurPos(CDC* pDC) +{ + CPen penPOV; + long startX,startY,endX,endY; + double lenX,lenY; + short left,right; + + penPOV.CreatePen(PS_SOLID,1,0x00005000); + pDC->SelectObject(&penPOV); + + lenX = (double)((10 * m_sin[m_cam_yaw])/PRECMULT); + lenY = (double)((15 * m_cos[m_cam_yaw])/PRECMULT); + + startX = (m_cam_pos.x * m_scale) - m_offX + (m_sizeX / 2); + startY = (-m_cam_pos.z * m_scale) - m_offY + (m_sizeY / 2); + + endX = startX + lenX; + endY = startY - lenY; + + pDC->MoveTo(startX,startY); + pDC->LineTo(endX,endY); + + // DO THE ARROWHEAD PART + + startX = endX; + startY = endY; + + left = m_cam_yaw + 4096 - 512; + left %= 4096; + + lenX = (m_sin[left]>>13); + lenY = (m_cos[left]>>13); + + endX = startX - lenX; + endY = startY + lenY; + + pDC->MoveTo(startX,startY); + pDC->LineTo(endX,endY); + + right = m_cam_yaw + 512; + right %= 4096; + + lenX = (m_sin[right]>>13); + lenY = (m_cos[right]>>13); + + endX = startX - lenX; + endY = startY + lenY; + + pDC->MoveTo(startX,startY); + pDC->LineTo(endX,endY); + +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame drawing +void CMainFrame::Draw2DView(CDC* pDC) +{ + long startX,startY,tempX,tempY; + long loop,loop2,pos; + tPoint2D *pnt; + CPen pengrid,penclosedline,pendoublesided,penblue,penltblue,*curpen; + CRect aRect; + pDC->SetROP2(R2_COPYPEN); + + pengrid.CreatePen(PS_SOLID,1,0x00c0c0c0); + penclosedline.CreatePen(PS_SOLID,1,0x00505050); + pendoublesided.CreatePen(PS_SOLID,1,0x000000FF); + penblue.CreatePen(PS_SOLID,1,0x00FF0000); + penltblue.CreatePen(PS_SOLID,1,0x00FF4040); + pDC->SelectObject(&pengrid); + + + GetWindowRect(&aRect); + m_sizeX = aRect.right - aRect.left; + m_sizeY = aRect.bottom - aRect.top; + + + if (m_gridsize > 1) + { + startX = -65536; + startY = -65536; + // DO ALL THE COLUMNS + for (loop = startX; loop < 65536; loop += m_gridsize) + { + pos = (long)((double)loop * m_scale); + pos = pos - m_offX + (m_sizeX / 2); + if (pos >=0 && pos < m_sizeX) + { + pDC->MoveTo(pos,0); + pDC->LineTo(pos,m_sizeY); + } + } + // DO ALL THE COLUMNS + for (loop = startY; loop < 65536; loop += m_gridsize) + { + pos = (long)((double)loop * m_scale); + pos = pos - m_offY + (m_sizeY / 2); + if (pos >=0 && pos < m_sizeY) + { + pDC->MoveTo(0,pos); + pDC->LineTo(m_sizeX,pos); + } + } + } + + // DRAW ALL THE LINES + for (loop = 0; loop < m_sectorcnt; loop++) // FOR ALL THE SECTORS + { + if ((m_sectorlist[loop].flags & SECTOR_FLAGS_CLOSED) == 0) + { + curpen = &penltblue; + } + else + { + curpen = &penclosedline; + } + pos = m_sectorlist[loop].edge; + for (loop2 = 0; loop2 < m_sectorlist[loop].edgecnt; loop2++) + { + pnt = &m_edgelist[pos].pos; + tempX = (pnt->x * m_scale) - m_offX + (m_sizeX / 2); + tempY = (-pnt->y * m_scale) - m_offY + (m_sizeY / 2); + if (loop2 == 0) // FIRST EDGE SAVE POINT + { + pDC->MoveTo(tempX,tempY); + startX = tempX; + startY = tempY; + } + else + { + pDC->LineTo(tempX,tempY); + } + if (m_edgelist[pos].backedge > -1) + { + pDC->SelectObject(&pendoublesided); + } + else + { + pDC->SelectObject(curpen); + } + pos = m_edgelist[pos].nextedge; + } + if ((m_sectorlist[loop].flags & SECTOR_FLAGS_CLOSED) > 0) + { + pDC->LineTo(startX,startY); + } + } + + // DRAW THE POINTS + for (loop = 0; loop < m_sectorcnt; loop++) // FOR ALL THE SECTORS + { + pDC->SelectObject(&penblue); + pos = m_sectorlist[loop].edge; + for (loop2 = 0; loop2 < m_sectorlist[loop].edgecnt; loop2++) + { + pnt = &m_edgelist[pos].pos; + startX = (pnt->x * m_scale) - m_offX + (m_sizeX / 2); + startY = (-pnt->y * m_scale) - m_offY + (m_sizeY / 2); + pDC->MoveTo(startX-2,startY-2); + pDC->LineTo(startX+2,startY-2); + pDC->LineTo(startX+2,startY+2); + pDC->LineTo(startX-2,startY+2); + pDC->LineTo(startX-2,startY-2); + pos = m_edgelist[pos].nextedge; + } + } + + if (m_nearest_edge > -1) + { + pDC->SelectObject(&penltblue); + startX = (m_nearest_pnt.x * m_scale) - m_offX + (m_sizeX / 2); + startY = (-m_nearest_pnt.y * m_scale) - m_offY + (m_sizeY / 2); + pDC->MoveTo(startX-1,startY-1); + pDC->LineTo(startX+1,startY-1); + pDC->LineTo(startX+1,startY+1); + pDC->LineTo(startX-1,startY+1); + pDC->LineTo(startX-1,startY-1); + } + + DrawCurPos(pDC); +/* + sprintf(message,"Nearest #%d",m_nearest_edge); + m_MainFrame->SetStatusText(0,message);*/ +} + +void CMainFrame::TransformPoint(long world_x, long world_z, long *camera_x, long *camera_z) +{ + long move_x, move_z; + + /* DO POSITION. TRANSLATE ABOUT LOOK AT POINT.. */ + move_x = world_x - m_cam_pos.x; + move_z = world_z - m_cam_pos.z; + + /* DO YAW... */ + *camera_x = (FixMult(m_cos[m_cam_yaw],move_x)) - + (FixMult(m_sin[m_cam_yaw],move_z)); + + *camera_z = (FixMult(m_cos[m_cam_yaw],move_z)) + + (FixMult(m_sin[m_cam_yaw],move_x)); + +} + +BOOL CMainFrame::OnSamePos(short pos1,short pos2) +{ + if (m_edgelist[pos1].pos.x == m_edgelist[pos2].pos.x && + m_edgelist[pos1].pos.y == m_edgelist[pos2].pos.y) + return TRUE; + else + return FALSE; +} + +// CHECK FOR DOUBLE SIDED EDGES +void CMainFrame::CheckDoubleSided() +{ + short inner,outer; + for (outer = 0; outer < m_edgecnt; outer++) + { + for (inner = 0; inner < m_edgecnt; inner++) + { + // THEY SHARE AN EDGE IF + if (OnSamePos(outer,m_edgelist[inner].nextedge) && + OnSamePos(inner,m_edgelist[outer].nextedge)) + { + m_edgelist[inner].backedge = outer; + m_edgelist[inner].backsector = m_edgelist[outer].sector; + m_edgelist[outer].backedge = inner; + m_edgelist[outer].backsector = m_edgelist[inner].sector; + } + } + } +} + +void CMainFrame::InsertPoint() +{ + tEdge *this_edge,*new_edge; + tPoint2D t_pnt; + if (m_nearest_edge >= 0) + { + t_pnt.x = m_nearest_pnt.x; + t_pnt.y = m_nearest_pnt.y; + SnapPoint(&t_pnt); + this_edge = &m_edgelist[m_nearest_edge]; + new_edge = &m_edgelist[m_edgecnt]; + new_edge->pos.x = t_pnt.x; + new_edge->pos.y = t_pnt.y; + new_edge->sector = this_edge->sector; + new_edge->backsector = -1; + new_edge->backedge = -1; + new_edge->prevedge = m_nearest_edge; + m_edgelist[this_edge->nextedge].prevedge = m_edgecnt; + new_edge->nextedge = this_edge->nextedge; + this_edge->nextedge = m_edgecnt; + m_edgecnt++; + m_sectorlist[this_edge->sector].edgecnt++; + } +} + +void CMainFrame::DeleteEdge(short which) +{ + short loop; + tEdge *t_edge; + t_edge = &m_edgelist[which]; + char message[80]; + sprintf(message,"Delete # %d",which); + MessageBox(message,"Delete Edge",MB_OK); + // FIX THE POINTERS TO THIS EDGE + // DO IT FOR THE SECTORS + for (loop = 0; loop < m_sectorcnt; loop ++) + { + if (m_sectorlist[loop].edge == which) + { + m_sectorlist[loop].edge = t_edge->nextedge; + m_edgelist[m_edgelist[loop].nextedge].prevedge = + m_edgelist[m_sectorlist[loop].edge].prevedge; + } + } + // DO IT FOR THE EDGES + for (loop = 0; loop < m_edgecnt; loop++) + { + if (m_edgelist[loop].nextedge == which) + { + m_edgelist[loop].nextedge = t_edge->nextedge; + m_edgelist[m_edgelist[loop].nextedge].prevedge = + m_edgelist[loop].prevedge; + } + } + + // RESET THE MEMORY AND THE POINTERS + for (loop = which; loop < m_edgecnt; loop++) + { + memcpy( &m_edgelist[loop],&m_edgelist[loop+1],sizeof(tEdge) ); + } + m_edgecnt--; // DECREMENT THE EDGECNT + // RESET THE POINTERS IN THE SECTORS + for (loop = 0; loop < m_sectorcnt; loop ++) + { + if (m_sectorlist[loop].edge >= which) + m_sectorlist[loop].edge--; + } + // RESET THE POINTERS IN THE EDGES + for (loop = 0; loop < m_edgecnt; loop ++) + { + if (m_edgelist[loop].nextedge >= which) + m_edgelist[loop].nextedge--; + if (m_edgelist[loop].prevedge>= which) + m_edgelist[loop].prevedge--; + } +} + +void CMainFrame::DeleteSector() +{ + char message[80]; + short loop, t_sector; + if (m_nearest_edge > -1) + { + t_sector = m_edgelist[m_nearest_edge].sector; + if (m_cursector == &m_sectorlist[t_sector]) + { + m_cursector = NULL; + } + // DELETE IN THE EDGES + for (loop = 0; loop < m_edgecnt; loop ++) + { + if (m_edgelist[loop].sector == t_sector) + { + DeleteEdge(loop); + loop --; + } + } + // DELETE THE ACTUAL SECTOR + for (loop = t_sector; loop < m_sectorcnt; loop ++) + { + memcpy( &m_sectorlist[loop],&m_sectorlist[loop+1],sizeof(tSector) ); + } + m_sectorcnt--; + } + sprintf(message,"Sectors = %d Edges = %d",m_sectorcnt,m_edgecnt); + SetStatusText(1,message); +} + +// CLOSES AN EDITING SECTOR IF IT IS OPEN +void CMainFrame::CloseSector() +{ + char message[80]; + sprintf(message,"Close Sector %d?",m_sectorcnt); + if (MessageBox(message,"Delete Edge",MB_YESNO)) + { + if (m_cursector != NULL) // I AM WORKING ON ONE + { + m_curedge->nextedge = m_cursector->edge; + m_firstedge->prevedge = m_edgecnt - 1; // LINK BACK THE START TO THE END + m_cursector->flags = SECTOR_FLAGS_CLOSED; + m_cursector->ceil_tex = 0; + m_cursector->floor_tex = 0; + m_cursector->floor_height = 0; + m_cursector->ceil_height = 2048; + m_cursector = NULL; + CheckDoubleSided(); + } + } +} + +void CMainFrame::SnapPoint(tPoint2D *point) +{ + if (m_snap && m_gridsize > 1) + { + if (point->x > 0) point->x += (m_gridsize / 2); + else point->x -= (m_gridsize / 2); + point->x = (point->x / m_gridsize) * m_gridsize; + if (point->y > 0) point->y += (m_gridsize / 2); + else point->y -= (m_gridsize / 2); + point->y = (point->y / m_gridsize) * m_gridsize; + } +} + +////////////////////////////////////////////////////////////////// +// CheckDeleteEdges +// Purpose: To find if moving a point caused an edge to be deleted +////////////////////////////////////////////////////////////////// +void CMainFrame::CheckDeleteEdges(tPoint2D *a,tPoint2D *b) +{ + short loop,next; + for (loop = 0; loop < m_edgecnt; loop++) + { + next = m_edgelist[loop].nextedge; + if (next > -1) + { + if (a->x == m_edgelist[loop].pos.x && a->y == m_edgelist[loop].pos.y && + b->x == m_edgelist[next].pos.x && + b->y == m_edgelist[next].pos.y) + { + DeleteEdge(loop); + loop--; + } + if (b->x == m_edgelist[loop].pos.x && b->y == m_edgelist[loop].pos.y && + a->x == m_edgelist[next].pos.x && + a->y == m_edgelist[next].pos.y) + { + DeleteEdge(loop); + loop--; + } + // IF IT IS A SINGLE POINT, DELETE IT + if (m_edgelist[loop].pos.x == + m_edgelist[next].pos.x && + m_edgelist[loop].pos.y == + m_edgelist[next].pos.y ) + { + DeleteEdge(loop); + loop--; + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: GetNearestPoint +// Purpose: Find the nearest point on a line segment +// Arguments: Two endpoints to a line segment a and b, +// and a test point c +// Returns: Sets the nearest point on the segment in nearest +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::GetNearestPoint(tPoint2D *a,tPoint2D *b,tPoint2D *c,tPoint2D *nearest) +{ +/// Local Variables /////////////////////////////////////////////////////////// + long dot_ta,dot_tb; +/////////////////////////////////////////////////////////////////////////////// + // SEE IF a IS THE NEAREST POINT - ANGLE IS OBTUSE + dot_ta = (c->x - a->x)*(b->x - a->x) + (c->y - a->y)*(b->y - a->y); + if (dot_ta <= 0) // It is off the a vertex + { + nearest->x = a->x; + nearest->y = a->y; + return; + } + dot_tb = (c->x - b->x)*(a->x - b->x) + (c->y - b->y)*(a->y - b->y); + // SEE IF b IS THE NEAREST POINT - ANGLE IS OBTUSE + if (dot_tb <= 0) + { + nearest->x = b->x; + nearest->y = b->y; + return; + } + // FIND THE REAL NEAREST POINT ON THE LINE SEGMENT - BASED ON RATIO + nearest->x = a->x + ((b->x - a->x) * dot_ta)/(dot_ta + dot_tb); + nearest->y = a->y + ((b->y - a->y) * dot_ta)/(dot_ta + dot_tb); +} + +short CMainFrame::GetNearestEdge(CPoint point) +{ + short loop,winner = -1,next; + long distance = 20000,tempdist; + tPoint2D *a,*b,temp,nearest; + temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale); + temp.y = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale); + // CHECK ALL POINTS + for (loop = 0; loop < m_edgecnt; loop++) + { + a = &m_edgelist[loop].pos; + next = m_edgelist[loop].nextedge; + if (next >= 0) + { + b = &m_edgelist[next].pos; + GetNearestPoint(a,b,&temp,&nearest); + tempdist = (nearest.x - temp.x) * (nearest.x - temp.x) + + (nearest.y - temp.y) * (nearest.y - temp.y); + if (tempdist < distance) + { + distance = tempdist; + winner = loop; + m_nearest_pnt.x = nearest.x; + m_nearest_pnt.y = nearest.y; + } + } + } + return winner; +} + +// DISTANCE THRESHOLD TO WALLS - SORT OF ARBITRARY - ABOUT A FOOT +#define DISTANCE_THRESH 256 + +////////////////////////////////////////////////////////////////// +// Procedure: CheckCollision +// Purpose: Make Sure view is not too close to wall +// Returns: TRUE if Valid Position, else FALSE +////////////////////////////////////////////////////////////////// +BOOL CMainFrame::CheckCollision(short sector, tPoint3D *test) +{ + short loop,next,cur; + long tempdist,temp2; + tPoint2D *a,*b,temp,nearest; + // CHECK ALL POINTS + + temp.x = test->x; + temp.y = test->z; + + // IF MY TEST POINT IS OUTSIDE THE CURRENT SECTOR, GET A NEW ONE + // TODO: COULD BE OPTIMISED BASED ON WHEN YOU CROSS A DOUBLE SIDED EDGE + // NO NEED NOW IT IS FAST ENOUGH + if (!PointInPoly(&m_sectorlist[sector], &temp)) + { + // GET THE SECTOR THAT THE TEST POINT IS IN + sector = m_cam_sector = InsideSector(&temp); + } + + if (sector > -1) + { + cur = m_sectorlist[sector].edge; + + for (loop = 0; loop < m_sectorlist[sector].edgecnt; loop++) + { + a = &m_edgelist[cur].pos; + next = m_edgelist[cur].nextedge; + if (next >= 0) // IF THERE IS A NEXT + { + b = &m_edgelist[next].pos; + // IF THE EDGE IS DOUBLE SIDED JUST CHECK ENDPOINTS + if (m_edgelist[cur].backedge > -1) + { + // CHECK ONLY THE SQUARED DISTANCE - NO NEED FOR A SQRT + tempdist = (a->x - test->x) * (a->x - test->x) + + (a->y - test->z) * (a->y - test->z); + temp2 = (b->x - test->x) * (b->x - test->x) + + (b->y - test->z) * (b->y - test->z); + // WHICH IS THE CLOSEST + if (temp2 < tempdist) + tempdist = temp2; + } + else // EDGE IS NOT DOUBLE SIDED SO FIND NEAREST POINT ON LINE + { + GetNearestPoint(a,b,&temp,&nearest); + // CHECK ONLY THE SQUARED DISTANCE - NO NEED FOR A SQRT + tempdist = (nearest.x - test->x) * (nearest.x - test->x) + + (nearest.y - test->z) * (nearest.y - test->z); + } + if (tempdist < DISTANCE_THRESH) + { + return FALSE; // TOO CLOSE + } + } + cur = next; + } + + return TRUE; // VALID POSITION + } + else + return FALSE; // OUTSIDE SECTOR + +} + +#ifdef USE_VERSION2 +// FIGURE OUT WHICH QUADRANT THE VERTEX IS RELATIVE TO THE HIT POINT +#define WHICH_QUAD(vertex, hitPos) \ + ( (vertex.x > hitPos->x) ? ((vertex.y > hitPos->y) ? 1 : 4) : ( (vertex.y > hitPos->y) ? 2 : 3) ) +// GET THE X INTERCEPT OF THE LINE FROM THE CURRENT VERTEX TO THE NEXT +#define X_INTERCEPT(point1, point2, hitY) \ + (point2.x - ( ((point2.y - hitY) * (point1.x - point2.x)) / (point1.y - point2.y) ) ) + +////////////////////////////////////////////////////////////////// +// Procedure: PointInPoly (SUM OF ANGLES CROSSING VERSION) +// Purpose: Check if a point is inside a polygon +// Returns: TRUE if Point is inside polygon, else FALSE +////////////////////////////////////////////////////////////////// +BOOL CMainFrame::PointInPoly(tSector *sector, tPoint2D *hitPos) +{ + short edge, first, next; + short quad, next_quad, delta, total; + + edge = first = sector->edge; + quad = WHICH_QUAD(m_edgelist[edge].pos, hitPos); + total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED + /* LOOP THROUGH THE VERTICES IN A SECTOR */ + do { + next = m_edgelist[edge].nextedge; + next_quad = WHICH_QUAD(m_edgelist[next].pos, hitPos); + delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED + // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE QUAD + switch (delta) { + case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT WAS CLOCKWISE OR COUNTER + case -2: + // US THE X POSITION AT THE HIT POINT TO DETERMINE WHICH WAY AROUND + if (X_INTERCEPT(m_edgelist[edge].pos, m_edgelist[next].pos, hitPos->y) > hitPos->x) + delta = - (delta); + break; + case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 + delta = -1; + break; + case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 + delta = 1; + break; + } + /* ADD IN THE DELTA */ + total += delta; + quad = next_quad; // RESET FOR NEXT STEP + edge = next; + } while (edge != first); + + /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ + if ((total == +4) || (total == -4)) return TRUE; else return FALSE; +} + +#else +////////////////////////////////////////////////////////////////// +// Procedure: PointInPoly (EDGE CROSSING VERSION) +// Purpose: Check if a point is inside a polygon +// Returns: TRUE if Point is inside polygon, else FALSE +////////////////////////////////////////////////////////////////// +BOOL CMainFrame::PointInPoly(tSector *sector, tPoint2D *hitPos) +{ + short edge, first, next; + tPoint2D *pnt1,*pnt2; + BOOL inside = FALSE; // INITIAL TEST CONDITION + BOOL flag1,flag2; + + edge = first = sector->edge; // SET UP INITIAL CONDITIONS + pnt1 = &m_edgelist[edge].pos; + flag1 = ( hitPos->y >= pnt1->y ) ; // IS THE FIRST VERTEX OVER OR UNDER THE LINE + /* LOOP THROUGH THE VERTICES IN A SECTOR */ + do { + next = m_edgelist[edge].nextedge; // CHECK THE NEXT VERTEX + pnt2 = &m_edgelist[next].pos; + flag2 = ( hitPos->y >= pnt2->y ); // IS IT OVER OR UNDER + + if (flag1 != flag2) // MAKE SURE THE EDGE ACTUALLY CROSSES THE TEST X AXIS + { + // CALCULATE WHETHER THE SEGMENT ACTUALLY CROSSES THE X TEST AXIS + // A TRICK FROM GRAPHIC GEMS IV TO GET RID OF THE X INTERCEPT DIVIDE + if (((pnt2->y - hitPos->y) * (pnt1->x - pnt2->x) >= + (pnt2->x - hitPos->x) * (pnt1->y - pnt2->y)) == flag2 ) + inside = !inside; // IF IT CROSSES TOGGLE THE INSIDE FLAG (ODD IS IN, EVEN OUT) + } + pnt1 = pnt2; // RESET FOR NEXT STEP + edge = next; + flag1 = flag2; + } while (edge != first); + return inside; +} +#endif + +////////////////////////////////////////////////////////////////// +// Procedure: InsideSector +// Purpose: Find What sector a Point is in +// Returns: Number of Sector that point is in or -1 +// Notes: Could be optimized based on adjacent sectors +////////////////////////////////////////////////////////////////// +short CMainFrame::InsideSector(tPoint2D *hitPos) +{ + unsigned short loop; + short ret = -1; + char message[80]; + for (loop = 0; loop < m_sectorcnt; loop++) // FOR ALL THE SECTORS + { + if ((m_sectorlist[loop].flags & SECTOR_FLAGS_CLOSED) == 1) + { + if (PointInPoly(&m_sectorlist[loop],hitPos)) + { + ret = loop; + break; + } + } + } + + sprintf(message,"Cam in Sector = %d",ret); + SetStatusText(1,message); + return ret; +} diff --git a/2D Collision/code/FATE/Mainfrm.h b/2D Collision/code/FATE/Mainfrm.h index 4b00bc4..db232e9 100644 --- a/2D Collision/code/FATE/Mainfrm.h +++ b/2D Collision/code/FATE/Mainfrm.h @@ -1,109 +1,109 @@ -// MainFrm.h : interface of the CMainFrame class -// -///////////////////////////////////////////////////////////////////////////// -#include "mathdefs.h" -#include "engine.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - void SetStatusText(short id,char *string ); - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - long m_offX,m_offY; - long m_sizeX,m_sizeY; - CRect m_window_rect; - double m_scale; - short m_gridsize; - BOOLEAN m_snap; - tPoint2D *m_point,m_temppoint; - tSector m_sectorlist[1024],*m_cursector; - tEdge m_edgelist[8192],*m_curedge,*m_firstedge; - short m_sectorcnt,m_edgecnt,m_nearest_edge; - tPoint2D m_nearest_pnt,m_old_pnt; - tPoint3D m_cam_pos; - short m_cam_yaw; - short m_cam_pitch; - short m_cam_sector; - long m_sin[4096]; - long m_cos[4096]; - CPoint m_clickpoint; // POINT WHERE MOUSE WAS CLICKED - - void Draw2DView(CDC* pDC); - void Draw3DView(CDC* pDC); - void SnapPoint(tPoint2D *point); - short InsideSector(tPoint2D *hitPos); - short GetNearestEdge(CPoint point); - void GetNearestPoint(tPoint2D *a,tPoint2D *b,tPoint2D *c,tPoint2D *near); - void InsertPoint(); - void CloseSector(); - void DeleteEdge(short which); - void DeleteSector(); - BOOL OnSamePos(short pos1,short pos2); - void CheckDoubleSided(); - void CheckDeleteEdges(tPoint2D *a,tPoint2D *b); - void LoadTextures(); - void TransformPoint(long world_x, long world_z, long *camera_x, long *camera_z); - - long FixMult(long a,long b) - { - long retval; - __asm mov eax,a - __asm mov ebx,b - __asm imul ebx - __asm shrd eax,edx,16 - __asm mov retval,eax - return (retval); - } - - BOOL PointInPoly(tSector *sector, tPoint2D *hitPos); - BOOL CheckCollision(short sector, tPoint3D *test); - void InitTrig(); - void DrawCurPos(CDC* pDC); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnOptionsGridDown(); - afx_msg void OnOptionsGridup(); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnOptionsZoomin(); - afx_msg void OnOptionsZoomout(); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnRButtonUp(UINT nFlags, CPoint point); - afx_msg void OnPaint(); - afx_msg void OnFileNew(); - afx_msg void OnFileOpen(); - afx_msg void OnFileSave(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// +// MainFrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// +#include "mathdefs.h" +#include "engine.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + void SetStatusText(short id,char *string ); + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + long m_offX,m_offY; + long m_sizeX,m_sizeY; + CRect m_window_rect; + double m_scale; + short m_gridsize; + BOOLEAN m_snap; + tPoint2D *m_point,m_temppoint; + tSector m_sectorlist[1024],*m_cursector; + tEdge m_edgelist[8192],*m_curedge,*m_firstedge; + short m_sectorcnt,m_edgecnt,m_nearest_edge; + tPoint2D m_nearest_pnt,m_old_pnt; + tPoint3D m_cam_pos; + short m_cam_yaw; + short m_cam_pitch; + short m_cam_sector; + long m_sin[4096]; + long m_cos[4096]; + CPoint m_clickpoint; // POINT WHERE MOUSE WAS CLICKED + + void Draw2DView(CDC* pDC); + void Draw3DView(CDC* pDC); + void SnapPoint(tPoint2D *point); + short InsideSector(tPoint2D *hitPos); + short GetNearestEdge(CPoint point); + void GetNearestPoint(tPoint2D *a,tPoint2D *b,tPoint2D *c,tPoint2D *near); + void InsertPoint(); + void CloseSector(); + void DeleteEdge(short which); + void DeleteSector(); + BOOL OnSamePos(short pos1,short pos2); + void CheckDoubleSided(); + void CheckDeleteEdges(tPoint2D *a,tPoint2D *b); + void LoadTextures(); + void TransformPoint(long world_x, long world_z, long *camera_x, long *camera_z); + + long FixMult(long a,long b) + { + long retval; + __asm mov eax,a + __asm mov ebx,b + __asm imul ebx + __asm shrd eax,edx,16 + __asm mov retval,eax + return (retval); + } + + BOOL PointInPoly(tSector *sector, tPoint2D *hitPos); + BOOL CheckCollision(short sector, tPoint3D *test); + void InitTrig(); + void DrawCurPos(CDC* pDC); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnOptionsGridDown(); + afx_msg void OnOptionsGridup(); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnOptionsZoomin(); + afx_msg void OnOptionsZoomout(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + afx_msg void OnPaint(); + afx_msg void OnFileNew(); + afx_msg void OnFileOpen(); + afx_msg void OnFileSave(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/2D Collision/code/FATE/MathDefs.h b/2D Collision/code/FATE/MathDefs.h index 8e4a555..96c04aa 100644 --- a/2D Collision/code/FATE/MathDefs.h +++ b/2D Collision/code/FATE/MathDefs.h @@ -1,55 +1,55 @@ -#define XRES 640 -#define YRES 480 - -#define MAX_ANGLE 4096 -#define WORLD_SEXTANT (MAX_ANGLE >> 4) -#define WORLD_OCTANT (MAX_ANGLE >> 3) -#define WORLD_QUADRANT (MAX_ANGLE >> 2) - -#define COSINE(a) (gSine[(a + WORLD_QUADRANT) % MAX_ANGLE]) - -#define MAX_DISTANCE 2000 -#define NEAR_Z_CLIP 10 - -#define PRECISION 16 -#define PRECMULT (1< b) ? a : b) -#define MIN(a,b) ((a < b) ? a : b) -#define CROSS3D(a,b,r) \ - (r).x = (a).y * (b).z - (a).z * (b).y; \ - (r).y = (a).z * (b).x - (a).x * (b).z; \ - (r).z = (a).x * (b).y - (a).y * (b).x - -#define DotProduct(xl,yl,xt,yt,xb,yb) \ - ((xt - xl) * (yl - yb) + (yl - yt) * (xl - xb)) - - -// KEYS THAT ARE NOT DEFINED -#define VK_PERIOD 0xbe - -#define POLY_TYPE_QUAD 0 -#define POLY_TYPE_TRI 1 -#define POLY_TYPE_COLOR 2 -#define POLY_TYPE_TRANS 4 -#define POLY_TYPE_2SIDED 8 -#define POLY_TYPE_SORT_FRONT 16 -#define POLY_TYPE_SORT_AVE 32 -#define POLY_TYPE_SORT_BACK 64 -#define POLY_TYPE_ERROR 128 -#define POLY_TYPE_SELECTED 256 -#define POLY_TYPE_TEXTURING 512 - -void initSinTable(); -extern long gSine[MAX_ANGLE]; +#define XRES 640 +#define YRES 480 + +#define MAX_ANGLE 4096 +#define WORLD_SEXTANT (MAX_ANGLE >> 4) +#define WORLD_OCTANT (MAX_ANGLE >> 3) +#define WORLD_QUADRANT (MAX_ANGLE >> 2) + +#define COSINE(a) (gSine[(a + WORLD_QUADRANT) % MAX_ANGLE]) + +#define MAX_DISTANCE 2000 +#define NEAR_Z_CLIP 10 + +#define PRECISION 16 +#define PRECMULT (1< b) ? a : b) +#define MIN(a,b) ((a < b) ? a : b) +#define CROSS3D(a,b,r) \ + (r).x = (a).y * (b).z - (a).z * (b).y; \ + (r).y = (a).z * (b).x - (a).x * (b).z; \ + (r).z = (a).x * (b).y - (a).y * (b).x + +#define DotProduct(xl,yl,xt,yt,xb,yb) \ + ((xt - xl) * (yl - yb) + (yl - yt) * (xl - xb)) + + +// KEYS THAT ARE NOT DEFINED +#define VK_PERIOD 0xbe + +#define POLY_TYPE_QUAD 0 +#define POLY_TYPE_TRI 1 +#define POLY_TYPE_COLOR 2 +#define POLY_TYPE_TRANS 4 +#define POLY_TYPE_2SIDED 8 +#define POLY_TYPE_SORT_FRONT 16 +#define POLY_TYPE_SORT_AVE 32 +#define POLY_TYPE_SORT_BACK 64 +#define POLY_TYPE_ERROR 128 +#define POLY_TYPE_SELECTED 256 +#define POLY_TYPE_TEXTURING 512 + +void initSinTable(); +extern long gSine[MAX_ANGLE]; diff --git a/2D Collision/code/FATE/RESOURCE.h b/2D Collision/code/FATE/RESOURCE.h index 8b77cf7..942b42e 100644 --- a/2D Collision/code/FATE/RESOURCE.h +++ b/2D Collision/code/FATE/RESOURCE.h @@ -1,36 +1,36 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Fate.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_FATETYPE 129 -#define IDD_SECTOR_ATTR 130 -#define IDC_CEIL 1000 -#define IDC_FLOOR 1001 -#define IDC_NUMBER 1002 -#define IDC_EDGECNT 1003 -#define IDC_CEIL_TEX 1004 -#define IDC_FLOORTEX 1005 -#define IDC_CEIL_SEL 1006 -#define IDC_FLOOR_SEL 1007 -#define ID_OPTIONS_GRIDUP 32771 -#define ID_OPTIONS_GRID_DOWN 32772 -#define ID_OPTIONS_ZOOMIN 32773 -#define ID_OPTIONS_ZOOMOUT 32774 -#define ID_INDICATOR_GRID 32775 -#define ID_INDICATOR_SC2 32776 -#define ID_INDICATOR_SNAP 32777 -#define ID_INDICATOR_INFO 32778 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 132 -#define _APS_NEXT_COMMAND_VALUE 32778 -#define _APS_NEXT_CONTROL_VALUE 1007 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Fate.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_FATETYPE 129 +#define IDD_SECTOR_ATTR 130 +#define IDC_CEIL 1000 +#define IDC_FLOOR 1001 +#define IDC_NUMBER 1002 +#define IDC_EDGECNT 1003 +#define IDC_CEIL_TEX 1004 +#define IDC_FLOORTEX 1005 +#define IDC_CEIL_SEL 1006 +#define IDC_FLOOR_SEL 1007 +#define ID_OPTIONS_GRIDUP 32771 +#define ID_OPTIONS_GRID_DOWN 32772 +#define ID_OPTIONS_ZOOMIN 32773 +#define ID_OPTIONS_ZOOMOUT 32774 +#define ID_INDICATOR_GRID 32775 +#define ID_INDICATOR_SC2 32776 +#define ID_INDICATOR_SNAP 32777 +#define ID_INDICATOR_INFO 32778 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 132 +#define _APS_NEXT_COMMAND_VALUE 32778 +#define _APS_NEXT_CONTROL_VALUE 1007 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/2D Collision/code/FATE/Readme.txt b/2D Collision/code/FATE/Readme.txt index 669f516..5ba55b5 100644 --- a/2D Collision/code/FATE/Readme.txt +++ b/2D Collision/code/FATE/Readme.txt @@ -1,57 +1,57 @@ -2D Collsion Detection in Real-time Demonstration Dec 5, 1998 ----------------------------------------------------------------------------- - -This is the sample application that accompanies the January 99 -Game Developer magazine. It is meant as a demonstration of -a method for 2D collision detection. - -This code is pulled from a portion of a "Duke Nukem" style -3D Engine level editor I wrote a while back. There are a bunch -of routines that editor writers may find useful. The math is -handled in Fixed Point trig which I don't use much anymore. -There is also some leftovers of sector structure for floor -and ceiling height that are not real important for the demo. - -Most of the interesting Computational Geometry routines are in -"MainFrame.cpp" at the bottom of the file. There are routines to -find the nearest point to a line segment and to check if a point -is in a concave polygon. All of the Drawing code just uses WinGDI -calls so no extra libraries are required. - -Load one of the sample files to check it out. - -Controls for the Application: ------------------------------------------------------------------------------ -Left/Right Arrow Keys - Rotate the player viewpoint on the map -Up/Down Arrow Keys - Move player forward and backward. -Right Mouse Button - Places the player on the map - -Ctrl + Left Mouse Button Adds a point to the current polygon. - - Create closed polygon sectors by CTRL+LMB on the map. Create the - polygons clockwise and hit on the first vertex to close the sector. - A new sector can be attached to the old one. Shared edges are - considered "passable" by the player and are colored red. - -Click and Drag a vertex with the Left mouse button to move a vertex. - -+ / - (Keypad) Increases and Decreases the Grid Resolution -A / Z Zoom the map in and out -S Turns Grid Snap On and Off - -Double Click Mouse - Tests whether the clicked point is inside a sector. ------------------------------------------------------------------------------ - -There is a bunch of other functions that may be useful to level editor -creators. It is largely leftover from production tools so it is up to you -to figure it out or not. The point was really the collision and the -inside sector test. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - +2D Collsion Detection in Real-time Demonstration Dec 5, 1998 +---------------------------------------------------------------------------- + +This is the sample application that accompanies the January 99 +Game Developer magazine. It is meant as a demonstration of +a method for 2D collision detection. + +This code is pulled from a portion of a "Duke Nukem" style +3D Engine level editor I wrote a while back. There are a bunch +of routines that editor writers may find useful. The math is +handled in Fixed Point trig which I don't use much anymore. +There is also some leftovers of sector structure for floor +and ceiling height that are not real important for the demo. + +Most of the interesting Computational Geometry routines are in +"MainFrame.cpp" at the bottom of the file. There are routines to +find the nearest point to a line segment and to check if a point +is in a concave polygon. All of the Drawing code just uses WinGDI +calls so no extra libraries are required. + +Load one of the sample files to check it out. + +Controls for the Application: +----------------------------------------------------------------------------- +Left/Right Arrow Keys - Rotate the player viewpoint on the map +Up/Down Arrow Keys - Move player forward and backward. +Right Mouse Button - Places the player on the map + +Ctrl + Left Mouse Button Adds a point to the current polygon. + + Create closed polygon sectors by CTRL+LMB on the map. Create the + polygons clockwise and hit on the first vertex to close the sector. + A new sector can be attached to the old one. Shared edges are + considered "passable" by the player and are colored red. + +Click and Drag a vertex with the Left mouse button to move a vertex. + ++ / - (Keypad) Increases and Decreases the Grid Resolution +A / Z Zoom the map in and out +S Turns Grid Snap On and Off + +Double Click Mouse - Tests whether the clicked point is inside a sector. +----------------------------------------------------------------------------- + +There is a bunch of other functions that may be useful to level editor +creators. It is largely leftover from production tools so it is up to you +to figure it out or not. The point was really the collision and the +inside sector test. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + diff --git a/2D Collision/code/FATE/STDAFX.cpp b/2D Collision/code/FATE/STDAFX.cpp index 5dd879d..0562864 100644 --- a/2D Collision/code/FATE/STDAFX.cpp +++ b/2D Collision/code/FATE/STDAFX.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Fate.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Fate.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/2D Collision/code/FATE/STDAFX.h b/2D Collision/code/FATE/STDAFX.h index 8a137a0..49a2dde 100644 --- a/2D Collision/code/FATE/STDAFX.h +++ b/2D Collision/code/FATE/STDAFX.h @@ -1,16 +1,16 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows 95 Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - - - +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows 95 Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + + + diff --git a/2D Water Effects/Code/OGL/Agua/Agua.cpp b/2D Water Effects/Code/OGL/Agua/Agua.cpp index 332788b..86d0c6d 100644 --- a/2D Water Effects/Code/OGL/Agua/Agua.cpp +++ b/2D Water Effects/Code/OGL/Agua/Agua.cpp @@ -1,56 +1,56 @@ -// Agua.cpp : Defines the class behaviors for the application. -// - -#include "stdafx.h" -#include "Agua.h" -#include "AguaDlg.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CAguaApp - -BEGIN_MESSAGE_MAP(CAguaApp, CWinApp) - //{{AFX_MSG_MAP(CAguaApp) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG - ON_COMMAND(ID_HELP, CWinApp::OnHelp) -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CAguaApp construction - -CAguaApp::CAguaApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CAguaApp object - -CAguaApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CAguaApp initialization - -BOOL CAguaApp::InitInstance() -{ - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - CAguaDlg dlg; - m_pMainWnd = &dlg; - int nResponse = dlg.DoModal(); - - return FALSE; -} +// Agua.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "Agua.h" +#include "AguaDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CAguaApp + +BEGIN_MESSAGE_MAP(CAguaApp, CWinApp) + //{{AFX_MSG_MAP(CAguaApp) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CAguaApp construction + +CAguaApp::CAguaApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CAguaApp object + +CAguaApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CAguaApp initialization + +BOOL CAguaApp::InitInstance() +{ + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + CAguaDlg dlg; + m_pMainWnd = &dlg; + int nResponse = dlg.DoModal(); + + return FALSE; +} diff --git a/2D Water Effects/Code/OGL/Agua/Agua.h b/2D Water Effects/Code/OGL/Agua/Agua.h index f48ae27..a54bfe7 100644 --- a/2D Water Effects/Code/OGL/Agua/Agua.h +++ b/2D Water Effects/Code/OGL/Agua/Agua.h @@ -1,49 +1,49 @@ -// Agua.h : main header file for the AGUA application -// - -#if !defined(AFX_AGUA_H__23260AB3_C27C_4749_9E84_57A4358F4623__INCLUDED_) -#define AFX_AGUA_H__23260AB3_C27C_4749_9E84_57A4358F4623__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CAguaApp: -// See Agua.cpp for the implementation of this class -// - -class CAguaApp : public CWinApp -{ -public: - CAguaApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAguaApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CAguaApp) - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_AGUA_H__23260AB3_C27C_4749_9E84_57A4358F4623__INCLUDED_) +// Agua.h : main header file for the AGUA application +// + +#if !defined(AFX_AGUA_H__23260AB3_C27C_4749_9E84_57A4358F4623__INCLUDED_) +#define AFX_AGUA_H__23260AB3_C27C_4749_9E84_57A4358F4623__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CAguaApp: +// See Agua.cpp for the implementation of this class +// + +class CAguaApp : public CWinApp +{ +public: + CAguaApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAguaApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CAguaApp) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_AGUA_H__23260AB3_C27C_4749_9E84_57A4358F4623__INCLUDED_) diff --git a/2D Water Effects/Code/OGL/Agua/AguaDlg.cpp b/2D Water Effects/Code/OGL/Agua/AguaDlg.cpp index d9903e2..c491265 100644 --- a/2D Water Effects/Code/OGL/Agua/AguaDlg.cpp +++ b/2D Water Effects/Code/OGL/Agua/AguaDlg.cpp @@ -1,483 +1,483 @@ -// AguaDlg.cpp : implementation file -// - -#include "stdafx.h" -#include -#include "Agua.h" -#include "AguaDlg.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -// TODO: Adjust this to make the field smaller and it will run faster -// 128 is pretty good for speed -#define WATER_SIZE 256 - -#define RGB32(r,g,b) ((r << 16) + (g << 8) + b) -#define GetR32(color) (0x000000ff & (color >> 16)) -#define GetG32(color) (0x000000ff & (color >> 8)) -#define GetB32(color) (0x000000ff & color) - -#define SETBUFFER(buf,x,y,value) (buf[((y) * WATER_SIZE) + (x)] = value) -#define READBUFFER(buf,x,y) (buf[((y) * WATER_SIZE) + (x)]) - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CAguaDlg dialog - -CAguaDlg::CAguaDlg(CWnd* pParent /*=NULL*/) - : CDialog(CAguaDlg::IDD, pParent) -{ - //{{AFX_DATA_INIT(CAguaDlg) - m_Drip_Radius = 12; - m_DampingFactor = 0.002f; - m_ImageFile = _T("Reflect.tga"); - m_Green = 128; - m_Red = 128; - m_Blue = 128; - m_UseImage = TRUE; - //}}AFX_DATA_INIT - // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 - m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); -} - -void CAguaDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAguaDlg) - DDX_Control(pDX, IDC_DISPLAY, m_Display); - DDX_Text(pDX, IDC_DRIP_RADIUS, m_Drip_Radius); - DDX_Text(pDX, IDC_DAMPING, m_DampingFactor); - DDX_Text(pDX, IDC_IMAGEFILE, m_ImageFile); - DDX_Text(pDX, IDC_GREEN, m_Green); - DDV_MinMaxUInt(pDX, m_Green, 0, 255); - DDX_Text(pDX, IDC_RED, m_Red); - DDV_MinMaxUInt(pDX, m_Red, 0, 255); - DDX_Text(pDX, IDC_BLUE, m_Blue); - DDV_MinMaxUInt(pDX, m_Blue, 0, 255); - DDX_Check(pDX, IDC_USEIMAGE, m_UseImage); - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAguaDlg, CDialog) - //{{AFX_MSG_MAP(CAguaDlg) - ON_WM_SYSCOMMAND() - ON_WM_PAINT() - ON_WM_QUERYDRAGICON() - ON_EN_UPDATE(IDC_DAMPING, OnUpdateDamping) - ON_EN_UPDATE(IDC_DRIP_RADIUS, OnUpdateDripRadius) - ON_BN_CLICKED(IDC_IMAGE_BROWSE, OnImageBrowse) - ON_EN_UPDATE(IDC_IMAGEFILE, OnUpdateImagefile) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CAguaDlg message handlers - -BOOL CAguaDlg::OnInitDialog() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - BITMAPINFO bmi; - CDC *hdc; -///////////////////////////////////////////////////////////////////////////////////// - CDialog::OnInitDialog(); - - // Add "About..." menu item to system menu. - - // IDM_ABOUTBOX must be in the system command range. - ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); - ASSERT(IDM_ABOUTBOX < 0xF000); - - CMenu* pSysMenu = GetSystemMenu(FALSE); - if (pSysMenu != NULL) - { - CString strAboutMenu; - strAboutMenu.LoadString(IDS_ABOUTBOX); - if (!strAboutMenu.IsEmpty()) - { - pSysMenu->AppendMenu(MF_SEPARATOR); - pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); - } - } - - // Set the icon for this dialog. The framework does this automatically - // when the application's main window is not a dialog - SetIcon(m_hIcon, TRUE); // Set big icon - SetIcon(m_hIcon, FALSE); // Set small icon - - memset ( &bmi, 0, sizeof(BITMAPINFO) ); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = WATER_SIZE; //wndRect.right; // 1024 mode - bmi.bmiHeader.biHeight = WATER_SIZE; //wndRect.bottom; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - - hdc = GetDC (); - if ( !hdc ) - return 0; - - m_Bitmap = CreateDIBSection ( hdc->m_hDC , &bmi, DIB_RGB_COLORS, (void **)&m_Buffer, NULL, 0 ); - ReleaseDC ( hdc); - - if ( !m_Bitmap ) - return 0; - - m_Display.SetBitmap(m_Bitmap); - - m_ReadBuffer = (char *)malloc(WATER_SIZE * WATER_SIZE); - m_WriteBuffer = (char *)malloc(WATER_SIZE * WATER_SIZE); - - for (int i = 0; i < WATER_SIZE * WATER_SIZE; i++) - { - m_ReadBuffer[i] = 0; - m_WriteBuffer[i] = 0; - } - - LoadTGAFile("Reflect.tga",&m_ReflectImage); - - SetDisplay(); - - SetTimer(1,5,NULL); // Set it up to animate via messages - - m_Drip_Radius_Sqr = m_Drip_Radius * m_Drip_Radius; - - return TRUE; // return TRUE unless you set the focus to a control -} - -void CAguaDlg::OnSysCommand(UINT nID, LPARAM lParam) -{ - if ((nID & 0xFFF0) == IDM_ABOUTBOX) - { - CAboutDlg dlgAbout; - dlgAbout.DoModal(); - } - else - { - CDialog::OnSysCommand(nID, lParam); - } -} - -// If you add a minimize button to your dialog, you will need the code below -// to draw the icon. For MFC applications using the document/view model, -// this is automatically done for you by the framework. - -void CAguaDlg::OnPaint() -{ - if (IsIconic()) - { - CPaintDC dc(this); // device context for painting - - SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); - - // Center icon in client rectangle - int cxIcon = GetSystemMetrics(SM_CXICON); - int cyIcon = GetSystemMetrics(SM_CYICON); - CRect rect; - GetClientRect(&rect); - int x = (rect.Width() - cxIcon + 1) / 2; - int y = (rect.Height() - cyIcon + 1) / 2; - - // Draw the icon - dc.DrawIcon(x, y, m_hIcon); - } - else - { - CDialog::OnPaint(); - } -} - -// The system calls this to obtain the cursor to display while the user drags -// the minimized window. -HCURSOR CAguaDlg::OnQueryDragIcon() -{ - return (HCURSOR) m_hIcon; -} - -LRESULT CAguaDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int xpos,ypos; - CRect rect; - CPoint pnt; - static bool dragging; -///////////////////////////////////////////////////////////////////////////////////// - switch (message) - { - case WM_LBUTTONDOWN: - dragging = true; - pnt.x = LOWORD(lParam); // horizontal position of cursor - pnt.y = HIWORD(lParam); // vertical position of cursor - ClientToScreen(&pnt); - m_Display.GetWindowRect(&rect); - if (rect.PtInRect(pnt)) - { - xpos = pnt.x - rect.left; - ypos = (WATER_SIZE - 1) - (pnt.y - rect.top); - MakeDrip(xpos,ypos, 16); - } - break; - case WM_LBUTTONUP: - dragging = false; - break; - case WM_MOUSEMOVE: - if (dragging) - { - pnt.x = LOWORD(lParam); // horizontal position of cursor - pnt.y = HIWORD(lParam); // vertical position of cursor - ClientToScreen(&pnt); - m_Display.GetWindowRect(&rect); - if (rect.PtInRect(pnt)) - { - xpos = pnt.x - rect.left; - ypos = (WATER_SIZE - 1) - (pnt.y - rect.top); - MakeDrip(xpos,ypos, 16); - } - } - break; - case WM_TIMER: - ProcessWater(); - break; - } - - return CDialog::WindowProc(message, wParam, lParam); -} - - -//////////////////////////////////////////////////////////////////////////////// -// Handle Control UI like text boxes and buttons -//////////////////////////////////////////////////////////////////////////////// - -void CAguaDlg::OnUpdateDamping() -{ - UpdateData(TRUE); -} - -void CAguaDlg::OnUpdateDripRadius() -{ - UpdateData(TRUE); -} - -void CAguaDlg::OnImageBrowse() -{ - char BASED_CODE szFilter[] = "Targa Files (*.tga)|*.tga||"; - CFileDialog *dialog; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(TRUE,"TGA",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - m_ImageFile = dialog->GetPathName(); - } - UpdateData(FALSE); - OnUpdateImagefile(); -} - -void CAguaDlg::OnUpdateImagefile() -{ - UpdateData(TRUE); - LoadTGAFile((char *)(LPCSTR)m_ImageFile,&m_ReflectImage); -} - -//////////////////////////////////////////////////////////////////////////////// -// Actual Code for creation of the water height field -//////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: SetDisplay -// Purpose: To convert the height field into something to look at in the dialog -///////////////////////////////////////////////////////////////////////////////////// -void CAguaDlg::SetDisplay() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *temp; - long color; - int r,g,b,xoff,yoff; -///////////////////////////////////////////////////////////////////////////////////// - // Swap the buffers - temp = m_ReadBuffer; - m_ReadBuffer = m_WriteBuffer; - m_WriteBuffer = temp; - - int cnt = 0; - for (int j = 0; j < WATER_SIZE; j++) - { - for (int i = 0; i < WATER_SIZE; i++, cnt++) - { - xoff = i; - if (i > 0 && i < WATER_SIZE - 1) - { - xoff -= (m_ReadBuffer[cnt - 1]); - xoff += (m_ReadBuffer[cnt + 1]); - } - - yoff = j; - if (j > 0 && j < WATER_SIZE - 1) - { - yoff -= m_ReadBuffer[cnt - WATER_SIZE]; - yoff += m_ReadBuffer[cnt + WATER_SIZE]; - } - - // Clamp the offset to actual picture range - if (xoff < 0) xoff = 0; - if (yoff < 0) yoff = 0; - if (xoff >= m_ReflectImage.header.d_width) xoff = m_ReflectImage.header.d_width - 1; - if (yoff >= m_ReflectImage.header.d_height) yoff = m_ReflectImage.header.d_height - 1; - - if (m_UseImage) - { - color = GetRGBFromTGA(&m_ReflectImage,xoff,yoff); - r = GetR32(color); - g = GetG32(color); - b = GetB32(color); - } - else - { - r = m_Red; - g = m_Green; - b = m_Blue; - } - - - r += m_ReadBuffer[cnt]; - g += m_ReadBuffer[cnt]; - b += m_ReadBuffer[cnt]; - // Clamp Color to the valid range - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - m_Buffer[cnt] = RGB32(r,g,b); - } - } - m_Display.Invalidate(); -} - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: SquaredDist -// Purpose: Find the Squared distance between two 2D points -///////////////////////////////////////////////////////////////////////////////////// -int inline CAguaDlg::SquaredDist(int sx, int sy, int dx, int dy) -{ - return ((dx - sx) * (dx - sx)) + ((dy - sy) * (dy - sy)); -} - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Make Drip -// Purpose: Creates an initial drip in the water field -// Usually caused by mouse press -///////////////////////////////////////////////////////////////////////////////////// -void CAguaDlg::MakeDrip(int x, int y, int depth) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int i,j,dist,finaldepth; - CRect bounds(0,0,WATER_SIZE - 1,WATER_SIZE - 1); -///////////////////////////////////////////////////////////////////////////////////// - for (j = y - m_Drip_Radius; j < y + m_Drip_Radius; j++) - { - for (i = x - m_Drip_Radius; i < x + m_Drip_Radius; i++) - { - if (bounds.PtInRect(CPoint(i,j))) - { - dist = SquaredDist(x,y,i,j); - if (dist < m_Drip_Radius_Sqr) - { - finaldepth = (int)((float)depth * ((float)(m_Drip_Radius - sqrt(dist))/(float)m_Drip_Radius)); - if (finaldepth > 127) finaldepth = 127; - if (finaldepth < -127) finaldepth = -127; - SETBUFFER(m_WriteBuffer,i,j,finaldepth); - } - } - } - } - m_Display.Invalidate(); -} - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: ProcessWater -// Purpose: Calculate new values for the water height field -///////////////////////////////////////////////////////////////////////////////////// -void CAguaDlg::ProcessWater() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int i,j; - float value; -///////////////////////////////////////////////////////////////////////////////////// - UpdateData(TRUE); // Get Value from Dialog - - for (j = 2; j < WATER_SIZE - 2; j++) - { - for (i = 2; i < WATER_SIZE - 2; i++) - { - // Sample a "circle" around the center point - value = (float)( - READBUFFER(m_ReadBuffer,i-2,j) + - READBUFFER(m_ReadBuffer,i+2,j) + - READBUFFER(m_ReadBuffer,i,j-2) + - READBUFFER(m_ReadBuffer,i,j+2) + - READBUFFER(m_ReadBuffer,i-1,j) + - READBUFFER(m_ReadBuffer,i+1,j) + - READBUFFER(m_ReadBuffer,i,j-1) + - READBUFFER(m_ReadBuffer,i,j+1) + - READBUFFER(m_ReadBuffer,i-1,j-1) + - READBUFFER(m_ReadBuffer,i+1,j-1) + - READBUFFER(m_ReadBuffer,i-1,j+1) + - READBUFFER(m_ReadBuffer,i+1,j+1)); - value /= 6.0f; // Average * 2 - value -= (float)READBUFFER(m_WriteBuffer,i,j); - // Values for damping from 0.04 - 0.0001 look pretty good - value -= (value * m_DampingFactor); - SETBUFFER(m_WriteBuffer,i,j,(int)value); - } - } - SetDisplay(); // Draw and Swap Buffers -} - +// AguaDlg.cpp : implementation file +// + +#include "stdafx.h" +#include +#include "Agua.h" +#include "AguaDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// TODO: Adjust this to make the field smaller and it will run faster +// 128 is pretty good for speed +#define WATER_SIZE 256 + +#define RGB32(r,g,b) ((r << 16) + (g << 8) + b) +#define GetR32(color) (0x000000ff & (color >> 16)) +#define GetG32(color) (0x000000ff & (color >> 8)) +#define GetB32(color) (0x000000ff & color) + +#define SETBUFFER(buf,x,y,value) (buf[((y) * WATER_SIZE) + (x)] = value) +#define READBUFFER(buf,x,y) (buf[((y) * WATER_SIZE) + (x)]) + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CAguaDlg dialog + +CAguaDlg::CAguaDlg(CWnd* pParent /*=NULL*/) + : CDialog(CAguaDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CAguaDlg) + m_Drip_Radius = 12; + m_DampingFactor = 0.002f; + m_ImageFile = _T("Reflect.tga"); + m_Green = 128; + m_Red = 128; + m_Blue = 128; + m_UseImage = TRUE; + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CAguaDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAguaDlg) + DDX_Control(pDX, IDC_DISPLAY, m_Display); + DDX_Text(pDX, IDC_DRIP_RADIUS, m_Drip_Radius); + DDX_Text(pDX, IDC_DAMPING, m_DampingFactor); + DDX_Text(pDX, IDC_IMAGEFILE, m_ImageFile); + DDX_Text(pDX, IDC_GREEN, m_Green); + DDV_MinMaxUInt(pDX, m_Green, 0, 255); + DDX_Text(pDX, IDC_RED, m_Red); + DDV_MinMaxUInt(pDX, m_Red, 0, 255); + DDX_Text(pDX, IDC_BLUE, m_Blue); + DDV_MinMaxUInt(pDX, m_Blue, 0, 255); + DDX_Check(pDX, IDC_USEIMAGE, m_UseImage); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAguaDlg, CDialog) + //{{AFX_MSG_MAP(CAguaDlg) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_EN_UPDATE(IDC_DAMPING, OnUpdateDamping) + ON_EN_UPDATE(IDC_DRIP_RADIUS, OnUpdateDripRadius) + ON_BN_CLICKED(IDC_IMAGE_BROWSE, OnImageBrowse) + ON_EN_UPDATE(IDC_IMAGEFILE, OnUpdateImagefile) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CAguaDlg message handlers + +BOOL CAguaDlg::OnInitDialog() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + BITMAPINFO bmi; + CDC *hdc; +///////////////////////////////////////////////////////////////////////////////////// + CDialog::OnInitDialog(); + + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + CString strAboutMenu; + strAboutMenu.LoadString(IDS_ABOUTBOX); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + memset ( &bmi, 0, sizeof(BITMAPINFO) ); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = WATER_SIZE; //wndRect.right; // 1024 mode + bmi.bmiHeader.biHeight = WATER_SIZE; //wndRect.bottom; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + hdc = GetDC (); + if ( !hdc ) + return 0; + + m_Bitmap = CreateDIBSection ( hdc->m_hDC , &bmi, DIB_RGB_COLORS, (void **)&m_Buffer, NULL, 0 ); + ReleaseDC ( hdc); + + if ( !m_Bitmap ) + return 0; + + m_Display.SetBitmap(m_Bitmap); + + m_ReadBuffer = (char *)malloc(WATER_SIZE * WATER_SIZE); + m_WriteBuffer = (char *)malloc(WATER_SIZE * WATER_SIZE); + + for (int i = 0; i < WATER_SIZE * WATER_SIZE; i++) + { + m_ReadBuffer[i] = 0; + m_WriteBuffer[i] = 0; + } + + LoadTGAFile("Reflect.tga",&m_ReflectImage); + + SetDisplay(); + + SetTimer(1,5,NULL); // Set it up to animate via messages + + m_Drip_Radius_Sqr = m_Drip_Radius * m_Drip_Radius; + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CAguaDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialog::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CAguaDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CAguaDlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +LRESULT CAguaDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int xpos,ypos; + CRect rect; + CPoint pnt; + static bool dragging; +///////////////////////////////////////////////////////////////////////////////////// + switch (message) + { + case WM_LBUTTONDOWN: + dragging = true; + pnt.x = LOWORD(lParam); // horizontal position of cursor + pnt.y = HIWORD(lParam); // vertical position of cursor + ClientToScreen(&pnt); + m_Display.GetWindowRect(&rect); + if (rect.PtInRect(pnt)) + { + xpos = pnt.x - rect.left; + ypos = (WATER_SIZE - 1) - (pnt.y - rect.top); + MakeDrip(xpos,ypos, 16); + } + break; + case WM_LBUTTONUP: + dragging = false; + break; + case WM_MOUSEMOVE: + if (dragging) + { + pnt.x = LOWORD(lParam); // horizontal position of cursor + pnt.y = HIWORD(lParam); // vertical position of cursor + ClientToScreen(&pnt); + m_Display.GetWindowRect(&rect); + if (rect.PtInRect(pnt)) + { + xpos = pnt.x - rect.left; + ypos = (WATER_SIZE - 1) - (pnt.y - rect.top); + MakeDrip(xpos,ypos, 16); + } + } + break; + case WM_TIMER: + ProcessWater(); + break; + } + + return CDialog::WindowProc(message, wParam, lParam); +} + + +//////////////////////////////////////////////////////////////////////////////// +// Handle Control UI like text boxes and buttons +//////////////////////////////////////////////////////////////////////////////// + +void CAguaDlg::OnUpdateDamping() +{ + UpdateData(TRUE); +} + +void CAguaDlg::OnUpdateDripRadius() +{ + UpdateData(TRUE); +} + +void CAguaDlg::OnImageBrowse() +{ + char BASED_CODE szFilter[] = "Targa Files (*.tga)|*.tga||"; + CFileDialog *dialog; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(TRUE,"TGA",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + m_ImageFile = dialog->GetPathName(); + } + UpdateData(FALSE); + OnUpdateImagefile(); +} + +void CAguaDlg::OnUpdateImagefile() +{ + UpdateData(TRUE); + LoadTGAFile((char *)(LPCSTR)m_ImageFile,&m_ReflectImage); +} + +//////////////////////////////////////////////////////////////////////////////// +// Actual Code for creation of the water height field +//////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: SetDisplay +// Purpose: To convert the height field into something to look at in the dialog +///////////////////////////////////////////////////////////////////////////////////// +void CAguaDlg::SetDisplay() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *temp; + long color; + int r,g,b,xoff,yoff; +///////////////////////////////////////////////////////////////////////////////////// + // Swap the buffers + temp = m_ReadBuffer; + m_ReadBuffer = m_WriteBuffer; + m_WriteBuffer = temp; + + int cnt = 0; + for (int j = 0; j < WATER_SIZE; j++) + { + for (int i = 0; i < WATER_SIZE; i++, cnt++) + { + xoff = i; + if (i > 0 && i < WATER_SIZE - 1) + { + xoff -= (m_ReadBuffer[cnt - 1]); + xoff += (m_ReadBuffer[cnt + 1]); + } + + yoff = j; + if (j > 0 && j < WATER_SIZE - 1) + { + yoff -= m_ReadBuffer[cnt - WATER_SIZE]; + yoff += m_ReadBuffer[cnt + WATER_SIZE]; + } + + // Clamp the offset to actual picture range + if (xoff < 0) xoff = 0; + if (yoff < 0) yoff = 0; + if (xoff >= m_ReflectImage.header.d_width) xoff = m_ReflectImage.header.d_width - 1; + if (yoff >= m_ReflectImage.header.d_height) yoff = m_ReflectImage.header.d_height - 1; + + if (m_UseImage) + { + color = GetRGBFromTGA(&m_ReflectImage,xoff,yoff); + r = GetR32(color); + g = GetG32(color); + b = GetB32(color); + } + else + { + r = m_Red; + g = m_Green; + b = m_Blue; + } + + + r += m_ReadBuffer[cnt]; + g += m_ReadBuffer[cnt]; + b += m_ReadBuffer[cnt]; + // Clamp Color to the valid range + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + m_Buffer[cnt] = RGB32(r,g,b); + } + } + m_Display.Invalidate(); +} + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: SquaredDist +// Purpose: Find the Squared distance between two 2D points +///////////////////////////////////////////////////////////////////////////////////// +int inline CAguaDlg::SquaredDist(int sx, int sy, int dx, int dy) +{ + return ((dx - sx) * (dx - sx)) + ((dy - sy) * (dy - sy)); +} + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Make Drip +// Purpose: Creates an initial drip in the water field +// Usually caused by mouse press +///////////////////////////////////////////////////////////////////////////////////// +void CAguaDlg::MakeDrip(int x, int y, int depth) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int i,j,dist,finaldepth; + CRect bounds(0,0,WATER_SIZE - 1,WATER_SIZE - 1); +///////////////////////////////////////////////////////////////////////////////////// + for (j = y - m_Drip_Radius; j < y + m_Drip_Radius; j++) + { + for (i = x - m_Drip_Radius; i < x + m_Drip_Radius; i++) + { + if (bounds.PtInRect(CPoint(i,j))) + { + dist = SquaredDist(x,y,i,j); + if (dist < m_Drip_Radius_Sqr) + { + finaldepth = (int)((float)depth * ((float)(m_Drip_Radius - sqrt(dist))/(float)m_Drip_Radius)); + if (finaldepth > 127) finaldepth = 127; + if (finaldepth < -127) finaldepth = -127; + SETBUFFER(m_WriteBuffer,i,j,finaldepth); + } + } + } + } + m_Display.Invalidate(); +} + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: ProcessWater +// Purpose: Calculate new values for the water height field +///////////////////////////////////////////////////////////////////////////////////// +void CAguaDlg::ProcessWater() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int i,j; + float value; +///////////////////////////////////////////////////////////////////////////////////// + UpdateData(TRUE); // Get Value from Dialog + + for (j = 2; j < WATER_SIZE - 2; j++) + { + for (i = 2; i < WATER_SIZE - 2; i++) + { + // Sample a "circle" around the center point + value = (float)( + READBUFFER(m_ReadBuffer,i-2,j) + + READBUFFER(m_ReadBuffer,i+2,j) + + READBUFFER(m_ReadBuffer,i,j-2) + + READBUFFER(m_ReadBuffer,i,j+2) + + READBUFFER(m_ReadBuffer,i-1,j) + + READBUFFER(m_ReadBuffer,i+1,j) + + READBUFFER(m_ReadBuffer,i,j-1) + + READBUFFER(m_ReadBuffer,i,j+1) + + READBUFFER(m_ReadBuffer,i-1,j-1) + + READBUFFER(m_ReadBuffer,i+1,j-1) + + READBUFFER(m_ReadBuffer,i-1,j+1) + + READBUFFER(m_ReadBuffer,i+1,j+1)); + value /= 6.0f; // Average * 2 + value -= (float)READBUFFER(m_WriteBuffer,i,j); + // Values for damping from 0.04 - 0.0001 look pretty good + value -= (value * m_DampingFactor); + SETBUFFER(m_WriteBuffer,i,j,(int)value); + } + } + SetDisplay(); // Draw and Swap Buffers +} + diff --git a/2D Water Effects/Code/OGL/Agua/AguaDlg.h b/2D Water Effects/Code/OGL/Agua/AguaDlg.h index 9bea6d5..dd1b48b 100644 --- a/2D Water Effects/Code/OGL/Agua/AguaDlg.h +++ b/2D Water Effects/Code/OGL/Agua/AguaDlg.h @@ -1,73 +1,73 @@ -// AguaDlg.h : header file -// - -#if !defined(AFX_AGUADLG_H__BB47BA75_6E1A_40E8_86EE_E5F79B1C91C6__INCLUDED_) -#define AFX_AGUADLG_H__BB47BA75_6E1A_40E8_86EE_E5F79B1C91C6__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "LoadTGA.h" - -///////////////////////////////////////////////////////////////////////////// -// CAguaDlg dialog - -class CAguaDlg : public CDialog -{ -// Construction -public: - CAguaDlg(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CAguaDlg) - enum { IDD = IDD_AGUA_DIALOG }; - CStatic m_Display; - int m_Drip_Radius; - float m_DampingFactor; - CString m_ImageFile; - UINT m_Green; - UINT m_Red; - UINT m_Blue; - BOOL m_UseImage; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAguaDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); - //}}AFX_VIRTUAL - -// Implementation -protected: - HICON m_hIcon; - HBITMAP m_Bitmap; - long *m_Buffer; - char *m_ReadBuffer, *m_WriteBuffer; // Water height map - tTGAFile_s m_ReflectImage; - int m_Drip_Radius_Sqr; // Squared Radius - - void SetDisplay(); // Draw the height field - void MakeDrip(int x, int y, int depth); - int SquaredDist(int sx, int sy, int dx, int dy); - void ProcessWater(); - - // Generated message map functions - //{{AFX_MSG(CAguaDlg) - virtual BOOL OnInitDialog(); - afx_msg void OnSysCommand(UINT nID, LPARAM lParam); - afx_msg void OnPaint(); - afx_msg HCURSOR OnQueryDragIcon(); - afx_msg void OnUpdateDamping(); - afx_msg void OnUpdateDripRadius(); - afx_msg void OnImageBrowse(); - afx_msg void OnUpdateImagefile(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_AGUADLG_H__BB47BA75_6E1A_40E8_86EE_E5F79B1C91C6__INCLUDED_) +// AguaDlg.h : header file +// + +#if !defined(AFX_AGUADLG_H__BB47BA75_6E1A_40E8_86EE_E5F79B1C91C6__INCLUDED_) +#define AFX_AGUADLG_H__BB47BA75_6E1A_40E8_86EE_E5F79B1C91C6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "LoadTGA.h" + +///////////////////////////////////////////////////////////////////////////// +// CAguaDlg dialog + +class CAguaDlg : public CDialog +{ +// Construction +public: + CAguaDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CAguaDlg) + enum { IDD = IDD_AGUA_DIALOG }; + CStatic m_Display; + int m_Drip_Radius; + float m_DampingFactor; + CString m_ImageFile; + UINT m_Green; + UINT m_Red; + UINT m_Blue; + BOOL m_UseImage; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAguaDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); + //}}AFX_VIRTUAL + +// Implementation +protected: + HICON m_hIcon; + HBITMAP m_Bitmap; + long *m_Buffer; + char *m_ReadBuffer, *m_WriteBuffer; // Water height map + tTGAFile_s m_ReflectImage; + int m_Drip_Radius_Sqr; // Squared Radius + + void SetDisplay(); // Draw the height field + void MakeDrip(int x, int y, int depth); + int SquaredDist(int sx, int sy, int dx, int dy); + void ProcessWater(); + + // Generated message map functions + //{{AFX_MSG(CAguaDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + afx_msg void OnUpdateDamping(); + afx_msg void OnUpdateDripRadius(); + afx_msg void OnImageBrowse(); + afx_msg void OnUpdateImagefile(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_AGUADLG_H__BB47BA75_6E1A_40E8_86EE_E5F79B1C91C6__INCLUDED_) diff --git a/2D Water Effects/Code/OGL/Agua/LoadTGA.cpp b/2D Water Effects/Code/OGL/Agua/LoadTGA.cpp index a792906..a30e373 100644 --- a/2D Water Effects/Code/OGL/Agua/LoadTGA.cpp +++ b/2D Water Effects/Code/OGL/Agua/LoadTGA.cpp @@ -1,105 +1,105 @@ -///////////////////////////////////////////////////////////////////////////////////// -// Routines to load the texture map -///////////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include "loadtga.h" - - -/////////////////////////////////////////////////////////////////////////////// -// This stuff forward is the TGA Loading Routines -// -/////////////////////////////////////////////////////////////////////////////// - -//----------------------------------------------------------------------- -// Name: LoadTGAFile() -// Desc: Given a filename of a TGA file, it loads the image in BITMAP form -//----------------------------------------------------------------------- -void LoadTGAFile( char * strFilename, tTGAFile_s *tgafile) -{ -/// Local Variables /////////////////////////////////////////////////////////// - short BitsPerPixel; - unsigned char *buffer; - int bitsize; /* Total size of bitmap */ - unsigned char *newbits; /* New RGB bits */ - unsigned char *from, *to; /* RGB looping vars */ - int i, j, /* Looping vars */ - width; /* Aligned width of bitmap */ - FILE *file; - long dwWidth, dwHeight; - tTGAHeader_s *header; -/////////////////////////////////////////////////////////////////////////////// - header = &tgafile->header; - - // Open the file and read the header - file = fopen( strFilename, "rb"); - if( NULL == file ) - return; - - if ( fread( header, sizeof( tTGAHeader_s ), 1, file ) != 1 ) - { - fclose( file ); - return; - } - - // Parse the TGA header - dwWidth = (long)header->d_width; - dwHeight = (long)header->d_height; - BitsPerPixel = (short)header->d_pixel_size; // 16, 24, or 32 - - // Create a bitmap to load the data into - - bitsize = dwWidth * dwHeight * (BitsPerPixel/8); - if ((newbits = (unsigned char *)calloc(bitsize, 1)) == NULL) - { - fclose( file ); - return; - } - buffer = (unsigned char *)malloc(dwWidth*dwHeight*(BitsPerPixel / 8)); - if ( fread( buffer, dwWidth*dwHeight*(BitsPerPixel / 8), 1, file ) != 1 ) - { - fclose( file ); - free(buffer); - free(newbits); - return; - } - - width = (BitsPerPixel / 8) * dwWidth; - - for (i = 0; i < dwHeight; i ++) - for (j = 0, from = ((unsigned char *)buffer) + i * width, - to = newbits + i * width; - j < dwWidth; - j ++, from += (BitsPerPixel / 8), to += (BitsPerPixel / 8)) - { - if (BitsPerPixel == 24) - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - } - else - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - to[3] = from[3]; - } - }; - free(buffer); - fclose( file ); - - tgafile->data = newbits; -} - - -long GetRGBFromTGA(tTGAFile_s *file, int x, int y) -{ - unsigned char *pixelpnt; - - pixelpnt = &file->data[((y * file->header.d_width) + x) * (file->header.d_pixel_size / 8)]; - if (file->header.d_pixel_size == 24) - return (0xff000000 + (pixelpnt[0] << 16) + (pixelpnt[1] << 8) + pixelpnt[2]); - else - return ((pixelpnt[0] << 24) + (pixelpnt[1] << 16) + (pixelpnt[2] << 8) + pixelpnt[3]); +///////////////////////////////////////////////////////////////////////////////////// +// Routines to load the texture map +///////////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include "loadtga.h" + + +/////////////////////////////////////////////////////////////////////////////// +// This stuff forward is the TGA Loading Routines +// +/////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------- +// Name: LoadTGAFile() +// Desc: Given a filename of a TGA file, it loads the image in BITMAP form +//----------------------------------------------------------------------- +void LoadTGAFile( char * strFilename, tTGAFile_s *tgafile) +{ +/// Local Variables /////////////////////////////////////////////////////////// + short BitsPerPixel; + unsigned char *buffer; + int bitsize; /* Total size of bitmap */ + unsigned char *newbits; /* New RGB bits */ + unsigned char *from, *to; /* RGB looping vars */ + int i, j, /* Looping vars */ + width; /* Aligned width of bitmap */ + FILE *file; + long dwWidth, dwHeight; + tTGAHeader_s *header; +/////////////////////////////////////////////////////////////////////////////// + header = &tgafile->header; + + // Open the file and read the header + file = fopen( strFilename, "rb"); + if( NULL == file ) + return; + + if ( fread( header, sizeof( tTGAHeader_s ), 1, file ) != 1 ) + { + fclose( file ); + return; + } + + // Parse the TGA header + dwWidth = (long)header->d_width; + dwHeight = (long)header->d_height; + BitsPerPixel = (short)header->d_pixel_size; // 16, 24, or 32 + + // Create a bitmap to load the data into + + bitsize = dwWidth * dwHeight * (BitsPerPixel/8); + if ((newbits = (unsigned char *)calloc(bitsize, 1)) == NULL) + { + fclose( file ); + return; + } + buffer = (unsigned char *)malloc(dwWidth*dwHeight*(BitsPerPixel / 8)); + if ( fread( buffer, dwWidth*dwHeight*(BitsPerPixel / 8), 1, file ) != 1 ) + { + fclose( file ); + free(buffer); + free(newbits); + return; + } + + width = (BitsPerPixel / 8) * dwWidth; + + for (i = 0; i < dwHeight; i ++) + for (j = 0, from = ((unsigned char *)buffer) + i * width, + to = newbits + i * width; + j < dwWidth; + j ++, from += (BitsPerPixel / 8), to += (BitsPerPixel / 8)) + { + if (BitsPerPixel == 24) + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + } + else + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + to[3] = from[3]; + } + }; + free(buffer); + fclose( file ); + + tgafile->data = newbits; +} + + +long GetRGBFromTGA(tTGAFile_s *file, int x, int y) +{ + unsigned char *pixelpnt; + + pixelpnt = &file->data[((y * file->header.d_width) + x) * (file->header.d_pixel_size / 8)]; + if (file->header.d_pixel_size == 24) + return (0xff000000 + (pixelpnt[0] << 16) + (pixelpnt[1] << 8) + pixelpnt[2]); + else + return ((pixelpnt[0] << 24) + (pixelpnt[1] << 16) + (pixelpnt[2] << 8) + pixelpnt[3]); } \ No newline at end of file diff --git a/2D Water Effects/Code/OGL/Agua/LoadTGA.h b/2D Water Effects/Code/OGL/Agua/LoadTGA.h index 1fb7194..14a5823 100644 --- a/2D Water Effects/Code/OGL/Agua/LoadTGA.h +++ b/2D Water Effects/Code/OGL/Agua/LoadTGA.h @@ -1,34 +1,34 @@ -typedef struct -{ - unsigned char d_iif_size; // IIF size (after header), usually 0 - unsigned char d_cmap_type; // ignored - unsigned char d_image_type; // should be 2 - unsigned char pad[5]; - - unsigned short d_x_origin; - unsigned short d_y_origin; - unsigned short d_width; - unsigned short d_height; - - unsigned char d_pixel_size; // 16, 24, or 32 - unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) -} tTGAHeader_s; - -typedef struct -{ - tTGAHeader_s header; - unsigned char *data; -} tTGAFile_s; - -#define RGB16(r,g,b) ( ((r>>3) << 10) + ((g>>3) << 5) + (b >> 3) ) -#define RGB24(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) -#define GET16R(v) (v >> 10) -#define GET16G(v) ((v >> 5) & 0x1f) -#define GET16B(v) (v & 0x1f) - -void LoadTGAFile( char * strFilename, tTGAFile_s *file); -long GetRGBFromTGA(tTGAFile_s *file, int x, int y); - +typedef struct +{ + unsigned char d_iif_size; // IIF size (after header), usually 0 + unsigned char d_cmap_type; // ignored + unsigned char d_image_type; // should be 2 + unsigned char pad[5]; + + unsigned short d_x_origin; + unsigned short d_y_origin; + unsigned short d_width; + unsigned short d_height; + + unsigned char d_pixel_size; // 16, 24, or 32 + unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) +} tTGAHeader_s; + +typedef struct +{ + tTGAHeader_s header; + unsigned char *data; +} tTGAFile_s; + +#define RGB16(r,g,b) ( ((r>>3) << 10) + ((g>>3) << 5) + (b >> 3) ) +#define RGB24(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) +#define GET16R(v) (v >> 10) +#define GET16G(v) ((v >> 5) & 0x1f) +#define GET16B(v) (v & 0x1f) + +void LoadTGAFile( char * strFilename, tTGAFile_s *file); +long GetRGBFromTGA(tTGAFile_s *file, int x, int y); + diff --git a/2D Water Effects/Code/OGL/Agua/ReadMe.txt b/2D Water Effects/Code/OGL/Agua/ReadMe.txt index 25047e6..e4b3886 100644 --- a/2D Water Effects/Code/OGL/Agua/ReadMe.txt +++ b/2D Water Effects/Code/OGL/Agua/ReadMe.txt @@ -1,50 +1,50 @@ -Agua Application 12/99 ----------------------------------------------- - -This is the Companion application to the December 1999 -Game Developer magazine. - -It implements an image processing method for creating -a rippling water surface. - -This app does not require 3D hardware. - -If it runs too slow, make the size of the height field -smaller by changing the WATER_SIZE define in AguaDlg.cpp -Try 128. Especially if you consider turning this into -a 3D height field, you will want a smaller field. - -The app is a Dialog based MFC app. - -Suggestions for playing around ------------------------------- - -Experiment with changes to the Process water routine -in AguaDlg.cpp. This is the actual convolution that -creates the effect. There are a lot of variations that -produce different effects. - -Optimize... I didn't spend much time making it fast. -Indexing tricks (especially in a 256x256 field) would -help as well as some assembly here and there. - -Take the height field and convert it to a 3D mesh. I -would use the 256x256 as a texture but make the resolution -of the 3D mesh something like 64x64. - - -Credits -------------------------------- - -Since I could not effectively figure out a original -source for this technique, I have received some mail -from people claiming to be the first. I will compile -a list of these on my website www.darwin3d.com/gamedev.htm. - -Should be fun to try different people's variations. - - -Jeff -jeffl@darwin3d.com - - +Agua Application 12/99 +---------------------------------------------- + +This is the Companion application to the December 1999 +Game Developer magazine. + +It implements an image processing method for creating +a rippling water surface. + +This app does not require 3D hardware. + +If it runs too slow, make the size of the height field +smaller by changing the WATER_SIZE define in AguaDlg.cpp +Try 128. Especially if you consider turning this into +a 3D height field, you will want a smaller field. + +The app is a Dialog based MFC app. + +Suggestions for playing around +------------------------------ + +Experiment with changes to the Process water routine +in AguaDlg.cpp. This is the actual convolution that +creates the effect. There are a lot of variations that +produce different effects. + +Optimize... I didn't spend much time making it fast. +Indexing tricks (especially in a 256x256 field) would +help as well as some assembly here and there. + +Take the height field and convert it to a 3D mesh. I +would use the 256x256 as a texture but make the resolution +of the 3D mesh something like 64x64. + + +Credits +------------------------------- + +Since I could not effectively figure out a original +source for this technique, I have received some mail +from people claiming to be the first. I will compile +a list of these on my website www.darwin3d.com/gamedev.htm. + +Should be fun to try different people's variations. + + +Jeff +jeffl@darwin3d.com + + diff --git a/2D Water Effects/Code/OGL/Agua/Resource.h b/2D Water Effects/Code/OGL/Agua/Resource.h index eaf68aa..1d0c4fa 100644 --- a/2D Water Effects/Code/OGL/Agua/Resource.h +++ b/2D Water Effects/Code/OGL/Agua/Resource.h @@ -1,29 +1,29 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Agua.rc -// -#define IDM_ABOUTBOX 0x0010 -#define IDD_ABOUTBOX 100 -#define IDS_ABOUTBOX 101 -#define IDD_AGUA_DIALOG 102 -#define IDR_MAINFRAME 128 -#define IDC_DISPLAY 1000 -#define IDC_DRIP_RADIUS 1001 -#define IDC_DAMPING 1002 -#define IDC_IMAGEFILE 1003 -#define IDC_IMAGE_BROWSE 1004 -#define IDC_USEIMAGE 1005 -#define IDC_RED 1006 -#define IDC_GREEN 1007 -#define IDC_BLUE 1008 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1007 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Agua.rc +// +#define IDM_ABOUTBOX 0x0010 +#define IDD_ABOUTBOX 100 +#define IDS_ABOUTBOX 101 +#define IDD_AGUA_DIALOG 102 +#define IDR_MAINFRAME 128 +#define IDC_DISPLAY 1000 +#define IDC_DRIP_RADIUS 1001 +#define IDC_DAMPING 1002 +#define IDC_IMAGEFILE 1003 +#define IDC_IMAGE_BROWSE 1004 +#define IDC_USEIMAGE 1005 +#define IDC_RED 1006 +#define IDC_GREEN 1007 +#define IDC_BLUE 1008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1007 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/2D Water Effects/Code/OGL/Agua/StdAfx.cpp b/2D Water Effects/Code/OGL/Agua/StdAfx.cpp index 8aab60e..c592c54 100644 --- a/2D Water Effects/Code/OGL/Agua/StdAfx.cpp +++ b/2D Water Effects/Code/OGL/Agua/StdAfx.cpp @@ -1,8 +1,8 @@ -// stdafx.cpp : source file that includes just the standard includes -// Agua.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - - - +// stdafx.cpp : source file that includes just the standard includes +// Agua.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/2D Water Effects/Code/OGL/Agua/StdAfx.h b/2D Water Effects/Code/OGL/Agua/StdAfx.h index 6784e49..471ea79 100644 --- a/2D Water Effects/Code/OGL/Agua/StdAfx.h +++ b/2D Water Effects/Code/OGL/Agua/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__DE5DA3C5_0485_49ED_90EB_3677C9EBFB6B__INCLUDED_) -#define AFX_STDAFX_H__DE5DA3C5_0485_49ED_90EB_3677C9EBFB6B__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC support for Internet Explorer 4 Common Controls -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__DE5DA3C5_0485_49ED_90EB_3677C9EBFB6B__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__DE5DA3C5_0485_49ED_90EB_3677C9EBFB6B__INCLUDED_) +#define AFX_STDAFX_H__DE5DA3C5_0485_49ED_90EB_3677C9EBFB6B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__DE5DA3C5_0485_49ED_90EB_3677C9EBFB6B__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/Bitmap.cpp b/3D Morphing/Code/OGL/Morphy/Bitmap.cpp index 271acf1..5ce5da9 100644 --- a/3D Morphing/Code/OGL/Morphy/Bitmap.cpp +++ b/3D Morphing/Code/OGL/Morphy/Bitmap.cpp @@ -1,626 +1,626 @@ -/* - * "$Id: bitmap.c,v 1.2 1996/01/09 22:52:53 mike Exp mike $" - * - * Device Independent Bitmap functions for OpenGL under MS Windows. - * - * Contents: - * - * LoadDIBitmap() - Load a DIB/BMP file from disk. - * SaveDIBitmap() - Save a bitmap to a DIB/BMP file on disk. - * ReadDIBitmap() - Read the current OpenGL viewport into a - * 24-bit RGB bitmap. - * PrintDIBitmap() - Print a bitmap to a GDI printer. - * ConvertRGB() - Convert a DIB/BMP image to 24-bit RGB pixels. - * - * Revision History: - * +/* + * "$Id: bitmap.c,v 1.2 1996/01/09 22:52:53 mike Exp mike $" + * + * Device Independent Bitmap functions for OpenGL under MS Windows. + * + * Contents: + * + * LoadDIBitmap() - Load a DIB/BMP file from disk. + * SaveDIBitmap() - Save a bitmap to a DIB/BMP file on disk. + * ReadDIBitmap() - Read the current OpenGL viewport into a + * 24-bit RGB bitmap. + * PrintDIBitmap() - Print a bitmap to a GDI printer. + * ConvertRGB() - Convert a DIB/BMP image to 24-bit RGB pixels. + * + * Revision History: + * * $Log: bitmap.c,v $ * Revision 1.2 1996/01/09 22:52:53 mike * Added PrintDIBitmap. - * - * Revision 1.1 1995/12/31 07:27:17 mike - * Initial revision - */ - -/* - * Include necessary headers. - */ - -#include "stdafx.h" -#include "bitmap.h" - - -/* - * 'LoadDIBitmap()' - Load a DIB/BMP file from disk. - * - * Returns a pointer to the bitmap if successful, NULL otherwise... - */ - -void * -LoadDIBitmap(char *filename, /* I - File to load */ - BITMAPINFO **info) /* O - Bitmap information */ -{ - FILE *fp; /* Open file pointer */ - void *bits; /* Bitmap pixel bits */ - long bitsize, /* Size of bitmap */ - infosize; /* Size of header information */ - BITMAPFILEHEADER header; /* File header */ - - - /* - * Try opening the file; use "rb" mode to read this *binary* file. - */ - - if ((fp = fopen(filename, "rb")) == NULL) - return (NULL); - - /* - * Read the file header and any following bitmap information... - */ - - if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1) - { - /* - * Couldn't read the file header - return NULL... - */ - - fclose(fp); - return (NULL); - }; - - if (header.bfType != 'MB') /* Check for BM reversed... */ - { - /* - * Not a bitmap file - return NULL... - */ - - fclose(fp); - return (NULL); - }; - - infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER); - if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL) - { - /* - * Couldn't allocate memory for bitmap info - return NULL... - */ - - fclose(fp); - return (NULL); - }; - - if (fread(*info, 1, infosize, fp) < infosize) - { - /* - * Couldn't read the bitmap header - return NULL... - */ - - free(*info); - fclose(fp); - return (NULL); - }; - - /* - * Now that we have all the header info read in, allocate memory for the - * bitmap and read *it* in... - */ - - if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0) - bitsize = ((*info)->bmiHeader.biWidth * - (*info)->bmiHeader.biBitCount + 7) / 8 * - abs((*info)->bmiHeader.biHeight); - - if ((bits = malloc(bitsize)) == NULL) - { - /* - * Couldn't allocate memory - return NULL! - */ - - free(*info); - fclose(fp); - return (NULL); - }; - - if (fread(bits, 1, bitsize, fp) < bitsize) - { - /* - * Couldn't read bitmap - free memory and return NULL! - */ - - free(*info); - free(bits); - fclose(fp); - return (NULL); - }; - - /* - * OK, everything went fine - return the allocated bitmap... - */ - - fclose(fp); - return (bits); -} - - -/* - * 'SaveDIBitmap()' - Save a bitmap to a DIB/BMP file on disk. - * - * Returns 0 if successful, non-zero otherwise... - */ - -int -SaveDIBitmap(char *filename, /* I - File to save to */ - BITMAPINFO *info, /* I - Bitmap information */ - void *bits) /* I - Bitmap pixel bits */ -{ - FILE *fp; /* Open file pointer */ - long size, /* Size of file */ - infosize, /* Size of bitmap info */ - bitsize; /* Size of bitmap pixels */ - BITMAPFILEHEADER header; /* File header */ - - - /* - * Try opening the file; use "wb" mode to write this *binary* file. - */ - - if ((fp = fopen(filename, "wb")) == NULL) - return (-1); - - if (info->bmiHeader.biSizeImage == 0) /* Figure out the bitmap size */ - bitsize = (info->bmiHeader.biWidth * - info->bmiHeader.biBitCount + 7) / 8 * - abs(info->bmiHeader.biHeight); - else - bitsize = info->bmiHeader.biSizeImage; - - infosize = sizeof(BITMAPINFOHEADER); - switch (info->bmiHeader.biCompression) - { - case BI_BITFIELDS : - infosize += 12; /* Add 3 RGB doubleword masks */ - if (info->bmiHeader.biClrUsed == 0) - break; - case BI_RGB : - if (info->bmiHeader.biBitCount > 8 && - info->bmiHeader.biClrUsed == 0) - break; - case BI_RLE8 : - case BI_RLE4 : - if (info->bmiHeader.biClrUsed == 0) - infosize += (1 << info->bmiHeader.biBitCount) * 4; - else - infosize += info->bmiHeader.biClrUsed * 4; - break; - }; - - size = sizeof(BITMAPFILEHEADER) + infosize + bitsize; - - /* - * Write the file header, bitmap information, and bitmap pixel data... - */ - - header.bfType = 'MB'; /* Non-portable... sigh */ - header.bfSize = size; - header.bfReserved1 = 0; - header.bfReserved2 = 0; - header.bfOffBits = sizeof(BITMAPFILEHEADER) + infosize; - - if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER)) - { - /* - * Couldn't write the file header - return... - */ - - fclose(fp); - return (-1); - }; - - if (fwrite(info, 1, infosize, fp) < infosize) - { - /* - * Couldn't write the bitmap header - return... - */ - - fclose(fp); - return (-1); - }; - - if (fwrite(bits, 1, bitsize, fp) < bitsize) - { - /* - * Couldn't write the bitmap - return... - */ - - fclose(fp); - return (-1); - }; - - /* - * OK, everything went fine - return... - */ - - fclose(fp); - return (0); -} - - -/* - * 'ReadDIBitmap()' - Read the current OpenGL viewport into a - * 24-bit RGB bitmap. - * - * Returns the bitmap pixels if successful and NULL otherwise. - */ - -void * -ReadDIBitmap(BITMAPINFO **info) /* O - Bitmap information */ -{ - long i, j, /* Looping var */ - bitsize, /* Total size of bitmap */ - width; /* Aligned width of a scanline */ - GLint viewport[4]; /* Current viewport */ - void *bits; /* RGB bits */ - GLubyte *rgb, /* RGB looping var */ - temp; /* Temporary var for swapping */ - - /* - * Grab the current viewport... - */ - - glGetIntegerv(GL_VIEWPORT, viewport); - - /* - * Allocate memory for the header and bitmap... - */ - - if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER))) == NULL) - { - /* - * Couldn't allocate memory for bitmap info - return NULL... - */ - - return (NULL); - }; - - width = viewport[2] * 3; /* Real width of scanline */ - width = (width + 3) & ~3; /* Aligned to 4 bytes */ - bitsize = width * viewport[3]; /* Size of bitmap, aligned */ - - if ((bits = calloc(bitsize, 1)) == NULL) - { - /* - * Couldn't allocate memory for bitmap pixels - return NULL... - */ - - free(*info); - return (NULL); - }; - - /* - * Read pixels from the framebuffer... - */ - - glFinish(); /* Finish all OpenGL commands */ - glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */ - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - - glReadPixels(0, 0, viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, - bits); - - /* - * Swap red and blue for the bitmap... - */ - - for (i = 0; i < viewport[3]; i ++) - for (j = 0, rgb = ((GLubyte *)bits) + i * width; - j < viewport[2]; - j ++, rgb += 3) - { - temp = rgb[0]; - rgb[0] = rgb[2]; - rgb[2] = temp; - }; - - /* - * Finally, initialize the bitmap header information... - */ - - (*info)->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - (*info)->bmiHeader.biWidth = viewport[2]; - (*info)->bmiHeader.biHeight = viewport[3]; - (*info)->bmiHeader.biPlanes = 1; - (*info)->bmiHeader.biBitCount = 24; - (*info)->bmiHeader.biCompression = BI_RGB; - (*info)->bmiHeader.biSizeImage = bitsize; - (*info)->bmiHeader.biXPelsPerMeter = 2952; /* 75 DPI */ - (*info)->bmiHeader.biYPelsPerMeter = 2952; /* 75 DPI */ - (*info)->bmiHeader.biClrUsed = 0; - (*info)->bmiHeader.biClrImportant = 0; - - return (bits); -} - - -/* - * 'PrintDIBitmap()' - Print a bitmap to a GDI printer. - */ - -int -PrintDIBitmap(HWND owner, /* I - Owner/parent window */ - BITMAPINFO *info, /* I - Bitmap information */ - void *bits) /* I - Bitmap pixel bits */ -{ - PRINTDLG pd; /* Print dialog information */ - long xsize, /* Size of printed image */ - ysize, - xoffset, /* Offset from edges for image */ - yoffset; - RECT rect; /* Page rectangle */ - DOCINFO di; /* Document info */ - HDC hdc; /* Device context for bitmap */ - HBITMAP bitmap; /* Bitmap image */ - HBRUSH brush; /* Background brush for page */ - HCURSOR busy, /* Busy cursor */ - oldcursor; /* Old cursor */ - - - /* - * Range check... - */ - - if (info == NULL || bits == NULL) - return (0); - - /* - * Initialize a PRINTDLG structure before displaying a standard Windows - * print dialog... - */ - - memset(&pd, 0, sizeof(pd)); - pd.lStructSize = sizeof(pd); - pd.hwndOwner = owner; - pd.Flags = PD_RETURNDC; - pd.hInstance = NULL; - if (!PrintDlg(&pd)) - return (0); /* User chose 'cancel'... */ - - /* - * OK, user wants to print, so set the cursor to 'busy' and start the - * print job... - */ - - busy = LoadCursor(NULL, IDC_WAIT); - oldcursor = SetCursor(busy); - - SetMapMode(pd.hDC, MM_TEXT); - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = "OpenGL Image"; - di.lpszOutput = NULL; - - StartDoc(pd.hDC, &di); - StartPage(pd.hDC); - - /* - * Clear the background to white... - */ - - rect.top = 0; - rect.left = 0; - rect.right = GetDeviceCaps(pd.hDC, HORZRES); - rect.bottom = GetDeviceCaps(pd.hDC, VERTRES); - brush = CreateSolidBrush(0x00ffffff); - FillRect(pd.hDC, &rect, brush); - - /* - * Stretch the bitmap to fit the page... - */ - - hdc = CreateCompatibleDC(pd.hDC); - bitmap = CreateDIBitmap(hdc, &(info->bmiHeader), CBM_INIT, bits, info, - DIB_RGB_COLORS); - SelectObject(hdc, bitmap); - - xsize = rect.right; - ysize = xsize * info->bmiHeader.biHeight / info->bmiHeader.biWidth; - if (ysize > rect.bottom) - { - ysize = rect.bottom; - xsize = ysize * info->bmiHeader.biWidth / info->bmiHeader.biHeight; - }; - - xoffset = (rect.right - xsize) / 2; - yoffset = (rect.bottom - ysize) / 2; - - StretchBlt(pd.hDC, xoffset, yoffset, xsize, ysize, - hdc, 0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight, - SRCCOPY); - - /* - * That's it. End the print job and free anything we allocated... - */ - - EndPage(pd.hDC); - EndDoc(pd.hDC); - DeleteDC(pd.hDC); - - DeleteObject(bitmap); - DeleteObject(brush); - DeleteObject(busy); - DeleteDC(hdc); - - /* - * Restore the cursor and return... - */ - - SetCursor(oldcursor); - - return (1); -} - - -/* - * 'ConvertRGB()' - Convert a DIB/BMP image to 24-bit RGB pixels. - * - * Returns an RGB pixel array if successful and NULL otherwise. - */ - -GLubyte * -ConvertRGB(BITMAPINFO *info, /* I - Original bitmap information */ - void *bits) /* I - Original bitmap pixels */ -{ - int i, j, /* Looping vars */ - bitsize, /* Total size of bitmap */ - width; /* Aligned width of bitmap */ - GLubyte *newbits; /* New RGB bits */ - GLubyte *from, *to, /* RGB looping vars */ - temp; /* Temporary var for swapping */ - - - /* - * Allocate memory for the RGB bitmap... - */ - - width = 3 * info->bmiHeader.biWidth; - width = (width + 3) & ~3; - bitsize = width * info->bmiHeader.biHeight; - if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL) - return (NULL); - - /* - * Copy the original bitmap to the new array, converting as necessary. - */ - - switch (info->bmiHeader.biCompression) - { - case BI_RGB : - if (info->bmiHeader.biBitCount == 24) - { - /* - * Swap red & blue in a 24-bit image... - */ - - for (i = 0; i < info->bmiHeader.biHeight; i ++) - for (j = 0, from = ((GLubyte *)bits) + i * width, - to = newbits + i * width; - j < info->bmiHeader.biWidth; - j ++, from += 3, to += 3) - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - }; - }; - break; - case BI_RLE4 : - case BI_RLE8 : - case BI_BITFIELDS : - break; - }; - - return (newbits); -} - - -/////////////////////////////////////////////////////////////////////////////// -// This stuff forward is the TGA Loading Routines -// -/////////////////////////////////////////////////////////////////////////////// - -//----------------------------------------------------------------------- -// Name: LoadTGAFile() -// Desc: Given a filename of a TGA file, it loads the image in BITMAP form -//----------------------------------------------------------------------- -GLubyte *LoadTGAFile( TCHAR* strFilename,tTGAHeader_s *header) -{ -/// Local Variables /////////////////////////////////////////////////////////// - short BPP; - unsigned char *buffer,*buffer2; - int loop,loop2; - int bitsize; /* Total size of bitmap */ - GLubyte *newbits; /* New RGB bits */ - GLubyte *from, *to; /* RGB looping vars */ - int i, j, /* Looping vars */ - width; /* Aligned width of bitmap */ - FILE* file; -/////////////////////////////////////////////////////////////////////////////// - - // Open the file and read the header - file = fopen( strFilename, TEXT("rb") ); - if( NULL == file ) - return NULL; - - if ( fread( header, sizeof( tTGAHeader_s ), 1, file ) != 1 ) - { - fclose( file ); - return NULL; - } - - // Parse the TGA header - DWORD dwWidth, dwHeight; - dwWidth = (DWORD)header->d_width; - dwHeight = (DWORD)header->d_height; - BPP = (short)header->d_pixel_size; // 16, 24, or 32 - - // JL TEST SMALL TEXTURES ONLY -// dwWidth = 2; -// dwHeight = 2; - // Create a bitmap to load the data into - - bitsize = dwWidth * dwHeight * (BPP/8); - if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL) - { - fclose( file ); - return NULL; - } - buffer = (unsigned char *)malloc(dwWidth*dwHeight*(BPP / 8)); - if ( fread( buffer, dwWidth*dwHeight*(BPP / 8), 1, file ) != 1 ) - { - fclose( file ); - free(buffer); - free(newbits); - return NULL; - } - - width = (BPP / 8) * dwWidth; - - for (i = 0; i < dwHeight; i ++) - for (j = 0, from = ((GLubyte *)buffer) + i * width, - to = newbits + i * width; - j < dwWidth; - j ++, from += (BPP / 8), to += (BPP / 8)) - { - if (BPP == 24) - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - } - else - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - to[3] = from[3]; - } - }; - // SINCE TGA IS UPSIDE DOWN, I HAVE TO REVERSE THIS DAMN THING -/* for (loop = 0; loop < dwHeight; loop++) - { - memcpy( &newbits[loop * dwWidth * (BPP / 8)], - &buffer[(dwHeight - (loop + 1)) * dwWidth * (BPP / 8)], - dwWidth * (BPP / 8)); - } -*/ - free(buffer); -// free(buffer2); - fclose( file ); - - return newbits; -} - - -/* - * End of "$Id: bitmap.c,v 1.2 1996/01/09 22:52:53 mike Exp mike $". - */ + * + * Revision 1.1 1995/12/31 07:27:17 mike + * Initial revision + */ + +/* + * Include necessary headers. + */ + +#include "stdafx.h" +#include "bitmap.h" + + +/* + * 'LoadDIBitmap()' - Load a DIB/BMP file from disk. + * + * Returns a pointer to the bitmap if successful, NULL otherwise... + */ + +void * +LoadDIBitmap(char *filename, /* I - File to load */ + BITMAPINFO **info) /* O - Bitmap information */ +{ + FILE *fp; /* Open file pointer */ + void *bits; /* Bitmap pixel bits */ + long bitsize, /* Size of bitmap */ + infosize; /* Size of header information */ + BITMAPFILEHEADER header; /* File header */ + + + /* + * Try opening the file; use "rb" mode to read this *binary* file. + */ + + if ((fp = fopen(filename, "rb")) == NULL) + return (NULL); + + /* + * Read the file header and any following bitmap information... + */ + + if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1) + { + /* + * Couldn't read the file header - return NULL... + */ + + fclose(fp); + return (NULL); + }; + + if (header.bfType != 'MB') /* Check for BM reversed... */ + { + /* + * Not a bitmap file - return NULL... + */ + + fclose(fp); + return (NULL); + }; + + infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER); + if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL) + { + /* + * Couldn't allocate memory for bitmap info - return NULL... + */ + + fclose(fp); + return (NULL); + }; + + if (fread(*info, 1, infosize, fp) < infosize) + { + /* + * Couldn't read the bitmap header - return NULL... + */ + + free(*info); + fclose(fp); + return (NULL); + }; + + /* + * Now that we have all the header info read in, allocate memory for the + * bitmap and read *it* in... + */ + + if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0) + bitsize = ((*info)->bmiHeader.biWidth * + (*info)->bmiHeader.biBitCount + 7) / 8 * + abs((*info)->bmiHeader.biHeight); + + if ((bits = malloc(bitsize)) == NULL) + { + /* + * Couldn't allocate memory - return NULL! + */ + + free(*info); + fclose(fp); + return (NULL); + }; + + if (fread(bits, 1, bitsize, fp) < bitsize) + { + /* + * Couldn't read bitmap - free memory and return NULL! + */ + + free(*info); + free(bits); + fclose(fp); + return (NULL); + }; + + /* + * OK, everything went fine - return the allocated bitmap... + */ + + fclose(fp); + return (bits); +} + + +/* + * 'SaveDIBitmap()' - Save a bitmap to a DIB/BMP file on disk. + * + * Returns 0 if successful, non-zero otherwise... + */ + +int +SaveDIBitmap(char *filename, /* I - File to save to */ + BITMAPINFO *info, /* I - Bitmap information */ + void *bits) /* I - Bitmap pixel bits */ +{ + FILE *fp; /* Open file pointer */ + long size, /* Size of file */ + infosize, /* Size of bitmap info */ + bitsize; /* Size of bitmap pixels */ + BITMAPFILEHEADER header; /* File header */ + + + /* + * Try opening the file; use "wb" mode to write this *binary* file. + */ + + if ((fp = fopen(filename, "wb")) == NULL) + return (-1); + + if (info->bmiHeader.biSizeImage == 0) /* Figure out the bitmap size */ + bitsize = (info->bmiHeader.biWidth * + info->bmiHeader.biBitCount + 7) / 8 * + abs(info->bmiHeader.biHeight); + else + bitsize = info->bmiHeader.biSizeImage; + + infosize = sizeof(BITMAPINFOHEADER); + switch (info->bmiHeader.biCompression) + { + case BI_BITFIELDS : + infosize += 12; /* Add 3 RGB doubleword masks */ + if (info->bmiHeader.biClrUsed == 0) + break; + case BI_RGB : + if (info->bmiHeader.biBitCount > 8 && + info->bmiHeader.biClrUsed == 0) + break; + case BI_RLE8 : + case BI_RLE4 : + if (info->bmiHeader.biClrUsed == 0) + infosize += (1 << info->bmiHeader.biBitCount) * 4; + else + infosize += info->bmiHeader.biClrUsed * 4; + break; + }; + + size = sizeof(BITMAPFILEHEADER) + infosize + bitsize; + + /* + * Write the file header, bitmap information, and bitmap pixel data... + */ + + header.bfType = 'MB'; /* Non-portable... sigh */ + header.bfSize = size; + header.bfReserved1 = 0; + header.bfReserved2 = 0; + header.bfOffBits = sizeof(BITMAPFILEHEADER) + infosize; + + if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER)) + { + /* + * Couldn't write the file header - return... + */ + + fclose(fp); + return (-1); + }; + + if (fwrite(info, 1, infosize, fp) < infosize) + { + /* + * Couldn't write the bitmap header - return... + */ + + fclose(fp); + return (-1); + }; + + if (fwrite(bits, 1, bitsize, fp) < bitsize) + { + /* + * Couldn't write the bitmap - return... + */ + + fclose(fp); + return (-1); + }; + + /* + * OK, everything went fine - return... + */ + + fclose(fp); + return (0); +} + + +/* + * 'ReadDIBitmap()' - Read the current OpenGL viewport into a + * 24-bit RGB bitmap. + * + * Returns the bitmap pixels if successful and NULL otherwise. + */ + +void * +ReadDIBitmap(BITMAPINFO **info) /* O - Bitmap information */ +{ + long i, j, /* Looping var */ + bitsize, /* Total size of bitmap */ + width; /* Aligned width of a scanline */ + GLint viewport[4]; /* Current viewport */ + void *bits; /* RGB bits */ + GLubyte *rgb, /* RGB looping var */ + temp; /* Temporary var for swapping */ + + /* + * Grab the current viewport... + */ + + glGetIntegerv(GL_VIEWPORT, viewport); + + /* + * Allocate memory for the header and bitmap... + */ + + if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER))) == NULL) + { + /* + * Couldn't allocate memory for bitmap info - return NULL... + */ + + return (NULL); + }; + + width = viewport[2] * 3; /* Real width of scanline */ + width = (width + 3) & ~3; /* Aligned to 4 bytes */ + bitsize = width * viewport[3]; /* Size of bitmap, aligned */ + + if ((bits = calloc(bitsize, 1)) == NULL) + { + /* + * Couldn't allocate memory for bitmap pixels - return NULL... + */ + + free(*info); + return (NULL); + }; + + /* + * Read pixels from the framebuffer... + */ + + glFinish(); /* Finish all OpenGL commands */ + glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */ + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + + glReadPixels(0, 0, viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, + bits); + + /* + * Swap red and blue for the bitmap... + */ + + for (i = 0; i < viewport[3]; i ++) + for (j = 0, rgb = ((GLubyte *)bits) + i * width; + j < viewport[2]; + j ++, rgb += 3) + { + temp = rgb[0]; + rgb[0] = rgb[2]; + rgb[2] = temp; + }; + + /* + * Finally, initialize the bitmap header information... + */ + + (*info)->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + (*info)->bmiHeader.biWidth = viewport[2]; + (*info)->bmiHeader.biHeight = viewport[3]; + (*info)->bmiHeader.biPlanes = 1; + (*info)->bmiHeader.biBitCount = 24; + (*info)->bmiHeader.biCompression = BI_RGB; + (*info)->bmiHeader.biSizeImage = bitsize; + (*info)->bmiHeader.biXPelsPerMeter = 2952; /* 75 DPI */ + (*info)->bmiHeader.biYPelsPerMeter = 2952; /* 75 DPI */ + (*info)->bmiHeader.biClrUsed = 0; + (*info)->bmiHeader.biClrImportant = 0; + + return (bits); +} + + +/* + * 'PrintDIBitmap()' - Print a bitmap to a GDI printer. + */ + +int +PrintDIBitmap(HWND owner, /* I - Owner/parent window */ + BITMAPINFO *info, /* I - Bitmap information */ + void *bits) /* I - Bitmap pixel bits */ +{ + PRINTDLG pd; /* Print dialog information */ + long xsize, /* Size of printed image */ + ysize, + xoffset, /* Offset from edges for image */ + yoffset; + RECT rect; /* Page rectangle */ + DOCINFO di; /* Document info */ + HDC hdc; /* Device context for bitmap */ + HBITMAP bitmap; /* Bitmap image */ + HBRUSH brush; /* Background brush for page */ + HCURSOR busy, /* Busy cursor */ + oldcursor; /* Old cursor */ + + + /* + * Range check... + */ + + if (info == NULL || bits == NULL) + return (0); + + /* + * Initialize a PRINTDLG structure before displaying a standard Windows + * print dialog... + */ + + memset(&pd, 0, sizeof(pd)); + pd.lStructSize = sizeof(pd); + pd.hwndOwner = owner; + pd.Flags = PD_RETURNDC; + pd.hInstance = NULL; + if (!PrintDlg(&pd)) + return (0); /* User chose 'cancel'... */ + + /* + * OK, user wants to print, so set the cursor to 'busy' and start the + * print job... + */ + + busy = LoadCursor(NULL, IDC_WAIT); + oldcursor = SetCursor(busy); + + SetMapMode(pd.hDC, MM_TEXT); + di.cbSize = sizeof(DOCINFO); + di.lpszDocName = "OpenGL Image"; + di.lpszOutput = NULL; + + StartDoc(pd.hDC, &di); + StartPage(pd.hDC); + + /* + * Clear the background to white... + */ + + rect.top = 0; + rect.left = 0; + rect.right = GetDeviceCaps(pd.hDC, HORZRES); + rect.bottom = GetDeviceCaps(pd.hDC, VERTRES); + brush = CreateSolidBrush(0x00ffffff); + FillRect(pd.hDC, &rect, brush); + + /* + * Stretch the bitmap to fit the page... + */ + + hdc = CreateCompatibleDC(pd.hDC); + bitmap = CreateDIBitmap(hdc, &(info->bmiHeader), CBM_INIT, bits, info, + DIB_RGB_COLORS); + SelectObject(hdc, bitmap); + + xsize = rect.right; + ysize = xsize * info->bmiHeader.biHeight / info->bmiHeader.biWidth; + if (ysize > rect.bottom) + { + ysize = rect.bottom; + xsize = ysize * info->bmiHeader.biWidth / info->bmiHeader.biHeight; + }; + + xoffset = (rect.right - xsize) / 2; + yoffset = (rect.bottom - ysize) / 2; + + StretchBlt(pd.hDC, xoffset, yoffset, xsize, ysize, + hdc, 0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight, + SRCCOPY); + + /* + * That's it. End the print job and free anything we allocated... + */ + + EndPage(pd.hDC); + EndDoc(pd.hDC); + DeleteDC(pd.hDC); + + DeleteObject(bitmap); + DeleteObject(brush); + DeleteObject(busy); + DeleteDC(hdc); + + /* + * Restore the cursor and return... + */ + + SetCursor(oldcursor); + + return (1); +} + + +/* + * 'ConvertRGB()' - Convert a DIB/BMP image to 24-bit RGB pixels. + * + * Returns an RGB pixel array if successful and NULL otherwise. + */ + +GLubyte * +ConvertRGB(BITMAPINFO *info, /* I - Original bitmap information */ + void *bits) /* I - Original bitmap pixels */ +{ + int i, j, /* Looping vars */ + bitsize, /* Total size of bitmap */ + width; /* Aligned width of bitmap */ + GLubyte *newbits; /* New RGB bits */ + GLubyte *from, *to, /* RGB looping vars */ + temp; /* Temporary var for swapping */ + + + /* + * Allocate memory for the RGB bitmap... + */ + + width = 3 * info->bmiHeader.biWidth; + width = (width + 3) & ~3; + bitsize = width * info->bmiHeader.biHeight; + if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL) + return (NULL); + + /* + * Copy the original bitmap to the new array, converting as necessary. + */ + + switch (info->bmiHeader.biCompression) + { + case BI_RGB : + if (info->bmiHeader.biBitCount == 24) + { + /* + * Swap red & blue in a 24-bit image... + */ + + for (i = 0; i < info->bmiHeader.biHeight; i ++) + for (j = 0, from = ((GLubyte *)bits) + i * width, + to = newbits + i * width; + j < info->bmiHeader.biWidth; + j ++, from += 3, to += 3) + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + }; + }; + break; + case BI_RLE4 : + case BI_RLE8 : + case BI_BITFIELDS : + break; + }; + + return (newbits); +} + + +/////////////////////////////////////////////////////////////////////////////// +// This stuff forward is the TGA Loading Routines +// +/////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------- +// Name: LoadTGAFile() +// Desc: Given a filename of a TGA file, it loads the image in BITMAP form +//----------------------------------------------------------------------- +GLubyte *LoadTGAFile( TCHAR* strFilename,tTGAHeader_s *header) +{ +/// Local Variables /////////////////////////////////////////////////////////// + short BPP; + unsigned char *buffer,*buffer2; + int loop,loop2; + int bitsize; /* Total size of bitmap */ + GLubyte *newbits; /* New RGB bits */ + GLubyte *from, *to; /* RGB looping vars */ + int i, j, /* Looping vars */ + width; /* Aligned width of bitmap */ + FILE* file; +/////////////////////////////////////////////////////////////////////////////// + + // Open the file and read the header + file = fopen( strFilename, TEXT("rb") ); + if( NULL == file ) + return NULL; + + if ( fread( header, sizeof( tTGAHeader_s ), 1, file ) != 1 ) + { + fclose( file ); + return NULL; + } + + // Parse the TGA header + DWORD dwWidth, dwHeight; + dwWidth = (DWORD)header->d_width; + dwHeight = (DWORD)header->d_height; + BPP = (short)header->d_pixel_size; // 16, 24, or 32 + + // JL TEST SMALL TEXTURES ONLY +// dwWidth = 2; +// dwHeight = 2; + // Create a bitmap to load the data into + + bitsize = dwWidth * dwHeight * (BPP/8); + if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL) + { + fclose( file ); + return NULL; + } + buffer = (unsigned char *)malloc(dwWidth*dwHeight*(BPP / 8)); + if ( fread( buffer, dwWidth*dwHeight*(BPP / 8), 1, file ) != 1 ) + { + fclose( file ); + free(buffer); + free(newbits); + return NULL; + } + + width = (BPP / 8) * dwWidth; + + for (i = 0; i < dwHeight; i ++) + for (j = 0, from = ((GLubyte *)buffer) + i * width, + to = newbits + i * width; + j < dwWidth; + j ++, from += (BPP / 8), to += (BPP / 8)) + { + if (BPP == 24) + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + } + else + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + to[3] = from[3]; + } + }; + // SINCE TGA IS UPSIDE DOWN, I HAVE TO REVERSE THIS DAMN THING +/* for (loop = 0; loop < dwHeight; loop++) + { + memcpy( &newbits[loop * dwWidth * (BPP / 8)], + &buffer[(dwHeight - (loop + 1)) * dwWidth * (BPP / 8)], + dwWidth * (BPP / 8)); + } +*/ + free(buffer); +// free(buffer2); + fclose( file ); + + return newbits; +} + + +/* + * End of "$Id: bitmap.c,v 1.2 1996/01/09 22:52:53 mike Exp mike $". + */ diff --git a/3D Morphing/Code/OGL/Morphy/Bitmap.h b/3D Morphing/Code/OGL/Morphy/Bitmap.h index 756859b..7fe7c3c 100644 --- a/3D Morphing/Code/OGL/Morphy/Bitmap.h +++ b/3D Morphing/Code/OGL/Morphy/Bitmap.h @@ -1,55 +1,55 @@ -/* - * "$Id: bitmap.h,v 1.2 1996/01/09 22:52:53 mike Exp mike $" - * - * Device Independent Bitmap definitions for OpenGL under MS Windows. - * - * Revision History: - * +/* + * "$Id: bitmap.h,v 1.2 1996/01/09 22:52:53 mike Exp mike $" + * + * Device Independent Bitmap definitions for OpenGL under MS Windows. + * + * Revision History: + * * $Log: bitmap.h,v $ * Revision 1.2 1996/01/09 22:52:53 mike * Added PrintDIBitmap. - * - * Revision 1.1 1995/12/31 07:26:54 mike - * Initial revision - */ - -/* - * Include necessary headers. - */ - -/* - * Make this header file work with C and C++ source code... - */ -#include -#include - -typedef struct -{ - unsigned char d_iif_size; // IIF size (after header), usually 0 - unsigned char d_cmap_type; // ignored - unsigned char d_image_type; // should be 2 - unsigned char pad[5]; - - unsigned short d_x_origin; - unsigned short d_y_origin; - unsigned short d_width; - unsigned short d_height; - - unsigned char d_pixel_size; // 16, 24, or 32 - unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) -} tTGAHeader_s; - -extern void *LoadDIBitmap(char *filename, BITMAPINFO **info); -extern int SaveDIBitmap(char *filename, BITMAPINFO *info, void *bits); -extern void *ReadDIBitmap(BITMAPINFO **info); -extern int PrintDIBitmap(HWND owner, BITMAPINFO *info, void *bits); -GLubyte *LoadTGAFile( TCHAR* strFilename,tTGAHeader_s *header); - -extern GLubyte *ConvertRGB(BITMAPINFO *info, void *bits); - -/* - * End of "$Id: bitmap.h,v 1.2 1996/01/09 22:52:53 mike Exp mike $". - */ + * + * Revision 1.1 1995/12/31 07:26:54 mike + * Initial revision + */ + +/* + * Include necessary headers. + */ + +/* + * Make this header file work with C and C++ source code... + */ +#include +#include + +typedef struct +{ + unsigned char d_iif_size; // IIF size (after header), usually 0 + unsigned char d_cmap_type; // ignored + unsigned char d_image_type; // should be 2 + unsigned char pad[5]; + + unsigned short d_x_origin; + unsigned short d_y_origin; + unsigned short d_width; + unsigned short d_height; + + unsigned char d_pixel_size; // 16, 24, or 32 + unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) +} tTGAHeader_s; + +extern void *LoadDIBitmap(char *filename, BITMAPINFO **info); +extern int SaveDIBitmap(char *filename, BITMAPINFO *info, void *bits); +extern void *ReadDIBitmap(BITMAPINFO **info); +extern int PrintDIBitmap(HWND owner, BITMAPINFO *info, void *bits); +GLubyte *LoadTGAFile( TCHAR* strFilename,tTGAHeader_s *header); + +extern GLubyte *ConvertRGB(BITMAPINFO *info, void *bits); + +/* + * End of "$Id: bitmap.h,v 1.2 1996/01/09 22:52:53 mike Exp mike $". + */ diff --git a/3D Morphing/Code/OGL/Morphy/LoadDlg.cpp b/3D Morphing/Code/OGL/Morphy/LoadDlg.cpp index 41c3890..5f57bc0 100644 --- a/3D Morphing/Code/OGL/Morphy/LoadDlg.cpp +++ b/3D Morphing/Code/OGL/Morphy/LoadDlg.cpp @@ -1,72 +1,72 @@ -// LoadDlg.cpp : implementation file -// - -#include "stdafx.h" -#include "morphy.h" -#include "LoadDlg.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CLoadDlg dialog - - -CLoadDlg::CLoadDlg(CWnd* pParent /*=NULL*/) - : CDialog(CLoadDlg::IDD, pParent) -{ - //{{AFX_DATA_INIT(CLoadDlg) - m_File1 = _T(""); - m_File2 = _T(""); - //}}AFX_DATA_INIT -} - - -void CLoadDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CLoadDlg) - DDX_Text(pDX, IDC_EDIT1, m_File1); - DDX_Text(pDX, IDC_EDIT2, m_File2); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CLoadDlg, CDialog) - //{{AFX_MSG_MAP(CLoadDlg) - ON_BN_CLICKED(IDC_BROWSE1, OnBrowse1) - ON_BN_CLICKED(IDC_BROWSE2, OnBrowse2) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CLoadDlg message handlers - -void CLoadDlg::OnBrowse1() -{ - char szFilter[] = "OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, NULL, szFilter, this); - CString name; - if (dialog.DoModal()) - { - name = dialog.GetFileName( ) ; - m_File1 = name; - UpdateData(FALSE); // UPDATE THE CONTROL - } -} - -void CLoadDlg::OnBrowse2() -{ - char szFilter[] = "OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, NULL, szFilter, this); - CString name; - if (dialog.DoModal()) - { - name = dialog.GetFileName( ) ; - m_File2 = name; - UpdateData(FALSE); // UPDATE THE CONTROL - } -} +// LoadDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "morphy.h" +#include "LoadDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CLoadDlg dialog + + +CLoadDlg::CLoadDlg(CWnd* pParent /*=NULL*/) + : CDialog(CLoadDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CLoadDlg) + m_File1 = _T(""); + m_File2 = _T(""); + //}}AFX_DATA_INIT +} + + +void CLoadDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CLoadDlg) + DDX_Text(pDX, IDC_EDIT1, m_File1); + DDX_Text(pDX, IDC_EDIT2, m_File2); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CLoadDlg, CDialog) + //{{AFX_MSG_MAP(CLoadDlg) + ON_BN_CLICKED(IDC_BROWSE1, OnBrowse1) + ON_BN_CLICKED(IDC_BROWSE2, OnBrowse2) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CLoadDlg message handlers + +void CLoadDlg::OnBrowse1() +{ + char szFilter[] = "OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, NULL, szFilter, this); + CString name; + if (dialog.DoModal()) + { + name = dialog.GetFileName( ) ; + m_File1 = name; + UpdateData(FALSE); // UPDATE THE CONTROL + } +} + +void CLoadDlg::OnBrowse2() +{ + char szFilter[] = "OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, NULL, szFilter, this); + CString name; + if (dialog.DoModal()) + { + name = dialog.GetFileName( ) ; + m_File2 = name; + UpdateData(FALSE); // UPDATE THE CONTROL + } +} diff --git a/3D Morphing/Code/OGL/Morphy/LoadOBJ.cpp b/3D Morphing/Code/OGL/Morphy/LoadOBJ.cpp index b79abb7..1e76e3b 100644 --- a/3D Morphing/Code/OGL/Morphy/LoadOBJ.cpp +++ b/3D Morphing/Code/OGL/Morphy/LoadOBJ.cpp @@ -1,324 +1,324 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = atof(words.GetAt(1)); - visual->Ka.g = atof(words.GetAt(2)); - visual->Ka.b = atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = atof(words.GetAt(1)); - visual->Kd.g = atof(words.GetAt(2)); - visual->Kd.b = atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = atof(words.GetAt(1)); - visual->Ks.g = atof(words.GetAt(2)); - visual->Ks.b = atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons. This only handles Triangles -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - // LOOP THROUGH THE 3 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < 4; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(char *filename,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = atof(words.GetAt(1)); - normal[nPos].y = atof(words.GetAt(2)); - normal[nPos].z = atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = atof(words.GetAt(1)); - texture[tPos].v = atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = atof(words.GetAt(1)); - vertex[vPos].y = atof(words.GetAt(2)); - vertex[vPos].z = atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 4) - { - sprintf(buffer,"Face %d has more then 3 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - if (nCnt > 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * 3); - visual->triCnt = fPos; - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * 3); - visual->triCnt = fPos; - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * 3); - visual->triCnt = fPos; - } - - data = visual->vertexData; - for (loop = 0; loop < fPos; loop++) - { - for (loop2 = 0; loop2 < 3; loop2++) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = atof(words.GetAt(1)); + visual->Ka.g = atof(words.GetAt(2)); + visual->Ka.b = atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = atof(words.GetAt(1)); + visual->Kd.g = atof(words.GetAt(2)); + visual->Kd.b = atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = atof(words.GetAt(1)); + visual->Ks.g = atof(words.GetAt(2)); + visual->Ks.b = atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons. This only handles Triangles +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + // LOOP THROUGH THE 3 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < 4; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(char *filename,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = atof(words.GetAt(1)); + normal[nPos].y = atof(words.GetAt(2)); + normal[nPos].z = atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = atof(words.GetAt(1)); + texture[tPos].v = atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = atof(words.GetAt(1)); + vertex[vPos].y = atof(words.GetAt(2)); + vertex[vPos].z = atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 4) + { + sprintf(buffer,"Face %d has more then 3 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + if (nCnt > 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * 3); + visual->triCnt = fPos; + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * 3); + visual->triCnt = fPos; + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * 3); + visual->triCnt = fPos; + } + + data = visual->vertexData; + for (loop = 0; loop < fPos; loop++) + { + for (loop2 = 0; loop2 < 3; loop2++) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/3D Morphing/Code/OGL/Morphy/LoadOBJ.h b/3D Morphing/Code/OGL/Morphy/LoadOBJ.h index daa1a56..49c68fa 100644 --- a/3D Morphing/Code/OGL/Morphy/LoadOBJ.h +++ b/3D Morphing/Code/OGL/Morphy/LoadOBJ.h @@ -1,32 +1,32 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -typedef struct -{ - long v[3],n[3],t[3]; -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(char *filename,t_Visual *visual); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +typedef struct +{ + long v[3],n[3],t[3]; +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(char *filename,t_Visual *visual); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/MainFrm.cpp b/3D Morphing/Code/OGL/Morphy/MainFrm.cpp index bcc89b7..ad3fbd7 100644 --- a/3D Morphing/Code/OGL/Morphy/MainFrm.cpp +++ b/3D Morphing/Code/OGL/Morphy/MainFrm.cpp @@ -1,212 +1,212 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Morphy.h" -#include "MainFrm.h" -#include "LoadDlg.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_Slider.Create(TBS_NOTICKS | TBS_BOTH | WS_CHILD | WS_VISIBLE, CRect(1, rect.bottom - 40,rect.right - 3,rect.bottom - 20),this,105); - - m_Slider.ShowWindow(TRUE); - - m_Slider.Invalidate(TRUE); - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Slider); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 45 , SWP_NOZORDER ); // -60 bottom - m_Slider.SetWindowPos( &wndTopMost, 1, cy - 44, cx - 3, 25 , SWP_NOZORDER ); // -60 bottom - - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case ' ': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -} - - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - - -void CMainFrame::OnFileOpen() -{ - CLoadDlg dialog; - if (dialog.DoModal() == IDOK) - { - m_OGLView.LoadFiles(dialog.m_File1, dialog.m_File2); - } -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Morphy.h" +#include "MainFrm.h" +#include "LoadDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_Slider.Create(TBS_NOTICKS | TBS_BOTH | WS_CHILD | WS_VISIBLE, CRect(1, rect.bottom - 40,rect.right - 3,rect.bottom - 20),this,105); + + m_Slider.ShowWindow(TRUE); + + m_Slider.Invalidate(TRUE); + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Slider); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 45 , SWP_NOZORDER ); // -60 bottom + m_Slider.SetWindowPos( &wndTopMost, 1, cy - 44, cx - 3, 25 , SWP_NOZORDER ); // -60 bottom + + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case ' ': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +} + + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + + +void CMainFrame::OnFileOpen() +{ + CLoadDlg dialog; + if (dialog.DoModal() == IDOK) + { + m_OGLView.LoadFiles(dialog.m_File1, dialog.m_File2); + } +} diff --git a/3D Morphing/Code/OGL/Morphy/MainFrm.h b/3D Morphing/Code/OGL/Morphy/MainFrm.h index cd91897..671ff76 100644 --- a/3D Morphing/Code/OGL/Morphy/MainFrm.h +++ b/3D Morphing/Code/OGL/Morphy/MainFrm.h @@ -1,88 +1,88 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" -#include "Slider.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - CSlider m_Slider; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnViewUsequaternions(); - afx_msg void OnUpdateViewUsequaternions(CCmdUI* pCmdUI); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileOpen(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" +#include "Slider.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + CSlider m_Slider; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnViewUsequaternions(); + afx_msg void OnUpdateViewUsequaternions(CCmdUI* pCmdUI); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileOpen(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/MathDefs.h b/3D Morphing/Code/OGL/Morphy/MathDefs.h index 0924c9e..d3caab4 100644 --- a/3D Morphing/Code/OGL/Morphy/MathDefs.h +++ b/3D Morphing/Code/OGL/Morphy/MathDefs.h @@ -1,88 +1,88 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/3D Morphing/Code/OGL/Morphy/Morphy.cpp b/3D Morphing/Code/OGL/Morphy/Morphy.cpp index caa2415..3f635f8 100644 --- a/3D Morphing/Code/OGL/Morphy/Morphy.cpp +++ b/3D Morphing/Code/OGL/Morphy/Morphy.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Morphy.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Morphy.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMorphyApp - -BEGIN_MESSAGE_MAP(CMorphyApp, CWinApp) - //{{AFX_MSG_MAP(CMorphyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CMorphyApp construction - -CMorphyApp::CMorphyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CMorphyApp object - -CMorphyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CMorphyApp initialization - -BOOL CMorphyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CMorphyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CMorphyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Morphy.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Morphy.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMorphyApp + +BEGIN_MESSAGE_MAP(CMorphyApp, CWinApp) + //{{AFX_MSG_MAP(CMorphyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMorphyApp construction + +CMorphyApp::CMorphyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CMorphyApp object + +CMorphyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CMorphyApp initialization + +BOOL CMorphyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CMorphyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CMorphyApp commands diff --git a/3D Morphing/Code/OGL/Morphy/Morphy.h b/3D Morphing/Code/OGL/Morphy/Morphy.h index a0150ea..2f5e7ce 100644 --- a/3D Morphing/Code/OGL/Morphy/Morphy.h +++ b/3D Morphing/Code/OGL/Morphy/Morphy.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Morphy.h : main header file for the Morphy application -// -// Purpose: header of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Morphy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Morphy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CMorphyApp: -// See Morphy.cpp for the implementation of this class -// - -class CMorphyApp : public CWinApp -{ -public: - CMorphyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMorphyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CMorphyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Morphy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Morphy.h : main header file for the Morphy application +// +// Purpose: header of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Morphy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Morphy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CMorphyApp: +// See Morphy.cpp for the implementation of this class +// + +class CMorphyApp : public CWinApp +{ +public: + CMorphyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMorphyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CMorphyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Morphy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/Morphy.mak b/3D Morphing/Code/OGL/Morphy/Morphy.mak index dd4158f..f6c7b4c 100644 --- a/3D Morphing/Code/OGL/Morphy/Morphy.mak +++ b/3D Morphing/Code/OGL/Morphy/Morphy.mak @@ -1,406 +1,406 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Morphy.dsp -!IF "$(CFG)" == "" -CFG=Morphy - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Morphy - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Morphy - Win32 Release" && "$(CFG)" != "Morphy - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Morphy.mak" CFG="Morphy - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Morphy - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Morphy - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Morphy - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\Morphy.exe" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\LoadDlg.obj" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\Morphy.obj" - -@erase "$(INTDIR)\Morphy.pch" - -@erase "$(INTDIR)\Morphy.res" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Slider.obj" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\Morphy.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Morphy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Morphy.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Morphy.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Morphy.pdb" /machine:I386 /out:"$(OUTDIR)\Morphy.exe" -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\LoadDlg.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\Morphy.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\Slider.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Morphy.res" - -"$(OUTDIR)\Morphy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "$(OUTDIR)\Morphy.exe" "$(OUTDIR)\Morphy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\LoadDlg.obj" - -@erase "$(INTDIR)\LoadDlg.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\Morphy.obj" - -@erase "$(INTDIR)\Morphy.pch" - -@erase "$(INTDIR)\Morphy.res" - -@erase "$(INTDIR)\Morphy.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\Slider.obj" - -@erase "$(INTDIR)\Slider.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\Morphy.bsc" - -@erase "$(OUTDIR)\Morphy.exe" - -@erase "$(OUTDIR)\Morphy.ilk" - -@erase "$(OUTDIR)\Morphy.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Morphy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Morphy.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Morphy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\LoadDlg.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\Morphy.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\Slider.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Morphy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Morphy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Morphy.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\LoadDlg.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\Morphy.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\Slider.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Morphy.res" - -"$(OUTDIR)\Morphy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("Morphy.dep") -!INCLUDE "Morphy.dep" -!ELSE -!MESSAGE Warning: cannot find "Morphy.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "Morphy - Win32 Release" || "$(CFG)" == "Morphy - Win32 Debug" -SOURCE=.\Bitmap.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\Bitmap.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\LoadDlg.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\LoadDlg.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\LoadDlg.obj" "$(INTDIR)\LoadDlg.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\LoadOBJ.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\LoadOBJ.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\MainFrm.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\Morphy.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\Morphy.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\Morphy.obj" "$(INTDIR)\Morphy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\Morphy.rc - -"$(INTDIR)\Morphy.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\OGLView.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\OGLView.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\Skeleton.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\Skeleton.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\Slider.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - - -"$(INTDIR)\Slider.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - - -"$(INTDIR)\Slider.obj" "$(INTDIR)\Slider.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" - - -!ENDIF - -SOURCE=.\StdAfx.cpp - -!IF "$(CFG)" == "Morphy - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Morphy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Morphy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Morphy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Morphy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Morphy.dsp +!IF "$(CFG)" == "" +CFG=Morphy - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Morphy - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Morphy - Win32 Release" && "$(CFG)" != "Morphy - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Morphy.mak" CFG="Morphy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Morphy - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Morphy - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Morphy - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\Morphy.exe" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\LoadDlg.obj" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\Morphy.obj" + -@erase "$(INTDIR)\Morphy.pch" + -@erase "$(INTDIR)\Morphy.res" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Slider.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\Morphy.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Morphy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Morphy.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Morphy.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Morphy.pdb" /machine:I386 /out:"$(OUTDIR)\Morphy.exe" +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\LoadDlg.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\Morphy.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\Slider.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Morphy.res" + +"$(OUTDIR)\Morphy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\Morphy.exe" "$(OUTDIR)\Morphy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\LoadDlg.obj" + -@erase "$(INTDIR)\LoadDlg.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\Morphy.obj" + -@erase "$(INTDIR)\Morphy.pch" + -@erase "$(INTDIR)\Morphy.res" + -@erase "$(INTDIR)\Morphy.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\Slider.obj" + -@erase "$(INTDIR)\Slider.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\Morphy.bsc" + -@erase "$(OUTDIR)\Morphy.exe" + -@erase "$(OUTDIR)\Morphy.ilk" + -@erase "$(OUTDIR)\Morphy.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Morphy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Morphy.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Morphy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\LoadDlg.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\Morphy.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\Slider.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Morphy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Morphy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Morphy.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\LoadDlg.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\Morphy.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\Slider.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Morphy.res" + +"$(OUTDIR)\Morphy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("Morphy.dep") +!INCLUDE "Morphy.dep" +!ELSE +!MESSAGE Warning: cannot find "Morphy.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "Morphy - Win32 Release" || "$(CFG)" == "Morphy - Win32 Debug" +SOURCE=.\Bitmap.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\Bitmap.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\LoadDlg.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\LoadDlg.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\LoadDlg.obj" "$(INTDIR)\LoadDlg.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\LoadOBJ.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\LoadOBJ.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\MainFrm.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\Morphy.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\Morphy.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\Morphy.obj" "$(INTDIR)\Morphy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\Morphy.rc + +"$(INTDIR)\Morphy.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\OGLView.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\OGLView.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\Skeleton.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\Skeleton.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\Slider.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + + +"$(INTDIR)\Slider.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + + +"$(INTDIR)\Slider.obj" "$(INTDIR)\Slider.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Morphy.pch" + + +!ENDIF + +SOURCE=.\StdAfx.cpp + +!IF "$(CFG)" == "Morphy - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Morphy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Morphy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Morphy - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Morphy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Morphy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/3D Morphing/Code/OGL/Morphy/OGLView.cpp b/3D Morphing/Code/OGL/Morphy/OGLView.cpp index 166fccb..336ffe0 100644 --- a/3D Morphing/Code/OGL/Morphy/OGLView.cpp +++ b/3D Morphing/Code/OGL/Morphy/OGLView.cpp @@ -1,689 +1,689 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Morphy.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "Bitmap.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION - -#define LERP(a,b,c) (a + ((b - a) * c)) -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.b_trans.z = -100.0f; - m_Skeleton.trans.z = -100.0f; - -} - -COGLView::~COGLView() -{ - DestroySkeleton(&m_Skeleton); -} - - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CSlider *slider, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual = NULL; -/////////////////////////////////////////////////////////////////////////////// - // I AM GOING TO HAVE TWO OBJECTS TO MORPH BETWEEN - visual = (t_Visual *)malloc(sizeof(t_Visual) * 3); - m_Skeleton.visuals = visual; - m_Skeleton.visualCnt = 3; - - strcpy(visual[0].map, ""); - strcpy(visual[1].map, ""); - strcpy(visual[2].map, ""); - - m_Slider = slider; - m_curVisual = 0; - m_MorphPos = 0.0f; - - visual[0].vertexData = NULL; - visual[1].vertexData = NULL; - visual[2].vertexData = NULL; -// LoadOBJ("Hero1.obj",&m_Skeleton.visuals[0]); -// LoadOBJ("Hero2.obj",&m_Skeleton.visuals[1]); - - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glDisable(GL_TEXTURE_2D); - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 - GLfloat ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); -// glPolygonMode(GL_FRONT,GL_LINE); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); - - glShadeModel(GL_SMOOTH); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); - glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); - glMaterialfv(GL_FRONT,GL_SPECULAR, specular); - glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 - glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glDisable(GL_LIGHTING); - glEnable(GL_LIGHT0); - -} - -/* - * 'LoadBoneTexture()' - Load texture images for the bone - * - * NOTES: THIS SHOULD LOOK THROUGH ALL BONES AND SEE IF TEXTURE IS ALREADY LOADED - */ -GLvoid COGLView::LoadBoneTexture(t_Bone *curBone) -{ - GLubyte *rgb; /* Bitmap RGB pixels */ - char realFilename[80],texName[80]; - int pos; - GLuint temp; - tTGAHeader_s tgaHeader; - -// m_SelectedBone = curBone; - - // GENERATE THE OPENGL TEXTURE ID - glGenTextures(1,&temp); - - curBone->visuals[0].glTex = temp; - // GET THE NAME OF THE ACTUAL IMAGE FROM THE PIC RESOURCE - strcpy(texName,curBone->visuals[0].map); - - pos = strlen(texName); - while (texName[pos] != '\\' && texName[pos] != '/' && pos > 0) - { - if (texName[pos] == '.') texName[pos] = '\0'; - pos--; - } - - if (pos > 0) pos++; - - sprintf(realFilename,"%s.tga",&texName[pos]); - /* - * Try loading the bitmap and converting it to RGB... - */ - - rgb = LoadTGAFile( realFilename,&tgaHeader); - if (rgb == NULL) - { - ::MessageBox(NULL,"Unable to Open File...",realFilename,MB_OK); - curBone->visuals[0].glTex = 0; - return; - } - - glBindTexture(GL_TEXTURE_2D, curBone->visuals[0].glTex); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - /* - * Define the 2D texture image. - */ - - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); /* Force 4-byte alignment */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - - if (tgaHeader.d_pixel_size == 32) - glTexImage2D(GL_TEXTURE_2D, 0, 4, tgaHeader.d_width, tgaHeader.d_height, 0, - GL_RGBA , GL_UNSIGNED_BYTE, rgb); - else - glTexImage2D(GL_TEXTURE_2D, 0, 3, tgaHeader.d_width, tgaHeader.d_height, 0, - GL_RGB, GL_UNSIGNED_BYTE, rgb); - - /* - *Free the bitmap and RGB images, then return 0 (no errors). - */ - - free(rgb); -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: morphModel -// Purpose: Does the Morph for the Model -// Arguments: Pointer to main bone -// Notes: Normals should probably be normalized (but it seems to work fine) -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::morphModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,pointloop; - float *dest,*src1,*src2,ratio; -/////////////////////////////////////////////////////////////////////////////// - if (curBone->visualCnt > m_curVisual && curBone->visuals[0].vertexData != NULL) - { - src1 = curBone->visuals[0].vertexData; // FRAME 1 - src2 = curBone->visuals[1].vertexData; // FRAME 2 - dest = curBone->visuals[2].vertexData; // DESTINATION FOR MORPHED FRAME - ratio = m_Slider->GetSetting(); // GET MORPH VALUE (0 - 1) - // LOOP THROUGH THE VERTICES - for (loop = 0; loop < curBone->visuals[0].triCnt * 3; loop++) - { - // GO THROUGH EACH ELEMENT IN THE VERTEX STRUCTURE - for (pointloop = 0; pointloop < curBone->visuals[0].vSize; pointloop++) - { - // THE NEW POSITION IS A LERP BETWEEN THE TWO POINTS - dest[(loop * curBone->visuals[0].vSize) + pointloop] = - LERP(src1[(loop * curBone->visuals[0].vSize) + pointloop], - src2[(loop * curBone->visuals[0].vSize) + pointloop],ratio); - } - } - } -} -// morphModel - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat color[4]; -/////////////////////////////////////////////////////////////////////////////// - if (curBone->visualCnt > 2 && curBone->visuals[2].vertexData != NULL) - { - glEnable(GL_LIGHTING); - if (curBone->visuals[0].glTex > 0) - glEnable(GL_TEXTURE_2D); - morphModel(curBone); // PERFORM THE MORPH - color[0] = curBone->visuals[0].Kd.r; - color[1] = curBone->visuals[0].Kd.g; - color[2] = curBone->visuals[0].Kd.b; - color[3] = 1.0f; - glMaterialfv(GL_FRONT,GL_DIFFUSE,color); - color[0] = curBone->visuals[0].Ka.r; - color[1] = curBone->visuals[0].Ka.g; - color[2] = curBone->visuals[0].Ka.b; - color[3] = 1.0f; - glMaterialfv(GL_FRONT,GL_AMBIENT,color); - color[0] = curBone->visuals[0].Ks.r; - color[1] = curBone->visuals[0].Ks.g; - color[2] = curBone->visuals[0].Ks.b; - color[3] = 1.0f; - glMaterialfv(GL_FRONT,GL_SPECULAR,color); - // Declare the Array of Data - glInterleavedArrays(curBone->visuals[2].dataFormat,0,(GLvoid *)curBone->visuals[2].vertexData); - glDrawArrays(GL_TRIANGLES,0,curBone->visuals[2].triCnt * 3); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - } -} -// drawModel - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; - if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; - if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); - - // ROTATE THE ROOT - glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); - - // IF I WANT TO, DRAW THE GEOMETRY - if (m_DrawGeometry) - drawModel(&m_Skeleton); - - // DRAW THE AXIS - glCallList(OGL_AXIS_DLIST); - - glPopMatrix(); - glFinish(); - - SwapBuffers(m_hDC); -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Grab_Rot_X = m_Skeleton.rot.x; - m_Grab_Rot_Y = m_Skeleton.rot.y; - m_Grab_Rot_Z = m_Skeleton.rot.z; - m_Grab_Trans_X = m_Skeleton.trans.x; - m_Grab_Trans_Y = m_Skeleton.trans.y; - m_Grab_Trans_Z = m_Skeleton.trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Grab_Rot_X = m_Skeleton.rot.x; - m_Grab_Rot_Y = m_Skeleton.rot.y; - m_Grab_Rot_Z = m_Skeleton.rot.z; - m_Grab_Trans_X = m_Skeleton.trans.x; - m_Grab_Trans_Y = m_Skeleton.trans.y; - m_Grab_Trans_Z = m_Skeleton.trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case 'G': - m_DrawGeometry = !m_DrawGeometry; - break; - case '1': m_curVisual = 0; - break; - case '2': m_curVisual = 1; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - break; - case 'F': - glPolygonMode(GL_FRONT,GL_FILL); - break; - } - drawScene(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CONTROL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(); - } - } - // ELSE ROTATE THE BONE - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadFiles -// Purpose: Loads the OBJ files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadFiles(CString file1, CString file2) -{ - if (m_Skeleton.visuals[0].vertexData != NULL) - { - free(m_Skeleton.visuals[0].vertexData); - m_Skeleton.visuals[0].vertexData = NULL; - } - if (m_Skeleton.visuals[1].vertexData != NULL) - { - free(m_Skeleton.visuals[1].vertexData); - m_Skeleton.visuals[1].vertexData = NULL; - } - if (m_Skeleton.visuals[2].vertexData != NULL) - { - free(m_Skeleton.visuals[2].vertexData); - m_Skeleton.visuals[2].vertexData = NULL; - } - - if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,&m_Skeleton.visuals[0])) - { - if (file2.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file2,&m_Skeleton.visuals[1])) - { - if (m_Skeleton.visuals[0].triCnt == m_Skeleton.visuals[1].triCnt) - { - m_Skeleton.visuals[2].dataFormat = m_Skeleton.visuals[0].dataFormat; - m_Skeleton.visuals[2].vertexData = (float *)malloc(sizeof(float) * m_Skeleton.visuals[0].vSize * m_Skeleton.visuals[0].triCnt * 3); - memcpy(m_Skeleton.visuals[2].vertexData,m_Skeleton.visuals[0].vertexData,sizeof(float) * m_Skeleton.visuals[0].vSize * m_Skeleton.visuals[0].triCnt * 3); - - m_Skeleton.visuals[2].triCnt = m_Skeleton.visuals[0].triCnt; - - if (m_Skeleton.visualCnt > 0 && strlen(m_Skeleton.visuals[0].map) > 0 ) - LoadBoneTexture(&m_Skeleton); - else - { - m_Skeleton.visuals[0].glTex = 0; - glBindTexture(GL_TEXTURE_2D, 0); - } - - } - else - { - MessageBox("OBJ Files must have the same number of triangles","Error",MB_OK); - free(m_Skeleton.visuals[0].vertexData); - free(m_Skeleton.visuals[1].vertexData); - m_Skeleton.visuals[0].vertexData = NULL; - m_Skeleton.visuals[1].vertexData = NULL; - } - } - else - { - MessageBox("Two Valid OBJ Files must be loaded","Error",MB_OK); - free(m_Skeleton.visuals[0].vertexData); - m_Skeleton.visuals[0].vertexData = NULL; - } - } - else - MessageBox("Two Valid OBJ Files must be loaded","Error",MB_OK); - -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Morphy.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "Bitmap.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION + +#define LERP(a,b,c) (a + ((b - a) * c)) +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.b_trans.z = -100.0f; + m_Skeleton.trans.z = -100.0f; + +} + +COGLView::~COGLView() +{ + DestroySkeleton(&m_Skeleton); +} + + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CSlider *slider, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual = NULL; +/////////////////////////////////////////////////////////////////////////////// + // I AM GOING TO HAVE TWO OBJECTS TO MORPH BETWEEN + visual = (t_Visual *)malloc(sizeof(t_Visual) * 3); + m_Skeleton.visuals = visual; + m_Skeleton.visualCnt = 3; + + strcpy(visual[0].map, ""); + strcpy(visual[1].map, ""); + strcpy(visual[2].map, ""); + + m_Slider = slider; + m_curVisual = 0; + m_MorphPos = 0.0f; + + visual[0].vertexData = NULL; + visual[1].vertexData = NULL; + visual[2].vertexData = NULL; +// LoadOBJ("Hero1.obj",&m_Skeleton.visuals[0]); +// LoadOBJ("Hero2.obj",&m_Skeleton.visuals[1]); + + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glDisable(GL_TEXTURE_2D); + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 + GLfloat ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); +// glPolygonMode(GL_FRONT,GL_LINE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + + glShadeModel(GL_SMOOTH); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT,GL_SPECULAR, specular); + glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_LIGHTING); + glEnable(GL_LIGHT0); + +} + +/* + * 'LoadBoneTexture()' - Load texture images for the bone + * + * NOTES: THIS SHOULD LOOK THROUGH ALL BONES AND SEE IF TEXTURE IS ALREADY LOADED + */ +GLvoid COGLView::LoadBoneTexture(t_Bone *curBone) +{ + GLubyte *rgb; /* Bitmap RGB pixels */ + char realFilename[80],texName[80]; + int pos; + GLuint temp; + tTGAHeader_s tgaHeader; + +// m_SelectedBone = curBone; + + // GENERATE THE OPENGL TEXTURE ID + glGenTextures(1,&temp); + + curBone->visuals[0].glTex = temp; + // GET THE NAME OF THE ACTUAL IMAGE FROM THE PIC RESOURCE + strcpy(texName,curBone->visuals[0].map); + + pos = strlen(texName); + while (texName[pos] != '\\' && texName[pos] != '/' && pos > 0) + { + if (texName[pos] == '.') texName[pos] = '\0'; + pos--; + } + + if (pos > 0) pos++; + + sprintf(realFilename,"%s.tga",&texName[pos]); + /* + * Try loading the bitmap and converting it to RGB... + */ + + rgb = LoadTGAFile( realFilename,&tgaHeader); + if (rgb == NULL) + { + ::MessageBox(NULL,"Unable to Open File...",realFilename,MB_OK); + curBone->visuals[0].glTex = 0; + return; + } + + glBindTexture(GL_TEXTURE_2D, curBone->visuals[0].glTex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* + * Define the 2D texture image. + */ + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); /* Force 4-byte alignment */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + + if (tgaHeader.d_pixel_size == 32) + glTexImage2D(GL_TEXTURE_2D, 0, 4, tgaHeader.d_width, tgaHeader.d_height, 0, + GL_RGBA , GL_UNSIGNED_BYTE, rgb); + else + glTexImage2D(GL_TEXTURE_2D, 0, 3, tgaHeader.d_width, tgaHeader.d_height, 0, + GL_RGB, GL_UNSIGNED_BYTE, rgb); + + /* + *Free the bitmap and RGB images, then return 0 (no errors). + */ + + free(rgb); +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: morphModel +// Purpose: Does the Morph for the Model +// Arguments: Pointer to main bone +// Notes: Normals should probably be normalized (but it seems to work fine) +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::morphModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,pointloop; + float *dest,*src1,*src2,ratio; +/////////////////////////////////////////////////////////////////////////////// + if (curBone->visualCnt > m_curVisual && curBone->visuals[0].vertexData != NULL) + { + src1 = curBone->visuals[0].vertexData; // FRAME 1 + src2 = curBone->visuals[1].vertexData; // FRAME 2 + dest = curBone->visuals[2].vertexData; // DESTINATION FOR MORPHED FRAME + ratio = m_Slider->GetSetting(); // GET MORPH VALUE (0 - 1) + // LOOP THROUGH THE VERTICES + for (loop = 0; loop < curBone->visuals[0].triCnt * 3; loop++) + { + // GO THROUGH EACH ELEMENT IN THE VERTEX STRUCTURE + for (pointloop = 0; pointloop < curBone->visuals[0].vSize; pointloop++) + { + // THE NEW POSITION IS A LERP BETWEEN THE TWO POINTS + dest[(loop * curBone->visuals[0].vSize) + pointloop] = + LERP(src1[(loop * curBone->visuals[0].vSize) + pointloop], + src2[(loop * curBone->visuals[0].vSize) + pointloop],ratio); + } + } + } +} +// morphModel + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat color[4]; +/////////////////////////////////////////////////////////////////////////////// + if (curBone->visualCnt > 2 && curBone->visuals[2].vertexData != NULL) + { + glEnable(GL_LIGHTING); + if (curBone->visuals[0].glTex > 0) + glEnable(GL_TEXTURE_2D); + morphModel(curBone); // PERFORM THE MORPH + color[0] = curBone->visuals[0].Kd.r; + color[1] = curBone->visuals[0].Kd.g; + color[2] = curBone->visuals[0].Kd.b; + color[3] = 1.0f; + glMaterialfv(GL_FRONT,GL_DIFFUSE,color); + color[0] = curBone->visuals[0].Ka.r; + color[1] = curBone->visuals[0].Ka.g; + color[2] = curBone->visuals[0].Ka.b; + color[3] = 1.0f; + glMaterialfv(GL_FRONT,GL_AMBIENT,color); + color[0] = curBone->visuals[0].Ks.r; + color[1] = curBone->visuals[0].Ks.g; + color[2] = curBone->visuals[0].Ks.b; + color[3] = 1.0f; + glMaterialfv(GL_FRONT,GL_SPECULAR,color); + // Declare the Array of Data + glInterleavedArrays(curBone->visuals[2].dataFormat,0,(GLvoid *)curBone->visuals[2].vertexData); + glDrawArrays(GL_TRIANGLES,0,curBone->visuals[2].triCnt * 3); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + } +} +// drawModel + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; + if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; + if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); + + // ROTATE THE ROOT + glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); + + // IF I WANT TO, DRAW THE GEOMETRY + if (m_DrawGeometry) + drawModel(&m_Skeleton); + + // DRAW THE AXIS + glCallList(OGL_AXIS_DLIST); + + glPopMatrix(); + glFinish(); + + SwapBuffers(m_hDC); +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Grab_Rot_X = m_Skeleton.rot.x; + m_Grab_Rot_Y = m_Skeleton.rot.y; + m_Grab_Rot_Z = m_Skeleton.rot.z; + m_Grab_Trans_X = m_Skeleton.trans.x; + m_Grab_Trans_Y = m_Skeleton.trans.y; + m_Grab_Trans_Z = m_Skeleton.trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Grab_Rot_X = m_Skeleton.rot.x; + m_Grab_Rot_Y = m_Skeleton.rot.y; + m_Grab_Rot_Z = m_Skeleton.rot.z; + m_Grab_Trans_X = m_Skeleton.trans.x; + m_Grab_Trans_Y = m_Skeleton.trans.y; + m_Grab_Trans_Z = m_Skeleton.trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case 'G': + m_DrawGeometry = !m_DrawGeometry; + break; + case '1': m_curVisual = 0; + break; + case '2': m_curVisual = 1; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + break; + case 'F': + glPolygonMode(GL_FRONT,GL_FILL); + break; + } + drawScene(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CONTROL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(); + } + } + // ELSE ROTATE THE BONE + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadFiles +// Purpose: Loads the OBJ files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadFiles(CString file1, CString file2) +{ + if (m_Skeleton.visuals[0].vertexData != NULL) + { + free(m_Skeleton.visuals[0].vertexData); + m_Skeleton.visuals[0].vertexData = NULL; + } + if (m_Skeleton.visuals[1].vertexData != NULL) + { + free(m_Skeleton.visuals[1].vertexData); + m_Skeleton.visuals[1].vertexData = NULL; + } + if (m_Skeleton.visuals[2].vertexData != NULL) + { + free(m_Skeleton.visuals[2].vertexData); + m_Skeleton.visuals[2].vertexData = NULL; + } + + if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,&m_Skeleton.visuals[0])) + { + if (file2.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file2,&m_Skeleton.visuals[1])) + { + if (m_Skeleton.visuals[0].triCnt == m_Skeleton.visuals[1].triCnt) + { + m_Skeleton.visuals[2].dataFormat = m_Skeleton.visuals[0].dataFormat; + m_Skeleton.visuals[2].vertexData = (float *)malloc(sizeof(float) * m_Skeleton.visuals[0].vSize * m_Skeleton.visuals[0].triCnt * 3); + memcpy(m_Skeleton.visuals[2].vertexData,m_Skeleton.visuals[0].vertexData,sizeof(float) * m_Skeleton.visuals[0].vSize * m_Skeleton.visuals[0].triCnt * 3); + + m_Skeleton.visuals[2].triCnt = m_Skeleton.visuals[0].triCnt; + + if (m_Skeleton.visualCnt > 0 && strlen(m_Skeleton.visuals[0].map) > 0 ) + LoadBoneTexture(&m_Skeleton); + else + { + m_Skeleton.visuals[0].glTex = 0; + glBindTexture(GL_TEXTURE_2D, 0); + } + + } + else + { + MessageBox("OBJ Files must have the same number of triangles","Error",MB_OK); + free(m_Skeleton.visuals[0].vertexData); + free(m_Skeleton.visuals[1].vertexData); + m_Skeleton.visuals[0].vertexData = NULL; + m_Skeleton.visuals[1].vertexData = NULL; + } + } + else + { + MessageBox("Two Valid OBJ Files must be loaded","Error",MB_OK); + free(m_Skeleton.visuals[0].vertexData); + m_Skeleton.visuals[0].vertexData = NULL; + } + } + else + MessageBox("Two Valid OBJ Files must be loaded","Error",MB_OK); + +} diff --git a/3D Morphing/Code/OGL/Morphy/OGLView.h b/3D Morphing/Code/OGL/Morphy/OGLView.h index 4c398e1..7a5b499 100644 --- a/3D Morphing/Code/OGL/Morphy/OGLView.h +++ b/3D Morphing/Code/OGL/Morphy/OGLView.h @@ -1,102 +1,102 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -#include "Slider.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry; - int m_curVisual; - float m_MorphPos; - CSlider *m_Slider; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - GLvoid morphModel(t_Bone *curBone); - GLvoid LoadBoneTexture(t_Bone *curBone); - void LoadFiles(CString file1, CString file2); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CSlider *slider, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Skeleton; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +#include "Slider.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry; + int m_curVisual; + float m_MorphPos; + CSlider *m_Slider; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + GLvoid morphModel(t_Bone *curBone); + GLvoid LoadBoneTexture(t_Bone *curBone); + void LoadFiles(CString file1, CString file2); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CSlider *slider, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Skeleton; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/ReadMe.txt b/3D Morphing/Code/OGL/Morphy/ReadMe.txt index 79f666b..15ef604 100644 --- a/3D Morphing/Code/OGL/Morphy/ReadMe.txt +++ b/3D Morphing/Code/OGL/Morphy/ReadMe.txt @@ -1,39 +1,39 @@ -3D Real-time Morphing in OpenGL Demonstration Nov 5, 1998 --------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the December 98 -Game Developer magazine. It is meant as a demonstration of -a method for 3D morphing in OpenGL. - -To use the program, load in two OBJ models having the exact same -vertex count. The slider will morph smoothly between the two. - -The function morphModel() does the main work. - -Note: The normals should probably be normalized after the morph -but in practice it seems to work fine without doing it. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm Feb 5, 1998 ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - +3D Real-time Morphing in OpenGL Demonstration Nov 5, 1998 +-------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the December 98 +Game Developer magazine. It is meant as a demonstration of +a method for 3D morphing in OpenGL. + +To use the program, load in two OBJ models having the exact same +vertex count. The slider will morph smoothly between the two. + +The function morphModel() does the main work. + +Note: The normals should probably be normalized after the morph +but in practice it seems to work fine without doing it. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm Feb 5, 1998 +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + diff --git a/3D Morphing/Code/OGL/Morphy/Skeleton.cpp b/3D Morphing/Code/OGL/Morphy/Skeleton.cpp index baf7c7b..d1b29e5 100644 --- a/3D Morphing/Code/OGL/Morphy/Skeleton.cpp +++ b/3D Morphing/Code/OGL/Morphy/Skeleton.cpp @@ -1,157 +1,157 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - if (root->visualCnt > 0) - { - free(root->visuals->vertexData); - free(root->visuals); - } - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + if (root->visualCnt > 0) + { + free(root->visuals->vertexData); + free(root->visuals); + } + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/3D Morphing/Code/OGL/Morphy/Skeleton.h b/3D Morphing/Code/OGL/Morphy/Skeleton.h index bbce6fb..d3faf31 100644 --- a/3D Morphing/Code/OGL/Morphy/Skeleton.h +++ b/3D Morphing/Code/OGL/Morphy/Skeleton.h @@ -1,146 +1,146 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "MathDefs.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - int vSize; // NUMBER OF FLOATS IN A VERTEX - long triCnt; // NUMBER OF TRIS IN VISUAL - tVector Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - int glTex; -}; - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "MathDefs.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + int vSize; // NUMBER OF FLOATS IN A VERTEX + long triCnt; // NUMBER OF TRIS IN VISUAL + tVector Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + int glTex; +}; + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/Slider.cpp b/3D Morphing/Code/OGL/Morphy/Slider.cpp index 09ef215..e845061 100644 --- a/3D Morphing/Code/OGL/Morphy/Slider.cpp +++ b/3D Morphing/Code/OGL/Morphy/Slider.cpp @@ -1,82 +1,82 @@ -// Slider.cpp : implementation file -// - -#include "stdafx.h" -#include "Morphy.h" -#include "Slider.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSlider - -CSlider::CSlider() -{ - // FLAG WHETHER I AM DRAGGING THE SLIDER - m_pressed = FALSE; -} - -CSlider::~CSlider() -{ -} - - -BEGIN_MESSAGE_MAP(CSlider, CSliderCtrl) - //{{AFX_MSG_MAP(CSlider) - ON_WM_CREATE() - ON_WM_LBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSlider message handlers - -int CSlider::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CSliderCtrl::OnCreate(lpCreateStruct) == -1) - return -1; - - // SET UP THE SLIDER SO IT GOES FROM 0 - 1024 - SetRange(0,1024,TRUE); - SetPos(0); - return 0; -} - -// GET A FLOAT REPRESENTING THE RELATIVE POSITION OF THE SLIDER -// Returns: float from 0-1 -float CSlider::GetSetting() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int position; -/////////////////////////////////////////////////////////////////////////////// - position = GetPos(); - return position / 1024.0f; -} - -void CSlider::OnLButtonDown(UINT nFlags, CPoint point) -{ - // MARK THE DRAG - m_pressed = TRUE; - CSliderCtrl::OnLButtonDown(nFlags, point); -} - -void CSlider::OnMouseMove(UINT nFlags, CPoint point) -{ - // IF I AM DRAGGING, REDRAW MY MAIN WINDOW - if (m_pressed) - GetParent()->InvalidateRect(NULL); - CSliderCtrl::OnMouseMove(nFlags, point); -} - -void CSlider::OnLButtonUp(UINT nFlags, CPoint point) -{ - // NOT DRAGGING ANY MORE - m_pressed = FALSE; - CSliderCtrl::OnLButtonUp(nFlags, point); -} +// Slider.cpp : implementation file +// + +#include "stdafx.h" +#include "Morphy.h" +#include "Slider.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSlider + +CSlider::CSlider() +{ + // FLAG WHETHER I AM DRAGGING THE SLIDER + m_pressed = FALSE; +} + +CSlider::~CSlider() +{ +} + + +BEGIN_MESSAGE_MAP(CSlider, CSliderCtrl) + //{{AFX_MSG_MAP(CSlider) + ON_WM_CREATE() + ON_WM_LBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSlider message handlers + +int CSlider::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CSliderCtrl::OnCreate(lpCreateStruct) == -1) + return -1; + + // SET UP THE SLIDER SO IT GOES FROM 0 - 1024 + SetRange(0,1024,TRUE); + SetPos(0); + return 0; +} + +// GET A FLOAT REPRESENTING THE RELATIVE POSITION OF THE SLIDER +// Returns: float from 0-1 +float CSlider::GetSetting() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int position; +/////////////////////////////////////////////////////////////////////////////// + position = GetPos(); + return position / 1024.0f; +} + +void CSlider::OnLButtonDown(UINT nFlags, CPoint point) +{ + // MARK THE DRAG + m_pressed = TRUE; + CSliderCtrl::OnLButtonDown(nFlags, point); +} + +void CSlider::OnMouseMove(UINT nFlags, CPoint point) +{ + // IF I AM DRAGGING, REDRAW MY MAIN WINDOW + if (m_pressed) + GetParent()->InvalidateRect(NULL); + CSliderCtrl::OnMouseMove(nFlags, point); +} + +void CSlider::OnLButtonUp(UINT nFlags, CPoint point) +{ + // NOT DRAGGING ANY MORE + m_pressed = FALSE; + CSliderCtrl::OnLButtonUp(nFlags, point); +} diff --git a/3D Morphing/Code/OGL/Morphy/Slider.h b/3D Morphing/Code/OGL/Morphy/Slider.h index 06570a8..94451bb 100644 --- a/3D Morphing/Code/OGL/Morphy/Slider.h +++ b/3D Morphing/Code/OGL/Morphy/Slider.h @@ -1,52 +1,52 @@ -#if !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// Slider.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSlider window - -class CSlider : public CSliderCtrl -{ -// Construction -public: - CSlider(); - float GetSetting(); - -// Attributes -private: - BOOL m_pressed; -// Operations -public: - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSlider) - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CSlider(); - - // Generated message map functions -protected: - //{{AFX_MSG(CSlider) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) +#if !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// Slider.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSlider window + +class CSlider : public CSliderCtrl +{ +// Construction +public: + CSlider(); + float GetSetting(); + +// Attributes +private: + BOOL m_pressed; +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSlider) + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CSlider(); + + // Generated message map functions +protected: + //{{AFX_MSG(CSlider) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/StdAfx.cpp b/3D Morphing/Code/OGL/Morphy/StdAfx.cpp index d62373e..3626a29 100644 --- a/3D Morphing/Code/OGL/Morphy/StdAfx.cpp +++ b/3D Morphing/Code/OGL/Morphy/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Morphy.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Morphy.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/3D Morphing/Code/OGL/Morphy/StdAfx.h b/3D Morphing/Code/OGL/Morphy/StdAfx.h index ddefdab..571c76c 100644 --- a/3D Morphing/Code/OGL/Morphy/StdAfx.h +++ b/3D Morphing/Code/OGL/Morphy/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/loaddlg.h b/3D Morphing/Code/OGL/Morphy/loaddlg.h index b8eebf0..d93e7b6 100644 --- a/3D Morphing/Code/OGL/Morphy/loaddlg.h +++ b/3D Morphing/Code/OGL/Morphy/loaddlg.h @@ -1,48 +1,48 @@ -#if !defined(AFX_LoadDlg_H__81F04AC0_7EFD_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_LoadDlg_H__81F04AC0_7EFD_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// LoadDlg.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CLoadDlg dialog - -class CLoadDlg : public CDialog -{ -// Construction -public: - CLoadDlg(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CLoadDlg) - enum { IDD = IDD_LOADOBJ }; - CString m_File1; - CString m_File2; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CLoadDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CLoadDlg) - afx_msg void OnBrowse1(); - afx_msg void OnBrowse2(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_LoadDlg_H__81F04AC0_7EFD_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_LoadDlg_H__81F04AC0_7EFD_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_LoadDlg_H__81F04AC0_7EFD_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// LoadDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CLoadDlg dialog + +class CLoadDlg : public CDialog +{ +// Construction +public: + CLoadDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CLoadDlg) + enum { IDD = IDD_LOADOBJ }; + CString m_File1; + CString m_File2; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CLoadDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CLoadDlg) + afx_msg void OnBrowse1(); + afx_msg void OnBrowse2(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_LoadDlg_H__81F04AC0_7EFD_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/3D Morphing/Code/OGL/Morphy/resource.h b/3D Morphing/Code/OGL/Morphy/resource.h index 288ed1f..73846d8 100644 --- a/3D Morphing/Code/OGL/Morphy/resource.h +++ b/3D Morphing/Code/OGL/Morphy/resource.h @@ -1,46 +1,46 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Morphy.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_MORPHYTYPE 129 -#define IDD_SETROTATE 130 -#define IDB_HUP 131 -#define IDB_HDN 132 -#define IDD_DIALOG1 132 -#define IDB_HUPP 133 -#define IDD_LOADOBJ 133 -#define IDB_HDNP 134 -#define IDB_VDN 135 -#define IDB_VUP 136 -#define IDB_VUPP 137 -#define IDB_VDNP 138 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_BUTTON1 1001 -#define IDC_BROWSE1 1001 -#define IDC_ZAXIS 1002 -#define IDC_BROWSE2 1002 -#define IDC_SLIDER1 1003 -#define IDC_EDIT1 1004 -#define IDC_EDIT2 1005 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 134 -#define _APS_NEXT_COMMAND_VALUE 32775 -#define _APS_NEXT_CONTROL_VALUE 1005 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Morphy.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_MORPHYTYPE 129 +#define IDD_SETROTATE 130 +#define IDB_HUP 131 +#define IDB_HDN 132 +#define IDD_DIALOG1 132 +#define IDB_HUPP 133 +#define IDD_LOADOBJ 133 +#define IDB_HDNP 134 +#define IDB_VDN 135 +#define IDB_VUP 136 +#define IDB_VUPP 137 +#define IDB_VDNP 138 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_BUTTON1 1001 +#define IDC_BROWSE1 1001 +#define IDC_ZAXIS 1002 +#define IDC_BROWSE2 1002 +#define IDC_SLIDER1 1003 +#define IDC_EDIT1 1004 +#define IDC_EDIT2 1005 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 32775 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Blob Modeling/Code/OGL/Blobby/Blobby.cpp b/Blob Modeling/Code/OGL/Blobby/Blobby.cpp index 438325d..457e71c 100644 --- a/Blob Modeling/Code/OGL/Blobby/Blobby.cpp +++ b/Blob Modeling/Code/OGL/Blobby/Blobby.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Blobby.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of OpenGL Window of 3D Blob modelling -// -// Created: -// JL 11/20/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Blobby.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CBlobbyApp - -BEGIN_MESSAGE_MAP(CBlobbyApp, CWinApp) - //{{AFX_MSG_MAP(CBlobbyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CBlobbyApp construction - -CBlobbyApp::CBlobbyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CBlobbyApp object - -CBlobbyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CBlobbyApp initialization - -BOOL CBlobbyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CBlobbyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CBlobbyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Blobby.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of OpenGL Window of 3D Blob modelling +// +// Created: +// JL 11/20/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Blobby.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CBlobbyApp + +BEGIN_MESSAGE_MAP(CBlobbyApp, CWinApp) + //{{AFX_MSG_MAP(CBlobbyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CBlobbyApp construction + +CBlobbyApp::CBlobbyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CBlobbyApp object + +CBlobbyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CBlobbyApp initialization + +BOOL CBlobbyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CBlobbyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CBlobbyApp commands diff --git a/Blob Modeling/Code/OGL/Blobby/Blobby.h b/Blob Modeling/Code/OGL/Blobby/Blobby.h index d6f3df7..c79b4cd 100644 --- a/Blob Modeling/Code/OGL/Blobby/Blobby.h +++ b/Blob Modeling/Code/OGL/Blobby/Blobby.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Blobby.h : main header file for the Blobby application -// -// Purpose: Implementation of OpenGL Window of 3D Blob Modelling -// -// Created: -// JL 11/20/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Blobby_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Blobby_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CBlobbyApp: -// See Blobby.cpp for the implementation of this class -// - -class CBlobbyApp : public CWinApp -{ -public: - CBlobbyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CBlobbyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CBlobbyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Blobby_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Blobby.h : main header file for the Blobby application +// +// Purpose: Implementation of OpenGL Window of 3D Blob Modelling +// +// Created: +// JL 11/20/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Blobby_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Blobby_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CBlobbyApp: +// See Blobby.cpp for the implementation of this class +// + +class CBlobbyApp : public CWinApp +{ +public: + CBlobbyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CBlobbyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CBlobbyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Blobby_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/EditBlob.cpp b/Blob Modeling/Code/OGL/Blobby/EditBlob.cpp index 9453d79..42bcc6f 100644 --- a/Blob Modeling/Code/OGL/Blobby/EditBlob.cpp +++ b/Blob Modeling/Code/OGL/Blobby/EditBlob.cpp @@ -1,46 +1,46 @@ -// EditBlob.cpp : implementation file -// - -#include "stdafx.h" -#include "blobby.h" -#include "EditBlob.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CEditBlob dialog - - -CEditBlob::CEditBlob(CWnd* pParent /*=NULL*/) - : CDialog(CEditBlob::IDD, pParent) -{ - //{{AFX_DATA_INIT(CEditBlob) - m_RadiusSquared = 0.0f; - m_Strength = 0.0f; - //}}AFX_DATA_INIT -} - - -void CEditBlob::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CEditBlob) - DDX_Text(pDX, IDC_RADIUS, m_RadiusSquared); - DDV_MinMaxFloat(pDX, m_RadiusSquared, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_STRENGTH, m_Strength); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CEditBlob, CDialog) - //{{AFX_MSG_MAP(CEditBlob) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CEditBlob message handlers +// EditBlob.cpp : implementation file +// + +#include "stdafx.h" +#include "blobby.h" +#include "EditBlob.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CEditBlob dialog + + +CEditBlob::CEditBlob(CWnd* pParent /*=NULL*/) + : CDialog(CEditBlob::IDD, pParent) +{ + //{{AFX_DATA_INIT(CEditBlob) + m_RadiusSquared = 0.0f; + m_Strength = 0.0f; + //}}AFX_DATA_INIT +} + + +void CEditBlob::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CEditBlob) + DDX_Text(pDX, IDC_RADIUS, m_RadiusSquared); + DDV_MinMaxFloat(pDX, m_RadiusSquared, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_STRENGTH, m_Strength); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CEditBlob, CDialog) + //{{AFX_MSG_MAP(CEditBlob) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CEditBlob message handlers diff --git a/Blob Modeling/Code/OGL/Blobby/EditBlob.h b/Blob Modeling/Code/OGL/Blobby/EditBlob.h index 87f0921..5204c3a 100644 --- a/Blob Modeling/Code/OGL/Blobby/EditBlob.h +++ b/Blob Modeling/Code/OGL/Blobby/EditBlob.h @@ -1,47 +1,47 @@ -#if !defined(AFX_EDITBLOB_H__6B58AB36_9FA2_44CA_B404_C35D4E6F5A18__INCLUDED_) -#define AFX_EDITBLOB_H__6B58AB36_9FA2_44CA_B404_C35D4E6F5A18__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// EditBlob.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CEditBlob dialog - -class CEditBlob : public CDialog -{ -// Construction -public: - CEditBlob(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CEditBlob) - enum { IDD = IDD_EDITBLOB }; - float m_RadiusSquared; - float m_Strength; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CEditBlob) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CEditBlob) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_EDITBLOB_H__6B58AB36_9FA2_44CA_B404_C35D4E6F5A18__INCLUDED_) +#if !defined(AFX_EDITBLOB_H__6B58AB36_9FA2_44CA_B404_C35D4E6F5A18__INCLUDED_) +#define AFX_EDITBLOB_H__6B58AB36_9FA2_44CA_B404_C35D4E6F5A18__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// EditBlob.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CEditBlob dialog + +class CEditBlob : public CDialog +{ +// Construction +public: + CEditBlob(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CEditBlob) + enum { IDD = IDD_EDITBLOB }; + float m_RadiusSquared; + float m_Strength; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEditBlob) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CEditBlob) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_EDITBLOB_H__6B58AB36_9FA2_44CA_B404_C35D4E6F5A18__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/EditSys.cpp b/Blob Modeling/Code/OGL/Blobby/EditSys.cpp index 41e65c7..b346525 100644 --- a/Blob Modeling/Code/OGL/Blobby/EditSys.cpp +++ b/Blob Modeling/Code/OGL/Blobby/EditSys.cpp @@ -1,47 +1,47 @@ -// EditSys.cpp : implementation file -// - -#include "stdafx.h" -#include "blobby.h" -#include "EditSys.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CEditSys dialog - - -CEditSys::CEditSys(CWnd* pParent /*=NULL*/) - : CDialog(CEditSys::IDD, pParent) -{ - //{{AFX_DATA_INIT(CEditSys) - m_SubDiv = 0; - m_Threshold = 0.0f; - //}}AFX_DATA_INIT -} - - -void CEditSys::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CEditSys) - DDX_Text(pDX, IDC_SUBDIV, m_SubDiv); - DDV_MinMaxInt(pDX, m_SubDiv, 5, 100); - DDX_Text(pDX, IDC_THRESHOLD, m_Threshold); - DDV_MinMaxFloat(pDX, m_Threshold, 0.f, 100.f); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CEditSys, CDialog) - //{{AFX_MSG_MAP(CEditSys) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CEditSys message handlers +// EditSys.cpp : implementation file +// + +#include "stdafx.h" +#include "blobby.h" +#include "EditSys.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CEditSys dialog + + +CEditSys::CEditSys(CWnd* pParent /*=NULL*/) + : CDialog(CEditSys::IDD, pParent) +{ + //{{AFX_DATA_INIT(CEditSys) + m_SubDiv = 0; + m_Threshold = 0.0f; + //}}AFX_DATA_INIT +} + + +void CEditSys::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CEditSys) + DDX_Text(pDX, IDC_SUBDIV, m_SubDiv); + DDV_MinMaxInt(pDX, m_SubDiv, 5, 100); + DDX_Text(pDX, IDC_THRESHOLD, m_Threshold); + DDV_MinMaxFloat(pDX, m_Threshold, 0.f, 100.f); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CEditSys, CDialog) + //{{AFX_MSG_MAP(CEditSys) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CEditSys message handlers diff --git a/Blob Modeling/Code/OGL/Blobby/EditSys.h b/Blob Modeling/Code/OGL/Blobby/EditSys.h index 3ccaa9d..8b3f950 100644 --- a/Blob Modeling/Code/OGL/Blobby/EditSys.h +++ b/Blob Modeling/Code/OGL/Blobby/EditSys.h @@ -1,47 +1,47 @@ -#if !defined(AFX_EDITSYS_H__7EE16A06_49C7_4105_A9C8_6D4BC12DA2FD__INCLUDED_) -#define AFX_EDITSYS_H__7EE16A06_49C7_4105_A9C8_6D4BC12DA2FD__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// EditSys.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CEditSys dialog - -class CEditSys : public CDialog -{ -// Construction -public: - CEditSys(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CEditSys) - enum { IDD = IDD_EDITSYS }; - int m_SubDiv; - float m_Threshold; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CEditSys) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CEditSys) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_EDITSYS_H__7EE16A06_49C7_4105_A9C8_6D4BC12DA2FD__INCLUDED_) +#if !defined(AFX_EDITSYS_H__7EE16A06_49C7_4105_A9C8_6D4BC12DA2FD__INCLUDED_) +#define AFX_EDITSYS_H__7EE16A06_49C7_4105_A9C8_6D4BC12DA2FD__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// EditSys.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CEditSys dialog + +class CEditSys : public CDialog +{ +// Construction +public: + CEditSys(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CEditSys) + enum { IDD = IDD_EDITSYS }; + int m_SubDiv; + float m_Threshold; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEditSys) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CEditSys) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_EDITSYS_H__7EE16A06_49C7_4105_A9C8_6D4BC12DA2FD__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/MainFrm.cpp b/Blob Modeling/Code/OGL/Blobby/MainFrm.cpp index b8c793f..b523e39 100644 --- a/Blob Modeling/Code/OGL/Blobby/MainFrm.cpp +++ b/Blob Modeling/Code/OGL/Blobby/MainFrm.cpp @@ -1,254 +1,254 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Blob modelling -// -// Created: -// JL 11/20/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Blobby.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_GOOP_ADDBLOB, OnGoopAddblob) - ON_COMMAND(ID_VIEW_DRAWBLOBS, OnViewDrawblobs) - ON_UPDATE_COMMAND_UI(ID_VIEW_DRAWBLOBS, OnUpdateViewDrawblobs) - ON_COMMAND(ID_VIEW_DRAWFIELD, OnViewDrawfield) - ON_UPDATE_COMMAND_UI(ID_VIEW_DRAWFIELD, OnUpdateViewDrawfield) - ON_COMMAND(ID_GOOP_EDITBLOB, OnGoopEditblob) - ON_COMMAND(ID_GOOP_SYSTEMSETTINGS, OnGoopSystemsettings) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.DrawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom - - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case ' ': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.DrawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnViewDrawblobs() -{ - m_OGLView.m_DrawBlobs = !m_OGLView.m_DrawBlobs; - m_OGLView.DrawScene(); -} - -void CMainFrame::OnUpdateViewDrawblobs(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawBlobs ); -} - -void CMainFrame::OnViewDrawfield() -{ - m_OGLView.m_DrawField = !m_OGLView.m_DrawField; - m_OGLView.DrawScene(); -} - -void CMainFrame::OnUpdateViewDrawfield(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawField ); -} - -void CMainFrame::OnFileOpen() -{ - char szFilter[] = "Blob files (*.blb)|*.blb||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, NULL, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ) ); - } -} - -void CMainFrame::OnFileSave() -{ - char szFilter[] = "Blob files (*.blb)|*.blb||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( FALSE, ".obj", NULL, NULL, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( ) ); - } -} - -void CMainFrame::OnGoopAddblob() -{ - m_OGLView.OnGoopAddblob(); -} - -void CMainFrame::OnGoopEditblob() -{ - m_OGLView.EditBlob(); -} - -void CMainFrame::OnGoopSystemsettings() -{ - m_OGLView.EditSys(); -} - +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Blob modelling +// +// Created: +// JL 11/20/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Blobby.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_GOOP_ADDBLOB, OnGoopAddblob) + ON_COMMAND(ID_VIEW_DRAWBLOBS, OnViewDrawblobs) + ON_UPDATE_COMMAND_UI(ID_VIEW_DRAWBLOBS, OnUpdateViewDrawblobs) + ON_COMMAND(ID_VIEW_DRAWFIELD, OnViewDrawfield) + ON_UPDATE_COMMAND_UI(ID_VIEW_DRAWFIELD, OnUpdateViewDrawfield) + ON_COMMAND(ID_GOOP_EDITBLOB, OnGoopEditblob) + ON_COMMAND(ID_GOOP_SYSTEMSETTINGS, OnGoopSystemsettings) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.DrawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom + + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case ' ': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.DrawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnViewDrawblobs() +{ + m_OGLView.m_DrawBlobs = !m_OGLView.m_DrawBlobs; + m_OGLView.DrawScene(); +} + +void CMainFrame::OnUpdateViewDrawblobs(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawBlobs ); +} + +void CMainFrame::OnViewDrawfield() +{ + m_OGLView.m_DrawField = !m_OGLView.m_DrawField; + m_OGLView.DrawScene(); +} + +void CMainFrame::OnUpdateViewDrawfield(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawField ); +} + +void CMainFrame::OnFileOpen() +{ + char szFilter[] = "Blob files (*.blb)|*.blb||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, NULL, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ) ); + } +} + +void CMainFrame::OnFileSave() +{ + char szFilter[] = "Blob files (*.blb)|*.blb||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( FALSE, ".obj", NULL, NULL, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( ) ); + } +} + +void CMainFrame::OnGoopAddblob() +{ + m_OGLView.OnGoopAddblob(); +} + +void CMainFrame::OnGoopEditblob() +{ + m_OGLView.EditBlob(); +} + +void CMainFrame::OnGoopSystemsettings() +{ + m_OGLView.EditSys(); +} + diff --git a/Blob Modeling/Code/OGL/Blobby/MainFrm.h b/Blob Modeling/Code/OGL/Blobby/MainFrm.h index 318cb86..88f68bc 100644 --- a/Blob Modeling/Code/OGL/Blobby/MainFrm.h +++ b/Blob Modeling/Code/OGL/Blobby/MainFrm.h @@ -1,88 +1,88 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Blob Modelling -// -// Created: -// JL 11/20/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileOpen(); - afx_msg void OnGoopAddblob(); - afx_msg void OnViewDrawblobs(); - afx_msg void OnUpdateViewDrawblobs(CCmdUI* pCmdUI); - afx_msg void OnViewDrawfield(); - afx_msg void OnUpdateViewDrawfield(CCmdUI* pCmdUI); - afx_msg void OnGoopEditblob(); - afx_msg void OnGoopSystemsettings(); - afx_msg void OnFileSave(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Blob Modelling +// +// Created: +// JL 11/20/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileOpen(); + afx_msg void OnGoopAddblob(); + afx_msg void OnViewDrawblobs(); + afx_msg void OnUpdateViewDrawblobs(CCmdUI* pCmdUI); + afx_msg void OnViewDrawfield(); + afx_msg void OnUpdateViewDrawfield(CCmdUI* pCmdUI); + afx_msg void OnGoopEditblob(); + afx_msg void OnGoopSystemsettings(); + afx_msg void OnFileSave(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/MathDefs.cpp b/Blob Modeling/Code/OGL/Blobby/MathDefs.cpp index 0ad2ec0..76e0264 100644 --- a/Blob Modeling/Code/OGL/Blobby/MathDefs.cpp +++ b/Blob Modeling/Code/OGL/Blobby/MathDefs.cpp @@ -1,105 +1,105 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/99 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void VectorMultiply(tVector *v, float scale) -{ - v->x = v->x * scale; - v->y = v->y * scale; - v->z = v->z * scale; -} - -void VectorSubtract(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/99 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void VectorMultiply(tVector *v, float scale) +{ + v->x = v->x * scale; + v->y = v->y * scale; + v->z = v->z * scale; +} + +void VectorSubtract(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/Blob Modeling/Code/OGL/Blobby/MathDefs.h b/Blob Modeling/Code/OGL/Blobby/MathDefs.h index dc4eddd..9dceb79 100644 --- a/Blob Modeling/Code/OGL/Blobby/MathDefs.h +++ b/Blob Modeling/Code/OGL/Blobby/MathDefs.h @@ -1,113 +1,113 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float nx,ny,nz; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void VectorMultiply(tVector *v, float scale); -void VectorSubtract(tVector *v1, tVector *v2, tVector *result); - - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float nx,ny,nz; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void VectorMultiply(tVector *v, float scale); +void VectorSubtract(tVector *v1, tVector *v2, tVector *result); + + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Blob Modeling/Code/OGL/Blobby/MetaGoop.cpp b/Blob Modeling/Code/OGL/Blobby/MetaGoop.cpp index 6c97664..c35932b 100644 --- a/Blob Modeling/Code/OGL/Blobby/MetaGoop.cpp +++ b/Blob Modeling/Code/OGL/Blobby/MetaGoop.cpp @@ -1,376 +1,376 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MetaGoop.cpp : implementation file -// -// Purpose: Implementation of MetaGoop -// This is the main file for the MetaGoop system. -// -// Created: -// JL 10/18/99 -// Revisions: Jan 2000 -// Lots of UI and tweaking -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include -#include -#include "MetaGoop.h" - -tMetaGoopSys m_GoopSys; - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_InitSys -// Purpose: Initialize System -///////////////////////////////////////////////////////////////////////////////////// -tMetaGoopSys *Goop_InitSys() -{ - m_GoopSys.nGoopCnt = 0; - m_GoopSys.pGoop = NULL; - return(&m_GoopSys); -} - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_FreeSys -// Purpose: Clear System -///////////////////////////////////////////////////////////////////////////////////// -void Goop_FreeSys() -{ - if (m_GoopSys.nGoopCnt > 0) - free(m_GoopSys.pGoop); - m_GoopSys.nGoopCnt = 0; - m_GoopSys.pGoop = NULL; -} - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_AddBlob -// Purpose: Add a new blob into the system and initialize it -///////////////////////////////////////////////////////////////////////////////////// -void Goop_AddBlob(tMetaGoopSys *pGoopSys) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - tMetaGoop *goop; -///////////////////////////////////////////////////////////////////////////////////// - goop = (tMetaGoop *)malloc(sizeof(tMetaGoop) * (pGoopSys->nGoopCnt + 1)); - if (pGoopSys->nGoopCnt > 0) - { - memcpy(goop,pGoopSys->pGoop,sizeof(tMetaGoop) * pGoopSys->nGoopCnt); - free(pGoopSys->pGoop); - } - // Initialize the Blob - goop[pGoopSys->nGoopCnt].position.x = 0.0f; - goop[pGoopSys->nGoopCnt].position.y = 0.0f; - goop[pGoopSys->nGoopCnt].position.z = 0.0f; - goop[pGoopSys->nGoopCnt].radiusSquared = 4.0f; - goop[pGoopSys->nGoopCnt].strength = 4.0f; - pGoopSys->pGoop = goop; - pGoopSys->nGoopCnt++; -} -// Goop_AddBlob - - tVector vMin,vMax; // Bounding box of the goop field - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_FindBounds -// Purpose: Find boundary of the energy meta field -///////////////////////////////////////////////////////////////////////////////////// -void Goop_FindBounds() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - tVector min = {FLT_MAX,FLT_MAX,FLT_MAX}; - tVector max = {-FLT_MAX,-FLT_MAX,-FLT_MAX}; - tMetaGoop *goop; - float radius; -///////////////////////////////////////////////////////////////////////////////////// - goop = m_GoopSys.pGoop; - for (int loop = 0; loop < m_GoopSys.nGoopCnt; loop++,goop++) - { - // Beef up radius to give me some room - radius = (float)sqrt(goop->radiusSquared) * 1.5f; - if (goop->position.x - radius < min.x) min.x = goop->position.x - radius; - if (goop->position.x + radius > max.x) max.x = goop->position.x + radius; - if (goop->position.y - radius < min.y) min.y = goop->position.y - radius; - if (goop->position.y + radius > max.y) max.y = goop->position.y + radius; - if (goop->position.z - radius < min.z) min.z = goop->position.z - radius; - if (goop->position.z + radius > max.z) max.z = goop->position.z + radius; - } - - memcpy(&m_GoopSys.vMin,&min,sizeof(tVector)); - memcpy(&m_GoopSys.vMax,&max,sizeof(tVector)); -} -// Goop_FindBounds - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_EvaluateField -// Purpose: Evaluate the energy in the meta field at a location -// Arguments: Position to test -// Returns: Field Strength -///////////////////////////////////////////////////////////////////////////////////// -float Goop_EvaluateField(tVector *pos) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - float distance, fieldStrength = 0.0f, falloff; - tMetaGoop *goop; -///////////////////////////////////////////////////////////////////////////////////// - goop = m_GoopSys.pGoop; - for (int loop = 0; loop < m_GoopSys.nGoopCnt; loop++,goop++) - { - distance = (float)VectorSquaredDistance(&goop->position, pos); - if (distance < goop->radiusSquared) - { - falloff = 1.0f - (distance / goop->radiusSquared); - fieldStrength += goop->strength * falloff * falloff; - } - } - - return(fieldStrength); -} -// Goop_EvaluateField - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_EvaluateLayer -// Purpose: Evaluate the energy in the meta field at a XZ plane -// Arguments: Pointer to layer, subdiv, and position variables -///////////////////////////////////////////////////////////////////////////////////// -void Goop_EvaluateLayer(tMetaGoopEval *field,int subDiv,float sx, float sz, float stepX, float stepZ, float y) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - tVector pos; - tMetaGoopEval *element; - int loopx, loopz; -///////////////////////////////////////////////////////////////////////////////////// - pos.y = y; - for (loopx = 0, pos.x = sx; loopx < subDiv; loopx++, pos.x += stepX) - for (loopz = 0, pos.z = sz; loopz < subDiv; loopz++, pos.z += stepZ) - { - element = &field[loopx * subDiv + loopz]; - element->value = Goop_EvaluateField(&pos); - memcpy(&element->pos,&pos,sizeof(tVector)); - } -} -// Goop_EvaluateLayer - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_CheckEdge -// Purpose: Check the Final edge to see if it crosses the meta surface -// Arguments: threshold for edge and edge vertices, collection of final points -///////////////////////////////////////////////////////////////////////////////////// -void Goop_CheckEdge(float threshold, tMetaGoopEval *a, tMetaGoopEval *b, tVector *vertex) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - tVector diff; - float ratio; -///////////////////////////////////////////////////////////////////////////////////// - VectorSubtract(&a->pos, &b->pos, &diff); - ratio = (threshold - a->value) / (b->value - a->value); - VectorMultiply(&diff, ratio); - VectorSubtract(&a->pos,&diff,vertex); -} -// - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_CheckPyramid -// Purpose: Check a Pyramid to see if it is on the edge of the meta surface -// Arguments: threshold for edge and list of cube vertices -///////////////////////////////////////////////////////////////////////////////////// -void Goop_CheckPyramid(float threshold,tMetaGoopEval **pyramid) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int inside = 0, outside = 0; - int firstIn = -1, firstOut = -1; - tVector vertex[4]; - int vCnt; -///////////////////////////////////////////////////////////////////////////////////// - // Count corners to see what is inside and outside - for (int loop = 0; loop < 4; loop++) - { - // Is it inside or outside - if (pyramid[loop]->inside) - { - inside++; - if (firstIn == -1) firstIn = loop; // Track the first - } - else - { - outside++; - if (firstOut == -1) firstOut = loop; // Track the first - } - } - // All in or all out, bail now - if (inside == 4 || outside == 4) - return; - - // TODO: Here I really need to track inside vs outside so polygons are created - // facing the right direction. This will be needed for culling and lighting - vCnt = 0; - if (pyramid[0]->inside != pyramid[1]->inside) - { - Goop_CheckEdge(threshold, pyramid[0], pyramid[1], &vertex[vCnt]); - vCnt++; - } - if (pyramid[1]->inside != pyramid[2]->inside) - { - Goop_CheckEdge(threshold, pyramid[1], pyramid[2], &vertex[vCnt]); - vCnt++; - } - if (pyramid[2]->inside != pyramid[0]->inside) - { - Goop_CheckEdge(threshold, pyramid[2], pyramid[0], &vertex[vCnt]); - vCnt++; - } - - if (pyramid[2]->inside != pyramid[3]->inside) - { - Goop_CheckEdge(threshold, pyramid[2], pyramid[3], &vertex[vCnt]); - vCnt++; - } - if (pyramid[0]->inside != pyramid[3]->inside) - { - Goop_CheckEdge(threshold, pyramid[0], pyramid[3], &vertex[vCnt]); - vCnt++; - } - if (pyramid[1]->inside != pyramid[3]->inside) - { - Goop_CheckEdge(threshold, pyramid[1], pyramid[3], &vertex[vCnt]); - vCnt++; - } - if (outside == 3 || inside == 3) - { - // TODO: Need to determine facing here. - glColor3f(1.0f, 0.0f, 0.0f); - glBegin(GL_TRIANGLES); - - glVertex3fv((float *)&vertex[0]); - glVertex3fv((float *)&vertex[1]); - glVertex3fv((float *)&vertex[2]); - glEnd(); - } - else // Handle the case with four vertices - { - // TODO: This is wrong, I think there are cases where the triangles will cross - glColor3f(1.0f, 0.0f, 0.0f); - glBegin(GL_TRIANGLES); - glVertex3fv((float *)&vertex[0]); - glVertex3fv((float *)&vertex[1]); - glVertex3fv((float *)&vertex[2]); - glVertex3fv((float *)&vertex[0]); - glVertex3fv((float *)&vertex[2]); - glVertex3fv((float *)&vertex[3]); - glEnd(); - } -} -// - - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_CheckCubeSurf -// Purpose: Check a Cube to see if it is on the edge of the meta surface -// Arguments: threshold for edge and list of cube vertices -///////////////////////////////////////////////////////////////////////////////////// -void Goop_CheckCubeSurf(float threshold,tMetaGoopEval **cube) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int inside = 0, outside = 0; - tMetaGoopEval *pyramid[4]; -///////////////////////////////////////////////////////////////////////////////////// - // Count corners to see what is inside and outside - for (int loop = 0; loop < 8; loop++) - { - // Is it inside or outside - if (cube[loop]->value > threshold) - { - cube[loop]->inside = TRUE; - inside++; - } - else - { - cube[loop]->inside = FALSE; - outside++; - } - } - // All in or all out, bail now - if (inside == 8 || outside == 8) - return; - - // Now that I know the cube is on the surface, break out pyramids - // TODO: This should be a table of vertex indices and optimize it a bit - pyramid[0] = cube[0]; pyramid[1] = cube[1]; pyramid[2] = cube[3]; pyramid[3] = cube[4]; - Goop_CheckPyramid(threshold, pyramid); - pyramid[0] = cube[1]; pyramid[1] = cube[2]; pyramid[2] = cube[3]; pyramid[3] = cube[5]; - Goop_CheckPyramid(threshold, pyramid); - pyramid[0] = cube[4]; pyramid[1] = cube[5]; pyramid[2] = cube[7]; pyramid[3] = cube[3]; - Goop_CheckPyramid(threshold, pyramid); - pyramid[0] = cube[5]; pyramid[1] = cube[6]; pyramid[2] = cube[7]; pyramid[3] = cube[2]; - Goop_CheckPyramid(threshold, pyramid); - pyramid[0] = cube[3]; pyramid[1] = cube[2]; pyramid[2] = cube[7]; pyramid[3] = cube[5]; - Goop_CheckPyramid(threshold, pyramid); - pyramid[0] = cube[1]; pyramid[1] = cube[4]; pyramid[2] = cube[5]; pyramid[3] = cube[3]; - Goop_CheckPyramid(threshold, pyramid); -} -// - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: Goop_EvaluateSurface -// Purpose: Evaluate the energy in the meta field at a XZ plane -// Arguments: edge threshold and subdivision count -///////////////////////////////////////////////////////////////////////////////////// -void Goop_EvaluateSurface(float threshold,int subDiv) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - tVector step; - float y; - tMetaGoopEval *layer[2]; // Store 2 layers - tMetaGoopEval *element[8]; -///////////////////////////////////////////////////////////////////////////////////// - - step.x = (m_GoopSys.vMax.x - m_GoopSys.vMin.x) / subDiv; - step.y = (m_GoopSys.vMax.y - m_GoopSys.vMin.y) / subDiv; - step.z = (m_GoopSys.vMax.z - m_GoopSys.vMin.z) / subDiv; - - if (step.x == 0.0f || step.y == 0.0f || step.z == 0.0f) return; - - // Allocate memory for a layers - layer[0] = (tMetaGoopEval *)malloc( subDiv * subDiv * sizeof(tMetaGoopEval)); - layer[1] = (tMetaGoopEval *)malloc( subDiv * subDiv * sizeof(tMetaGoopEval)); - - // Evaluate first XZ plane - Goop_EvaluateLayer(layer[0], subDiv, m_GoopSys.vMin.x, m_GoopSys.vMin.z, step.x, step.z, m_GoopSys.vMin.y); - - // Go through each vertical slice - for (y = m_GoopSys.vMin.y + step.y; y <= m_GoopSys.vMax.y; y += step.y) - { - // Evaluate next XZ plane - Goop_EvaluateLayer(layer[1], subDiv, m_GoopSys.vMin.x, m_GoopSys.vMin.z, step.x, step.z, y); - for (int loopx = 0; loopx < subDiv - 1; loopx++) - { - for (int loopz = 0; loopz < subDiv - 1; loopz++) - { - // Gather eight corners of cube - element[0] = &layer[0][loopx * subDiv + loopz]; - element[1] = &layer[0][(loopx + 1) * subDiv + loopz]; - element[2] = &layer[0][(loopx + 1) * subDiv + loopz + 1]; - element[3] = &layer[0][loopx * subDiv + loopz + 1]; - element[4] = &layer[1][loopx * subDiv + loopz]; - element[5] = &layer[1][(loopx + 1) * subDiv + loopz]; - element[6] = &layer[1][(loopx + 1) * subDiv + loopz + 1]; - element[7] = &layer[1][loopx * subDiv + loopz + 1]; - Goop_CheckCubeSurf(threshold,element); - } - } - - // Copy Layer for next pass - memcpy(layer[0],layer[1],subDiv * subDiv * sizeof(tMetaGoopEval)); - } -} -// Goop_EvaluateSurface - - - +/////////////////////////////////////////////////////////////////////////////// +// +// MetaGoop.cpp : implementation file +// +// Purpose: Implementation of MetaGoop +// This is the main file for the MetaGoop system. +// +// Created: +// JL 10/18/99 +// Revisions: Jan 2000 +// Lots of UI and tweaking +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include +#include "MetaGoop.h" + +tMetaGoopSys m_GoopSys; + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_InitSys +// Purpose: Initialize System +///////////////////////////////////////////////////////////////////////////////////// +tMetaGoopSys *Goop_InitSys() +{ + m_GoopSys.nGoopCnt = 0; + m_GoopSys.pGoop = NULL; + return(&m_GoopSys); +} + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_FreeSys +// Purpose: Clear System +///////////////////////////////////////////////////////////////////////////////////// +void Goop_FreeSys() +{ + if (m_GoopSys.nGoopCnt > 0) + free(m_GoopSys.pGoop); + m_GoopSys.nGoopCnt = 0; + m_GoopSys.pGoop = NULL; +} + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_AddBlob +// Purpose: Add a new blob into the system and initialize it +///////////////////////////////////////////////////////////////////////////////////// +void Goop_AddBlob(tMetaGoopSys *pGoopSys) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + tMetaGoop *goop; +///////////////////////////////////////////////////////////////////////////////////// + goop = (tMetaGoop *)malloc(sizeof(tMetaGoop) * (pGoopSys->nGoopCnt + 1)); + if (pGoopSys->nGoopCnt > 0) + { + memcpy(goop,pGoopSys->pGoop,sizeof(tMetaGoop) * pGoopSys->nGoopCnt); + free(pGoopSys->pGoop); + } + // Initialize the Blob + goop[pGoopSys->nGoopCnt].position.x = 0.0f; + goop[pGoopSys->nGoopCnt].position.y = 0.0f; + goop[pGoopSys->nGoopCnt].position.z = 0.0f; + goop[pGoopSys->nGoopCnt].radiusSquared = 4.0f; + goop[pGoopSys->nGoopCnt].strength = 4.0f; + pGoopSys->pGoop = goop; + pGoopSys->nGoopCnt++; +} +// Goop_AddBlob + + tVector vMin,vMax; // Bounding box of the goop field + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_FindBounds +// Purpose: Find boundary of the energy meta field +///////////////////////////////////////////////////////////////////////////////////// +void Goop_FindBounds() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + tVector min = {FLT_MAX,FLT_MAX,FLT_MAX}; + tVector max = {-FLT_MAX,-FLT_MAX,-FLT_MAX}; + tMetaGoop *goop; + float radius; +///////////////////////////////////////////////////////////////////////////////////// + goop = m_GoopSys.pGoop; + for (int loop = 0; loop < m_GoopSys.nGoopCnt; loop++,goop++) + { + // Beef up radius to give me some room + radius = (float)sqrt(goop->radiusSquared) * 1.5f; + if (goop->position.x - radius < min.x) min.x = goop->position.x - radius; + if (goop->position.x + radius > max.x) max.x = goop->position.x + radius; + if (goop->position.y - radius < min.y) min.y = goop->position.y - radius; + if (goop->position.y + radius > max.y) max.y = goop->position.y + radius; + if (goop->position.z - radius < min.z) min.z = goop->position.z - radius; + if (goop->position.z + radius > max.z) max.z = goop->position.z + radius; + } + + memcpy(&m_GoopSys.vMin,&min,sizeof(tVector)); + memcpy(&m_GoopSys.vMax,&max,sizeof(tVector)); +} +// Goop_FindBounds + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_EvaluateField +// Purpose: Evaluate the energy in the meta field at a location +// Arguments: Position to test +// Returns: Field Strength +///////////////////////////////////////////////////////////////////////////////////// +float Goop_EvaluateField(tVector *pos) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + float distance, fieldStrength = 0.0f, falloff; + tMetaGoop *goop; +///////////////////////////////////////////////////////////////////////////////////// + goop = m_GoopSys.pGoop; + for (int loop = 0; loop < m_GoopSys.nGoopCnt; loop++,goop++) + { + distance = (float)VectorSquaredDistance(&goop->position, pos); + if (distance < goop->radiusSquared) + { + falloff = 1.0f - (distance / goop->radiusSquared); + fieldStrength += goop->strength * falloff * falloff; + } + } + + return(fieldStrength); +} +// Goop_EvaluateField + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_EvaluateLayer +// Purpose: Evaluate the energy in the meta field at a XZ plane +// Arguments: Pointer to layer, subdiv, and position variables +///////////////////////////////////////////////////////////////////////////////////// +void Goop_EvaluateLayer(tMetaGoopEval *field,int subDiv,float sx, float sz, float stepX, float stepZ, float y) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + tVector pos; + tMetaGoopEval *element; + int loopx, loopz; +///////////////////////////////////////////////////////////////////////////////////// + pos.y = y; + for (loopx = 0, pos.x = sx; loopx < subDiv; loopx++, pos.x += stepX) + for (loopz = 0, pos.z = sz; loopz < subDiv; loopz++, pos.z += stepZ) + { + element = &field[loopx * subDiv + loopz]; + element->value = Goop_EvaluateField(&pos); + memcpy(&element->pos,&pos,sizeof(tVector)); + } +} +// Goop_EvaluateLayer + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_CheckEdge +// Purpose: Check the Final edge to see if it crosses the meta surface +// Arguments: threshold for edge and edge vertices, collection of final points +///////////////////////////////////////////////////////////////////////////////////// +void Goop_CheckEdge(float threshold, tMetaGoopEval *a, tMetaGoopEval *b, tVector *vertex) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + tVector diff; + float ratio; +///////////////////////////////////////////////////////////////////////////////////// + VectorSubtract(&a->pos, &b->pos, &diff); + ratio = (threshold - a->value) / (b->value - a->value); + VectorMultiply(&diff, ratio); + VectorSubtract(&a->pos,&diff,vertex); +} +// + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_CheckPyramid +// Purpose: Check a Pyramid to see if it is on the edge of the meta surface +// Arguments: threshold for edge and list of cube vertices +///////////////////////////////////////////////////////////////////////////////////// +void Goop_CheckPyramid(float threshold,tMetaGoopEval **pyramid) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int inside = 0, outside = 0; + int firstIn = -1, firstOut = -1; + tVector vertex[4]; + int vCnt; +///////////////////////////////////////////////////////////////////////////////////// + // Count corners to see what is inside and outside + for (int loop = 0; loop < 4; loop++) + { + // Is it inside or outside + if (pyramid[loop]->inside) + { + inside++; + if (firstIn == -1) firstIn = loop; // Track the first + } + else + { + outside++; + if (firstOut == -1) firstOut = loop; // Track the first + } + } + // All in or all out, bail now + if (inside == 4 || outside == 4) + return; + + // TODO: Here I really need to track inside vs outside so polygons are created + // facing the right direction. This will be needed for culling and lighting + vCnt = 0; + if (pyramid[0]->inside != pyramid[1]->inside) + { + Goop_CheckEdge(threshold, pyramid[0], pyramid[1], &vertex[vCnt]); + vCnt++; + } + if (pyramid[1]->inside != pyramid[2]->inside) + { + Goop_CheckEdge(threshold, pyramid[1], pyramid[2], &vertex[vCnt]); + vCnt++; + } + if (pyramid[2]->inside != pyramid[0]->inside) + { + Goop_CheckEdge(threshold, pyramid[2], pyramid[0], &vertex[vCnt]); + vCnt++; + } + + if (pyramid[2]->inside != pyramid[3]->inside) + { + Goop_CheckEdge(threshold, pyramid[2], pyramid[3], &vertex[vCnt]); + vCnt++; + } + if (pyramid[0]->inside != pyramid[3]->inside) + { + Goop_CheckEdge(threshold, pyramid[0], pyramid[3], &vertex[vCnt]); + vCnt++; + } + if (pyramid[1]->inside != pyramid[3]->inside) + { + Goop_CheckEdge(threshold, pyramid[1], pyramid[3], &vertex[vCnt]); + vCnt++; + } + if (outside == 3 || inside == 3) + { + // TODO: Need to determine facing here. + glColor3f(1.0f, 0.0f, 0.0f); + glBegin(GL_TRIANGLES); + + glVertex3fv((float *)&vertex[0]); + glVertex3fv((float *)&vertex[1]); + glVertex3fv((float *)&vertex[2]); + glEnd(); + } + else // Handle the case with four vertices + { + // TODO: This is wrong, I think there are cases where the triangles will cross + glColor3f(1.0f, 0.0f, 0.0f); + glBegin(GL_TRIANGLES); + glVertex3fv((float *)&vertex[0]); + glVertex3fv((float *)&vertex[1]); + glVertex3fv((float *)&vertex[2]); + glVertex3fv((float *)&vertex[0]); + glVertex3fv((float *)&vertex[2]); + glVertex3fv((float *)&vertex[3]); + glEnd(); + } +} +// + + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_CheckCubeSurf +// Purpose: Check a Cube to see if it is on the edge of the meta surface +// Arguments: threshold for edge and list of cube vertices +///////////////////////////////////////////////////////////////////////////////////// +void Goop_CheckCubeSurf(float threshold,tMetaGoopEval **cube) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int inside = 0, outside = 0; + tMetaGoopEval *pyramid[4]; +///////////////////////////////////////////////////////////////////////////////////// + // Count corners to see what is inside and outside + for (int loop = 0; loop < 8; loop++) + { + // Is it inside or outside + if (cube[loop]->value > threshold) + { + cube[loop]->inside = TRUE; + inside++; + } + else + { + cube[loop]->inside = FALSE; + outside++; + } + } + // All in or all out, bail now + if (inside == 8 || outside == 8) + return; + + // Now that I know the cube is on the surface, break out pyramids + // TODO: This should be a table of vertex indices and optimize it a bit + pyramid[0] = cube[0]; pyramid[1] = cube[1]; pyramid[2] = cube[3]; pyramid[3] = cube[4]; + Goop_CheckPyramid(threshold, pyramid); + pyramid[0] = cube[1]; pyramid[1] = cube[2]; pyramid[2] = cube[3]; pyramid[3] = cube[5]; + Goop_CheckPyramid(threshold, pyramid); + pyramid[0] = cube[4]; pyramid[1] = cube[5]; pyramid[2] = cube[7]; pyramid[3] = cube[3]; + Goop_CheckPyramid(threshold, pyramid); + pyramid[0] = cube[5]; pyramid[1] = cube[6]; pyramid[2] = cube[7]; pyramid[3] = cube[2]; + Goop_CheckPyramid(threshold, pyramid); + pyramid[0] = cube[3]; pyramid[1] = cube[2]; pyramid[2] = cube[7]; pyramid[3] = cube[5]; + Goop_CheckPyramid(threshold, pyramid); + pyramid[0] = cube[1]; pyramid[1] = cube[4]; pyramid[2] = cube[5]; pyramid[3] = cube[3]; + Goop_CheckPyramid(threshold, pyramid); +} +// + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: Goop_EvaluateSurface +// Purpose: Evaluate the energy in the meta field at a XZ plane +// Arguments: edge threshold and subdivision count +///////////////////////////////////////////////////////////////////////////////////// +void Goop_EvaluateSurface(float threshold,int subDiv) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + tVector step; + float y; + tMetaGoopEval *layer[2]; // Store 2 layers + tMetaGoopEval *element[8]; +///////////////////////////////////////////////////////////////////////////////////// + + step.x = (m_GoopSys.vMax.x - m_GoopSys.vMin.x) / subDiv; + step.y = (m_GoopSys.vMax.y - m_GoopSys.vMin.y) / subDiv; + step.z = (m_GoopSys.vMax.z - m_GoopSys.vMin.z) / subDiv; + + if (step.x == 0.0f || step.y == 0.0f || step.z == 0.0f) return; + + // Allocate memory for a layers + layer[0] = (tMetaGoopEval *)malloc( subDiv * subDiv * sizeof(tMetaGoopEval)); + layer[1] = (tMetaGoopEval *)malloc( subDiv * subDiv * sizeof(tMetaGoopEval)); + + // Evaluate first XZ plane + Goop_EvaluateLayer(layer[0], subDiv, m_GoopSys.vMin.x, m_GoopSys.vMin.z, step.x, step.z, m_GoopSys.vMin.y); + + // Go through each vertical slice + for (y = m_GoopSys.vMin.y + step.y; y <= m_GoopSys.vMax.y; y += step.y) + { + // Evaluate next XZ plane + Goop_EvaluateLayer(layer[1], subDiv, m_GoopSys.vMin.x, m_GoopSys.vMin.z, step.x, step.z, y); + for (int loopx = 0; loopx < subDiv - 1; loopx++) + { + for (int loopz = 0; loopz < subDiv - 1; loopz++) + { + // Gather eight corners of cube + element[0] = &layer[0][loopx * subDiv + loopz]; + element[1] = &layer[0][(loopx + 1) * subDiv + loopz]; + element[2] = &layer[0][(loopx + 1) * subDiv + loopz + 1]; + element[3] = &layer[0][loopx * subDiv + loopz + 1]; + element[4] = &layer[1][loopx * subDiv + loopz]; + element[5] = &layer[1][(loopx + 1) * subDiv + loopz]; + element[6] = &layer[1][(loopx + 1) * subDiv + loopz + 1]; + element[7] = &layer[1][loopx * subDiv + loopz + 1]; + Goop_CheckCubeSurf(threshold,element); + } + } + + // Copy Layer for next pass + memcpy(layer[0],layer[1],subDiv * subDiv * sizeof(tMetaGoopEval)); + } +} +// Goop_EvaluateSurface + + + diff --git a/Blob Modeling/Code/OGL/Blobby/MetaGoop.h b/Blob Modeling/Code/OGL/Blobby/MetaGoop.h index d1d564c..e5bdbdf 100644 --- a/Blob Modeling/Code/OGL/Blobby/MetaGoop.h +++ b/Blob Modeling/Code/OGL/Blobby/MetaGoop.h @@ -1,56 +1,56 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MetaGoop.h : implementation file -// -// Purpose: Implementation of Blob routines -// -// Created: -// JL 10/18/99 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(METAGOOP_H__INCLUDED_) -#define METAGOOP_H__INCLUDED_ - -#include "MathDefs.h" - -// The metagoop structure. It is pretty simple. This could be modified -// in a number of ways for example you could create non-sphere blobs via -// scaling and rotation. -typedef struct -{ - tVector position; // Where is the blob - float radiusSquared; // Size of blob - float strength; // Amount of influence -} tMetaGoop; - -typedef struct -{ - tMetaGoop *pGoop; // Where is the Goop - int nGoopCnt; - tVector vMin,vMax; // Bounding box of the goop field -} tMetaGoopSys; - -typedef struct -{ - float value; // Evaluated field value - tVector pos; // Position in the Field - BOOL inside; // Is it in or out of the threshold -} tMetaGoopEval; - -tMetaGoopSys *Goop_InitSys(); -void Goop_FreeSys(); -void Goop_AddBlob(tMetaGoopSys *pGoopSys); -float Goop_EvaluateField(tVector *pos); -void Goop_FindBounds(); -void Goop_EvaluateLayer(tMetaGoopEval *field,int subDiv,float sx, float sz, float stepX, float stepZ, float y); -void Goop_EvaluateSurface(float threshold,int subDiv); -#endif // !defined(METAGOOP_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MetaGoop.h : implementation file +// +// Purpose: Implementation of Blob routines +// +// Created: +// JL 10/18/99 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(METAGOOP_H__INCLUDED_) +#define METAGOOP_H__INCLUDED_ + +#include "MathDefs.h" + +// The metagoop structure. It is pretty simple. This could be modified +// in a number of ways for example you could create non-sphere blobs via +// scaling and rotation. +typedef struct +{ + tVector position; // Where is the blob + float radiusSquared; // Size of blob + float strength; // Amount of influence +} tMetaGoop; + +typedef struct +{ + tMetaGoop *pGoop; // Where is the Goop + int nGoopCnt; + tVector vMin,vMax; // Bounding box of the goop field +} tMetaGoopSys; + +typedef struct +{ + float value; // Evaluated field value + tVector pos; // Position in the Field + BOOL inside; // Is it in or out of the threshold +} tMetaGoopEval; + +tMetaGoopSys *Goop_InitSys(); +void Goop_FreeSys(); +void Goop_AddBlob(tMetaGoopSys *pGoopSys); +float Goop_EvaluateField(tVector *pos); +void Goop_FindBounds(); +void Goop_EvaluateLayer(tMetaGoopEval *field,int subDiv,float sx, float sz, float stepX, float stepZ, float y); +void Goop_EvaluateSurface(float threshold,int subDiv); +#endif // !defined(METAGOOP_H__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/OGLView.cpp b/Blob Modeling/Code/OGL/Blobby/OGLView.cpp index 6156eb4..186f496 100644 --- a/Blob Modeling/Code/OGL/Blobby/OGLView.cpp +++ b/Blob Modeling/Code/OGL/Blobby/OGLView.cpp @@ -1,767 +1,767 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of 3D Blob Modelling -// -// Created: -// JL 10/1/99 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Blobby.h" -#include "OGLView.h" -#include "Math.h" -#include "EditBlob.h" -#include "EditSys.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define OGL_ICON_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION - -#define LERP(a,b,c) (a + ((b - a) * c)) -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - m_CameraRot.x = m_CameraRot.y = m_CameraRot.z = 0.0f; - m_CameraTrans.x = m_CameraTrans.y = 0.0f; - m_CameraTrans.z = -80.0f; - - m_pGoopSys = Goop_InitSys(); // Initialize the Blob system - m_pCurBlob = NULL; - - m_DrawGeometry = TRUE; - m_DrawBlobs = TRUE; - m_DrawField = FALSE; - - m_Subdivisions = 25; // How fine to divide the goop field - m_Threshold = 0.7f; // Surface Threshold -} - -COGLView::~COGLView() -{ - Goop_FreeSys(); -} - - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glNewList(OGL_ICON_DLIST,GL_COMPILE); - glBegin(GL_TRIANGLES); - glVertex3f(0.0000f, -0.5000f, 0.0000f); - glVertex3f(0.5000f, 0.0000f, 0.0000f); - glVertex3f(0.0000f, 0.0000f, 0.5000f); - glVertex3f(-0.5000f, 0.0000f, -0.0000f); - glVertex3f(0.0000f, 0.5000f, 0.0000f); - glVertex3f(0.0000f, 0.0000f, -0.5000f); - glVertex3f(0.5000f, 0.0000f, 0.0000f); - glVertex3f(0.0000f, -0.5000f, 0.0000f); - glVertex3f(0.0000f, 0.0000f, -0.5000f); - glVertex3f(0.0000f, 0.0000f, 0.5000f); - glVertex3f(-0.5000f, 0.0000f, -0.0000f); - glVertex3f(0.0000f, -0.5000f, 0.0000f); - glVertex3f(0.0000f, 0.0000f, -0.5000f); - glVertex3f(0.0000f, -0.5000f, 0.0000f); - glVertex3f(-0.5000f, 0.0000f, -0.0000f); - glVertex3f(0.0000f, 0.0000f, -0.5000f); - glVertex3f(0.0000f, 0.5000f, 0.0000f); - glVertex3f(0.5000f, 0.0000f, 0.0000f); - glVertex3f(0.0000f, 0.5000f, 0.0000f); - glVertex3f(0.0000f, 0.0000f, 0.5000f); - glVertex3f(0.5000f, 0.0000f, 0.0000f); - glVertex3f(0.0000f, 0.5000f, 0.0000f); - glVertex3f(-0.5000f, 0.0000f, -0.0000f); - glVertex3f(0.0000f, 0.0000f, 0.5000f); - glEnd(); - glEndList(); - - glDisable(GL_TEXTURE_2D); - - DrawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - m_Aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, m_Aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 - GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - m_Aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, m_Aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP -// glPolygonMode(GL_FRONT,GL_FILL); - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - glLineWidth(1.0f); - glPointSize(2.0f); // JUST 1 PIXEL DOTS FOR NOW - glDisable(GL_LINE_SMOOTH); - glDepthFunc(GL_LEQUAL); - glDisable(GL_CULL_FACE); - - glShadeModel(GL_SMOOTH); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); - glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); - glMaterialfv(GL_FRONT,GL_SPECULAR, specular); - glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 - glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glDisable(GL_LIGHTING); - glEnable(GL_LIGHT0); - -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: DrawField -// Purpose: Draws the meta field cool to visualize -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DrawField() -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector pos; - tVector step; - tMetaGoopEval *field,*element; - int loopx,loopz; -/////////////////////////////////////////////////////////////////////////////// - step.x = (m_pGoopSys->vMax.x - m_pGoopSys->vMin.x) / m_Subdivisions; - step.y = (m_pGoopSys->vMax.y - m_pGoopSys->vMin.y) / m_Subdivisions; - step.z = (m_pGoopSys->vMax.z - m_pGoopSys->vMin.z) / m_Subdivisions; - - if (step.x == 0.0f || step.y == 0.0f || step.z == 0.0f) return; - - glBegin(GL_POINTS); - - // Allocate memory for a layer - field = (tMetaGoopEval *)calloc( m_Subdivisions * m_Subdivisions, sizeof(tMetaGoopEval)); - element = field; - - // Go through each vertical slice - for (pos.y = m_pGoopSys->vMin.y; pos.y <= m_pGoopSys->vMax.y; pos.y += step.y) - { - // Evaluate one XZ plane - Goop_EvaluateLayer(field, m_Subdivisions,m_pGoopSys->vMin.x, m_pGoopSys->vMin.z, step.x, step.z, pos.y); - for (loopx = 0, pos.x = m_pGoopSys->vMin.x; loopx < m_Subdivisions; loopx++, pos.x += step.x) - for (loopz = 0, pos.z = m_pGoopSys->vMin.z; loopz < m_Subdivisions; loopz++, pos.z += step.z) - { - element = &field[loopx * m_Subdivisions + loopz]; - // Color each point based on the test threshold - if (element->value < m_Threshold) - { - glColor3f((element->value / m_Threshold),(element->value / m_Threshold), 0.0f); //Yellow - } - else - glColor3f(0.0f, (m_Threshold / element->value), 0.0f); // Green - if (fabs(element->value - m_Threshold) < 0.2f) // Points right on the edge, color red - glColor3f(1.0f, 0.0f, 0.0f); - glVertex3f(pos.x, pos.y, pos.z); - } - } - glEnd(); - -// free(field); // THIS SHOULD WORK BUT CRASHES ON MY SYS. DAMN VC PASSING POINTERS -} -// DrawField - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: DrawSurface -// Purpose: Draws the model associated with a energy field -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DrawSurface() -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - Goop_EvaluateSurface(m_Threshold,m_Subdivisions); -} -// DrawSurface - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: DrawBlobs -// Purpose: Draws the elements of the blob system -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DrawBlobs(BOOL selecting) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tMetaGoop *pGoop; -/////////////////////////////////////////////////////////////////////////////// - pGoop = m_pGoopSys->pGoop; - for (int loop = 0; loop < m_pGoopSys->nGoopCnt; loop++, pGoop++) - { - glPushMatrix(); - - // Set the blobs position - glTranslatef(pGoop->position.x, pGoop->position.y, pGoop->position.z); - - if (pGoop == m_pCurBlob) // Is it selected - glColor3f(1.0f, 1.0f, 0.0f); //Yellow - else - glColor3f(0.0f, 0.0f, 1.0f); // Blue - - glScalef(pGoop->radiusSquared,pGoop->radiusSquared,pGoop->radiusSquared); - - if (selecting) glLoadName(loop); // Mark the Blobs for Picking - - glCallList(OGL_ICON_DLIST); - - glPopMatrix(); - } -} -// DrawBlobs - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: DrawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DrawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_CameraTrans.x, m_CameraTrans.y, m_CameraTrans.z); - - // ROTATE THE ROOT - glRotatef(m_CameraRot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_CameraRot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_CameraRot.x, 0.0f, 0.0f, 1.0f); - - if (m_DrawBlobs) - DrawBlobs(FALSE); - - if (m_DrawField) - DrawField(); - - if (m_DrawGeometry) - DrawSurface(); - - glPopMatrix(); - - glFinish(); - - SwapBuffers(m_hDC); -} -// drawScene - -#define BUFSIZE 512 - -GLvoid COGLView::SelectScene(int x, int y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLuint selectbuf[BUFSIZE]; - GLint hits; - GLint viewport[4]; -/////////////////////////////////////////////////////////////////////////////// - - glGetIntegerv(GL_VIEWPORT,viewport); - glSelectBuffer(BUFSIZE,selectbuf); - glRenderMode(GL_SELECT); - glInitNames(); - glPushName(0); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3] - y), 5.0, 5.0, viewport); - gluPerspective(10.0f, m_Aspect,1.0f, 2000.0f); - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_CameraTrans.x, m_CameraTrans.y, m_CameraTrans.z); - - // ROTATE THE ROOT - glRotatef(m_CameraRot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_CameraRot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_CameraRot.x, 0.0f, 0.0f, 1.0f); - - DrawBlobs(TRUE); - - glPopMatrix(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - - glFlush(); - - hits = glRenderMode(GL_RENDER); - ProcessSelection(hits, selectbuf); - -} - -void COGLView::ProcessSelection(GLint hits, GLuint buffer[]) -{ - int i; - unsigned int j; - GLuint names, *ptr,item; - float z1,z2,nearest = 99999.0f; - - ptr = (GLuint *)buffer; - for (i = 0; i < hits; i++) - { - names = *ptr; - ptr++; - z1 = (float)*ptr/0x7fffffff; ptr++; - z2 = (float)*ptr/0x7fffffff; ptr++; - for (j = 0; j < names; j++) - { - item = *ptr; - ptr++; - - if (z1 < nearest) - { - m_pCurBlob = &m_pGoopSys->pGoop[item]; - nearest = z1; - } - } - - } - if (nearest == 99999.0f) // NOTHING HIT SET TO NOTHING - m_pCurBlob = NULL; -} - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - DrawScene(); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - - // Pick a blob to move or manipulate - SelectScene(point.x,point.y); - - m_Base_Rot_X = m_CameraRot.x; - m_Base_Rot_Y = m_CameraRot.y; - m_Base_Rot_Z = m_CameraRot.z; - if (m_pCurBlob != NULL) - { - m_Grab_Trans_X = m_pCurBlob->position.x; - m_Grab_Trans_Y = m_pCurBlob->position.y; - m_Grab_Trans_Z = m_pCurBlob->position.z; - } - DrawScene(); - CWnd::OnLButtonDown(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_CameraRot.x; - m_Base_Rot_Y = m_CameraRot.y; - m_Base_Rot_Z = m_CameraRot.z; - if (m_pCurBlob != NULL) - { - m_Grab_Trans_X = m_pCurBlob->position.x; - m_Grab_Trans_Y = m_pCurBlob->position.y; - m_Grab_Trans_Z = m_pCurBlob->position.z; - } - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case 'G': - m_DrawGeometry = !m_DrawGeometry; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - break; - case 'F': - m_DrawField = !m_DrawField; -// glPolygonMode(GL_FRONT,GL_FILL); - break; - case ' ': - break; - } - DrawScene(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - float sinAngle,cosAngle; - sinAngle = (float)sin(DEGTORAD(m_CameraRot.y)); - cosAngle = (float)cos(DEGTORAD(m_CameraRot.y)); - if (nFlags & MK_LBUTTON > 0) - { - if ((nFlags & MK_CONTROL) > 0) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - } - else - { - if (m_pCurBlob) - { - m_pCurBlob->position.x = m_Grab_Trans_X + ((float)(point.x - m_mousepos.x) * 0.028f * cosAngle); - m_pCurBlob->position.z = m_Grab_Trans_Z + ((float)(point.x - m_mousepos.x) * 0.028f * sinAngle); - m_pCurBlob->position.y = m_Grab_Trans_Y - ((float)(point.y - m_mousepos.y) * 0.028f); - Goop_FindBounds(); - DrawScene(); - } - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - } - else - { - m_CameraRot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - m_CameraRot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - DrawScene(); - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Current Blob -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - EditBlob(); -} - -void COGLView::EditBlob() -{ -/// Local Variables /////////////////////////////////////////////////////////// - CEditBlob dialog; -/////////////////////////////////////////////////////////////////////////////// - if (m_pCurBlob) - { - dialog.m_RadiusSquared = m_pCurBlob->radiusSquared; - dialog.m_Strength = m_pCurBlob->strength; - if (dialog.DoModal()) - { - m_pCurBlob->radiusSquared = dialog.m_RadiusSquared; - m_pCurBlob->strength = dialog.m_Strength; - DrawScene(); - } - } -} - -void COGLView::EditSys() -{ -/// Local Variables /////////////////////////////////////////////////////////// - CEditSys dialog; -/////////////////////////////////////////////////////////////////////////////// - dialog.m_SubDiv = m_Subdivisions; - dialog.m_Threshold = m_Threshold; - if (dialog.DoModal()) - { - m_Subdivisions = dialog.m_SubDiv; - m_Threshold = dialog.m_Threshold; - DrawScene(); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadFiles -// Purpose: Loads the Blob files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadFile(CString file1,CString baseName) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; - int loop,cnt; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen((LPCSTR)file1,"rb"); - if (fp) - { - Goop_FreeSys(); - fread(&m_Subdivisions, sizeof(int),1,fp); - fread(&m_Threshold, sizeof(int),1,fp); - fread(&cnt,sizeof(int),1,fp); - for (loop = 0; loop < cnt; loop++) - { - Goop_AddBlob(m_pGoopSys); - m_pCurBlob = &m_pGoopSys->pGoop[m_pGoopSys->nGoopCnt - 1]; - fread(&m_pCurBlob->position, sizeof(tVector),1,fp); - fread(&m_pCurBlob->radiusSquared, sizeof(float),1,fp); - fread(&m_pCurBlob->strength, sizeof(float),1,fp); - } - Goop_FindBounds(); - DrawScene(); - m_pCurBlob = NULL; - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: SaveFiles -// Purpose: Saves the Blob files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SaveFile(CString file1,CString baseName) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; - int loop; - tMetaGoop *pGoop; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen((LPCSTR)file1,"wb"); - if (fp) - { - fwrite(&m_Subdivisions, sizeof(int),1,fp); - fwrite(&m_Threshold, sizeof(int),1,fp); - fwrite(&m_pGoopSys->nGoopCnt,sizeof(int),1,fp); - pGoop = m_pGoopSys->pGoop; - for (loop = 0; loop < m_pGoopSys->nGoopCnt; loop++, pGoop++) - { - fwrite(&pGoop->position, sizeof(tVector),1,fp); - fwrite(&pGoop->radiusSquared, sizeof(float),1,fp); - fwrite(&pGoop->strength, sizeof(float),1,fp); - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnGoopAddblob -// Purpose: Add a blob to the system -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnGoopAddblob() -{ - Goop_AddBlob(m_pGoopSys); - m_pCurBlob = &m_pGoopSys->pGoop[m_pGoopSys->nGoopCnt - 1]; - Goop_FindBounds(); - DrawScene(); -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of 3D Blob Modelling +// +// Created: +// JL 10/1/99 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Blobby.h" +#include "OGLView.h" +#include "Math.h" +#include "EditBlob.h" +#include "EditSys.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define OGL_ICON_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION + +#define LERP(a,b,c) (a + ((b - a) * c)) +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + m_CameraRot.x = m_CameraRot.y = m_CameraRot.z = 0.0f; + m_CameraTrans.x = m_CameraTrans.y = 0.0f; + m_CameraTrans.z = -80.0f; + + m_pGoopSys = Goop_InitSys(); // Initialize the Blob system + m_pCurBlob = NULL; + + m_DrawGeometry = TRUE; + m_DrawBlobs = TRUE; + m_DrawField = FALSE; + + m_Subdivisions = 25; // How fine to divide the goop field + m_Threshold = 0.7f; // Surface Threshold +} + +COGLView::~COGLView() +{ + Goop_FreeSys(); +} + + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glNewList(OGL_ICON_DLIST,GL_COMPILE); + glBegin(GL_TRIANGLES); + glVertex3f(0.0000f, -0.5000f, 0.0000f); + glVertex3f(0.5000f, 0.0000f, 0.0000f); + glVertex3f(0.0000f, 0.0000f, 0.5000f); + glVertex3f(-0.5000f, 0.0000f, -0.0000f); + glVertex3f(0.0000f, 0.5000f, 0.0000f); + glVertex3f(0.0000f, 0.0000f, -0.5000f); + glVertex3f(0.5000f, 0.0000f, 0.0000f); + glVertex3f(0.0000f, -0.5000f, 0.0000f); + glVertex3f(0.0000f, 0.0000f, -0.5000f); + glVertex3f(0.0000f, 0.0000f, 0.5000f); + glVertex3f(-0.5000f, 0.0000f, -0.0000f); + glVertex3f(0.0000f, -0.5000f, 0.0000f); + glVertex3f(0.0000f, 0.0000f, -0.5000f); + glVertex3f(0.0000f, -0.5000f, 0.0000f); + glVertex3f(-0.5000f, 0.0000f, -0.0000f); + glVertex3f(0.0000f, 0.0000f, -0.5000f); + glVertex3f(0.0000f, 0.5000f, 0.0000f); + glVertex3f(0.5000f, 0.0000f, 0.0000f); + glVertex3f(0.0000f, 0.5000f, 0.0000f); + glVertex3f(0.0000f, 0.0000f, 0.5000f); + glVertex3f(0.5000f, 0.0000f, 0.0000f); + glVertex3f(0.0000f, 0.5000f, 0.0000f); + glVertex3f(-0.5000f, 0.0000f, -0.0000f); + glVertex3f(0.0000f, 0.0000f, 0.5000f); + glEnd(); + glEndList(); + + glDisable(GL_TEXTURE_2D); + + DrawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + m_Aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, m_Aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 + GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + m_Aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, m_Aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP +// glPolygonMode(GL_FRONT,GL_FILL); + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glLineWidth(1.0f); + glPointSize(2.0f); // JUST 1 PIXEL DOTS FOR NOW + glDisable(GL_LINE_SMOOTH); + glDepthFunc(GL_LEQUAL); + glDisable(GL_CULL_FACE); + + glShadeModel(GL_SMOOTH); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); + glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT,GL_SPECULAR, specular); + glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_LIGHTING); + glEnable(GL_LIGHT0); + +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: DrawField +// Purpose: Draws the meta field cool to visualize +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DrawField() +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector pos; + tVector step; + tMetaGoopEval *field,*element; + int loopx,loopz; +/////////////////////////////////////////////////////////////////////////////// + step.x = (m_pGoopSys->vMax.x - m_pGoopSys->vMin.x) / m_Subdivisions; + step.y = (m_pGoopSys->vMax.y - m_pGoopSys->vMin.y) / m_Subdivisions; + step.z = (m_pGoopSys->vMax.z - m_pGoopSys->vMin.z) / m_Subdivisions; + + if (step.x == 0.0f || step.y == 0.0f || step.z == 0.0f) return; + + glBegin(GL_POINTS); + + // Allocate memory for a layer + field = (tMetaGoopEval *)calloc( m_Subdivisions * m_Subdivisions, sizeof(tMetaGoopEval)); + element = field; + + // Go through each vertical slice + for (pos.y = m_pGoopSys->vMin.y; pos.y <= m_pGoopSys->vMax.y; pos.y += step.y) + { + // Evaluate one XZ plane + Goop_EvaluateLayer(field, m_Subdivisions,m_pGoopSys->vMin.x, m_pGoopSys->vMin.z, step.x, step.z, pos.y); + for (loopx = 0, pos.x = m_pGoopSys->vMin.x; loopx < m_Subdivisions; loopx++, pos.x += step.x) + for (loopz = 0, pos.z = m_pGoopSys->vMin.z; loopz < m_Subdivisions; loopz++, pos.z += step.z) + { + element = &field[loopx * m_Subdivisions + loopz]; + // Color each point based on the test threshold + if (element->value < m_Threshold) + { + glColor3f((element->value / m_Threshold),(element->value / m_Threshold), 0.0f); //Yellow + } + else + glColor3f(0.0f, (m_Threshold / element->value), 0.0f); // Green + if (fabs(element->value - m_Threshold) < 0.2f) // Points right on the edge, color red + glColor3f(1.0f, 0.0f, 0.0f); + glVertex3f(pos.x, pos.y, pos.z); + } + } + glEnd(); + +// free(field); // THIS SHOULD WORK BUT CRASHES ON MY SYS. DAMN VC PASSING POINTERS +} +// DrawField + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: DrawSurface +// Purpose: Draws the model associated with a energy field +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DrawSurface() +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + Goop_EvaluateSurface(m_Threshold,m_Subdivisions); +} +// DrawSurface + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: DrawBlobs +// Purpose: Draws the elements of the blob system +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DrawBlobs(BOOL selecting) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tMetaGoop *pGoop; +/////////////////////////////////////////////////////////////////////////////// + pGoop = m_pGoopSys->pGoop; + for (int loop = 0; loop < m_pGoopSys->nGoopCnt; loop++, pGoop++) + { + glPushMatrix(); + + // Set the blobs position + glTranslatef(pGoop->position.x, pGoop->position.y, pGoop->position.z); + + if (pGoop == m_pCurBlob) // Is it selected + glColor3f(1.0f, 1.0f, 0.0f); //Yellow + else + glColor3f(0.0f, 0.0f, 1.0f); // Blue + + glScalef(pGoop->radiusSquared,pGoop->radiusSquared,pGoop->radiusSquared); + + if (selecting) glLoadName(loop); // Mark the Blobs for Picking + + glCallList(OGL_ICON_DLIST); + + glPopMatrix(); + } +} +// DrawBlobs + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: DrawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DrawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_CameraTrans.x, m_CameraTrans.y, m_CameraTrans.z); + + // ROTATE THE ROOT + glRotatef(m_CameraRot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_CameraRot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_CameraRot.x, 0.0f, 0.0f, 1.0f); + + if (m_DrawBlobs) + DrawBlobs(FALSE); + + if (m_DrawField) + DrawField(); + + if (m_DrawGeometry) + DrawSurface(); + + glPopMatrix(); + + glFinish(); + + SwapBuffers(m_hDC); +} +// drawScene + +#define BUFSIZE 512 + +GLvoid COGLView::SelectScene(int x, int y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLuint selectbuf[BUFSIZE]; + GLint hits; + GLint viewport[4]; +/////////////////////////////////////////////////////////////////////////////// + + glGetIntegerv(GL_VIEWPORT,viewport); + glSelectBuffer(BUFSIZE,selectbuf); + glRenderMode(GL_SELECT); + glInitNames(); + glPushName(0); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3] - y), 5.0, 5.0, viewport); + gluPerspective(10.0f, m_Aspect,1.0f, 2000.0f); + glMatrixMode(GL_MODELVIEW); + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_CameraTrans.x, m_CameraTrans.y, m_CameraTrans.z); + + // ROTATE THE ROOT + glRotatef(m_CameraRot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_CameraRot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_CameraRot.x, 0.0f, 0.0f, 1.0f); + + DrawBlobs(TRUE); + + glPopMatrix(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glFlush(); + + hits = glRenderMode(GL_RENDER); + ProcessSelection(hits, selectbuf); + +} + +void COGLView::ProcessSelection(GLint hits, GLuint buffer[]) +{ + int i; + unsigned int j; + GLuint names, *ptr,item; + float z1,z2,nearest = 99999.0f; + + ptr = (GLuint *)buffer; + for (i = 0; i < hits; i++) + { + names = *ptr; + ptr++; + z1 = (float)*ptr/0x7fffffff; ptr++; + z2 = (float)*ptr/0x7fffffff; ptr++; + for (j = 0; j < names; j++) + { + item = *ptr; + ptr++; + + if (z1 < nearest) + { + m_pCurBlob = &m_pGoopSys->pGoop[item]; + nearest = z1; + } + } + + } + if (nearest == 99999.0f) // NOTHING HIT SET TO NOTHING + m_pCurBlob = NULL; +} + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + DrawScene(); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + + // Pick a blob to move or manipulate + SelectScene(point.x,point.y); + + m_Base_Rot_X = m_CameraRot.x; + m_Base_Rot_Y = m_CameraRot.y; + m_Base_Rot_Z = m_CameraRot.z; + if (m_pCurBlob != NULL) + { + m_Grab_Trans_X = m_pCurBlob->position.x; + m_Grab_Trans_Y = m_pCurBlob->position.y; + m_Grab_Trans_Z = m_pCurBlob->position.z; + } + DrawScene(); + CWnd::OnLButtonDown(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_CameraRot.x; + m_Base_Rot_Y = m_CameraRot.y; + m_Base_Rot_Z = m_CameraRot.z; + if (m_pCurBlob != NULL) + { + m_Grab_Trans_X = m_pCurBlob->position.x; + m_Grab_Trans_Y = m_pCurBlob->position.y; + m_Grab_Trans_Z = m_pCurBlob->position.z; + } + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case 'G': + m_DrawGeometry = !m_DrawGeometry; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + break; + case 'F': + m_DrawField = !m_DrawField; +// glPolygonMode(GL_FRONT,GL_FILL); + break; + case ' ': + break; + } + DrawScene(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + float sinAngle,cosAngle; + sinAngle = (float)sin(DEGTORAD(m_CameraRot.y)); + cosAngle = (float)cos(DEGTORAD(m_CameraRot.y)); + if (nFlags & MK_LBUTTON > 0) + { + if ((nFlags & MK_CONTROL) > 0) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + } + else + { + if (m_pCurBlob) + { + m_pCurBlob->position.x = m_Grab_Trans_X + ((float)(point.x - m_mousepos.x) * 0.028f * cosAngle); + m_pCurBlob->position.z = m_Grab_Trans_Z + ((float)(point.x - m_mousepos.x) * 0.028f * sinAngle); + m_pCurBlob->position.y = m_Grab_Trans_Y - ((float)(point.y - m_mousepos.y) * 0.028f); + Goop_FindBounds(); + DrawScene(); + } + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + } + else + { + m_CameraRot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + m_CameraRot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + DrawScene(); + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Current Blob +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + EditBlob(); +} + +void COGLView::EditBlob() +{ +/// Local Variables /////////////////////////////////////////////////////////// + CEditBlob dialog; +/////////////////////////////////////////////////////////////////////////////// + if (m_pCurBlob) + { + dialog.m_RadiusSquared = m_pCurBlob->radiusSquared; + dialog.m_Strength = m_pCurBlob->strength; + if (dialog.DoModal()) + { + m_pCurBlob->radiusSquared = dialog.m_RadiusSquared; + m_pCurBlob->strength = dialog.m_Strength; + DrawScene(); + } + } +} + +void COGLView::EditSys() +{ +/// Local Variables /////////////////////////////////////////////////////////// + CEditSys dialog; +/////////////////////////////////////////////////////////////////////////////// + dialog.m_SubDiv = m_Subdivisions; + dialog.m_Threshold = m_Threshold; + if (dialog.DoModal()) + { + m_Subdivisions = dialog.m_SubDiv; + m_Threshold = dialog.m_Threshold; + DrawScene(); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadFiles +// Purpose: Loads the Blob files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadFile(CString file1,CString baseName) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; + int loop,cnt; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen((LPCSTR)file1,"rb"); + if (fp) + { + Goop_FreeSys(); + fread(&m_Subdivisions, sizeof(int),1,fp); + fread(&m_Threshold, sizeof(int),1,fp); + fread(&cnt,sizeof(int),1,fp); + for (loop = 0; loop < cnt; loop++) + { + Goop_AddBlob(m_pGoopSys); + m_pCurBlob = &m_pGoopSys->pGoop[m_pGoopSys->nGoopCnt - 1]; + fread(&m_pCurBlob->position, sizeof(tVector),1,fp); + fread(&m_pCurBlob->radiusSquared, sizeof(float),1,fp); + fread(&m_pCurBlob->strength, sizeof(float),1,fp); + } + Goop_FindBounds(); + DrawScene(); + m_pCurBlob = NULL; + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: SaveFiles +// Purpose: Saves the Blob files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SaveFile(CString file1,CString baseName) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; + int loop; + tMetaGoop *pGoop; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen((LPCSTR)file1,"wb"); + if (fp) + { + fwrite(&m_Subdivisions, sizeof(int),1,fp); + fwrite(&m_Threshold, sizeof(int),1,fp); + fwrite(&m_pGoopSys->nGoopCnt,sizeof(int),1,fp); + pGoop = m_pGoopSys->pGoop; + for (loop = 0; loop < m_pGoopSys->nGoopCnt; loop++, pGoop++) + { + fwrite(&pGoop->position, sizeof(tVector),1,fp); + fwrite(&pGoop->radiusSquared, sizeof(float),1,fp); + fwrite(&pGoop->strength, sizeof(float),1,fp); + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnGoopAddblob +// Purpose: Add a blob to the system +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnGoopAddblob() +{ + Goop_AddBlob(m_pGoopSys); + m_pCurBlob = &m_pGoopSys->pGoop[m_pGoopSys->nGoopCnt - 1]; + Goop_FindBounds(); + DrawScene(); +} diff --git a/Blob Modeling/Code/OGL/Blobby/OGLView.h b/Blob Modeling/Code/OGL/Blobby/OGLView.h index 3dbd4c0..bf9a2a5 100644 --- a/Blob Modeling/Code/OGL/Blobby/OGLView.h +++ b/Blob Modeling/Code/OGL/Blobby/OGLView.h @@ -1,114 +1,114 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/99 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "MathDefs.h" -#include "MetaGoop.h" - -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry,m_DrawBlobs,m_DrawField; - tVector m_CameraRot,m_CameraTrans; - float m_Aspect; // Aspect Ration - - int m_Subdivisions; // How fine to divide the goop field - float m_Threshold; // Surface Threshold - - tMetaGoopSys *m_pGoopSys; - tMetaGoop *m_pCurBlob; - - -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid DrawScene(GLvoid); - GLvoid DrawSurface(); - GLvoid DrawField(); - GLvoid DrawBlobs(BOOL selecting); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - void LoadFile(CString file1,CString baseName); - void SaveFile(CString file1,CString baseName); - void OnGoopAddblob(); - void EditBlob(); - void EditSys(); - GLvoid SelectScene(int x, int y); - void ProcessSelection(GLint hits, GLuint buffer[]); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/99 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "MathDefs.h" +#include "MetaGoop.h" + +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry,m_DrawBlobs,m_DrawField; + tVector m_CameraRot,m_CameraTrans; + float m_Aspect; // Aspect Ration + + int m_Subdivisions; // How fine to divide the goop field + float m_Threshold; // Surface Threshold + + tMetaGoopSys *m_pGoopSys; + tMetaGoop *m_pCurBlob; + + +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid DrawScene(GLvoid); + GLvoid DrawSurface(); + GLvoid DrawField(); + GLvoid DrawBlobs(BOOL selecting); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + void LoadFile(CString file1,CString baseName); + void SaveFile(CString file1,CString baseName); + void OnGoopAddblob(); + void EditBlob(); + void EditSys(); + GLvoid SelectScene(int x, int y); + void ProcessSelection(GLint hits, GLuint buffer[]); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/ReadMe.txt b/Blob Modeling/Code/OGL/Blobby/ReadMe.txt index 44b5388..7430a7f 100644 --- a/Blob Modeling/Code/OGL/Blobby/ReadMe.txt +++ b/Blob Modeling/Code/OGL/Blobby/ReadMe.txt @@ -1,59 +1,59 @@ -3D Real-time Blob Modelling Demonstration Nov 20, 1999 --------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the November 99 -Game Developer magazine. It is meant as a demonstration of -a method for 3D Blob Modelling in OpenGL. - -I really wanted to work on this more but I am so behind on demos, -I will just put it out there and try to update. - -Lots of things you can add to this to make it better. - -1. Fix the isosurface generation. It has some issues marked with TODO - in the code - -2. Blob triangles and vertices do not have normals, create them from - the field gradients so you can light the objects - -3. Isosurface generation can be optimized like crazy. Add the - surface tracking idea I talked about it the article - -4. Add a color component to each blob and blend the colors with - the strength function and use vertex coloring to draw it. - -5. Add support for non-sphere objects or non-uniform scaling of blobs - -6. Add animation support - -All the blob routines are in the MetaGoop.h/cpp files so it could -be adapted to non-MFC apps easy. - -There is also an example of using OpenGL name picking in the -OGLView.cpp routine. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm Nov 5, 1999 ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - +3D Real-time Blob Modelling Demonstration Nov 20, 1999 +-------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the November 99 +Game Developer magazine. It is meant as a demonstration of +a method for 3D Blob Modelling in OpenGL. + +I really wanted to work on this more but I am so behind on demos, +I will just put it out there and try to update. + +Lots of things you can add to this to make it better. + +1. Fix the isosurface generation. It has some issues marked with TODO + in the code + +2. Blob triangles and vertices do not have normals, create them from + the field gradients so you can light the objects + +3. Isosurface generation can be optimized like crazy. Add the + surface tracking idea I talked about it the article + +4. Add a color component to each blob and blend the colors with + the strength function and use vertex coloring to draw it. + +5. Add support for non-sphere objects or non-uniform scaling of blobs + +6. Add animation support + +All the blob routines are in the MetaGoop.h/cpp files so it could +be adapted to non-MFC apps easy. + +There is also an example of using OpenGL name picking in the +OGLView.cpp routine. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm Nov 5, 1999 +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + diff --git a/Blob Modeling/Code/OGL/Blobby/StdAfx.cpp b/Blob Modeling/Code/OGL/Blobby/StdAfx.cpp index 2a4374b..db64902 100644 --- a/Blob Modeling/Code/OGL/Blobby/StdAfx.cpp +++ b/Blob Modeling/Code/OGL/Blobby/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Blobby.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Blobby.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Blob Modeling/Code/OGL/Blobby/StdAfx.h b/Blob Modeling/Code/OGL/Blobby/StdAfx.h index ddefdab..571c76c 100644 --- a/Blob Modeling/Code/OGL/Blobby/StdAfx.h +++ b/Blob Modeling/Code/OGL/Blobby/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Blob Modeling/Code/OGL/Blobby/resource.h b/Blob Modeling/Code/OGL/Blobby/resource.h index d8eb536..136c611 100644 --- a/Blob Modeling/Code/OGL/Blobby/resource.h +++ b/Blob Modeling/Code/OGL/Blobby/resource.h @@ -1,62 +1,62 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Blobby.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_BLOBBYTYPE 129 -#define IDD_SETROTATE 130 -#define IDB_HUP 131 -#define IDB_HDN 132 -#define IDD_DIALOG1 132 -#define IDB_HUPP 133 -#define IDD_LOADOBJ 133 -#define IDD_PICKOBJ 133 -#define IDD_EDITBLOB 133 -#define IDB_HDNP 134 -#define IDD_EDITSYS 134 -#define IDB_VDN 135 -#define IDB_VUP 136 -#define IDB_VUPP 137 -#define IDB_VDNP 138 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_BUTTON1 1001 -#define IDC_BROWSE1 1001 -#define IDC_ZAXIS 1002 -#define IDC_BROWSE2 1002 -#define IDC_SLIDER1 1003 -#define IDC_EDIT1 1004 -#define IDC_RADIUS 1004 -#define IDC_EDIT2 1005 -#define IDC_OBJLIST 1005 -#define IDC_STRENGTH 1005 -#define IDC_THRESHOLD 1006 -#define IDC_SUBDIV 1007 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_METHOD_FASTBBOX 32775 -#define ID_VIEW_SHOWBBOX 32776 -#define ID_VIEW_SHOWOBBOX 32777 -#define ID_GOOP_ADDBLOB 32778 -#define ID_VIEW_DRAWBLOBS 32779 -#define ID_VIEW_DRAWFIELD 32780 -#define ID_GOOP_EDITBLOB 32781 -#define ID_GOOP_SYSTEMSETTINGS 32782 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 134 -#define _APS_NEXT_COMMAND_VALUE 32783 -#define _APS_NEXT_CONTROL_VALUE 1008 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Blobby.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_BLOBBYTYPE 129 +#define IDD_SETROTATE 130 +#define IDB_HUP 131 +#define IDB_HDN 132 +#define IDD_DIALOG1 132 +#define IDB_HUPP 133 +#define IDD_LOADOBJ 133 +#define IDD_PICKOBJ 133 +#define IDD_EDITBLOB 133 +#define IDB_HDNP 134 +#define IDD_EDITSYS 134 +#define IDB_VDN 135 +#define IDB_VUP 136 +#define IDB_VUPP 137 +#define IDB_VDNP 138 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_BUTTON1 1001 +#define IDC_BROWSE1 1001 +#define IDC_ZAXIS 1002 +#define IDC_BROWSE2 1002 +#define IDC_SLIDER1 1003 +#define IDC_EDIT1 1004 +#define IDC_RADIUS 1004 +#define IDC_EDIT2 1005 +#define IDC_OBJLIST 1005 +#define IDC_STRENGTH 1005 +#define IDC_THRESHOLD 1006 +#define IDC_SUBDIV 1007 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_METHOD_FASTBBOX 32775 +#define ID_VIEW_SHOWBBOX 32776 +#define ID_VIEW_SHOWOBBOX 32777 +#define ID_GOOP_ADDBLOB 32778 +#define ID_VIEW_DRAWBLOBS 32779 +#define ID_VIEW_DRAWFIELD 32780 +#define ID_GOOP_EDITBLOB 32781 +#define ID_GOOP_SYSTEMSETTINGS 32782 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 32783 +#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/CCD3D.cpp b/CCD3D.cpp index 7c0b9ab..8bdc19d 100644 --- a/CCD3D.cpp +++ b/CCD3D.cpp @@ -2,7 +2,7 @@ // Procedure: CheckDOFRestrictions // Purpose: Make sure link is within valid DOF // Arguments: Link -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// void COGLView::CheckDOFRestrictions(t_Bone *link) { /// Local Variables /////////////////////////////////////////////////////////// @@ -13,17 +13,17 @@ void COGLView::CheckDOFRestrictions(t_Bone *link) QuatToEuler(&link->quat, &euler); // CHECK THE DOF SETTINGS - if (euler.x > (float)link->max_rx) + if (euler.x > (float)link->max_rx) euler.x = (float)link->max_rx; - if (euler.x < (float)link->min_rx) + if (euler.x < (float)link->min_rx) euler.x = (float)link->min_rx; - if (euler.y > (float)link->max_ry) + if (euler.y > (float)link->max_ry) euler.y = (float)link->max_ry; - if (euler.y < (float)link->min_ry) + if (euler.y < (float)link->min_ry) euler.y = (float)link->min_ry; - if (euler.z > (float)link->max_rz) + if (euler.z > (float)link->max_rz) euler.z = (float)link->max_rz; - if (euler.z < (float)link->min_rz) + if (euler.z < (float)link->min_rz) euler.z = (float)link->min_rz; // BACK TO QUATERNION @@ -35,7 +35,7 @@ void COGLView::CheckDOFRestrictions(t_Bone *link) // Purpose: Compute an IK Solution to an end effector position in 3D // Arguments: End Target (x,y,z) // Returns: TRUE if a solution exists, FALSE if the position isn't in reach -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// BOOL COGLView::ComputeCCDLink(tVector endPos) { /// Local Variables /////////////////////////////////////////////////////////// @@ -93,7 +93,7 @@ BOOL COGLView::ComputeCCDLink(tVector endPos) turnAngle = acos((float)cosAngle); // GET THE ANGLE turnDeg = RADTODEG(turnAngle); // COVERT TO DEGREES // DAMPING - if (m_Damping && turnDeg > m_Link[link].damp_width) + if (m_Damping && turnDeg > m_Link[link].damp_width) turnDeg = m_Link[link].damp_width; AxisAngleToQuat(&crossResult,turnDeg,&aquat); MultQuaternions(&m_Link[link].quat, &aquat,&m_Link[link].quat); @@ -106,7 +106,7 @@ BOOL COGLView::ComputeCCDLink(tVector endPos) if (--link < 0) link = EFFECTOR_POS - 1; // START OF THE CHAIN, RESTART } // QUIT IF I AM CLOSE ENOUGH OR BEEN RUNNING LONG ENOUGH - } while (tries++ < MAX_IK_TRIES && + } while (tries++ < MAX_IK_TRIES && VectorSquaredDistance(&curEnd, &desiredEnd) > IK_POS_THRESH); if (tries == MAX_IK_TRIES) return FALSE; diff --git a/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.cpp b/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.cpp index d50204b..561507b 100644 --- a/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.cpp @@ -1,353 +1,353 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vertexCnt = 0; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = (float)atof(words.GetAt(1)); - visual->Ka.g = (float)atof(words.GetAt(2)); - visual->Ka.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = (float)atof(words.GetAt(1)); - visual->Kd.g = (float)atof(words.GetAt(2)); - visual->Kd.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = (float)atof(words.GetAt(1)); - visual->Ks.g = (float)atof(words.GetAt(2)); - visual->Ks.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = (float)atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle anything other than -// 3-4 vertex polygons. -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loopcnt; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - loopcnt = words->GetSize(); - - // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < loopcnt; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } - face->flags = 0; - if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; - if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; - if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; - else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; - else - { - ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); - face->flags |= FACE_TYPE_TRI; - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(const char *filename,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - visual->glTex = 0; - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = (float)atof(words.GetAt(1)); - normal[nPos].y = (float)atof(words.GetAt(2)); - normal[nPos].z = (float)atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = (float)atof(words.GetAt(1)); - texture[tPos].v = (float)atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = (float)atof(words.GetAt(1)); - vertex[vPos].y = (float)atof(words.GetAt(2)); - vertex[vPos].z = (float)atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 5) - { - sprintf(buffer,"Face %d has more than 4 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS - // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF - // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER - if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; - else visual->vPerFace = 4; - - if (nCnt > 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->vertexCol = (tVector *)malloc(sizeof(tVector) * fPos * visual->vPerFace); - visual->faceCnt = fPos; - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->faceCnt = fPos; - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->faceCnt = fPos; - } - - visual->vertexCnt = visual->vPerFace * visual->faceCnt; // Set the vertex count - - data = visual->vertexData; - for (loop = 0; loop < fPos; loop++) - { - // ERROR CHECKING TO MAKE SURE - if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - - for (loop2 = 0; loop2 < visual->vPerFace; loop2++) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vertexCnt = 0; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = (float)atof(words.GetAt(1)); + visual->Ka.g = (float)atof(words.GetAt(2)); + visual->Ka.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = (float)atof(words.GetAt(1)); + visual->Kd.g = (float)atof(words.GetAt(2)); + visual->Kd.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = (float)atof(words.GetAt(1)); + visual->Ks.g = (float)atof(words.GetAt(2)); + visual->Ks.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = (float)atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle anything other than +// 3-4 vertex polygons. +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loopcnt; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + loopcnt = words->GetSize(); + + // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < loopcnt; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } + face->flags = 0; + if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; + if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; + if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; + else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; + else + { + ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); + face->flags |= FACE_TYPE_TRI; + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(const char *filename,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + visual->glTex = 0; + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = (float)atof(words.GetAt(1)); + normal[nPos].y = (float)atof(words.GetAt(2)); + normal[nPos].z = (float)atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = (float)atof(words.GetAt(1)); + texture[tPos].v = (float)atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = (float)atof(words.GetAt(1)); + vertex[vPos].y = (float)atof(words.GetAt(2)); + vertex[vPos].z = (float)atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 5) + { + sprintf(buffer,"Face %d has more than 4 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS + // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF + // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER + if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; + else visual->vPerFace = 4; + + if (nCnt > 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->vertexCol = (tVector *)malloc(sizeof(tVector) * fPos * visual->vPerFace); + visual->faceCnt = fPos; + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->faceCnt = fPos; + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->faceCnt = fPos; + } + + visual->vertexCnt = visual->vPerFace * visual->faceCnt; // Set the vertex count + + data = visual->vertexData; + for (loop = 0; loop < fPos; loop++) + { + // ERROR CHECKING TO MAKE SURE + if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + + for (loop2 = 0; loop2 < visual->vPerFace; loop2++) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.h b/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.h index 19798a8..1b4bfe6 100644 --- a/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.h +++ b/Cartoon Rendering/Code/OGL/Loony/LoadOBJ.h @@ -1,39 +1,39 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS -typedef struct -{ - long v[4],n[4],t[4]; - int flags; // FACE TYPES -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(const char *filename,t_Visual *visual); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS +typedef struct +{ + long v[4],n[4],t[4]; + int flags; // FACE TYPES +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(const char *filename,t_Visual *visual); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/Cartoon Rendering/Code/OGL/Loony/Loony.cpp b/Cartoon Rendering/Code/OGL/Loony/Loony.cpp index 255bb4f..67659f5 100644 --- a/Cartoon Rendering/Code/OGL/Loony/Loony.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/Loony.cpp @@ -1,158 +1,158 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Loony.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Loony.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CLoonyApp - -BEGIN_MESSAGE_MAP(CLoonyApp, CWinApp) - //{{AFX_MSG_MAP(CLoonyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CLoonyApp construction - -CLoonyApp::CLoonyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CLoonyApp object - -CLoonyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CLoonyApp initialization - -BOOL CLoonyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Loony")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - - // Enable drag/drop open - m_pMainWnd->DragAcceptFiles(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CLoonyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CLoonyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Loony.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Loony.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CLoonyApp + +BEGIN_MESSAGE_MAP(CLoonyApp, CWinApp) + //{{AFX_MSG_MAP(CLoonyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CLoonyApp construction + +CLoonyApp::CLoonyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CLoonyApp object + +CLoonyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CLoonyApp initialization + +BOOL CLoonyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Loony")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + + // Enable drag/drop open + m_pMainWnd->DragAcceptFiles(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CLoonyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CLoonyApp commands diff --git a/Cartoon Rendering/Code/OGL/Loony/Loony.h b/Cartoon Rendering/Code/OGL/Loony/Loony.h index 88f8359..191e0c3 100644 --- a/Cartoon Rendering/Code/OGL/Loony/Loony.h +++ b/Cartoon Rendering/Code/OGL/Loony/Loony.h @@ -1,67 +1,67 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Loony.h : main header file for the Loony application -// -// Purpose: Implementation of OpenGL Window of Cartoon Rendering System -// -// Created: -// JL 1/12/00 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2000 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Loony_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Loony_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID - -///////////////////////////////////////////////////////////////////////////// -// CLoonyApp: -// See Loony.cpp for the implementation of this class -// - -class CLoonyApp : public CWinApp -{ -public: - CLoonyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CLoonyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CLoonyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Loony_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Loony.h : main header file for the Loony application +// +// Purpose: Implementation of OpenGL Window of Cartoon Rendering System +// +// Created: +// JL 1/12/00 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2000 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Loony_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Loony_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID + +///////////////////////////////////////////////////////////////////////////// +// CLoonyApp: +// See Loony.cpp for the implementation of this class +// + +class CLoonyApp : public CWinApp +{ +public: + CLoonyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CLoonyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CLoonyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Loony_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cartoon Rendering/Code/OGL/Loony/MainFrm.cpp b/Cartoon Rendering/Code/OGL/Loony/MainFrm.cpp index 38d7198..77570f4 100644 --- a/Cartoon Rendering/Code/OGL/Loony/MainFrm.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/MainFrm.cpp @@ -1,278 +1,278 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of Cartoon Rendering System -// -// Created: -// JL 1/12/00 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2000 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "mmsystem.h" // NEED THIS FOR THE TIMEGETTIME -#include "Loony.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Local Defines ///////////////////////////////////////////////////////////// -#define OGLWIN_START_X 1 // STARTING X POSITION OF OPENGL WINDOW -#define OGLWIN_START_Y 1 // STARTING Y POSITION OF OPENGL WINDOW -#define OGLWIN_WIDTH 4 // WIDTH OF OPENGL WINDOW SUBTRACTED FROM MAX -#define OGLWIN_BOTTOM 20 // BOTTOM BORDER OF OPENGL WINDOW -/////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_SIZE() - ON_WM_KEYUP() - ON_WM_KEYDOWN() - ON_WM_PAINT() - ON_COMMAND(ID_WHICHOGL, OnWhichogl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_FILE_OPENOBJECTMESH, OnFileOpenObjectMesh) - ON_COMMAND(ID_CARTOON_ANTIALIAS, OnCartoonAntialias) - ON_UPDATE_COMMAND_UI(ID_CARTOON_ANTIALIAS, OnUpdateCartoonAntialias) - ON_COMMAND(ID_CARTOON_SETTINGS, OnCartoonSettings) - ON_COMMAND(ID_CARTOON_DRAWSILHOUETTE, OnCartoonDrawsilhouette) - ON_UPDATE_COMMAND_UI(ID_CARTOON_DRAWSILHOUETTE, OnUpdateCartoonDrawsilhouette) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_Wireframe = TRUE; - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, - CRect(OGLWIN_START_X, OGLWIN_START_Y,rect.right - OGLWIN_WIDTH,rect.bottom - OGLWIN_BOTTOM),this,104); - m_OGLView.ShowWindow(TRUE); - - m_OGLView.m_StatusBar = &m_wndStatusBar; - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - HICON hicon; - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame implementation - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnWhichogl -// Purpose: Create dialog to Show which version of OGL is running -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnWhichogl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) -{ - - return CFrameWnd::OnCreateClient(lpcs, pContext); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnPaint -// Purpose: This routine grabs the message loop if I am animating and -// handles the messages. This way I can play back as fast -// as possible -// Reference: OpenGL Programming for Windows 95 by Ron Fosner -// Sort of a variation on that code -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} -/// OnPaint //////////////////////////////////////////////////////////// - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - // RESET THE m_OGLView WINDOW SIZE - m_OGLView.SetWindowPos( &wndTopMost, OGLWIN_START_X, OGLWIN_START_Y, cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM, SWP_NOZORDER ); - // RESET THE ACTUAL OPENGL WINDOW SIZE - m_OGLView.resize( cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM); - CFrameWnd::OnSize(nType, cx, cy); -} - -// HAVEN'T IMPLEMENTED ADDING A BONE -#if 0 -void CMainFrame::OnAddBone() -{ - m_HierWin.AddBone(); -} -#endif - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); - m_OGLView.HandleKeyUp(nChar); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -///////////////////////////////////////////////////////////////////////////// -// View Manipulation Functions - -///////////////////////////////////////////////////////////////////////////// - - -void CMainFrame::OnFileOpen() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Shade Table (*.shd)|*.shd||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(TRUE,"shd",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - m_OGLView.LoadShadeTexture((LPCSTR)dialog->GetPathName()); - m_OGLView.drawScene(); - } - delete dialog; - -} - -void CMainFrame::OnFileOpenObjectMesh() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Object Mesh OBJ (*.obj)|*.obj||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(TRUE,"dcm",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - m_OGLView.LoadOBJModel(dialog->GetPathName()); - m_OGLView.drawScene(); - } - delete dialog; -} - -void CMainFrame::OnCartoonAntialias() -{ - m_OGLView.m_AntiAlias = !m_OGLView.m_AntiAlias; - m_OGLView.drawScene(); -} - -void CMainFrame::OnUpdateCartoonAntialias(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_AntiAlias ); -} - -void CMainFrame::OnCartoonSettings() -{ - m_OGLView.CartoonSettings(); -} - -void CMainFrame::OnCartoonDrawsilhouette() -{ - m_OGLView.m_Silhouette = !m_OGLView.m_Silhouette; - m_OGLView.drawScene(); -} - -void CMainFrame::OnUpdateCartoonDrawsilhouette(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_Silhouette ); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of Cartoon Rendering System +// +// Created: +// JL 1/12/00 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2000 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "mmsystem.h" // NEED THIS FOR THE TIMEGETTIME +#include "Loony.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Local Defines ///////////////////////////////////////////////////////////// +#define OGLWIN_START_X 1 // STARTING X POSITION OF OPENGL WINDOW +#define OGLWIN_START_Y 1 // STARTING Y POSITION OF OPENGL WINDOW +#define OGLWIN_WIDTH 4 // WIDTH OF OPENGL WINDOW SUBTRACTED FROM MAX +#define OGLWIN_BOTTOM 20 // BOTTOM BORDER OF OPENGL WINDOW +/////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_KEYUP() + ON_WM_KEYDOWN() + ON_WM_PAINT() + ON_COMMAND(ID_WHICHOGL, OnWhichogl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_OPENOBJECTMESH, OnFileOpenObjectMesh) + ON_COMMAND(ID_CARTOON_ANTIALIAS, OnCartoonAntialias) + ON_UPDATE_COMMAND_UI(ID_CARTOON_ANTIALIAS, OnUpdateCartoonAntialias) + ON_COMMAND(ID_CARTOON_SETTINGS, OnCartoonSettings) + ON_COMMAND(ID_CARTOON_DRAWSILHOUETTE, OnCartoonDrawsilhouette) + ON_UPDATE_COMMAND_UI(ID_CARTOON_DRAWSILHOUETTE, OnUpdateCartoonDrawsilhouette) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_Wireframe = TRUE; + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, + CRect(OGLWIN_START_X, OGLWIN_START_Y,rect.right - OGLWIN_WIDTH,rect.bottom - OGLWIN_BOTTOM),this,104); + m_OGLView.ShowWindow(TRUE); + + m_OGLView.m_StatusBar = &m_wndStatusBar; + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + HICON hicon; + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame implementation + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnWhichogl +// Purpose: Create dialog to Show which version of OGL is running +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnWhichogl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) +{ + + return CFrameWnd::OnCreateClient(lpcs, pContext); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnPaint +// Purpose: This routine grabs the message loop if I am animating and +// handles the messages. This way I can play back as fast +// as possible +// Reference: OpenGL Programming for Windows 95 by Ron Fosner +// Sort of a variation on that code +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} +/// OnPaint //////////////////////////////////////////////////////////// + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + // RESET THE m_OGLView WINDOW SIZE + m_OGLView.SetWindowPos( &wndTopMost, OGLWIN_START_X, OGLWIN_START_Y, cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM, SWP_NOZORDER ); + // RESET THE ACTUAL OPENGL WINDOW SIZE + m_OGLView.resize( cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM); + CFrameWnd::OnSize(nType, cx, cy); +} + +// HAVEN'T IMPLEMENTED ADDING A BONE +#if 0 +void CMainFrame::OnAddBone() +{ + m_HierWin.AddBone(); +} +#endif + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); + m_OGLView.HandleKeyUp(nChar); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +///////////////////////////////////////////////////////////////////////////// +// View Manipulation Functions + +///////////////////////////////////////////////////////////////////////////// + + +void CMainFrame::OnFileOpen() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Shade Table (*.shd)|*.shd||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(TRUE,"shd",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + m_OGLView.LoadShadeTexture((LPCSTR)dialog->GetPathName()); + m_OGLView.drawScene(); + } + delete dialog; + +} + +void CMainFrame::OnFileOpenObjectMesh() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Object Mesh OBJ (*.obj)|*.obj||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(TRUE,"dcm",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + m_OGLView.LoadOBJModel(dialog->GetPathName()); + m_OGLView.drawScene(); + } + delete dialog; +} + +void CMainFrame::OnCartoonAntialias() +{ + m_OGLView.m_AntiAlias = !m_OGLView.m_AntiAlias; + m_OGLView.drawScene(); +} + +void CMainFrame::OnUpdateCartoonAntialias(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_AntiAlias ); +} + +void CMainFrame::OnCartoonSettings() +{ + m_OGLView.CartoonSettings(); +} + +void CMainFrame::OnCartoonDrawsilhouette() +{ + m_OGLView.m_Silhouette = !m_OGLView.m_Silhouette; + m_OGLView.drawScene(); +} + +void CMainFrame::OnUpdateCartoonDrawsilhouette(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_Silhouette ); +} diff --git a/Cartoon Rendering/Code/OGL/Loony/MainFrm.h b/Cartoon Rendering/Code/OGL/Loony/MainFrm.h index e0152f7..0edb820 100644 --- a/Cartoon Rendering/Code/OGL/Loony/MainFrm.h +++ b/Cartoon Rendering/Code/OGL/Loony/MainFrm.h @@ -1,90 +1,90 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of Cartoon Rendering System -// -// Created: -// JL 1/12/00 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2000 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - BOOL m_Wireframe; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - protected: - virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - CToolBar m_wndToolBar; - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnPaint(); - afx_msg void OnWhichogl(); - afx_msg void OnFileOpen(); - afx_msg void OnFileOpenObjectMesh(); - afx_msg void OnCartoonAntialias(); - afx_msg void OnUpdateCartoonAntialias(CCmdUI* pCmdUI); - afx_msg void OnCartoonSettings(); - afx_msg void OnCartoonDrawsilhouette(); - afx_msg void OnUpdateCartoonDrawsilhouette(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of Cartoon Rendering System +// +// Created: +// JL 1/12/00 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2000 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + BOOL m_Wireframe; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + protected: + virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnPaint(); + afx_msg void OnWhichogl(); + afx_msg void OnFileOpen(); + afx_msg void OnFileOpenObjectMesh(); + afx_msg void OnCartoonAntialias(); + afx_msg void OnUpdateCartoonAntialias(CCmdUI* pCmdUI); + afx_msg void OnCartoonSettings(); + afx_msg void OnCartoonDrawsilhouette(); + afx_msg void OnUpdateCartoonDrawsilhouette(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif diff --git a/Cartoon Rendering/Code/OGL/Loony/MathDefs.cpp b/Cartoon Rendering/Code/OGL/Loony/MathDefs.cpp index 785e5b3..d6c9a3b 100644 --- a/Cartoon Rendering/Code/OGL/Loony/MathDefs.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/MathDefs.cpp @@ -1,286 +1,286 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByRotMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z); - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z); - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z); -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Two Utility functions that I pulled from the Mesa GL source -// This is a great source of information about the inner working of functions -// in OpenGL -// -// www.mesagl.com for info -// -// Adapted to work with my data types -/////////////////////////////////////////////////////////////////////////////// - -// Multiply two OpenGL Matrices together -void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b) -{ - /* This matmul was contributed by Thomas Malik */ - int i; - -#define A(row,col) a->m[(col<<2)+row] -#define B(row,col) b->m[(col<<2)+row] -#define P(row,col) product->m[(col<<2)+row] - - /* i-te Zeile */ - for (i = 0; i < 4; i++) { - float ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); - P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); - P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); - P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); - P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); - } - -#undef A -#undef B -#undef P -} - -// Invert an OpenGL 4x4 matrix -BOOL InvertMatrix(float *m, float *out ) -{ -/* NB. OpenGL Matrices are COLUMN major. */ -#define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } -#define MAT(m,r,c) (m)[(c)*4+(r)] - - float wtmp[4][8]; - float m0, m1, m2, m3, s; - float *r0, *r1, *r2, *r3; - - r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; - - r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), - r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), - r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, - - r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), - r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), - r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, - - r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), - r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), - r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, - - r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), - r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), - r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; - - /* choose pivot - or die */ - if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); - if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); - if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); - if (0.0 == r0[0]) return FALSE; - - /* eliminate first variable */ - m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; - s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; - s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; - s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; - s = r0[4]; - if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r0[5]; - if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r0[6]; - if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r0[7]; - if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); - if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); - if (0.0 == r1[1]) return FALSE; - - /* eliminate second variable */ - m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; - r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; - r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; - s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); - if (0.0 == r2[2]) return FALSE; - - /* eliminate third variable */ - m3 = r3[2]/r2[2]; - r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], - r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], - r3[7] -= m3 * r2[7]; - - /* last check */ - if (0.0 == r3[3]) return FALSE; - - s = 1.0/r3[3]; /* now back substitute row 3 */ - r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; - - m2 = r2[3]; /* now back substitute row 2 */ - s = 1.0/r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), - r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, - r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, - r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; - - m1 = r1[2]; /* now back substitute row 1 */ - s = 1.0/r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), - r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, - r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; - - m0 = r0[1]; /* now back substitute row 0 */ - s = 1.0/r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), - r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); - - MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], - MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], - MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], - MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], - MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], - MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], - MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], - MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; - - return TRUE; - -#undef MAT -#undef SWAP_ROWS -} - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void ScaleVector(tVector *v, float scale, tVector *result) -{ - result->x = v->x * scale; - result->y = v->y * scale; - result->z = v->z * scale; -} - -void VectorSum(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x + v2->x; - result->y = v1->y + v2->y; - result->z = v1->z + v2->z; -} - -void VectorDifference(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByRotMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z); + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z); + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z); +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Two Utility functions that I pulled from the Mesa GL source +// This is a great source of information about the inner working of functions +// in OpenGL +// +// www.mesagl.com for info +// +// Adapted to work with my data types +/////////////////////////////////////////////////////////////////////////////// + +// Multiply two OpenGL Matrices together +void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b) +{ + /* This matmul was contributed by Thomas Malik */ + int i; + +#define A(row,col) a->m[(col<<2)+row] +#define B(row,col) b->m[(col<<2)+row] +#define P(row,col) product->m[(col<<2)+row] + + /* i-te Zeile */ + for (i = 0; i < 4; i++) { + float ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); + } + +#undef A +#undef B +#undef P +} + +// Invert an OpenGL 4x4 matrix +BOOL InvertMatrix(float *m, float *out ) +{ +/* NB. OpenGL Matrices are COLUMN major. */ +#define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } +#define MAT(m,r,c) (m)[(c)*4+(r)] + + float wtmp[4][8]; + float m0, m1, m2, m3, s; + float *r0, *r1, *r2, *r3; + + r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; + + r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), + r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), + r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, + + r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), + r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), + r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, + + r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), + r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), + r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, + + r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), + r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), + r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; + + /* choose pivot - or die */ + if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); + if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); + if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); + if (0.0 == r0[0]) return FALSE; + + /* eliminate first variable */ + m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; + s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; + s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; + s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r0[5]; + if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r0[6]; + if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r0[7]; + if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); + if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); + if (0.0 == r1[1]) return FALSE; + + /* eliminate second variable */ + m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; + r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; + s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); + if (0.0 == r2[2]) return FALSE; + + /* eliminate third variable */ + m3 = r3[2]/r2[2]; + r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], + r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], + r3[7] -= m3 * r2[7]; + + /* last check */ + if (0.0 == r3[3]) return FALSE; + + s = 1.0/r3[3]; /* now back substitute row 3 */ + r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; + + m2 = r2[3]; /* now back substitute row 2 */ + s = 1.0/r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), + r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, + r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, + r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; + + m1 = r1[2]; /* now back substitute row 1 */ + s = 1.0/r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), + r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, + r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; + + m0 = r0[1]; /* now back substitute row 0 */ + s = 1.0/r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), + r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); + + MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], + MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], + MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], + MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], + MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], + MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], + MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], + MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; + + return TRUE; + +#undef MAT +#undef SWAP_ROWS +} + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void ScaleVector(tVector *v, float scale, tVector *result) +{ + result->x = v->x * scale; + result->y = v->y * scale; + result->z = v->z * scale; +} + +void VectorSum(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x + v2->x; + result->y = v1->y + v2->y; + result->z = v1->z + v2->z; +} + +void VectorDifference(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/Cartoon Rendering/Code/OGL/Loony/MathDefs.h b/Cartoon Rendering/Code/OGL/Loony/MathDefs.h index 049392f..b4d5177 100644 --- a/Cartoon Rendering/Code/OGL/Loony/MathDefs.h +++ b/Cartoon Rendering/Code/OGL/Loony/MathDefs.h @@ -1,118 +1,118 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float r,g,b; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b); -BOOL InvertMatrix(float *m, float *out ); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float r,g,b; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b); +BOOL InvertMatrix(float *m, float *out ); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Cartoon Rendering/Code/OGL/Loony/OGLView.cpp b/Cartoon Rendering/Code/OGL/Loony/OGLView.cpp index 93b996a..2fb92ae 100644 --- a/Cartoon Rendering/Code/OGL/Loony/OGLView.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/OGLView.cpp @@ -1,750 +1,750 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Cartoon Rendering System -// -// Created: -// JL 1/12/00 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2000 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include "Loony.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "ToonSet.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define OGL_SELECTED_DLIST 2 // SELECTED BONE OPENGL DISPLAY LIST -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_StatusBar = NULL; // CLEAR THIS. IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT - m_AntiAlias = FALSE; - m_Dragging = FALSE; - m_Silhouette = TRUE; - - // INITIALIZE SOME OF THE CAMERA VARIABLES - ResetBone(&m_Camera, NULL); - m_Camera.id = -1; - strcpy(m_Camera.name,"Camera"); - m_Camera.rot.x = 0.0f; - m_Camera.rot.y = 0.0f; - m_Camera.rot.z = 0.0f; - m_Camera.b_trans.y = 0.0f; - m_Camera.b_trans.z = -50.0f; - m_Camera.trans.y = 0.0f; - m_Camera.trans.z = -50.0f; - - m_Model.vertexData = NULL; - - // Set the Default Light Direction - m_ShadeLight.x = 0.3f; - m_ShadeLight.y = 0.1f; - m_ShadeLight.z = 0.8f; - NormalizeVector(&m_ShadeLight); // Normalize it since I know I didn't - - m_SilhouetteColor.r = 0.0f; - m_SilhouetteColor.g = 0.0f; - m_SilhouetteColor.b = 0.0f; - m_SilhouetteWidth = 3; // Width of Silhouette line - -} - -COGLView::~COGLView() -{ -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_MOVE() - ON_WM_LBUTTONUP() - ON_WM_RBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // GENERATE THE OPENGL TEXTURE ID - glGenTextures(1,&m_ShadeTexture); - - LoadShadeTexture("default.shd"); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glEndList(); - - drawScene(); - return 0; -} - -/* OpenGL code */ - -/////////////////////////////////////////////////////////////////////////////// -// Function: resize -// Purpose: This code handles the windows resize for OpenGL -// Arguments: Width and heights of the view window -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(20.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - m_ScreenWidth = width; - m_ScreenHeight = height; - -} -//// resize ///////////////////////////////////////////////////////////////// - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.7f, 0.7f, 0.7f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LESS); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(60.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LESS); - glEnable(GL_CULL_FACE); - glPointSize(8.0); // NICE BEEFY POINTS FOR THE VERTEX SELECTION - glDisable(GL_TEXTURE_2D); - - glDisable(GL_LIGHTING); - - glEnable(GL_BLEND); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: CalculateShadow -// Purpose: Calculate the shadow coordinate value for a normal -// Arguments: The vertex normal, Light vector, and Object rotation matrix -// Returns: An index coordinate into the shade table -/////////////////////////////////////////////////////////////////////////////// -float COGLView::CalculateShadow(tVector *normal,tVector *light, tMatrix *mat) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - tVector post; - float dot; -///////////////////////////////////////////////////////////////////////////////////// - // Rotate the normal by the current object matrix - MultVectorByRotMatrix(mat, normal, &post); - dot = DotProduct(&post,light); // Calculate the Dot Product - - if (dot < 0) dot = 0; // Make sure the Back half dark - return fabs(dot); // Return the shadow value -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawModel -// Purpose: Draw the Mesh model either deformed or not -// Arguments: Pointer to the model -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Visual *model) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tMatrix mat; // Needed for Lighting Calc - int loop; - float u; - tVector *vertex, *normal; -/////////////////////////////////////////////////////////////////////////////// - - if (model->vertexData != NULL) - { - // Turn on anti-aliased silhouette lines if selected - if (m_AntiAlias) - { - glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); - glEnable(GL_LINE_SMOOTH); - } - else - glDisable(GL_LINE_SMOOTH); - - glPolygonMode(GL_FRONT,GL_FILL); - - // Bind my 1D shade texture - glEnable(GL_TEXTURE_1D); - glBindTexture( GL_TEXTURE_1D,m_ShadeTexture); - - // Set the Base color of the Model from the material - glColor3fv(&model->Kd.r); - glDisable(GL_LIGHTING); - - // Grab the matrix for lighting calc - glGetFloatv(GL_MODELVIEW_MATRIX,mat.m); - - // Get the Normal and Vertex from any format model that has vertex and normal - switch(model->dataFormat) - { - case GL_T2F_N3F_V3F: - vertex = (tVector *)&model->vertexData[5]; - normal = (tVector *)&model->vertexData[2]; - break; - case GL_N3F_V3F: - vertex = (tVector *)&model->vertexData[3]; - normal = (tVector *)&model->vertexData[0]; - break; - case GL_V3F: - vertex = (tVector *)&model->vertexData[0]; - normal = NULL; - break; - } - - glBegin(GL_TRIANGLES); - for (loop = 0; loop < model->faceCnt * 3; loop++) - { - // calculate an index into the 1D texture using normal and light - u = CalculateShadow(normal,&m_ShadeLight, &mat); - glTexCoord1f(u); - glVertex3fv((float *)vertex); - // Increment pointers - vertex = (tVector *)((float *)vertex + model->vSize); - normal = (tVector *)((float *)normal + model->vSize); - } - glEnd(); - - glDisable(GL_TEXTURE_1D); - - // Do the silhouette lines if desired - if (m_Silhouette) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - glColor3fv(&m_SilhouetteColor.r); // Set Line Color - glLineWidth(m_SilhouetteWidth); // Give it some beef - glDepthFunc(GL_LEQUAL); // Draw shared edges - glPolygonMode(GL_BACK,GL_LINE); // Draw Lines - glCullFace(GL_FRONT); // Draw backfacing edges only - - glInterleavedArrays(model->dataFormat,0,(GLvoid *)model->vertexData); - glDrawArrays(GL_TRIANGLES,0,model->faceCnt * 3); - - // Set Everything Back to original settings - glDepthFunc(GL_LESS); - glColor3f(1.0f, 1.0f, 1.0f); - glCullFace(GL_BACK); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawScene -// Purpose: Actually draw the OpenGL Scene -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene() -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Camera.rot.y > 360.0f) m_Camera.rot.y -= 360.0f; - if (m_Camera.rot.x > 360.0f) m_Camera.rot.x -= 360.0f; - if (m_Camera.rot.z > 360.0f) m_Camera.rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set camera's orientation and position - glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); - - glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); - glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f); - - // Draw any loaded model - drawModel(&m_Model); - - glPopMatrix(); - - // glFinish(); - - SwapBuffers(m_hDC); - -} -//// drawScene ////////////////////////////////////////////////////// - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - // STORE OFF THE HIT POINT AND SETTINGS FOR THE MOVEMENT LATER - m_mousepos = point; - m_Dragging = TRUE; - m_Grab_Rot_X = m_Camera.rot.x; - m_Grab_Rot_Y = m_Camera.rot.y; - m_Grab_Rot_Z = m_Camera.rot.z; - m_Grab_Trans_X = m_Camera.trans.x; - m_Grab_Trans_Y = m_Camera.trans.y; - m_Grab_Trans_Z = m_Camera.trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - // STORE OFF THE HIT POINT AND SETTINGS FOR THE MOVEMENT LATER - m_mousepos = point; - m_Dragging = TRUE; - m_Grab_Rot_X = m_Camera.rot.x; - m_Grab_Rot_Y = m_Camera.rot.y; - m_Grab_Rot_Z = m_Camera.rot.z; - m_Grab_Trans_X = m_Camera.trans.x; - m_Grab_Trans_Y = m_Camera.trans.y; - m_Grab_Trans_Z = m_Camera.trans.z; - CWnd::OnRButtonDown(nFlags, point); -} - - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - m_Dragging = FALSE; - CWnd::OnLButtonUp(nFlags, point); -} - -void COGLView::OnRButtonUp(UINT nFlags, CPoint point) -{ - m_Dragging = FALSE; - CWnd::OnRButtonUp(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnMouseMove -// Purpose: Handler for the mouse. Handles movement when pressed -// Arguments: Flags for key masks and point -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (!m_Dragging) return; - -// UpdateStatusBar(0); - if (nFlags & MK_LBUTTON > 0) - { - if ((nFlags & MK_CONTROL) > 0) - { - } - // ELSE "SHIFT" MOVE THE BONE IN XY - else if ((nFlags & MK_SHIFT) > 0) - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) // Rotate Camera in Z - { - m_Camera.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) // Rotate Camera in Y - { - m_Camera.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) // Rotate Camera in X - { - m_Camera.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - UpdateStatusBar(2); - if ((point.x - m_mousepos.x) != 0) // Move Camera in X - { - m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) // Move Camera in Y - { - m_Camera.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(); - } - } - // IF I AM HOLDING THE RM BUTTON Translate IN Z - else - { - UpdateStatusBar(2); - if ((point.x - m_mousepos.x) != 0) // Move Camera in X - { - m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Camera.trans.z = m_Grab_Trans_Z + (.1f * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - - CWnd::OnMouseMove(nFlags, point); -} -//// OnMouseMove ////////////////////////////////////////////////////// - -void COGLView::OnMove(int x, int y) -{ - CWnd::OnMove(x, y); - - resize( x,y ); - -} - -// 0 = READY -// 1 = ROTATE -// 2 = TRANSLATE -void COGLView::UpdateStatusBar(int mode) -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - if (mode == 1) - { - sprintf(message,"Rotate (%.2f,%.2f,%.2f)",m_Camera.rot.x,m_Camera.rot.y,m_Camera.rot.z); - } - else if (mode == 2) - { - sprintf(message,"Translate (%.2f,%.2f,%.2f)",m_Camera.trans.x,m_Camera.trans.y,m_Camera.trans.z); - } - else - { - strcpy(message,"Ready"); - } - m_StatusBar->SetPaneText(0,message); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - switch (nChar) - { - case VK_SPACE: - break; - case 'I': - break; - case 'W': - break; - case 'F': - break; - } - - Invalidate(TRUE); - -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetGLInfo -// Purpose: Get the OpenGL Vendor and Renderer -/////////////////////////////////////////////////////////////////////////////// -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} -//// GetGLInfo ///////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadOBJModel -// Purpose: Load an OBJ Model into the system -// Arguments: Name of the file to open -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::LoadOBJModel(CString name) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - if (m_Model.vertexData != NULL) // Free model data if exists - { - free(m_Model.vertexData); - m_Model.vertexData = NULL; - } - LoadOBJ((LPCSTR)name,&m_Model); - m_Camera.rot.x = 0.0f; - m_Camera.rot.y = 0.0f; - m_Camera.rot.z = 0.0f; - m_Camera.b_trans.y = 0.0f; - m_Camera.b_trans.z = -50.0f; - m_Camera.trans.y = 0.0f; - m_Camera.trans.z = -50.0f; - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadShadeTexture -// Purpose: Load a shaded environment texture -// Arguments: Name of the file to open -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadShadeTexture(const char *texfile) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int loop; - FILE *fp; - char line[255]; - float value; -///////////////////////////////////////////////////////////////////////////////////// - - // Make a Default one One shade with highlight - for (loop = 0; loop < 32; loop++) - { - - if (loop < 8) - { - MAKEVECTOR(m_ShadeSrc[loop], 0.4f, 0.4f, 0.4f) - } - else if (loop < 28) - { - MAKEVECTOR(m_ShadeSrc[loop], 0.9f, 0.9f, 0.9f) - } - else - { - MAKEVECTOR(m_ShadeSrc[loop], 1.0f, 1.0f, 1.0f) - } - } - - // Totally simple file format to load a 1D shade table - // just a list of floats in a text file - fp = fopen(texfile,"r"); - if (fp) - { - for (loop = 0; loop < 32; loop++) - { - if (feof(fp)) - break; - // Get a line from the file - fgets(line,255,fp); - // Convert it to a shade value - value = atof(line); - m_ShadeSrc[loop].x = m_ShadeSrc[loop].y = m_ShadeSrc[loop].z = value; - } - fclose(fp); - } - glBindTexture(GL_TEXTURE_1D, m_ShadeTexture); - - // Do not allow bilinear filtering - not for cartoon rendering - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, - GL_RGB , GL_FLOAT, (float *)m_ShadeSrc); //visual->texData); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: CartoonSettings -// Purpose: Adjust Line Settings for Cartoon Render -// Arguments: Name of the file to open -/////////////////////////////////////////////////////////////////////////////// -void COGLView::CartoonSettings() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - CToonSet dialog; -///////////////////////////////////////////////////////////////////////////////////// - dialog.m_Sil_Red = m_SilhouetteColor.r; - dialog.m_Sil_Green = m_SilhouetteColor.g; - dialog.m_Sil_Blue = m_SilhouetteColor.b; - dialog.m_LineWidth = m_SilhouetteWidth; - dialog.m_Light_X = m_ShadeLight.x; - dialog.m_Light_Y = m_ShadeLight.y; - dialog.m_Light_Z = m_ShadeLight.z; - if (dialog.DoModal()) - { - m_SilhouetteColor.r = dialog.m_Sil_Red; - m_SilhouetteColor.g = dialog.m_Sil_Green; - m_SilhouetteColor.b = dialog.m_Sil_Blue; - m_SilhouetteWidth = dialog.m_LineWidth; - m_ShadeLight.x = dialog.m_Light_X; - m_ShadeLight.y = dialog.m_Light_Y; - m_ShadeLight.z = dialog.m_Light_Z; - NormalizeVector(&m_ShadeLight); // Normalize it since I know I didn't - } - Invalidate(TRUE); -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Cartoon Rendering System +// +// Created: +// JL 1/12/00 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2000 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include "Loony.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "ToonSet.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define OGL_SELECTED_DLIST 2 // SELECTED BONE OPENGL DISPLAY LIST +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_StatusBar = NULL; // CLEAR THIS. IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT + m_AntiAlias = FALSE; + m_Dragging = FALSE; + m_Silhouette = TRUE; + + // INITIALIZE SOME OF THE CAMERA VARIABLES + ResetBone(&m_Camera, NULL); + m_Camera.id = -1; + strcpy(m_Camera.name,"Camera"); + m_Camera.rot.x = 0.0f; + m_Camera.rot.y = 0.0f; + m_Camera.rot.z = 0.0f; + m_Camera.b_trans.y = 0.0f; + m_Camera.b_trans.z = -50.0f; + m_Camera.trans.y = 0.0f; + m_Camera.trans.z = -50.0f; + + m_Model.vertexData = NULL; + + // Set the Default Light Direction + m_ShadeLight.x = 0.3f; + m_ShadeLight.y = 0.1f; + m_ShadeLight.z = 0.8f; + NormalizeVector(&m_ShadeLight); // Normalize it since I know I didn't + + m_SilhouetteColor.r = 0.0f; + m_SilhouetteColor.g = 0.0f; + m_SilhouetteColor.b = 0.0f; + m_SilhouetteWidth = 3; // Width of Silhouette line + +} + +COGLView::~COGLView() +{ +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_MOVE() + ON_WM_LBUTTONUP() + ON_WM_RBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // GENERATE THE OPENGL TEXTURE ID + glGenTextures(1,&m_ShadeTexture); + + LoadShadeTexture("default.shd"); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glEndList(); + + drawScene(); + return 0; +} + +/* OpenGL code */ + +/////////////////////////////////////////////////////////////////////////////// +// Function: resize +// Purpose: This code handles the windows resize for OpenGL +// Arguments: Width and heights of the view window +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(20.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + m_ScreenWidth = width; + m_ScreenHeight = height; + +} +//// resize ///////////////////////////////////////////////////////////////// + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.7f, 0.7f, 0.7f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LESS); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(60.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glPointSize(8.0); // NICE BEEFY POINTS FOR THE VERTEX SELECTION + glDisable(GL_TEXTURE_2D); + + glDisable(GL_LIGHTING); + + glEnable(GL_BLEND); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: CalculateShadow +// Purpose: Calculate the shadow coordinate value for a normal +// Arguments: The vertex normal, Light vector, and Object rotation matrix +// Returns: An index coordinate into the shade table +/////////////////////////////////////////////////////////////////////////////// +float COGLView::CalculateShadow(tVector *normal,tVector *light, tMatrix *mat) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + tVector post; + float dot; +///////////////////////////////////////////////////////////////////////////////////// + // Rotate the normal by the current object matrix + MultVectorByRotMatrix(mat, normal, &post); + dot = DotProduct(&post,light); // Calculate the Dot Product + + if (dot < 0) dot = 0; // Make sure the Back half dark + return fabs(dot); // Return the shadow value +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawModel +// Purpose: Draw the Mesh model either deformed or not +// Arguments: Pointer to the model +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Visual *model) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tMatrix mat; // Needed for Lighting Calc + int loop; + float u; + tVector *vertex, *normal; +/////////////////////////////////////////////////////////////////////////////// + + if (model->vertexData != NULL) + { + // Turn on anti-aliased silhouette lines if selected + if (m_AntiAlias) + { + glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); + glEnable(GL_LINE_SMOOTH); + } + else + glDisable(GL_LINE_SMOOTH); + + glPolygonMode(GL_FRONT,GL_FILL); + + // Bind my 1D shade texture + glEnable(GL_TEXTURE_1D); + glBindTexture( GL_TEXTURE_1D,m_ShadeTexture); + + // Set the Base color of the Model from the material + glColor3fv(&model->Kd.r); + glDisable(GL_LIGHTING); + + // Grab the matrix for lighting calc + glGetFloatv(GL_MODELVIEW_MATRIX,mat.m); + + // Get the Normal and Vertex from any format model that has vertex and normal + switch(model->dataFormat) + { + case GL_T2F_N3F_V3F: + vertex = (tVector *)&model->vertexData[5]; + normal = (tVector *)&model->vertexData[2]; + break; + case GL_N3F_V3F: + vertex = (tVector *)&model->vertexData[3]; + normal = (tVector *)&model->vertexData[0]; + break; + case GL_V3F: + vertex = (tVector *)&model->vertexData[0]; + normal = NULL; + break; + } + + glBegin(GL_TRIANGLES); + for (loop = 0; loop < model->faceCnt * 3; loop++) + { + // calculate an index into the 1D texture using normal and light + u = CalculateShadow(normal,&m_ShadeLight, &mat); + glTexCoord1f(u); + glVertex3fv((float *)vertex); + // Increment pointers + vertex = (tVector *)((float *)vertex + model->vSize); + normal = (tVector *)((float *)normal + model->vSize); + } + glEnd(); + + glDisable(GL_TEXTURE_1D); + + // Do the silhouette lines if desired + if (m_Silhouette) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glColor3fv(&m_SilhouetteColor.r); // Set Line Color + glLineWidth(m_SilhouetteWidth); // Give it some beef + glDepthFunc(GL_LEQUAL); // Draw shared edges + glPolygonMode(GL_BACK,GL_LINE); // Draw Lines + glCullFace(GL_FRONT); // Draw backfacing edges only + + glInterleavedArrays(model->dataFormat,0,(GLvoid *)model->vertexData); + glDrawArrays(GL_TRIANGLES,0,model->faceCnt * 3); + + // Set Everything Back to original settings + glDepthFunc(GL_LESS); + glColor3f(1.0f, 1.0f, 1.0f); + glCullFace(GL_BACK); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawScene +// Purpose: Actually draw the OpenGL Scene +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene() +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Camera.rot.y > 360.0f) m_Camera.rot.y -= 360.0f; + if (m_Camera.rot.x > 360.0f) m_Camera.rot.x -= 360.0f; + if (m_Camera.rot.z > 360.0f) m_Camera.rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set camera's orientation and position + glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); + + glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); + glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f); + + // Draw any loaded model + drawModel(&m_Model); + + glPopMatrix(); + + // glFinish(); + + SwapBuffers(m_hDC); + +} +//// drawScene ////////////////////////////////////////////////////// + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + // STORE OFF THE HIT POINT AND SETTINGS FOR THE MOVEMENT LATER + m_mousepos = point; + m_Dragging = TRUE; + m_Grab_Rot_X = m_Camera.rot.x; + m_Grab_Rot_Y = m_Camera.rot.y; + m_Grab_Rot_Z = m_Camera.rot.z; + m_Grab_Trans_X = m_Camera.trans.x; + m_Grab_Trans_Y = m_Camera.trans.y; + m_Grab_Trans_Z = m_Camera.trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + // STORE OFF THE HIT POINT AND SETTINGS FOR THE MOVEMENT LATER + m_mousepos = point; + m_Dragging = TRUE; + m_Grab_Rot_X = m_Camera.rot.x; + m_Grab_Rot_Y = m_Camera.rot.y; + m_Grab_Rot_Z = m_Camera.rot.z; + m_Grab_Trans_X = m_Camera.trans.x; + m_Grab_Trans_Y = m_Camera.trans.y; + m_Grab_Trans_Z = m_Camera.trans.z; + CWnd::OnRButtonDown(nFlags, point); +} + + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + m_Dragging = FALSE; + CWnd::OnLButtonUp(nFlags, point); +} + +void COGLView::OnRButtonUp(UINT nFlags, CPoint point) +{ + m_Dragging = FALSE; + CWnd::OnRButtonUp(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnMouseMove +// Purpose: Handler for the mouse. Handles movement when pressed +// Arguments: Flags for key masks and point +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (!m_Dragging) return; + +// UpdateStatusBar(0); + if (nFlags & MK_LBUTTON > 0) + { + if ((nFlags & MK_CONTROL) > 0) + { + } + // ELSE "SHIFT" MOVE THE BONE IN XY + else if ((nFlags & MK_SHIFT) > 0) + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) // Rotate Camera in Z + { + m_Camera.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) // Rotate Camera in Y + { + m_Camera.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) // Rotate Camera in X + { + m_Camera.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + UpdateStatusBar(2); + if ((point.x - m_mousepos.x) != 0) // Move Camera in X + { + m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) // Move Camera in Y + { + m_Camera.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(); + } + } + // IF I AM HOLDING THE RM BUTTON Translate IN Z + else + { + UpdateStatusBar(2); + if ((point.x - m_mousepos.x) != 0) // Move Camera in X + { + m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Camera.trans.z = m_Grab_Trans_Z + (.1f * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + + CWnd::OnMouseMove(nFlags, point); +} +//// OnMouseMove ////////////////////////////////////////////////////// + +void COGLView::OnMove(int x, int y) +{ + CWnd::OnMove(x, y); + + resize( x,y ); + +} + +// 0 = READY +// 1 = ROTATE +// 2 = TRANSLATE +void COGLView::UpdateStatusBar(int mode) +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + if (mode == 1) + { + sprintf(message,"Rotate (%.2f,%.2f,%.2f)",m_Camera.rot.x,m_Camera.rot.y,m_Camera.rot.z); + } + else if (mode == 2) + { + sprintf(message,"Translate (%.2f,%.2f,%.2f)",m_Camera.trans.x,m_Camera.trans.y,m_Camera.trans.z); + } + else + { + strcpy(message,"Ready"); + } + m_StatusBar->SetPaneText(0,message); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + switch (nChar) + { + case VK_SPACE: + break; + case 'I': + break; + case 'W': + break; + case 'F': + break; + } + + Invalidate(TRUE); + +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetGLInfo +// Purpose: Get the OpenGL Vendor and Renderer +/////////////////////////////////////////////////////////////////////////////// +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} +//// GetGLInfo ///////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadOBJModel +// Purpose: Load an OBJ Model into the system +// Arguments: Name of the file to open +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::LoadOBJModel(CString name) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + if (m_Model.vertexData != NULL) // Free model data if exists + { + free(m_Model.vertexData); + m_Model.vertexData = NULL; + } + LoadOBJ((LPCSTR)name,&m_Model); + m_Camera.rot.x = 0.0f; + m_Camera.rot.y = 0.0f; + m_Camera.rot.z = 0.0f; + m_Camera.b_trans.y = 0.0f; + m_Camera.b_trans.z = -50.0f; + m_Camera.trans.y = 0.0f; + m_Camera.trans.z = -50.0f; + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadShadeTexture +// Purpose: Load a shaded environment texture +// Arguments: Name of the file to open +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadShadeTexture(const char *texfile) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int loop; + FILE *fp; + char line[255]; + float value; +///////////////////////////////////////////////////////////////////////////////////// + + // Make a Default one One shade with highlight + for (loop = 0; loop < 32; loop++) + { + + if (loop < 8) + { + MAKEVECTOR(m_ShadeSrc[loop], 0.4f, 0.4f, 0.4f) + } + else if (loop < 28) + { + MAKEVECTOR(m_ShadeSrc[loop], 0.9f, 0.9f, 0.9f) + } + else + { + MAKEVECTOR(m_ShadeSrc[loop], 1.0f, 1.0f, 1.0f) + } + } + + // Totally simple file format to load a 1D shade table + // just a list of floats in a text file + fp = fopen(texfile,"r"); + if (fp) + { + for (loop = 0; loop < 32; loop++) + { + if (feof(fp)) + break; + // Get a line from the file + fgets(line,255,fp); + // Convert it to a shade value + value = atof(line); + m_ShadeSrc[loop].x = m_ShadeSrc[loop].y = m_ShadeSrc[loop].z = value; + } + fclose(fp); + } + glBindTexture(GL_TEXTURE_1D, m_ShadeTexture); + + // Do not allow bilinear filtering - not for cartoon rendering + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, + GL_RGB , GL_FLOAT, (float *)m_ShadeSrc); //visual->texData); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: CartoonSettings +// Purpose: Adjust Line Settings for Cartoon Render +// Arguments: Name of the file to open +/////////////////////////////////////////////////////////////////////////////// +void COGLView::CartoonSettings() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + CToonSet dialog; +///////////////////////////////////////////////////////////////////////////////////// + dialog.m_Sil_Red = m_SilhouetteColor.r; + dialog.m_Sil_Green = m_SilhouetteColor.g; + dialog.m_Sil_Blue = m_SilhouetteColor.b; + dialog.m_LineWidth = m_SilhouetteWidth; + dialog.m_Light_X = m_ShadeLight.x; + dialog.m_Light_Y = m_ShadeLight.y; + dialog.m_Light_Z = m_ShadeLight.z; + if (dialog.DoModal()) + { + m_SilhouetteColor.r = dialog.m_Sil_Red; + m_SilhouetteColor.g = dialog.m_Sil_Green; + m_SilhouetteColor.b = dialog.m_Sil_Blue; + m_SilhouetteWidth = dialog.m_LineWidth; + m_ShadeLight.x = dialog.m_Light_X; + m_ShadeLight.y = dialog.m_Light_Y; + m_ShadeLight.z = dialog.m_Light_Z; + NormalizeVector(&m_ShadeLight); // Normalize it since I know I didn't + } + Invalidate(TRUE); +} diff --git a/Cartoon Rendering/Code/OGL/Loony/OGLView.h b/Cartoon Rendering/Code/OGL/Loony/OGLView.h index 88b00b4..0b2dd57 100644 --- a/Cartoon Rendering/Code/OGL/Loony/OGLView.h +++ b/Cartoon Rendering/Code/OGL/Loony/OGLView.h @@ -1,107 +1,107 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Cartoon Rendering System -// -// Created: -// JL 1/12/00 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 200 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - CStatusBar *m_StatusBar; - int m_ScreenWidth, m_ScreenHeight; - BOOL m_AntiAlias, m_Dragging,m_Silhouette; - t_Bone m_Camera; // For the Camera - t_Visual m_Model; // Actual Model to be Drawn - tVector m_ShadeSrc[32]; // Shade Texture - tVector m_ShadeLight; // Light for Calculating Shade - tVector m_SilhouetteColor; // Color For silhouette line - float m_SilhouetteWidth; // Width of Silhouette line - - unsigned int m_ShadeTexture; // Pointer to Shaded texture -// Operations -public: - float CalculateShadow(tVector *normal,tVector *light, tMatrix *mat); - void LoadShadeTexture(const char *texfile); - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawModel(t_Visual *model); - GLvoid drawScene(); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - BOOL LoadOBJModel(CString name); - void CartoonSettings(); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - void UpdateStatusBar(int mode); - void UpdateStatusBarFrameInfo(); - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnMove(int x, int y); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnRButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Cartoon Rendering System +// +// Created: +// JL 1/12/00 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 200 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + CStatusBar *m_StatusBar; + int m_ScreenWidth, m_ScreenHeight; + BOOL m_AntiAlias, m_Dragging,m_Silhouette; + t_Bone m_Camera; // For the Camera + t_Visual m_Model; // Actual Model to be Drawn + tVector m_ShadeSrc[32]; // Shade Texture + tVector m_ShadeLight; // Light for Calculating Shade + tVector m_SilhouetteColor; // Color For silhouette line + float m_SilhouetteWidth; // Width of Silhouette line + + unsigned int m_ShadeTexture; // Pointer to Shaded texture +// Operations +public: + float CalculateShadow(tVector *normal,tVector *light, tMatrix *mat); + void LoadShadeTexture(const char *texfile); + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawModel(t_Visual *model); + GLvoid drawScene(); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + BOOL LoadOBJModel(CString name); + void CartoonSettings(); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + void UpdateStatusBar(int mode); + void UpdateStatusBarFrameInfo(); + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnMove(int x, int y); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cartoon Rendering/Code/OGL/Loony/Skeleton.cpp b/Cartoon Rendering/Code/OGL/Loony/Skeleton.cpp index 31d68b7..7e9e239 100644 --- a/Cartoon Rendering/Code/OGL/Loony/Skeleton.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/Skeleton.cpp @@ -1,257 +1,257 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: DestroySkeleton -// Purpose: Clear memory for a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - if (child->curMatrix) - free(child->curMatrix); - } - free(root->children); - if (root->curMatrix) - free(root->curMatrix); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->CV_select = NULL; // POINTER TO WEIGHTS - root->CV_weight = NULL; // POINTER TO VISUALS - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} -//// DestroySkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ResetSkeleton -// Purpose: Reset a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void ResetSkeleton(t_Bone *bone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - bone->rot.x = bone->b_rot.x; - bone->rot.y = bone->b_rot.y; - bone->rot.z = bone->b_rot.z; - - bone->trans.x = bone->b_trans.x; - bone->trans.y = bone->b_trans.y; - bone->trans.z = bone->b_trans.z; - - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - ResetSkeleton(child); - } - } -} -//// ResetSkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: FreezeSkeleton -// Purpose: Freeze a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void FreezeSkeleton(t_Bone *bone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - bone->b_rot.x = bone->rot.x; - bone->b_rot.y = bone->rot.y; - bone->b_rot.z = bone->rot.z; - - bone->b_trans.x = bone->trans.x; - bone->b_trans.y = bone->trans.y; - bone->b_trans.z = bone->trans.z; - - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - FreezeSkeleton(child); - } - } -} -//// FreezeSkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ResetBone -// Purpose: Reset the bone system and set the parent bone -// Arguments: Pointer to bone system, and parent bone (could be null) -/////////////////////////////////////////////////////////////////////////////// -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - bone->animBlend = 0.0f; - - bone->bsphere = 1.0f; - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER - bone->parent = parent; - bone->CV_select = NULL; // POINTER TO WEIGHTS - bone->CV_weight = NULL; // POINTER TO VISUALS - bone->curMatrix = NULL; -} -//// ResetBone //////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: BoneSetFrame -// Purpose: Set the animation stream for a bone -// Arguments: Pointer to bone system, frame to set to -/////////////////////////////////////////////////////////////////////////////// -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - // THIS HANDLES THE INDIVIDUAL STREAM TYPES. ONLY ONE NOW. - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - -// I DON'T REALLY WANT MY ANIMATION TO DEAL WITH SCALE RIGHT NOW -// EVEN THOUGH IT IS IN THE BVA FILE -// bone->scale.x = offset[6]; -// bone->scale.y = offset[7]; -// bone->scale.z = offset[8]; - break; - - } - } -} -//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: BoneAdvanceFrame -// Purpose: Increment the animation stream for a bone and possible the -// children attached to that bone1 -// Arguments: Pointer to bone system, Delta frame value to move, if it is recursive -/////////////////////////////////////////////////////////////////////////////// -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - // THERE MUST BE SOME THINGS TO ADVANCE - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - // ADVANCE THE STREAM - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } -} -//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: DestroySkeleton +// Purpose: Clear memory for a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + if (child->curMatrix) + free(child->curMatrix); + } + free(root->children); + if (root->curMatrix) + free(root->curMatrix); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->CV_select = NULL; // POINTER TO WEIGHTS + root->CV_weight = NULL; // POINTER TO VISUALS + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} +//// DestroySkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ResetSkeleton +// Purpose: Reset a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void ResetSkeleton(t_Bone *bone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + bone->rot.x = bone->b_rot.x; + bone->rot.y = bone->b_rot.y; + bone->rot.z = bone->b_rot.z; + + bone->trans.x = bone->b_trans.x; + bone->trans.y = bone->b_trans.y; + bone->trans.z = bone->b_trans.z; + + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + ResetSkeleton(child); + } + } +} +//// ResetSkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: FreezeSkeleton +// Purpose: Freeze a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void FreezeSkeleton(t_Bone *bone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + bone->b_rot.x = bone->rot.x; + bone->b_rot.y = bone->rot.y; + bone->b_rot.z = bone->rot.z; + + bone->b_trans.x = bone->trans.x; + bone->b_trans.y = bone->trans.y; + bone->b_trans.z = bone->trans.z; + + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + FreezeSkeleton(child); + } + } +} +//// FreezeSkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ResetBone +// Purpose: Reset the bone system and set the parent bone +// Arguments: Pointer to bone system, and parent bone (could be null) +/////////////////////////////////////////////////////////////////////////////// +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + bone->animBlend = 0.0f; + + bone->bsphere = 1.0f; + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER + bone->parent = parent; + bone->CV_select = NULL; // POINTER TO WEIGHTS + bone->CV_weight = NULL; // POINTER TO VISUALS + bone->curMatrix = NULL; +} +//// ResetBone //////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: BoneSetFrame +// Purpose: Set the animation stream for a bone +// Arguments: Pointer to bone system, frame to set to +/////////////////////////////////////////////////////////////////////////////// +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + // THIS HANDLES THE INDIVIDUAL STREAM TYPES. ONLY ONE NOW. + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + +// I DON'T REALLY WANT MY ANIMATION TO DEAL WITH SCALE RIGHT NOW +// EVEN THOUGH IT IS IN THE BVA FILE +// bone->scale.x = offset[6]; +// bone->scale.y = offset[7]; +// bone->scale.z = offset[8]; + break; + + } + } +} +//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: BoneAdvanceFrame +// Purpose: Increment the animation stream for a bone and possible the +// children attached to that bone1 +// Arguments: Pointer to bone system, Delta frame value to move, if it is recursive +/////////////////////////////////////////////////////////////////////////////// +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + // THERE MUST BE SOME THINGS TO ADVANCE + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + // ADVANCE THE STREAM + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } +} +//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// diff --git a/Cartoon Rendering/Code/OGL/Loony/Skeleton.h b/Cartoon Rendering/Code/OGL/Loony/Skeleton.h index 324a55b..ec0ec63 100644 --- a/Cartoon Rendering/Code/OGL/Loony/Skeleton.h +++ b/Cartoon Rendering/Code/OGL/Loony/Skeleton.h @@ -1,208 +1,208 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -#include "MathDefs.h" - -#define ushort unsigned short -#define uint unsigned int -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Bone Definitions ////////////////////////////////////////////////////////// -#define BONE_DOF_ACTIVE 256 // APPLY DOF -#define BONE_HIDDEN 512 // APPLY DOF - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -typedef struct -{ - float r,g,b,a; -} tColor; - -typedef struct -{ - float u,v; -} t2DCoord; - -typedef struct { - t2DCoord t1[4],t2[4]; - unsigned int TexNdx1; - unsigned int TexNdx2; - unsigned short index[4]; - long type; - long color[4]; // RGB VERTEX COLOR -} tPrimPoly; - -/// Structure Definitions /////////////////////////////////////////////////////// -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - tVector *vertexCol; - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - BOOL *CV_select; // Vertex is selected - float *deformData; // DEFORMED VERTEX DATA - int vSize; // NUMBER OF FLOATS IN A VERTEX - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *faceNormal; // POINTER TO FACE NORMALS - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tColor Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - uint glTex; - long *texData; // - int texWidth,texHeight; - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -}; - -struct t_VWeight -{ - int vertex; - float weight; -}; - -/// Structure Definitions /////////////////////////////////////////////////////// - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - float min_rx, max_rx; // ROTATION X LIMITS - float min_ry, max_ry; // ROTATION Y LIMITS - float min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_select; // POINTER TO CONTROL VERTICES - t_VWeight *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - tMatrix *curMatrix; // STORE THE CURRENT MATRIX -// float elast; // ELASTICITY -}; - -struct t_NewBone -{ - // HIERARCHY INFO - t_NewBone *parent; // Pointer to bone base - int childCnt; // Count of Children - t_NewBone *children; // Pointer to Children - // TRANSFORMATION INFO - tVector b_scale; // Base Scale - tVector b_rot; // Base Rotations - tVector b_trans; // Base Translation - tMatrix baseToWorldMat; // Base to World Origin Transformation - tVector scale; // Current Bone Scale - tVector rot; // Current Bone Rotation - tVector trans; // Current Bone Translation - tMatrix baseToModelMat; // Combined Base to new Model Pose -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetSkeleton(t_Bone *root); -void FreezeSkeleton(t_Bone *bone); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +#include "MathDefs.h" + +#define ushort unsigned short +#define uint unsigned int +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Bone Definitions ////////////////////////////////////////////////////////// +#define BONE_DOF_ACTIVE 256 // APPLY DOF +#define BONE_HIDDEN 512 // APPLY DOF + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +typedef struct +{ + float r,g,b,a; +} tColor; + +typedef struct +{ + float u,v; +} t2DCoord; + +typedef struct { + t2DCoord t1[4],t2[4]; + unsigned int TexNdx1; + unsigned int TexNdx2; + unsigned short index[4]; + long type; + long color[4]; // RGB VERTEX COLOR +} tPrimPoly; + +/// Structure Definitions /////////////////////////////////////////////////////// +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + tVector *vertexCol; + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + BOOL *CV_select; // Vertex is selected + float *deformData; // DEFORMED VERTEX DATA + int vSize; // NUMBER OF FLOATS IN A VERTEX + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *faceNormal; // POINTER TO FACE NORMALS + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tColor Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + uint glTex; + long *texData; // + int texWidth,texHeight; + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +}; + +struct t_VWeight +{ + int vertex; + float weight; +}; + +/// Structure Definitions /////////////////////////////////////////////////////// + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + float min_rx, max_rx; // ROTATION X LIMITS + float min_ry, max_ry; // ROTATION Y LIMITS + float min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_select; // POINTER TO CONTROL VERTICES + t_VWeight *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + tMatrix *curMatrix; // STORE THE CURRENT MATRIX +// float elast; // ELASTICITY +}; + +struct t_NewBone +{ + // HIERARCHY INFO + t_NewBone *parent; // Pointer to bone base + int childCnt; // Count of Children + t_NewBone *children; // Pointer to Children + // TRANSFORMATION INFO + tVector b_scale; // Base Scale + tVector b_rot; // Base Rotations + tVector b_trans; // Base Translation + tMatrix baseToWorldMat; // Base to World Origin Transformation + tVector scale; // Current Bone Scale + tVector rot; // Current Bone Rotation + tVector trans; // Current Bone Translation + tMatrix baseToModelMat; // Combined Base to new Model Pose +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetSkeleton(t_Bone *root); +void FreezeSkeleton(t_Bone *bone); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Cartoon Rendering/Code/OGL/Loony/StdAfx.cpp b/Cartoon Rendering/Code/OGL/Loony/StdAfx.cpp index ef1dfd5..ae3f87e 100644 --- a/Cartoon Rendering/Code/OGL/Loony/StdAfx.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Skully.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Skully.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Cartoon Rendering/Code/OGL/Loony/StdAfx.h b/Cartoon Rendering/Code/OGL/Loony/StdAfx.h index ed96a91..f78606a 100644 --- a/Cartoon Rendering/Code/OGL/Loony/StdAfx.h +++ b/Cartoon Rendering/Code/OGL/Loony/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cartoon Rendering/Code/OGL/Loony/ToonSet.cpp b/Cartoon Rendering/Code/OGL/Loony/ToonSet.cpp index 0194659..591f357 100644 --- a/Cartoon Rendering/Code/OGL/Loony/ToonSet.cpp +++ b/Cartoon Rendering/Code/OGL/Loony/ToonSet.cpp @@ -1,59 +1,59 @@ -// ToonSet.cpp : implementation file -// - -#include "stdafx.h" -#include "loony.h" -#include "ToonSet.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CToonSet dialog - - -CToonSet::CToonSet(CWnd* pParent /*=NULL*/) - : CDialog(CToonSet::IDD, pParent) -{ - //{{AFX_DATA_INIT(CToonSet) - m_Sil_Blue = 0.0f; - m_Sil_Green = 0.0f; - m_Sil_Red = 0.0f; - m_LineWidth = 0.0f; - m_Light_X = 0.0f; - m_Light_Y = 0.0f; - m_Light_Z = 0.0f; - //}}AFX_DATA_INIT -} - - -void CToonSet::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CToonSet) - DDX_Text(pDX, IDC_SIL_BLUE, m_Sil_Blue); - DDV_MinMaxFloat(pDX, m_Sil_Blue, 0.f, 1.f); - DDX_Text(pDX, IDC_SIL_GREEN, m_Sil_Green); - DDV_MinMaxFloat(pDX, m_Sil_Green, 0.f, 1.f); - DDX_Text(pDX, IDC_SIL_RED, m_Sil_Red); - DDV_MinMaxFloat(pDX, m_Sil_Red, 0.f, 1.f); - DDX_Text(pDX, IDC_SIL_WIDTH, m_LineWidth); - DDV_MinMaxFloat(pDX, m_LineWidth, 1.f, 10.f); - DDX_Text(pDX, IDC_LIGHT_X, m_Light_X); - DDX_Text(pDX, IDC_LIGHT_Y, m_Light_Y); - DDX_Text(pDX, IDC_LIGHT_Z, m_Light_Z); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CToonSet, CDialog) - //{{AFX_MSG_MAP(CToonSet) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CToonSet message handlers +// ToonSet.cpp : implementation file +// + +#include "stdafx.h" +#include "loony.h" +#include "ToonSet.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CToonSet dialog + + +CToonSet::CToonSet(CWnd* pParent /*=NULL*/) + : CDialog(CToonSet::IDD, pParent) +{ + //{{AFX_DATA_INIT(CToonSet) + m_Sil_Blue = 0.0f; + m_Sil_Green = 0.0f; + m_Sil_Red = 0.0f; + m_LineWidth = 0.0f; + m_Light_X = 0.0f; + m_Light_Y = 0.0f; + m_Light_Z = 0.0f; + //}}AFX_DATA_INIT +} + + +void CToonSet::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CToonSet) + DDX_Text(pDX, IDC_SIL_BLUE, m_Sil_Blue); + DDV_MinMaxFloat(pDX, m_Sil_Blue, 0.f, 1.f); + DDX_Text(pDX, IDC_SIL_GREEN, m_Sil_Green); + DDV_MinMaxFloat(pDX, m_Sil_Green, 0.f, 1.f); + DDX_Text(pDX, IDC_SIL_RED, m_Sil_Red); + DDV_MinMaxFloat(pDX, m_Sil_Red, 0.f, 1.f); + DDX_Text(pDX, IDC_SIL_WIDTH, m_LineWidth); + DDV_MinMaxFloat(pDX, m_LineWidth, 1.f, 10.f); + DDX_Text(pDX, IDC_LIGHT_X, m_Light_X); + DDX_Text(pDX, IDC_LIGHT_Y, m_Light_Y); + DDX_Text(pDX, IDC_LIGHT_Z, m_Light_Z); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CToonSet, CDialog) + //{{AFX_MSG_MAP(CToonSet) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CToonSet message handlers diff --git a/Cartoon Rendering/Code/OGL/Loony/ToonSet.h b/Cartoon Rendering/Code/OGL/Loony/ToonSet.h index 5cd77fb..3024847 100644 --- a/Cartoon Rendering/Code/OGL/Loony/ToonSet.h +++ b/Cartoon Rendering/Code/OGL/Loony/ToonSet.h @@ -1,52 +1,52 @@ -#if !defined(AFX_TOONSET_H__9FB3CCD9_2BF9_440F_9B7A_90910E067CF7__INCLUDED_) -#define AFX_TOONSET_H__9FB3CCD9_2BF9_440F_9B7A_90910E067CF7__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// ToonSet.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CToonSet dialog - -class CToonSet : public CDialog -{ -// Construction -public: - CToonSet(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CToonSet) - enum { IDD = IDD_CARTOON_SET }; - float m_Sil_Blue; - float m_Sil_Green; - float m_Sil_Red; - float m_LineWidth; - float m_Light_X; - float m_Light_Y; - float m_Light_Z; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CToonSet) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CToonSet) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_TOONSET_H__9FB3CCD9_2BF9_440F_9B7A_90910E067CF7__INCLUDED_) +#if !defined(AFX_TOONSET_H__9FB3CCD9_2BF9_440F_9B7A_90910E067CF7__INCLUDED_) +#define AFX_TOONSET_H__9FB3CCD9_2BF9_440F_9B7A_90910E067CF7__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// ToonSet.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CToonSet dialog + +class CToonSet : public CDialog +{ +// Construction +public: + CToonSet(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CToonSet) + enum { IDD = IDD_CARTOON_SET }; + float m_Sil_Blue; + float m_Sil_Green; + float m_Sil_Red; + float m_LineWidth; + float m_Light_X; + float m_Light_Y; + float m_Light_Z; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CToonSet) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CToonSet) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TOONSET_H__9FB3CCD9_2BF9_440F_9B7A_90910E067CF7__INCLUDED_) diff --git a/Cartoon Rendering/Code/OGL/Loony/readme.txt b/Cartoon Rendering/Code/OGL/Loony/readme.txt index d6c4f1f..d4259cf 100644 --- a/Cartoon Rendering/Code/OGL/Loony/readme.txt +++ b/Cartoon Rendering/Code/OGL/Loony/readme.txt @@ -1,78 +1,78 @@ - -3D Real-time Cartoon Rendering February 2000 --------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the February 2000 -Game Developer magazine. It is meant as a demonstration of -a method for Non-photorealistic cartoon rendering. - -The February issue didn't really do any cartoon shading so there -wasn't much to do. Just the silhouette lines. Lots of people wanted -the app before the March issue though so I am releasing it. - -But since you haven't seen the March issue yet, you won't know -about the shading method. So, here it is in a nutshell: - -I use a 1D texture as a non-linear shading function. The dot product -of the light vector and the surface normal is used to calculate which -entry to grab out of that table. This gets rid of the Gouraud shaded -look and allows me to be very flexible on the shading. - -For this demo, there are 32 entries in the shade table. This may not -be enough precision for some shaders. If you look at the "gradient.shd" -which is a smooth gradient, you will see the banding. This is also -because the bilinear filtering is turned off also. If it was on, -the shader wouldn't look like a Toon. - -You can edit the .SHD files and create your own settings. They are -simple text files. - -Model files are Wavefront OBJs. I get the model base color from the -Diffuse color in the MTL file. - -Use settings to change the line color, width and light direction variables. -Anti-Alias may really slow things down on some OpenGL implementations. -This anti-aliases the sihouette lines. - -Manipulating the View ---------------------------------------------------------------------- -LMB to Rotate view in X and Y -LMB+SHIFT to Rotate in Z - -RMB to Translate in Z -RMB+SHIFT to Translate in X and Y - ---------------------------------------------------------------------- - -Stuff you can do to improve: - -Add support for multiple materials and then add in material lines. -Add blending with a texture. - ---------------------------------------------------------------------- - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX Voodoo or -Voodoo 2. 3DFX Voodoo and Voodoo 2 OpenGL do not support -OpenGL in a window so will not work with this application. - + +3D Real-time Cartoon Rendering February 2000 +-------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the February 2000 +Game Developer magazine. It is meant as a demonstration of +a method for Non-photorealistic cartoon rendering. + +The February issue didn't really do any cartoon shading so there +wasn't much to do. Just the silhouette lines. Lots of people wanted +the app before the March issue though so I am releasing it. + +But since you haven't seen the March issue yet, you won't know +about the shading method. So, here it is in a nutshell: + +I use a 1D texture as a non-linear shading function. The dot product +of the light vector and the surface normal is used to calculate which +entry to grab out of that table. This gets rid of the Gouraud shaded +look and allows me to be very flexible on the shading. + +For this demo, there are 32 entries in the shade table. This may not +be enough precision for some shaders. If you look at the "gradient.shd" +which is a smooth gradient, you will see the banding. This is also +because the bilinear filtering is turned off also. If it was on, +the shader wouldn't look like a Toon. + +You can edit the .SHD files and create your own settings. They are +simple text files. + +Model files are Wavefront OBJs. I get the model base color from the +Diffuse color in the MTL file. + +Use settings to change the line color, width and light direction variables. +Anti-Alias may really slow things down on some OpenGL implementations. +This anti-aliases the sihouette lines. + +Manipulating the View +--------------------------------------------------------------------- +LMB to Rotate view in X and Y +LMB+SHIFT to Rotate in Z + +RMB to Translate in Z +RMB+SHIFT to Translate in X and Y + +--------------------------------------------------------------------- + +Stuff you can do to improve: + +Add support for multiple materials and then add in material lines. +Add blending with a texture. + +--------------------------------------------------------------------- + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX Voodoo or +Voodoo 2. 3DFX Voodoo and Voodoo 2 OpenGL do not support +OpenGL in a window so will not work with this application. + diff --git a/Cartoon Rendering/Code/OGL/Loony/resource.h b/Cartoon Rendering/Code/OGL/Loony/resource.h index 60fa473..ee390e4 100644 --- a/Cartoon Rendering/Code/OGL/Loony/resource.h +++ b/Cartoon Rendering/Code/OGL/Loony/resource.h @@ -1,93 +1,93 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Loony.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SKULLYTYPE 129 -#define IDD_BONE_INFO 132 -#define IDD_CARTOON_SET 132 -#define IDD_SPEED 133 -#define IDD_SIMPROP 134 -#define IDD_ADDSPHERE 138 -#define IDD_WEIGHT 164 -#define IDC_BONE_NAME 1001 -#define IDC_SIL_WIDTH 1001 -#define IDC_TRANS_X 1002 -#define IDC_SIL_RED 1002 -#define IDC_TRANS_Y 1003 -#define IDC_PLAYBACK_SPEED 1003 -#define IDC_SIL_GREEN 1003 -#define IDC_TRANS_Z 1004 -#define IDC_GRAVX 1004 -#define IDC_XPOS 1004 -#define IDC_SIL_BLUE 1004 -#define IDC_ROT_X 1005 -#define IDC_GRAVY 1005 -#define IDC_YPOS 1005 -#define IDC_LIGHT_X 1005 -#define IDC_ROT_Y 1006 -#define IDC_GRAVZ 1006 -#define IDC_ZPOS 1006 -#define IDC_LIGHT_Y 1006 -#define IDC_ROT_Z 1007 -#define IDC_COEFREST 1007 -#define IDC_RADIUS 1007 -#define IDC_LIGHT_Z 1007 -#define IDC_MIN_X 1008 -#define IDC_SPRINGCONST 1008 -#define IDC_MAX_X 1009 -#define IDC_Damping 1009 -#define IDC_MIN_Y 1010 -#define IDC_SPRINGDAMP 1010 -#define IDC_MAX_Y 1011 -#define IDC_USERFORCEMAG 1011 -#define IDC_MIN_Z 1012 -#define IDC_MAX_Z 1013 -#define IDC_BSPHERE 1014 -#define IDC_BONEWEIGHT 1014 -#define IDC_DOF_ACTIVE 1015 -#define IDC_SCRIPTLIST 1232 -#define ID_PLAY_FORWARD 32777 -#define ID_FORWARD_FRAME 32778 -#define ID_STOP 32779 -#define ID_BACK_FRAME 32780 -#define ID_PLAY_BACK 32781 -#define ID_ADD_BONE 32782 -#define ID_DELETE_BONE 32783 -#define ID_VIEW_RESETSKELETON 32784 -#define ID_FILE_LOADANIM 32785 -#define ID_ANIMATION_PLAYBACKSPEED 32788 -#define ID_WHICHOGL 32789 -#define ID_SKELETON_RESETSKELETON 32790 -#define ID_VIEW_OUTLINE 32791 -#define ID_CARTOON_SETTINGS 32791 -#define ID_FILE_OPENCHARACTERMESH 32792 -#define ID_FILE_OPENOBJECTMESH 32792 -#define ID_VIEW_VIEWSKELETON 32793 -#define ID_VIEW_VIEWPARTICLES 32794 -#define ID_FILE_OPENPARTICLESYSTEM 32795 -#define ID_FILE_SAVE_PART 32796 -#define ID_MODEL_REPLACEMESH 32798 -#define ID_MODEL_REPLACETEXTURE 32799 -#define ID_VIEW_DRAWDEFORMED 32800 -#define ID_SKELETON_SETRESTPOSE 32801 -#define ID_SKELETON_SETBONEWEIGHTS 32802 -#define ID_FILE_OPENWEIGHT 32803 -#define ID_SKELETON_CLEARSELECTEDWEIGHTS 32804 -#define ID_CARTOON_ANTIALIAS 32805 -#define ID_CARTOON_DRAWSILHOUETTE 32806 -#define ID_INDICATOR_FRAME 59142 -#define ID_INDICATOR_FRAME2 59143 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 135 -#define _APS_NEXT_COMMAND_VALUE 32807 -#define _APS_NEXT_CONTROL_VALUE 1016 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Loony.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SKULLYTYPE 129 +#define IDD_BONE_INFO 132 +#define IDD_CARTOON_SET 132 +#define IDD_SPEED 133 +#define IDD_SIMPROP 134 +#define IDD_ADDSPHERE 138 +#define IDD_WEIGHT 164 +#define IDC_BONE_NAME 1001 +#define IDC_SIL_WIDTH 1001 +#define IDC_TRANS_X 1002 +#define IDC_SIL_RED 1002 +#define IDC_TRANS_Y 1003 +#define IDC_PLAYBACK_SPEED 1003 +#define IDC_SIL_GREEN 1003 +#define IDC_TRANS_Z 1004 +#define IDC_GRAVX 1004 +#define IDC_XPOS 1004 +#define IDC_SIL_BLUE 1004 +#define IDC_ROT_X 1005 +#define IDC_GRAVY 1005 +#define IDC_YPOS 1005 +#define IDC_LIGHT_X 1005 +#define IDC_ROT_Y 1006 +#define IDC_GRAVZ 1006 +#define IDC_ZPOS 1006 +#define IDC_LIGHT_Y 1006 +#define IDC_ROT_Z 1007 +#define IDC_COEFREST 1007 +#define IDC_RADIUS 1007 +#define IDC_LIGHT_Z 1007 +#define IDC_MIN_X 1008 +#define IDC_SPRINGCONST 1008 +#define IDC_MAX_X 1009 +#define IDC_Damping 1009 +#define IDC_MIN_Y 1010 +#define IDC_SPRINGDAMP 1010 +#define IDC_MAX_Y 1011 +#define IDC_USERFORCEMAG 1011 +#define IDC_MIN_Z 1012 +#define IDC_MAX_Z 1013 +#define IDC_BSPHERE 1014 +#define IDC_BONEWEIGHT 1014 +#define IDC_DOF_ACTIVE 1015 +#define IDC_SCRIPTLIST 1232 +#define ID_PLAY_FORWARD 32777 +#define ID_FORWARD_FRAME 32778 +#define ID_STOP 32779 +#define ID_BACK_FRAME 32780 +#define ID_PLAY_BACK 32781 +#define ID_ADD_BONE 32782 +#define ID_DELETE_BONE 32783 +#define ID_VIEW_RESETSKELETON 32784 +#define ID_FILE_LOADANIM 32785 +#define ID_ANIMATION_PLAYBACKSPEED 32788 +#define ID_WHICHOGL 32789 +#define ID_SKELETON_RESETSKELETON 32790 +#define ID_VIEW_OUTLINE 32791 +#define ID_CARTOON_SETTINGS 32791 +#define ID_FILE_OPENCHARACTERMESH 32792 +#define ID_FILE_OPENOBJECTMESH 32792 +#define ID_VIEW_VIEWSKELETON 32793 +#define ID_VIEW_VIEWPARTICLES 32794 +#define ID_FILE_OPENPARTICLESYSTEM 32795 +#define ID_FILE_SAVE_PART 32796 +#define ID_MODEL_REPLACEMESH 32798 +#define ID_MODEL_REPLACETEXTURE 32799 +#define ID_VIEW_DRAWDEFORMED 32800 +#define ID_SKELETON_SETRESTPOSE 32801 +#define ID_SKELETON_SETBONEWEIGHTS 32802 +#define ID_FILE_OPENWEIGHT 32803 +#define ID_SKELETON_CLEARSELECTEDWEIGHTS 32804 +#define ID_CARTOON_ANTIALIAS 32805 +#define ID_CARTOON_DRAWSILHOUETTE 32806 +#define ID_INDICATOR_FRAME 59142 +#define ID_INDICATOR_FRAME2 59143 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 135 +#define _APS_NEXT_COMMAND_VALUE 32807 +#define _APS_NEXT_CONTROL_VALUE 1016 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.cpp index af1804d..56d11c0 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.cpp @@ -1,50 +1,50 @@ -// AddSpher.cpp : implementation file -// - -#include "stdafx.h" -#include "clothy.h" -#include "AddSpher.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CAddSpher dialog - - -CAddSpher::CAddSpher(CWnd* pParent /*=NULL*/) - : CDialog(CAddSpher::IDD, pParent) -{ - //{{AFX_DATA_INIT(CAddSpher) - m_Radius = 0.0f; - m_XPos = 0.0f; - m_YPos = 0.0f; - m_ZPos = 0.0f; - //}}AFX_DATA_INIT -} - - -void CAddSpher::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAddSpher) - DDX_Text(pDX, IDC_RADIUS, m_Radius); - DDV_MinMaxFloat(pDX, m_Radius, 1.e-003f, 10.f); - DDX_Text(pDX, IDC_XPOS, m_XPos); - DDX_Text(pDX, IDC_YPOS, m_YPos); - DDX_Text(pDX, IDC_ZPOS, m_ZPos); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CAddSpher, CDialog) - //{{AFX_MSG_MAP(CAddSpher) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CAddSpher message handlers +// AddSpher.cpp : implementation file +// + +#include "stdafx.h" +#include "clothy.h" +#include "AddSpher.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CAddSpher dialog + + +CAddSpher::CAddSpher(CWnd* pParent /*=NULL*/) + : CDialog(CAddSpher::IDD, pParent) +{ + //{{AFX_DATA_INIT(CAddSpher) + m_Radius = 0.0f; + m_XPos = 0.0f; + m_YPos = 0.0f; + m_ZPos = 0.0f; + //}}AFX_DATA_INIT +} + + +void CAddSpher::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAddSpher) + DDX_Text(pDX, IDC_RADIUS, m_Radius); + DDV_MinMaxFloat(pDX, m_Radius, 1.e-003f, 10.f); + DDX_Text(pDX, IDC_XPOS, m_XPos); + DDX_Text(pDX, IDC_YPOS, m_YPos); + DDX_Text(pDX, IDC_ZPOS, m_ZPos); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CAddSpher, CDialog) + //{{AFX_MSG_MAP(CAddSpher) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CAddSpher message handlers diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.h index 30aefe5..e4a02fb 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/AddSpher.h @@ -1,49 +1,49 @@ -#if !defined(AFX_ADDSPHER_H__F770F421_F0FE_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_ADDSPHER_H__F770F421_F0FE_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// AddSpher.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CAddSpher dialog - -class CAddSpher : public CDialog -{ -// Construction -public: - CAddSpher(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CAddSpher) - enum { IDD = IDD_ADDSPHERE }; - float m_Radius; - float m_XPos; - float m_YPos; - float m_ZPos; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAddSpher) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CAddSpher) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_ADDSPHER_H__F770F421_F0FE_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_ADDSPHER_H__F770F421_F0FE_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_ADDSPHER_H__F770F421_F0FE_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// AddSpher.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CAddSpher dialog + +class CAddSpher : public CDialog +{ +// Construction +public: + CAddSpher(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CAddSpher) + enum { IDD = IDD_ADDSPHERE }; + float m_Radius; + float m_XPos; + float m_YPos; + float m_ZPos; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAddSpher) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CAddSpher) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ADDSPHER_H__F770F421_F0FE_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.cpp index 4c54a3c..ac73cde 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Clothy.cpp : Defines the class behaviors for the application. -// -// Purpose: Application file for 3D Cloth Simulation -// -// Created: -// JL 2/12/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Clothy.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CClothyApp - -BEGIN_MESSAGE_MAP(CClothyApp, CWinApp) - //{{AFX_MSG_MAP(CClothyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CClothyApp construction - -CClothyApp::CClothyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CClothyApp object - -CClothyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CClothyApp initialization - -BOOL CClothyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CClothyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CClothyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Clothy.cpp : Defines the class behaviors for the application. +// +// Purpose: Application file for 3D Cloth Simulation +// +// Created: +// JL 2/12/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Clothy.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CClothyApp + +BEGIN_MESSAGE_MAP(CClothyApp, CWinApp) + //{{AFX_MSG_MAP(CClothyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CClothyApp construction + +CClothyApp::CClothyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CClothyApp object + +CClothyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CClothyApp initialization + +BOOL CClothyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CClothyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CClothyApp commands diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.h index 44fa045..c901234 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.h @@ -1,67 +1,67 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Clothy.h : main header file for the Clothy application -// -// Purpose: Application file for 3D Cloth Simulation -// -// Created: -// JL 2/12/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Clothy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Clothy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID - -///////////////////////////////////////////////////////////////////////////// -// CClothyApp: -// See Clothy.cpp for the implementation of this class -// - -class CClothyApp : public CWinApp -{ -public: - CClothyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CClothyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CClothyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Clothy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Clothy.h : main header file for the Clothy application +// +// Purpose: Application file for 3D Cloth Simulation +// +// Created: +// JL 2/12/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Clothy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Clothy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID + +///////////////////////////////////////////////////////////////////////////// +// CClothyApp: +// See Clothy.cpp for the implementation of this class +// + +class CClothyApp : public CWinApp +{ +public: + CClothyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CClothyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CClothyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Clothy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.mak b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.mak index 57d6731..47b6a34 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.mak +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Clothy.mak @@ -1,394 +1,394 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Clothy.dsp -!IF "$(CFG)" == "" -CFG=Clothy - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Clothy - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Clothy - Win32 Release" && "$(CFG)" != "Clothy - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Clothy.mak" CFG="Clothy - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Clothy - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Clothy - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Clothy - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\Clothy.exe" "$(OUTDIR)\Clothy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\AddSpher.obj" - -@erase "$(INTDIR)\AddSpher.sbr" - -@erase "$(INTDIR)\Clothy.obj" - -@erase "$(INTDIR)\Clothy.pch" - -@erase "$(INTDIR)\Clothy.res" - -@erase "$(INTDIR)\Clothy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\NewCloth.obj" - -@erase "$(INTDIR)\NewCloth.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PhysEnv.obj" - -@erase "$(INTDIR)\PhysEnv.sbr" - -@erase "$(INTDIR)\SetVert.obj" - -@erase "$(INTDIR)\SetVert.sbr" - -@erase "$(INTDIR)\SimProps.obj" - -@erase "$(INTDIR)\SimProps.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\TimeProps.obj" - -@erase "$(INTDIR)\TimeProps.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\Clothy.bsc" - -@erase "$(OUTDIR)\Clothy.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Clothy.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Clothy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\AddSpher.sbr" \ - "$(INTDIR)\Clothy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\NewCloth.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PhysEnv.sbr" \ - "$(INTDIR)\SetVert.sbr" \ - "$(INTDIR)\SimProps.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" \ - "$(INTDIR)\TimeProps.sbr" - -"$(OUTDIR)\Clothy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Clothy.pdb" /machine:I386 /out:"$(OUTDIR)\Clothy.exe" -LINK32_OBJS= \ - "$(INTDIR)\AddSpher.obj" \ - "$(INTDIR)\Clothy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\NewCloth.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PhysEnv.obj" \ - "$(INTDIR)\SetVert.obj" \ - "$(INTDIR)\SimProps.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\TimeProps.obj" \ - "$(INTDIR)\Clothy.res" - -"$(OUTDIR)\Clothy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Clothy - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "$(OUTDIR)\Clothy.exe" "$(OUTDIR)\Clothy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\AddSpher.obj" - -@erase "$(INTDIR)\AddSpher.sbr" - -@erase "$(INTDIR)\Clothy.obj" - -@erase "$(INTDIR)\Clothy.pch" - -@erase "$(INTDIR)\Clothy.res" - -@erase "$(INTDIR)\Clothy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\NewCloth.obj" - -@erase "$(INTDIR)\NewCloth.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PhysEnv.obj" - -@erase "$(INTDIR)\PhysEnv.sbr" - -@erase "$(INTDIR)\SetVert.obj" - -@erase "$(INTDIR)\SetVert.sbr" - -@erase "$(INTDIR)\SimProps.obj" - -@erase "$(INTDIR)\SimProps.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\TimeProps.obj" - -@erase "$(INTDIR)\TimeProps.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\Clothy.bsc" - -@erase "$(OUTDIR)\Clothy.exe" - -@erase "$(OUTDIR)\Clothy.ilk" - -@erase "$(OUTDIR)\Clothy.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Clothy.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Clothy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\AddSpher.sbr" \ - "$(INTDIR)\Clothy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\NewCloth.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PhysEnv.sbr" \ - "$(INTDIR)\SetVert.sbr" \ - "$(INTDIR)\SimProps.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" \ - "$(INTDIR)\TimeProps.sbr" - -"$(OUTDIR)\Clothy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Clothy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Clothy.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\AddSpher.obj" \ - "$(INTDIR)\Clothy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\NewCloth.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PhysEnv.obj" \ - "$(INTDIR)\SetVert.obj" \ - "$(INTDIR)\SimProps.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\TimeProps.obj" \ - "$(INTDIR)\Clothy.res" - -"$(OUTDIR)\Clothy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("Clothy.dep") -!INCLUDE "Clothy.dep" -!ELSE -!MESSAGE Warning: cannot find "Clothy.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "Clothy - Win32 Release" || "$(CFG)" == "Clothy - Win32 Debug" -SOURCE=.\AddSpher.cpp - -"$(INTDIR)\AddSpher.obj" "$(INTDIR)\AddSpher.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\Clothy.cpp - -"$(INTDIR)\Clothy.obj" "$(INTDIR)\Clothy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\Clothy.rc - -"$(INTDIR)\Clothy.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\LoadOBJ.cpp - -"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\MainFrm.cpp - -"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\MathDefs.cpp - -"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\NewCloth.cpp - -"$(INTDIR)\NewCloth.obj" "$(INTDIR)\NewCloth.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\OGLView.cpp - -"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\PhysEnv.cpp - -"$(INTDIR)\PhysEnv.obj" "$(INTDIR)\PhysEnv.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\SetVert.cpp - -"$(INTDIR)\SetVert.obj" "$(INTDIR)\SetVert.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\SimProps.cpp - -"$(INTDIR)\SimProps.obj" "$(INTDIR)\SimProps.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\Skeleton.cpp - -"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - -SOURCE=.\StdAfx.cpp - -!IF "$(CFG)" == "Clothy - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Clothy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Clothy - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Clothy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - -SOURCE=.\TimeProps.cpp - -"$(INTDIR)\TimeProps.obj" "$(INTDIR)\TimeProps.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" - - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Clothy.dsp +!IF "$(CFG)" == "" +CFG=Clothy - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Clothy - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Clothy - Win32 Release" && "$(CFG)" != "Clothy - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Clothy.mak" CFG="Clothy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Clothy - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Clothy - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Clothy - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\Clothy.exe" "$(OUTDIR)\Clothy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\AddSpher.obj" + -@erase "$(INTDIR)\AddSpher.sbr" + -@erase "$(INTDIR)\Clothy.obj" + -@erase "$(INTDIR)\Clothy.pch" + -@erase "$(INTDIR)\Clothy.res" + -@erase "$(INTDIR)\Clothy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\NewCloth.obj" + -@erase "$(INTDIR)\NewCloth.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PhysEnv.obj" + -@erase "$(INTDIR)\PhysEnv.sbr" + -@erase "$(INTDIR)\SetVert.obj" + -@erase "$(INTDIR)\SetVert.sbr" + -@erase "$(INTDIR)\SimProps.obj" + -@erase "$(INTDIR)\SimProps.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\TimeProps.obj" + -@erase "$(INTDIR)\TimeProps.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\Clothy.bsc" + -@erase "$(OUTDIR)\Clothy.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Clothy.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Clothy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\AddSpher.sbr" \ + "$(INTDIR)\Clothy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\NewCloth.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PhysEnv.sbr" \ + "$(INTDIR)\SetVert.sbr" \ + "$(INTDIR)\SimProps.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" \ + "$(INTDIR)\TimeProps.sbr" + +"$(OUTDIR)\Clothy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Clothy.pdb" /machine:I386 /out:"$(OUTDIR)\Clothy.exe" +LINK32_OBJS= \ + "$(INTDIR)\AddSpher.obj" \ + "$(INTDIR)\Clothy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\NewCloth.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PhysEnv.obj" \ + "$(INTDIR)\SetVert.obj" \ + "$(INTDIR)\SimProps.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\TimeProps.obj" \ + "$(INTDIR)\Clothy.res" + +"$(OUTDIR)\Clothy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Clothy - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\Clothy.exe" "$(OUTDIR)\Clothy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\AddSpher.obj" + -@erase "$(INTDIR)\AddSpher.sbr" + -@erase "$(INTDIR)\Clothy.obj" + -@erase "$(INTDIR)\Clothy.pch" + -@erase "$(INTDIR)\Clothy.res" + -@erase "$(INTDIR)\Clothy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\NewCloth.obj" + -@erase "$(INTDIR)\NewCloth.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PhysEnv.obj" + -@erase "$(INTDIR)\PhysEnv.sbr" + -@erase "$(INTDIR)\SetVert.obj" + -@erase "$(INTDIR)\SetVert.sbr" + -@erase "$(INTDIR)\SimProps.obj" + -@erase "$(INTDIR)\SimProps.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\TimeProps.obj" + -@erase "$(INTDIR)\TimeProps.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\Clothy.bsc" + -@erase "$(OUTDIR)\Clothy.exe" + -@erase "$(OUTDIR)\Clothy.ilk" + -@erase "$(OUTDIR)\Clothy.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Clothy.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Clothy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\AddSpher.sbr" \ + "$(INTDIR)\Clothy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\NewCloth.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PhysEnv.sbr" \ + "$(INTDIR)\SetVert.sbr" \ + "$(INTDIR)\SimProps.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" \ + "$(INTDIR)\TimeProps.sbr" + +"$(OUTDIR)\Clothy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Clothy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Clothy.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\AddSpher.obj" \ + "$(INTDIR)\Clothy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\NewCloth.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PhysEnv.obj" \ + "$(INTDIR)\SetVert.obj" \ + "$(INTDIR)\SimProps.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\TimeProps.obj" \ + "$(INTDIR)\Clothy.res" + +"$(OUTDIR)\Clothy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("Clothy.dep") +!INCLUDE "Clothy.dep" +!ELSE +!MESSAGE Warning: cannot find "Clothy.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "Clothy - Win32 Release" || "$(CFG)" == "Clothy - Win32 Debug" +SOURCE=.\AddSpher.cpp + +"$(INTDIR)\AddSpher.obj" "$(INTDIR)\AddSpher.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\Clothy.cpp + +"$(INTDIR)\Clothy.obj" "$(INTDIR)\Clothy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\Clothy.rc + +"$(INTDIR)\Clothy.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\LoadOBJ.cpp + +"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\MainFrm.cpp + +"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\MathDefs.cpp + +"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\NewCloth.cpp + +"$(INTDIR)\NewCloth.obj" "$(INTDIR)\NewCloth.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\OGLView.cpp + +"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\PhysEnv.cpp + +"$(INTDIR)\PhysEnv.obj" "$(INTDIR)\PhysEnv.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\SetVert.cpp + +"$(INTDIR)\SetVert.obj" "$(INTDIR)\SetVert.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\SimProps.cpp + +"$(INTDIR)\SimProps.obj" "$(INTDIR)\SimProps.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\Skeleton.cpp + +"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + +SOURCE=.\StdAfx.cpp + +!IF "$(CFG)" == "Clothy - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Clothy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Clothy - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Clothy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Clothy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + +SOURCE=.\TimeProps.cpp + +"$(INTDIR)\TimeProps.obj" "$(INTDIR)\TimeProps.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Clothy.pch" + + + +!ENDIF + diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.cpp index 144fb4e..29c273c 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.cpp @@ -1,376 +1,376 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = (float)atof(words.GetAt(1)); - visual->Ka.g = (float)atof(words.GetAt(2)); - visual->Ka.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = (float)atof(words.GetAt(1)); - visual->Kd.g = (float)atof(words.GetAt(2)); - visual->Kd.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = (float)atof(words.GetAt(1)); - visual->Ks.g = (float)atof(words.GetAt(2)); - visual->Ks.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = (float)atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle anything other than -// 3-4 vertex polygons. -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loopcnt; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - loopcnt = words->GetSize(); - - // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < loopcnt; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } - face->flags = 0; - if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; - if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; - if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; - else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; - else - { - ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); - face->flags |= FACE_TYPE_TRI; - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone, flags of what to load -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; - unsigned short *indexData; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = (float)atof(words.GetAt(1)); - normal[nPos].y = (float)atof(words.GetAt(2)); - normal[nPos].z = (float)atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = (float)atof(words.GetAt(1)); - texture[tPos].v = (float)atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = (float)atof(words.GetAt(1)); - vertex[vPos].y = (float)atof(words.GetAt(2)); - vertex[vPos].z = (float)atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 5) - { - sprintf(buffer,"Face %d has more than 4 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS - // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF - // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER - if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; - else visual->vPerFace = 4; - - if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - } - visual->faceCnt = fPos; - if ((flags & LOADOBJ_REUSEVERTICES) > 0) - { - visual->reuseVertices = TRUE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); - visual->vertexCnt = vPos; - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); - if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA - { - memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); - } - else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS - { - visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT - } - } - else - { - visual->reuseVertices = FALSE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->vertexCnt = fPos * visual->vPerFace; - visual->faceIndex = NULL; - } - - data = visual->vertexData; - indexData = visual->faceIndex; - for (loop = 0; loop < fPos; loop++) - { - // ERROR CHECKING TO MAKE SURE - if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - - for (loop2 = 0; loop2 < visual->vPerFace; loop2++) - { - // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT - if ((flags & LOADOBJ_REUSEVERTICES) == 0) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - } - else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE - { - *indexData++ = face[loop].v[loop2] - 1; - } - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = (float)atof(words.GetAt(1)); + visual->Ka.g = (float)atof(words.GetAt(2)); + visual->Ka.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = (float)atof(words.GetAt(1)); + visual->Kd.g = (float)atof(words.GetAt(2)); + visual->Kd.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = (float)atof(words.GetAt(1)); + visual->Ks.g = (float)atof(words.GetAt(2)); + visual->Ks.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = (float)atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle anything other than +// 3-4 vertex polygons. +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loopcnt; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + loopcnt = words->GetSize(); + + // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < loopcnt; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } + face->flags = 0; + if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; + if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; + if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; + else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; + else + { + ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); + face->flags |= FACE_TYPE_TRI; + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone, flags of what to load +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; + unsigned short *indexData; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = (float)atof(words.GetAt(1)); + normal[nPos].y = (float)atof(words.GetAt(2)); + normal[nPos].z = (float)atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = (float)atof(words.GetAt(1)); + texture[tPos].v = (float)atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = (float)atof(words.GetAt(1)); + vertex[vPos].y = (float)atof(words.GetAt(2)); + vertex[vPos].z = (float)atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 5) + { + sprintf(buffer,"Face %d has more than 4 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS + // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF + // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER + if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; + else visual->vPerFace = 4; + + if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + } + visual->faceCnt = fPos; + if ((flags & LOADOBJ_REUSEVERTICES) > 0) + { + visual->reuseVertices = TRUE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); + visual->vertexCnt = vPos; + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); + if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA + { + memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); + } + else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS + { + visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT + } + } + else + { + visual->reuseVertices = FALSE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->vertexCnt = fPos * visual->vPerFace; + visual->faceIndex = NULL; + } + + data = visual->vertexData; + indexData = visual->faceIndex; + for (loop = 0; loop < fPos; loop++) + { + // ERROR CHECKING TO MAKE SURE + if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + + for (loop2 = 0; loop2 < visual->vPerFace; loop2++) + { + // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT + if ((flags & LOADOBJ_REUSEVERTICES) == 0) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + } + else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE + { + *indexData++ = face[loop].v[loop2] - 1; + } + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.h index 2b75bb3..8184168 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/LoadOBJ.h @@ -1,46 +1,46 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -enum LOAD_OBJFLAGS -{ - LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO - LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA - LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS -}; - -// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS -typedef struct -{ - long v[4],n[4],t[4]; - int flags; // FACE TYPES -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +enum LOAD_OBJFLAGS +{ + LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO + LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA + LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS +}; + +// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS +typedef struct +{ + long v[4],n[4],t[4]; + int flags; // FACE TYPES +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.cpp index 281838f..773017b 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.cpp @@ -1,438 +1,438 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Cloth Simulation -// -// Created: -// JL 2/12/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Clothy.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) - ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) - ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) - ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) - ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) - ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) - ON_WM_CLOSE() - ON_COMMAND(ID_FILE_CREATECLOTHPATCH, OnFileCreateclothpatch) - ON_COMMAND(ID_SIMULATION_SETVERTEXPROPERTIES, OnSimulationSetvertexproperties) - ON_COMMAND(ID_VIEW_COLLISIONACTIVE, OnViewCollisionactive) - ON_UPDATE_COMMAND_UI(ID_VIEW_COLLISIONACTIVE, OnUpdateViewCollisionactive) - ON_COMMAND(ID_VIEW_SHOWSHEAR, OnViewShowshear) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSHEAR, OnUpdateViewShowshear) - ON_COMMAND(ID_VIEW_SHOWSTRUCTURAL, OnViewShowstructural) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSTRUCTURAL, OnUpdateViewShowstructural) - ON_COMMAND(ID_VIEW_SHOWBEND, OnViewShowbend) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWBEND, OnUpdateViewShowbend) - ON_COMMAND(ID_INTEULER, OnInteuler) - ON_UPDATE_COMMAND_UI(ID_INTEULER, OnUpdateInteuler) - ON_COMMAND(ID_INTMIDPOINT, OnIntmidpoint) - ON_UPDATE_COMMAND_UI(ID_INTMIDPOINT, OnUpdateIntmidpoint) - ON_COMMAND(ID_INTRK4, OnIntrk4) - ON_UPDATE_COMMAND_UI(ID_INTRK4, OnUpdateIntrk4) - ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) - ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) - ON_COMMAND(ID_SIMULATION_ADDCOLLISIONSPHERE, OnSimulationAddcollisionsphere) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom - - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case ' ': - break; - } - m_OGLView.HandleKeyUp(nChar); -// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -} - - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnFileNewsystem() -{ - m_OGLView.NewSystem(); -} - -void CMainFrame::OnFileOpen() -{ - char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnFileSave() -{ - char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnSimulationRunning() -{ - m_OGLView.HandleKeyUp('R'); -// m_OGLView.m_SimRunning = !m_OGLView.m_SimRunning; -// m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_SimRunning ); -} - -void CMainFrame::OnSimulationReset() -{ - m_OGLView.m_PhysEnv.ResetWorld(); - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnSimulationSetsimproperties() -{ - m_OGLView.OnSimulationSetsimproperties(); -} - -void CMainFrame::OnSimulationSetvertexproperties() -{ - m_OGLView.OnSetVertexProperties(); -} - -void CMainFrame::OnSimulationUsegravity() -{ - m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); -} - - -void CMainFrame::OnViewShowgeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnViewShowsprings() -{ - m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); -} - -void CMainFrame::OnViewShowstructural() -{ - m_OGLView.m_PhysEnv.m_DrawStructural = !m_OGLView.m_PhysEnv.m_DrawStructural; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowstructural(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawStructural ); -} - -void CMainFrame::OnViewShowshear() -{ - m_OGLView.m_PhysEnv.m_DrawShear = !m_OGLView.m_PhysEnv.m_DrawShear; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowshear(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawShear ); -} - -void CMainFrame::OnViewShowbend() -{ - m_OGLView.m_PhysEnv.m_DrawBend = !m_OGLView.m_PhysEnv.m_DrawBend; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowbend(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawBend ); -} - -void CMainFrame::OnViewShowvertices() -{ - m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); -} - -void CMainFrame::OnClose() -{ - m_OGLView.m_SimRunning = FALSE; - - CFrameWnd::OnClose(); -} - -BOOL CMainFrame::DestroyWindow() -{ - - return CFrameWnd::DestroyWindow(); -} - -void CMainFrame::OnFileCreateclothpatch() -{ - m_OGLView.CreateClothPatch(); - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnViewCollisionactive() -{ - m_OGLView.m_PhysEnv.m_CollisionActive = !m_OGLView.m_PhysEnv.m_CollisionActive; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewCollisionactive(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_CollisionActive ); -} - - -void CMainFrame::OnInteuler() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = EULER_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateInteuler(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == EULER_INTEGRATOR ); -} - -void CMainFrame::OnIntmidpoint() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = MIDPOINT_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntmidpoint(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == MIDPOINT_INTEGRATOR ); -} - -void CMainFrame::OnIntrk4() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = RK4_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntrk4(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == RK4_INTEGRATOR ); -} - -void CMainFrame::OnSimulationSettimingproperties() -{ - m_OGLView.OnSetTimeProperties(); -} - -// Add a collision sphere to the physical simulation -void CMainFrame::OnSimulationAddcollisionsphere() -{ - m_OGLView.m_PhysEnv.AddCollisionSphere(); - m_OGLView.Invalidate(TRUE); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Cloth Simulation +// +// Created: +// JL 2/12/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Clothy.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) + ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) + ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) + ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) + ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) + ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) + ON_WM_CLOSE() + ON_COMMAND(ID_FILE_CREATECLOTHPATCH, OnFileCreateclothpatch) + ON_COMMAND(ID_SIMULATION_SETVERTEXPROPERTIES, OnSimulationSetvertexproperties) + ON_COMMAND(ID_VIEW_COLLISIONACTIVE, OnViewCollisionactive) + ON_UPDATE_COMMAND_UI(ID_VIEW_COLLISIONACTIVE, OnUpdateViewCollisionactive) + ON_COMMAND(ID_VIEW_SHOWSHEAR, OnViewShowshear) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSHEAR, OnUpdateViewShowshear) + ON_COMMAND(ID_VIEW_SHOWSTRUCTURAL, OnViewShowstructural) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSTRUCTURAL, OnUpdateViewShowstructural) + ON_COMMAND(ID_VIEW_SHOWBEND, OnViewShowbend) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWBEND, OnUpdateViewShowbend) + ON_COMMAND(ID_INTEULER, OnInteuler) + ON_UPDATE_COMMAND_UI(ID_INTEULER, OnUpdateInteuler) + ON_COMMAND(ID_INTMIDPOINT, OnIntmidpoint) + ON_UPDATE_COMMAND_UI(ID_INTMIDPOINT, OnUpdateIntmidpoint) + ON_COMMAND(ID_INTRK4, OnIntrk4) + ON_UPDATE_COMMAND_UI(ID_INTRK4, OnUpdateIntrk4) + ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) + ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) + ON_COMMAND(ID_SIMULATION_ADDCOLLISIONSPHERE, OnSimulationAddcollisionsphere) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom + + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case ' ': + break; + } + m_OGLView.HandleKeyUp(nChar); +// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +} + + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnFileNewsystem() +{ + m_OGLView.NewSystem(); +} + +void CMainFrame::OnFileOpen() +{ + char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnFileSave() +{ + char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnSimulationRunning() +{ + m_OGLView.HandleKeyUp('R'); +// m_OGLView.m_SimRunning = !m_OGLView.m_SimRunning; +// m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_SimRunning ); +} + +void CMainFrame::OnSimulationReset() +{ + m_OGLView.m_PhysEnv.ResetWorld(); + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnSimulationSetsimproperties() +{ + m_OGLView.OnSimulationSetsimproperties(); +} + +void CMainFrame::OnSimulationSetvertexproperties() +{ + m_OGLView.OnSetVertexProperties(); +} + +void CMainFrame::OnSimulationUsegravity() +{ + m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); +} + + +void CMainFrame::OnViewShowgeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnViewShowsprings() +{ + m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); +} + +void CMainFrame::OnViewShowstructural() +{ + m_OGLView.m_PhysEnv.m_DrawStructural = !m_OGLView.m_PhysEnv.m_DrawStructural; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowstructural(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawStructural ); +} + +void CMainFrame::OnViewShowshear() +{ + m_OGLView.m_PhysEnv.m_DrawShear = !m_OGLView.m_PhysEnv.m_DrawShear; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowshear(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawShear ); +} + +void CMainFrame::OnViewShowbend() +{ + m_OGLView.m_PhysEnv.m_DrawBend = !m_OGLView.m_PhysEnv.m_DrawBend; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowbend(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawBend ); +} + +void CMainFrame::OnViewShowvertices() +{ + m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); +} + +void CMainFrame::OnClose() +{ + m_OGLView.m_SimRunning = FALSE; + + CFrameWnd::OnClose(); +} + +BOOL CMainFrame::DestroyWindow() +{ + + return CFrameWnd::DestroyWindow(); +} + +void CMainFrame::OnFileCreateclothpatch() +{ + m_OGLView.CreateClothPatch(); + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnViewCollisionactive() +{ + m_OGLView.m_PhysEnv.m_CollisionActive = !m_OGLView.m_PhysEnv.m_CollisionActive; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewCollisionactive(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_CollisionActive ); +} + + +void CMainFrame::OnInteuler() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = EULER_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateInteuler(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == EULER_INTEGRATOR ); +} + +void CMainFrame::OnIntmidpoint() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = MIDPOINT_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntmidpoint(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == MIDPOINT_INTEGRATOR ); +} + +void CMainFrame::OnIntrk4() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = RK4_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntrk4(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == RK4_INTEGRATOR ); +} + +void CMainFrame::OnSimulationSettimingproperties() +{ + m_OGLView.OnSetTimeProperties(); +} + +// Add a collision sphere to the physical simulation +void CMainFrame::OnSimulationAddcollisionsphere() +{ + m_OGLView.m_PhysEnv.AddCollisionSphere(); + m_OGLView.Invalidate(TRUE); +} diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.h index 0f04e5a..6da6ac3 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MainFrm.h @@ -1,119 +1,119 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual BOOL DestroyWindow(); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileOpen(); - afx_msg void OnSimulationRunning(); - afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); - afx_msg void OnSimulationReset(); - afx_msg void OnSimulationSetsimproperties(); - afx_msg void OnSimulationUsegravity(); - afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); - afx_msg void OnFileSave(); - afx_msg void OnViewShowgeometry(); - afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); - afx_msg void OnViewShowsprings(); - afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); - afx_msg void OnViewShowvertices(); - afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); - afx_msg void OnClose(); - afx_msg void OnFileCreateclothpatch(); - afx_msg void OnSimulationSetvertexproperties(); - afx_msg void OnViewCollisionactive(); - afx_msg void OnUpdateViewCollisionactive(CCmdUI* pCmdUI); - afx_msg void OnViewShowshear(); - afx_msg void OnUpdateViewShowshear(CCmdUI* pCmdUI); - afx_msg void OnViewShowstructural(); - afx_msg void OnUpdateViewShowstructural(CCmdUI* pCmdUI); - afx_msg void OnViewShowbend(); - afx_msg void OnUpdateViewShowbend(CCmdUI* pCmdUI); - afx_msg void OnInteuler(); - afx_msg void OnUpdateInteuler(CCmdUI* pCmdUI); - afx_msg void OnIntmidpoint(); - afx_msg void OnUpdateIntmidpoint(CCmdUI* pCmdUI); - afx_msg void OnIntrk4(); - afx_msg void OnUpdateIntrk4(CCmdUI* pCmdUI); - afx_msg void OnFileNewsystem(); - afx_msg void OnSimulationSettimingproperties(); - afx_msg void OnSimulationAddcollisionsphere(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL DestroyWindow(); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileOpen(); + afx_msg void OnSimulationRunning(); + afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); + afx_msg void OnSimulationReset(); + afx_msg void OnSimulationSetsimproperties(); + afx_msg void OnSimulationUsegravity(); + afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); + afx_msg void OnFileSave(); + afx_msg void OnViewShowgeometry(); + afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); + afx_msg void OnViewShowsprings(); + afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); + afx_msg void OnViewShowvertices(); + afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); + afx_msg void OnClose(); + afx_msg void OnFileCreateclothpatch(); + afx_msg void OnSimulationSetvertexproperties(); + afx_msg void OnViewCollisionactive(); + afx_msg void OnUpdateViewCollisionactive(CCmdUI* pCmdUI); + afx_msg void OnViewShowshear(); + afx_msg void OnUpdateViewShowshear(CCmdUI* pCmdUI); + afx_msg void OnViewShowstructural(); + afx_msg void OnUpdateViewShowstructural(CCmdUI* pCmdUI); + afx_msg void OnViewShowbend(); + afx_msg void OnUpdateViewShowbend(CCmdUI* pCmdUI); + afx_msg void OnInteuler(); + afx_msg void OnUpdateInteuler(CCmdUI* pCmdUI); + afx_msg void OnIntmidpoint(); + afx_msg void OnUpdateIntmidpoint(CCmdUI* pCmdUI); + afx_msg void OnIntrk4(); + afx_msg void OnUpdateIntrk4(CCmdUI* pCmdUI); + afx_msg void OnFileNewsystem(); + afx_msg void OnSimulationSettimingproperties(); + afx_msg void OnSimulationAddcollisionsphere(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.cpp index c244c23..c4c41fc 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.cpp @@ -1,112 +1,112 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void ScaleVector(tVector *v, float scale, tVector *result) -{ - result->x = v->x * scale; - result->y = v->y * scale; - result->z = v->z * scale; -} - -void VectorSum(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x + v2->x; - result->y = v1->y + v2->y; - result->z = v1->z + v2->z; -} - -void VectorDifference(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void ScaleVector(tVector *v, float scale, tVector *result) +{ + result->x = v->x * scale; + result->y = v->y * scale; + result->z = v->z * scale; +} + +void VectorSum(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x + v2->x; + result->y = v1->y + v2->y; + result->z = v1->z + v2->z; +} + +void VectorDifference(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.h index cb2bc2d..4950a12 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/MathDefs.h @@ -1,115 +1,115 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float nx,ny,nz; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float nx,ny,nz; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.cpp index 9752f79..9608407 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.cpp @@ -1,73 +1,73 @@ -// NewCloth.cpp : implementation file -// - -#include "stdafx.h" -#include "clothy.h" -#include "NewCloth.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// NewCloth dialog - - -NewCloth::NewCloth(CWnd* pParent /*=NULL*/) - : CDialog(NewCloth::IDD, pParent) -{ - //{{AFX_DATA_INIT(NewCloth) - m_BendCoef = 0.0f; - m_BendDamp = 0.0f; - m_ShearCoef = 0.0f; - m_ShearDamp = 0.0f; - m_StructCoef = 0.0f; - m_StructDamp = 0.0f; - m_USize = 0; - m_VSize = 0; - m_Vertical = FALSE; - m_UseBend = FALSE; - m_UseShear = FALSE; - m_UseStruct = FALSE; - //}}AFX_DATA_INIT -} - - -void NewCloth::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(NewCloth) - DDX_Text(pDX, IDC_BENDCOEF, m_BendCoef); - DDV_MinMaxFloat(pDX, m_BendCoef, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_BENDDAMP, m_BendDamp); - DDV_MinMaxFloat(pDX, m_BendDamp, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_SHEARCOEF, m_ShearCoef); - DDV_MinMaxFloat(pDX, m_ShearCoef, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_SHEARDAMP, m_ShearDamp); - DDV_MinMaxFloat(pDX, m_ShearDamp, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_STRUCTCOEF, m_StructCoef); - DDV_MinMaxFloat(pDX, m_StructCoef, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_STRUCTDAMP, m_StructDamp); - DDV_MinMaxFloat(pDX, m_StructDamp, 1.e-004f, 1000.f); - DDX_Text(pDX, IDC_USIZE, m_USize); - DDV_MinMaxInt(pDX, m_USize, 1, 128); - DDX_Text(pDX, IDC_VSIZE, m_VSize); - DDV_MinMaxInt(pDX, m_VSize, 1, 128); - DDX_Check(pDX, IDC_VERTICAL, m_Vertical); - DDX_Check(pDX, IDC_USEBEND, m_UseBend); - DDX_Check(pDX, IDC_USESHEAR, m_UseShear); - DDX_Check(pDX, IDC_USESTRUCT, m_UseStruct); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(NewCloth, CDialog) - //{{AFX_MSG_MAP(NewCloth) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// NewCloth message handlers +// NewCloth.cpp : implementation file +// + +#include "stdafx.h" +#include "clothy.h" +#include "NewCloth.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// NewCloth dialog + + +NewCloth::NewCloth(CWnd* pParent /*=NULL*/) + : CDialog(NewCloth::IDD, pParent) +{ + //{{AFX_DATA_INIT(NewCloth) + m_BendCoef = 0.0f; + m_BendDamp = 0.0f; + m_ShearCoef = 0.0f; + m_ShearDamp = 0.0f; + m_StructCoef = 0.0f; + m_StructDamp = 0.0f; + m_USize = 0; + m_VSize = 0; + m_Vertical = FALSE; + m_UseBend = FALSE; + m_UseShear = FALSE; + m_UseStruct = FALSE; + //}}AFX_DATA_INIT +} + + +void NewCloth::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(NewCloth) + DDX_Text(pDX, IDC_BENDCOEF, m_BendCoef); + DDV_MinMaxFloat(pDX, m_BendCoef, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_BENDDAMP, m_BendDamp); + DDV_MinMaxFloat(pDX, m_BendDamp, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_SHEARCOEF, m_ShearCoef); + DDV_MinMaxFloat(pDX, m_ShearCoef, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_SHEARDAMP, m_ShearDamp); + DDV_MinMaxFloat(pDX, m_ShearDamp, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_STRUCTCOEF, m_StructCoef); + DDV_MinMaxFloat(pDX, m_StructCoef, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_STRUCTDAMP, m_StructDamp); + DDV_MinMaxFloat(pDX, m_StructDamp, 1.e-004f, 1000.f); + DDX_Text(pDX, IDC_USIZE, m_USize); + DDV_MinMaxInt(pDX, m_USize, 1, 128); + DDX_Text(pDX, IDC_VSIZE, m_VSize); + DDV_MinMaxInt(pDX, m_VSize, 1, 128); + DDX_Check(pDX, IDC_VERTICAL, m_Vertical); + DDX_Check(pDX, IDC_USEBEND, m_UseBend); + DDX_Check(pDX, IDC_USESHEAR, m_UseShear); + DDX_Check(pDX, IDC_USESTRUCT, m_UseStruct); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(NewCloth, CDialog) + //{{AFX_MSG_MAP(NewCloth) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// NewCloth message handlers diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.h index 7c2a096..67bd370 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/NewCloth.h @@ -1,57 +1,57 @@ -#if !defined(AFX_NEWCLOTH_H__F770F420_F0FE_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_NEWCLOTH_H__F770F420_F0FE_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// NewCloth.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// NewCloth dialog - -class NewCloth : public CDialog -{ -// Construction -public: - NewCloth(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(NewCloth) - enum { IDD = IDD_MAKECLOTH }; - float m_BendCoef; - float m_BendDamp; - float m_ShearCoef; - float m_ShearDamp; - float m_StructCoef; - float m_StructDamp; - int m_USize; - int m_VSize; - BOOL m_Vertical; - BOOL m_UseBend; - BOOL m_UseShear; - BOOL m_UseStruct; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(NewCloth) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(NewCloth) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_NEWCLOTH_H__F770F420_F0FE_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_NEWCLOTH_H__F770F420_F0FE_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_NEWCLOTH_H__F770F420_F0FE_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// NewCloth.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// NewCloth dialog + +class NewCloth : public CDialog +{ +// Construction +public: + NewCloth(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(NewCloth) + enum { IDD = IDD_MAKECLOTH }; + float m_BendCoef; + float m_BendDamp; + float m_ShearCoef; + float m_ShearDamp; + float m_StructCoef; + float m_StructDamp; + int m_USize; + int m_VSize; + BOOL m_Vertical; + BOOL m_UseBend; + BOOL m_UseShear; + BOOL m_UseStruct; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(NewCloth) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(NewCloth) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_NEWCLOTH_H__F770F420_F0FE_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.cpp index fda201a..7ed4256 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.cpp @@ -1,1011 +1,1011 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of 3D Cloth Simulation -// -// Created: -// JL 2/12/99 -// -// Notes: -// This program is very similar to the mass-spring sim from January. -// CreateClothPatch contains the "MACRO" routine that creates a cloth -// patch from a mass-spring system -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "Clothy.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "TimeProps.h" -#include "NewCloth.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_SimRunning = FALSE; - m_CurBone = NULL; - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.b_trans.z = -100.0f; - m_Skeleton.trans.z = -100.0f; - - m_TimeIterations = 10; - m_UseFixedTimeStep = TRUE; - m_MaxTimeStep = 0.01f; - - m_FrameCnt = 0; - - m_PickX = -1; - m_PickY = -1; - m_hDC = NULL; -} - -COGLView::~COGLView() -{ - DestroySkeleton(&m_Skeleton); - m_hDC = NULL; -} - - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual = NULL; -/////////////////////////////////////////////////////////////////////////////// - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_CLOSE() - ON_WM_LBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -float COGLView::GetTime( void ) -{ - static DWORD StartMilliseconds; - if(!StartMilliseconds) - { - // yes, the first time through will be a 0 timestep - StartMilliseconds = timeGetTime(); - } - - DWORD CurrentMilliseconds = timeGetTime(); - return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; -} - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glDisable(GL_TEXTURE_2D); - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 - GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); -// glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); -// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - glLineWidth(2.0f); - glPointSize(8.0f); - glDisable(GL_LINE_SMOOTH); - glDepthFunc(GL_LEQUAL); - glDisable(GL_CULL_FACE); - -// glShadeModel(GL_SMOOTH); -// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - -// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); -// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); -// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); -// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 -// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glDisable(GL_LIGHTING); -// glEnable(GL_LIGHT0); - -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: RunSim -// Purpose: Actual simulation loop -// Notes: Allows you to adjust the rate of simulation or to change it -// to fixed time steps or actual timesteps. -/////////////////////////////////////////////////////////////////////////////// -void COGLView::RunSim() -{ -/// Local Variables /////////////////////////////////////////////////////////// - float Time; - float DeltaTime; -/////////////////////////////////////////////////////////////////////////////// - - if (m_UseFixedTimeStep) - Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); - else - Time = GetTime() * m_TimeIterations; - - if (m_SimRunning) - { - while(m_LastTime < Time) - { - DeltaTime = Time - m_LastTime; - if(DeltaTime > m_MaxTimeStep) - { - DeltaTime = m_MaxTimeStep; - } - - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - m_LastTime += DeltaTime; - } - m_LastTime = Time; - } - else - { - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - } -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) - { - glColor3f(1.0f,1.0f,1.0f); - // Declare the Array of Data - glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); - if (curBone->visuals[0].reuseVertices) - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - else - glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - } - else - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); - else - glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); - } - } -} -// drawModel - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; - if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; - if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; - - // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); - - // ROTATE THE ROOT - glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); - - if (m_PickX > -1) - m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); - - RunSim(); - - m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION - - glPopMatrix(); - glFinish(); - - if (m_hDC) - SwapBuffers(m_hDC); - - m_PickX = -1; - m_PickY = -1; -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - m_ScreenWidth = cx; - m_ScreenHeight = cy; - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - if ((nFlags & MK_SHIFT) == 0) - { - m_PickX = point.x; - m_PickY = m_ScreenHeight - point.y; - drawScene(); - } - SetCapture( ); - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE - ReleaseCapture(); - CWnd::OnLButtonUp(nFlags, point); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - tVector userforce; - switch (nChar) - { - case 13: - m_PhysEnv.AddSpring(); - break; - case 'G': - m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; -// m_DrawGeometry = !m_DrawGeometry; - break; - case '1': m_curVisual = 0; - break; - case '2': m_curVisual = 1; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - break; - case 'F': - glPolygonMode(GL_FRONT,GL_FILL); - break; - case 'R': - m_SimRunning = !m_SimRunning; - if (m_SimRunning) - m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM - m_StartTime = timeGetTime(); - m_FrameCnt = 0; - break; - case 'T': - m_PhysEnv.ResetWorld(); - break; - case VK_HOME: - userforce.x = m_Skeleton.matrix.m[1]; - userforce.y = m_Skeleton.matrix.m[5]; - userforce.z = m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_END: - userforce.x = -m_Skeleton.matrix.m[1]; - userforce.y = -m_Skeleton.matrix.m[5]; - userforce.z = -m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_RIGHT: - userforce.x = m_Skeleton.matrix.m[0]; - userforce.y = m_Skeleton.matrix.m[4]; - userforce.z = m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_LEFT: - userforce.x = -m_Skeleton.matrix.m[0]; - userforce.y = -m_Skeleton.matrix.m[4]; - userforce.z = -m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_UP: - userforce.x = -m_Skeleton.matrix.m[2]; - userforce.y = -m_Skeleton.matrix.m[6]; - userforce.z = -m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_DOWN: - userforce.x = m_Skeleton.matrix.m[2]; - userforce.y = m_Skeleton.matrix.m[6]; - userforce.z = m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - } - - MSG msg; - - if (m_SimRunning) - { - while (m_SimRunning == TRUE) - { - while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - m_SimRunning = FALSE; - m_hDC = NULL; // KEEP THE WINDOWS STUFF STRAIGHT - ::PostQuitMessage(0); - break; - } - if (msg.message == WM_CLOSE) - { - m_hDC = NULL; // KEEP THE WINDOWS STUFF STRAIGHT - m_SimRunning = FALSE; - } - - // Dispatch any messages as needed - if (!AfxGetApp()->PreTranslateMessage(&msg)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - // Give the Idle system some time - AfxGetApp()->OnIdle(0); - AfxGetApp()->OnIdle(1); - - } - if (m_SimRunning) drawScene(); - } - } - else - Invalidate(TRUE); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - tVector localX,localY; - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CONTROL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - // ELSE ROTATE THE BONE - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS - { - // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES - localY.x = m_Skeleton.matrix.m[1]; - localY.y = m_Skeleton.matrix.m[5]; - localY.z = m_Skeleton.matrix.m[9]; - - localX.x = m_Skeleton.matrix.m[0]; - localX.y = m_Skeleton.matrix.m[4]; - localX.z = m_Skeleton.matrix.m[8]; - - m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); - m_PhysEnv.m_MouseForceActive = TRUE; - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: NewSystem -// Purpose: Clears the Simulation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::NewSystem() -{ - m_PhysEnv.FreeSystem(); - m_SimRunning = FALSE; - if (m_Skeleton.childCnt > 0) - { - if (m_Skeleton.children->visuals->vertexData) - free(m_Skeleton.children->visuals->vertexData); - if (m_Skeleton.children->visuals->faceIndex) - free(m_Skeleton.children->visuals->faceIndex); - free(m_Skeleton.children->visuals); - free(m_Skeleton.children); - m_Skeleton.childCnt = 0; - } - drawScene(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadFiles -// Purpose: Loads the OBJ files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadFile(CString file1,CString baseName,CString ext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *children; - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - ext.MakeUpper(); - if (ext == "OBJ") - { - visual = (t_Visual *)malloc(sizeof(t_Visual)); - NewSystem(); // CLEAR WHAT DATA IS THERE - // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT - if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, - LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) - { - // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SetWorldParticles((tTexturedVertex *)visual->vertexData,visual->vertexCnt); - if (m_Skeleton.childCnt > 0) - { - if (m_Skeleton.children->visuals->faceIndex != NULL) - free(m_Skeleton.children->visuals->faceIndex); - free(m_Skeleton.children->visuals); - free(m_Skeleton.children->visuals->vertexData); - free(m_Skeleton.children); - m_Skeleton.childCnt = 0; - } - children = (t_Bone *)malloc(sizeof(t_Bone)); - m_CurBone = &children[m_Skeleton.childCnt]; - ResetBone(m_CurBone,&m_Skeleton); - strcpy(m_CurBone->name,(LPCTSTR)baseName); - m_CurBone->visuals = visual; - m_CurBone->visualCnt = 1; - m_Skeleton.childCnt = 1; - m_Skeleton.children = children; - } - else - { - MessageBox("Must Be A Valid OBJ File","Error",MB_OK); - free(visual); - } - } - else // LOAD SIM SYSTEM - { - if (file1.GetLength()) - { - fp = fopen(file1,"rb"); - if (fp != NULL) - { - NewSystem(); // CLEAR WHAT DATA IS THERE - fread(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); - fread(m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); - visual = m_Skeleton.children->visuals; - fread(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); - fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.LoadData(fp); - } - } - fclose(fp); - } - } - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: SaveFiles -// Purpose: Saves the Particle System -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SaveFile(CString file1,CString baseName) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - if (file1.GetLength() > 0) - { - fp = fopen(file1,"wb"); - if (fp != NULL) - { - fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - fwrite(&m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - visual = m_Skeleton.children->visuals; - fwrite(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SaveData(fp); - } - } - fclose(fp); - } - } -} - -void COGLView::OnClose() -{ - - CWnd::OnClose(); -} - -void COGLView::OnSimulationSetsimproperties() -{ - m_PhysEnv.SetWorldProperties(); -} - -void COGLView::OnSetTimeProperties() -{ - CTimeProps dialog; - dialog.m_Iterations = m_TimeIterations; - dialog.m_FixedTimeSteps = m_UseFixedTimeStep; - dialog.m_MaxTimeStep = m_MaxTimeStep; - if (dialog.DoModal()) - { - m_TimeIterations = dialog.m_Iterations; - m_UseFixedTimeStep = dialog.m_FixedTimeSteps; - m_MaxTimeStep = dialog.m_MaxTimeStep; - } -} - -void COGLView::OnSetVertexProperties() -{ - m_PhysEnv.SetVertexProperties(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: CreateClothPatch -// Purpose: Creates a System to Represent a Cloth Patch -// Arguments: Number of Segments in U and V to build -/////////////////////////////////////////////////////////////////////////////// -void COGLView::CreateClothPatch() -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *children; - t_Visual *visual; - int fPos,vPos,l1,l2; - tTexturedVertex *vertex; - float sx,sy,stepx,stepy; - BOOL orientHoriz = TRUE; - int u = 9, v = 9; - float w = 8.0f, h = 8.0,tsu,tsv,tdu,tdv; - float SstK = 4.0f,SstD = 0.6f; //SstK = 2.5f,SstD = 1.2f; - float SshK = 4.0f,SshD = 0.6f; - float SflK = 2.4f,SflD = 0.8f; - NewCloth dialog; -/////////////////////////////////////////////////////////////////////////////// - dialog.m_StructCoef = SstK; - dialog.m_StructDamp = SstD; - dialog.m_ShearCoef = SshK; - dialog.m_ShearDamp = SshD; - dialog.m_BendCoef = SflK; - dialog.m_BendDamp = SflD; - dialog.m_USize = u; - dialog.m_VSize = v; - dialog.m_Vertical = !orientHoriz; - dialog.m_UseStruct = TRUE; - dialog.m_UseShear = TRUE; - dialog.m_UseBend = TRUE; - if (dialog.DoModal()) - { - NewSystem(); // CLEAR WHAT DATA IS THERE - SstK = dialog.m_StructCoef; - SstD = dialog.m_StructDamp; - SshK = dialog.m_ShearCoef; - SshK = dialog.m_ShearDamp; - SflK = dialog.m_BendCoef; - SflD = dialog.m_BendDamp; - u = dialog.m_USize; - v = dialog.m_VSize; - orientHoriz = !dialog.m_Vertical; - - sx = -(w / 2.0f); - sy = (h / 2.0f); - stepx = w / (float)u; - stepy = -(h / (float)v); - - tsu = 0.0f; - tsv = 0.0f; - tdu = 1.0f / (float)u; - tdv = 1.0f / (float)v; - - fPos = (u - 1) * (v - 1) * 2; // FACE COUNT - vPos = u * v; - visual = (t_Visual *)malloc(sizeof(t_Visual)); - - visual->reuseVertices = TRUE; - visual->dataFormat = GL_T2F_V3F; - visual->vPerFace = 3; - visual->vSize = 5; // 3 floats for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); - visual->vertexCnt = vPos; - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); - visual->faceCnt = fPos; - - // SET THE VERTICES - vertex = (tTexturedVertex *)visual->vertexData; - for (l1 = 0; l1 < v; l1++,tsv+=tdv) - for (l2 = 0; l2 < u; l2++,tsu+=tdu) - { - vertex->u = tsu; - vertex->v = tsv; - - vertex->x = sx + (stepx * l2); - if (orientHoriz) - { - vertex->z = sy + (stepy * l1); - vertex->y = 0.0f; - } - else - { - vertex->y = sy + (stepy * l1); - vertex->z = 0.0f; - } - vertex++; - } - - // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SetWorldParticles((tTexturedVertex *)visual->vertexData,visual->vertexCnt); - - if (m_Skeleton.childCnt > 0) - { - if (m_Skeleton.children->visuals->faceIndex != NULL) - free(m_Skeleton.children->visuals->faceIndex); - free(m_Skeleton.children->visuals); - free(m_Skeleton.children->visuals->vertexData); - free(m_Skeleton.children); - m_Skeleton.childCnt = 0; - } - children = (t_Bone *)malloc(sizeof(t_Bone)); - m_CurBone = &children[m_Skeleton.childCnt]; - ResetBone(m_CurBone,&m_Skeleton); - strcpy(m_CurBone->name,"Cloth"); - m_CurBone->visuals = visual; - m_CurBone->visualCnt = 1; - m_Skeleton.childCnt = 1; - m_Skeleton.children = children; - - if (dialog.m_UseStruct) - { - // Horizontal - for (l1 = 0; l1 < v; l1++) // v - for (l2 = 0; l2 < (u - 1); l2++) - { - m_PhysEnv.AddSpring((l1 * u) + l2,(l1 * u) + l2 + 1,SstK,SstD,STRUCTURAL_SPRING); - } - - // Vertical - for (l1 = 0; l1 < (u); l1++) - for (l2 = 0; l2 < (v - 1); l2++) - { - m_PhysEnv.AddSpring((l2 * u) + l1,((l2 + 1) * u) + l1,SstK,SstD,STRUCTURAL_SPRING); - } - } - - if (dialog.m_UseShear) - { - // Shearing Springs - for (l1 = 0; l1 < (v - 1); l1++) - for (l2 = 0; l2 < (u - 1); l2++) - { - m_PhysEnv.AddSpring((l1 * u) + l2,((l1 + 1) * u) + l2 + 1,SshK,SshD,SHEAR_SPRING); - m_PhysEnv.AddSpring(((l1 + 1) * u) + l2,(l1 * u) + l2 + 1,SshK,SshD,SHEAR_SPRING); - } - } - - if (dialog.m_UseBend) - { - // Bend Springs - for (l1 = 0; l1 < (v); l1++) - { - for (l2 = 0; l2 < (u - 2); l2++) - { - m_PhysEnv.AddSpring((l1 * u) + l2,(l1 * u) + l2 + 2,SflK,SflD,BEND_SPRING); - } - m_PhysEnv.AddSpring((l1 * u) + (u - 3),(l1 * u) + (u - 1),SflK,SflD,BEND_SPRING); - } - for (l1 = 0; l1 < (u); l1++) - { - for (l2 = 0; l2 < (v - 2); l2++) - { - m_PhysEnv.AddSpring((l2 * u) + l1,((l2 + 2) * u) + l1,SflK,SflD,BEND_SPRING); - } - m_PhysEnv.AddSpring(((v - 3) * u) + l1,((v - 1) * u) + l1,SflK,SflD,BEND_SPRING); - } - } - } - -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of 3D Cloth Simulation +// +// Created: +// JL 2/12/99 +// +// Notes: +// This program is very similar to the mass-spring sim from January. +// CreateClothPatch contains the "MACRO" routine that creates a cloth +// patch from a mass-spring system +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "Clothy.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "TimeProps.h" +#include "NewCloth.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_SimRunning = FALSE; + m_CurBone = NULL; + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.b_trans.z = -100.0f; + m_Skeleton.trans.z = -100.0f; + + m_TimeIterations = 10; + m_UseFixedTimeStep = TRUE; + m_MaxTimeStep = 0.01f; + + m_FrameCnt = 0; + + m_PickX = -1; + m_PickY = -1; + m_hDC = NULL; +} + +COGLView::~COGLView() +{ + DestroySkeleton(&m_Skeleton); + m_hDC = NULL; +} + + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual = NULL; +/////////////////////////////////////////////////////////////////////////////// + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_CLOSE() + ON_WM_LBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +float COGLView::GetTime( void ) +{ + static DWORD StartMilliseconds; + if(!StartMilliseconds) + { + // yes, the first time through will be a 0 timestep + StartMilliseconds = timeGetTime(); + } + + DWORD CurrentMilliseconds = timeGetTime(); + return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; +} + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glDisable(GL_TEXTURE_2D); + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 + GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); +// glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); +// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glLineWidth(2.0f); + glPointSize(8.0f); + glDisable(GL_LINE_SMOOTH); + glDepthFunc(GL_LEQUAL); + glDisable(GL_CULL_FACE); + +// glShadeModel(GL_SMOOTH); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); +// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); +// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); +// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 +// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_LIGHTING); +// glEnable(GL_LIGHT0); + +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: RunSim +// Purpose: Actual simulation loop +// Notes: Allows you to adjust the rate of simulation or to change it +// to fixed time steps or actual timesteps. +/////////////////////////////////////////////////////////////////////////////// +void COGLView::RunSim() +{ +/// Local Variables /////////////////////////////////////////////////////////// + float Time; + float DeltaTime; +/////////////////////////////////////////////////////////////////////////////// + + if (m_UseFixedTimeStep) + Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); + else + Time = GetTime() * m_TimeIterations; + + if (m_SimRunning) + { + while(m_LastTime < Time) + { + DeltaTime = Time - m_LastTime; + if(DeltaTime > m_MaxTimeStep) + { + DeltaTime = m_MaxTimeStep; + } + + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + m_LastTime += DeltaTime; + } + m_LastTime = Time; + } + else + { + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + } +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) + { + glColor3f(1.0f,1.0f,1.0f); + // Declare the Array of Data + glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); + if (curBone->visuals[0].reuseVertices) + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + else + glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + } + else + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); + else + glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); + } + } +} +// drawModel + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; + if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; + if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; + + // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); + + // ROTATE THE ROOT + glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); + + if (m_PickX > -1) + m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); + + RunSim(); + + m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION + + glPopMatrix(); + glFinish(); + + if (m_hDC) + SwapBuffers(m_hDC); + + m_PickX = -1; + m_PickY = -1; +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + m_ScreenWidth = cx; + m_ScreenHeight = cy; + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + if ((nFlags & MK_SHIFT) == 0) + { + m_PickX = point.x; + m_PickY = m_ScreenHeight - point.y; + drawScene(); + } + SetCapture( ); + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE + ReleaseCapture(); + CWnd::OnLButtonUp(nFlags, point); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + tVector userforce; + switch (nChar) + { + case 13: + m_PhysEnv.AddSpring(); + break; + case 'G': + m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; +// m_DrawGeometry = !m_DrawGeometry; + break; + case '1': m_curVisual = 0; + break; + case '2': m_curVisual = 1; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + break; + case 'F': + glPolygonMode(GL_FRONT,GL_FILL); + break; + case 'R': + m_SimRunning = !m_SimRunning; + if (m_SimRunning) + m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM + m_StartTime = timeGetTime(); + m_FrameCnt = 0; + break; + case 'T': + m_PhysEnv.ResetWorld(); + break; + case VK_HOME: + userforce.x = m_Skeleton.matrix.m[1]; + userforce.y = m_Skeleton.matrix.m[5]; + userforce.z = m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_END: + userforce.x = -m_Skeleton.matrix.m[1]; + userforce.y = -m_Skeleton.matrix.m[5]; + userforce.z = -m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_RIGHT: + userforce.x = m_Skeleton.matrix.m[0]; + userforce.y = m_Skeleton.matrix.m[4]; + userforce.z = m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_LEFT: + userforce.x = -m_Skeleton.matrix.m[0]; + userforce.y = -m_Skeleton.matrix.m[4]; + userforce.z = -m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_UP: + userforce.x = -m_Skeleton.matrix.m[2]; + userforce.y = -m_Skeleton.matrix.m[6]; + userforce.z = -m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_DOWN: + userforce.x = m_Skeleton.matrix.m[2]; + userforce.y = m_Skeleton.matrix.m[6]; + userforce.z = m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + } + + MSG msg; + + if (m_SimRunning) + { + while (m_SimRunning == TRUE) + { + while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + m_SimRunning = FALSE; + m_hDC = NULL; // KEEP THE WINDOWS STUFF STRAIGHT + ::PostQuitMessage(0); + break; + } + if (msg.message == WM_CLOSE) + { + m_hDC = NULL; // KEEP THE WINDOWS STUFF STRAIGHT + m_SimRunning = FALSE; + } + + // Dispatch any messages as needed + if (!AfxGetApp()->PreTranslateMessage(&msg)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + // Give the Idle system some time + AfxGetApp()->OnIdle(0); + AfxGetApp()->OnIdle(1); + + } + if (m_SimRunning) drawScene(); + } + } + else + Invalidate(TRUE); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + tVector localX,localY; + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CONTROL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + // ELSE ROTATE THE BONE + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS + { + // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES + localY.x = m_Skeleton.matrix.m[1]; + localY.y = m_Skeleton.matrix.m[5]; + localY.z = m_Skeleton.matrix.m[9]; + + localX.x = m_Skeleton.matrix.m[0]; + localX.y = m_Skeleton.matrix.m[4]; + localX.z = m_Skeleton.matrix.m[8]; + + m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); + m_PhysEnv.m_MouseForceActive = TRUE; + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: NewSystem +// Purpose: Clears the Simulation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::NewSystem() +{ + m_PhysEnv.FreeSystem(); + m_SimRunning = FALSE; + if (m_Skeleton.childCnt > 0) + { + if (m_Skeleton.children->visuals->vertexData) + free(m_Skeleton.children->visuals->vertexData); + if (m_Skeleton.children->visuals->faceIndex) + free(m_Skeleton.children->visuals->faceIndex); + free(m_Skeleton.children->visuals); + free(m_Skeleton.children); + m_Skeleton.childCnt = 0; + } + drawScene(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadFiles +// Purpose: Loads the OBJ files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadFile(CString file1,CString baseName,CString ext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *children; + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + ext.MakeUpper(); + if (ext == "OBJ") + { + visual = (t_Visual *)malloc(sizeof(t_Visual)); + NewSystem(); // CLEAR WHAT DATA IS THERE + // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT + if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, + LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) + { + // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SetWorldParticles((tTexturedVertex *)visual->vertexData,visual->vertexCnt); + if (m_Skeleton.childCnt > 0) + { + if (m_Skeleton.children->visuals->faceIndex != NULL) + free(m_Skeleton.children->visuals->faceIndex); + free(m_Skeleton.children->visuals); + free(m_Skeleton.children->visuals->vertexData); + free(m_Skeleton.children); + m_Skeleton.childCnt = 0; + } + children = (t_Bone *)malloc(sizeof(t_Bone)); + m_CurBone = &children[m_Skeleton.childCnt]; + ResetBone(m_CurBone,&m_Skeleton); + strcpy(m_CurBone->name,(LPCTSTR)baseName); + m_CurBone->visuals = visual; + m_CurBone->visualCnt = 1; + m_Skeleton.childCnt = 1; + m_Skeleton.children = children; + } + else + { + MessageBox("Must Be A Valid OBJ File","Error",MB_OK); + free(visual); + } + } + else // LOAD SIM SYSTEM + { + if (file1.GetLength()) + { + fp = fopen(file1,"rb"); + if (fp != NULL) + { + NewSystem(); // CLEAR WHAT DATA IS THERE + fread(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); + fread(m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); + visual = m_Skeleton.children->visuals; + fread(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); + fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.LoadData(fp); + } + } + fclose(fp); + } + } + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: SaveFiles +// Purpose: Saves the Particle System +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SaveFile(CString file1,CString baseName) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + if (file1.GetLength() > 0) + { + fp = fopen(file1,"wb"); + if (fp != NULL) + { + fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + fwrite(&m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + visual = m_Skeleton.children->visuals; + fwrite(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SaveData(fp); + } + } + fclose(fp); + } + } +} + +void COGLView::OnClose() +{ + + CWnd::OnClose(); +} + +void COGLView::OnSimulationSetsimproperties() +{ + m_PhysEnv.SetWorldProperties(); +} + +void COGLView::OnSetTimeProperties() +{ + CTimeProps dialog; + dialog.m_Iterations = m_TimeIterations; + dialog.m_FixedTimeSteps = m_UseFixedTimeStep; + dialog.m_MaxTimeStep = m_MaxTimeStep; + if (dialog.DoModal()) + { + m_TimeIterations = dialog.m_Iterations; + m_UseFixedTimeStep = dialog.m_FixedTimeSteps; + m_MaxTimeStep = dialog.m_MaxTimeStep; + } +} + +void COGLView::OnSetVertexProperties() +{ + m_PhysEnv.SetVertexProperties(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: CreateClothPatch +// Purpose: Creates a System to Represent a Cloth Patch +// Arguments: Number of Segments in U and V to build +/////////////////////////////////////////////////////////////////////////////// +void COGLView::CreateClothPatch() +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *children; + t_Visual *visual; + int fPos,vPos,l1,l2; + tTexturedVertex *vertex; + float sx,sy,stepx,stepy; + BOOL orientHoriz = TRUE; + int u = 9, v = 9; + float w = 8.0f, h = 8.0,tsu,tsv,tdu,tdv; + float SstK = 4.0f,SstD = 0.6f; //SstK = 2.5f,SstD = 1.2f; + float SshK = 4.0f,SshD = 0.6f; + float SflK = 2.4f,SflD = 0.8f; + NewCloth dialog; +/////////////////////////////////////////////////////////////////////////////// + dialog.m_StructCoef = SstK; + dialog.m_StructDamp = SstD; + dialog.m_ShearCoef = SshK; + dialog.m_ShearDamp = SshD; + dialog.m_BendCoef = SflK; + dialog.m_BendDamp = SflD; + dialog.m_USize = u; + dialog.m_VSize = v; + dialog.m_Vertical = !orientHoriz; + dialog.m_UseStruct = TRUE; + dialog.m_UseShear = TRUE; + dialog.m_UseBend = TRUE; + if (dialog.DoModal()) + { + NewSystem(); // CLEAR WHAT DATA IS THERE + SstK = dialog.m_StructCoef; + SstD = dialog.m_StructDamp; + SshK = dialog.m_ShearCoef; + SshK = dialog.m_ShearDamp; + SflK = dialog.m_BendCoef; + SflD = dialog.m_BendDamp; + u = dialog.m_USize; + v = dialog.m_VSize; + orientHoriz = !dialog.m_Vertical; + + sx = -(w / 2.0f); + sy = (h / 2.0f); + stepx = w / (float)u; + stepy = -(h / (float)v); + + tsu = 0.0f; + tsv = 0.0f; + tdu = 1.0f / (float)u; + tdv = 1.0f / (float)v; + + fPos = (u - 1) * (v - 1) * 2; // FACE COUNT + vPos = u * v; + visual = (t_Visual *)malloc(sizeof(t_Visual)); + + visual->reuseVertices = TRUE; + visual->dataFormat = GL_T2F_V3F; + visual->vPerFace = 3; + visual->vSize = 5; // 3 floats for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); + visual->vertexCnt = vPos; + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); + visual->faceCnt = fPos; + + // SET THE VERTICES + vertex = (tTexturedVertex *)visual->vertexData; + for (l1 = 0; l1 < v; l1++,tsv+=tdv) + for (l2 = 0; l2 < u; l2++,tsu+=tdu) + { + vertex->u = tsu; + vertex->v = tsv; + + vertex->x = sx + (stepx * l2); + if (orientHoriz) + { + vertex->z = sy + (stepy * l1); + vertex->y = 0.0f; + } + else + { + vertex->y = sy + (stepy * l1); + vertex->z = 0.0f; + } + vertex++; + } + + // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SetWorldParticles((tTexturedVertex *)visual->vertexData,visual->vertexCnt); + + if (m_Skeleton.childCnt > 0) + { + if (m_Skeleton.children->visuals->faceIndex != NULL) + free(m_Skeleton.children->visuals->faceIndex); + free(m_Skeleton.children->visuals); + free(m_Skeleton.children->visuals->vertexData); + free(m_Skeleton.children); + m_Skeleton.childCnt = 0; + } + children = (t_Bone *)malloc(sizeof(t_Bone)); + m_CurBone = &children[m_Skeleton.childCnt]; + ResetBone(m_CurBone,&m_Skeleton); + strcpy(m_CurBone->name,"Cloth"); + m_CurBone->visuals = visual; + m_CurBone->visualCnt = 1; + m_Skeleton.childCnt = 1; + m_Skeleton.children = children; + + if (dialog.m_UseStruct) + { + // Horizontal + for (l1 = 0; l1 < v; l1++) // v + for (l2 = 0; l2 < (u - 1); l2++) + { + m_PhysEnv.AddSpring((l1 * u) + l2,(l1 * u) + l2 + 1,SstK,SstD,STRUCTURAL_SPRING); + } + + // Vertical + for (l1 = 0; l1 < (u); l1++) + for (l2 = 0; l2 < (v - 1); l2++) + { + m_PhysEnv.AddSpring((l2 * u) + l1,((l2 + 1) * u) + l1,SstK,SstD,STRUCTURAL_SPRING); + } + } + + if (dialog.m_UseShear) + { + // Shearing Springs + for (l1 = 0; l1 < (v - 1); l1++) + for (l2 = 0; l2 < (u - 1); l2++) + { + m_PhysEnv.AddSpring((l1 * u) + l2,((l1 + 1) * u) + l2 + 1,SshK,SshD,SHEAR_SPRING); + m_PhysEnv.AddSpring(((l1 + 1) * u) + l2,(l1 * u) + l2 + 1,SshK,SshD,SHEAR_SPRING); + } + } + + if (dialog.m_UseBend) + { + // Bend Springs + for (l1 = 0; l1 < (v); l1++) + { + for (l2 = 0; l2 < (u - 2); l2++) + { + m_PhysEnv.AddSpring((l1 * u) + l2,(l1 * u) + l2 + 2,SflK,SflD,BEND_SPRING); + } + m_PhysEnv.AddSpring((l1 * u) + (u - 3),(l1 * u) + (u - 1),SflK,SflD,BEND_SPRING); + } + for (l1 = 0; l1 < (u); l1++) + { + for (l2 = 0; l2 < (v - 2); l2++) + { + m_PhysEnv.AddSpring((l2 * u) + l1,((l2 + 2) * u) + l1,SflK,SflD,BEND_SPRING); + } + m_PhysEnv.AddSpring(((v - 3) * u) + l1,((v - 1) * u) + l1,SflK,SflD,BEND_SPRING); + } + } + } + +} diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.h index 91e27e6..492da1c 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/OGLView.h @@ -1,122 +1,122 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Cloth Animation -// -// Created: -// JL 2/1/99 -// -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -#include "PhysEnv.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry,m_SimRunning; - int m_curVisual; - float m_MorphPos; - DWORD m_StartTime; - DWORD m_FrameCnt; - int m_TimeIterations; - BOOL m_UseFixedTimeStep; - float m_MaxTimeStep; - float m_LastTime; - - CPhysEnv m_PhysEnv; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - void OnSimulationSetsimproperties(); - void OnSetTimeProperties(); - void OnSetVertexProperties(); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - GLvoid morphModel(t_Bone *curBone); - GLvoid LoadBoneTexture(t_Bone *curBone); - void NewSystem(); - void LoadFile(CString file1,CString baseName,CString ext); - void SaveFile(CString file1,CString baseName); - void CreateClothPatch(); - void RunSim(); - float GetTime( void ); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Skeleton,*m_CurBone; - int m_PickX, m_PickY; - int m_ScreenWidth; - int m_ScreenHeight; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnClose(); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Cloth Animation +// +// Created: +// JL 2/1/99 +// +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +#include "PhysEnv.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry,m_SimRunning; + int m_curVisual; + float m_MorphPos; + DWORD m_StartTime; + DWORD m_FrameCnt; + int m_TimeIterations; + BOOL m_UseFixedTimeStep; + float m_MaxTimeStep; + float m_LastTime; + + CPhysEnv m_PhysEnv; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + void OnSimulationSetsimproperties(); + void OnSetTimeProperties(); + void OnSetVertexProperties(); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + GLvoid morphModel(t_Bone *curBone); + GLvoid LoadBoneTexture(t_Bone *curBone); + void NewSystem(); + void LoadFile(CString file1,CString baseName,CString ext); + void SaveFile(CString file1,CString baseName); + void CreateClothPatch(); + void RunSim(); + float GetTime( void ); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Skeleton,*m_CurBone; + int m_PickX, m_PickY; + int m_ScreenWidth; + int m_ScreenHeight; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnClose(); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.cpp index 6c0059d..d923348 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.cpp @@ -1,1183 +1,1183 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// PhysEnv.cpp : Physical World implementation file -// -// Purpose: Implementation of Particle Physics System -// -// Created: -// JL 2/10/99 Modified from Mass-Spring Particle demo to handle cloth -// Modified: -// JL 3/6/99 - FIXED GRAVITY FORCE CALCULATION BUG -// JL 3/8/99 - ADDED MORE POSSIBLE CONTACTS AS EACH VERTEX CAN CONTACT MORE -// THEN ONE COLLISION SURFACE (SHOULD IT BE DYNAMICALLY ALLOC'ED?) -// JL 3/20/99 - ADDED THE MIDPOINT AND RK INTEGRATOR NEEDED TO ALLOC 5 TEMP PARTICLE ARRAYS -// -// Notes: A bit of this along with the organization comes from Chris Hecker's -// Physics Articles from last year www.d6.com. Hopefully this will get -// everyone back up to speed before we dig deeper into the world of Dynamics. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998-1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include -#include - -#include "Clothy.h" -#include "PhysEnv.h" -#include "SimProps.h" -#include "SetVert.h" -#include "AddSpher.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -///////////////////////////////////////////////////////////////////////////// -// CPhysEnv - -// INITIALIZE THE SIMULATION WORLD -CPhysEnv::CPhysEnv() -{ - m_IntegratorType = EULER_INTEGRATOR; - - m_Pick[0] = -1; - m_Pick[1] = -1; - m_ParticleSys[0] = NULL; - m_ParticleSys[1] = NULL; - m_ParticleSys[2] = NULL; // RESET BUFFER - // THESE TEMP PARTICLE BUFFERS ARE NEEDED FOR THE MIDPOINT AND RK4 INTEGRATOR - for (int i = 0; i < 5; i++) - m_TempSys[i] = NULL; - m_ParticleCnt = 0; - m_Contact = NULL; - m_Spring = NULL; - m_SpringCnt = 0; - m_MouseForceActive = FALSE; - - m_UseGravity = TRUE; - m_DrawSprings = TRUE; - m_DrawStructural = TRUE; // By default only draw structural springs - m_DrawBend = FALSE; - m_DrawShear = FALSE; - m_DrawVertices = TRUE; - m_CollisionActive = TRUE; - m_CollisionRootFinding = FALSE; // I AM NOT LOOKING FOR A COLLISION RIGHT AWAY - - MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) - m_UserForceMag = 100.0; - m_UserForceActive = FALSE; - m_MouseForceKs = 2.0f; // MOUSE SPRING CONSTANT - m_Kd = 0.04f; // DAMPING FACTOR - m_Kr = 0.1f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT - m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT - m_Ksd = 0.1f; // SPRING DAMPING CONSTANT - - // CREATE THE SIZE FOR THE SIMULATION WORLD - m_WorldSizeX = 15.0f; - m_WorldSizeY = 15.0f; - m_WorldSizeZ = 15.0f; - - m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); - m_CollisionPlaneCnt = 6; - - // MAKE THE TOP PLANE (CEILING) - MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) - m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; - - // MAKE THE BOTTOM PLANE (FLOOR) - MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) - m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; - - // MAKE THE LEFT PLANE - MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) - m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; - - // MAKE THE RIGHT PLANE - MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) - m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; - - // MAKE THE FRONT PLANE - MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) - m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; - - // MAKE THE BACK PLANE - MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) - m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; - - m_SphereCnt = 0; - -} - -CPhysEnv::~CPhysEnv() -{ - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - free(m_TempSys[i]); - } - if (m_Contact) - free(m_Contact); - free(m_CollisionPlane); - free(m_Spring); - - free(m_Sphere); -} - -void CPhysEnv::RenderWorld() -{ - tParticle *tempParticle; - tSpring *tempSpring; - - // FIRST DRAW THE WORLD CONTAINER - glColor3f(1.0f,1.0f,1.0f); - // do a big linestrip to get most of edges - glBegin(GL_LINE_STRIP); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glEnd(); - // fill in the stragglers - glBegin(GL_LINES); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - - // draw floor - glDisable(GL_CULL_FACE); - glBegin(GL_QUADS); - glColor3f(0.0f,0.0f,0.5f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - glEnable(GL_CULL_FACE); - - - if (m_ParticleSys) - { - if (m_Spring && m_DrawSprings) - { - glBegin(GL_LINES); - glColor3f(0.0f,0.8f,0.8f); - tempSpring = m_Spring; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - // Only draw normal springs or the cloth "structural" ones - if ((tempSpring->type == MANUAL_SPRING) || - (tempSpring->type == STRUCTURAL_SPRING && m_DrawStructural) || - (tempSpring->type == SHEAR_SPRING && m_DrawShear) || - (tempSpring->type == BEND_SPRING && m_DrawBend)) - { - glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); - glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); - } - tempSpring++; - } - if (m_MouseForceActive) // DRAW MOUSESPRING FORCE - { - if (m_Pick[0] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); - glVertex3fv((float *)&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); - glVertex3fv((float *)&m_MouseDragPos[1]); - } - } - glEnd(); - } - if (m_DrawVertices) - { - glBegin(GL_POINTS); - tempParticle = m_CurrentSys; - for (int loop = 0; loop < m_ParticleCnt; loop++) - { - if (loop == m_Pick[0]) - glColor3f(0.0f,0.8f,0.0f); - else if (loop == m_Pick[1]) - glColor3f(0.8f,0.0f,0.0f); - else - glColor3f(0.8f,0.8f,0.0f); - glVertex3fv((float *)&tempParticle->pos); - tempParticle++; - } - glEnd(); - } - } - - if (m_SphereCnt > 0 && m_CollisionActive) - { - glColor3f(0.5f,0.0f,0.0f); - for (int loop = 0; loop < m_SphereCnt; loop++) - { - glPushMatrix(); - glTranslatef(m_Sphere[loop].pos.x, m_Sphere[loop].pos.y, m_Sphere[loop].pos.z); - glScalef(m_Sphere[loop].radius,m_Sphere[loop].radius,m_Sphere[loop].radius); - glCallList(OGL_AXIS_DLIST); - glPopMatrix(); - } - } -} - -void CPhysEnv::GetNearestPoint(int x, int y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *feedBuffer; - int hitCount; - tParticle *tempParticle; - int loop; -/////////////////////////////////////////////////////////////////////////////// - // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) - feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); - // TELL OPENGL ABOUT THE BUFFER - glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); - (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE - - tempParticle = m_CurrentSys; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS - glPassThrough((float)loop); - // SEND THE VERTEX - glBegin(GL_POINTS); - glVertex3fv((float *)&tempParticle->pos); - glEnd(); - tempParticle++; - } - hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET - CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT - free(feedBuffer); // GET RID OF THE MEMORY -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: CompareBuffer -// Purpose: Check the feedback buffer to see if anything is hit -// Arguments: Number of hits, pointer to buffer, point to test -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLint count; - GLfloat token,point[3]; - int loop,currentVertex,result = -1; - long nearest = -1, dist; -/////////////////////////////////////////////////////////////////////////////// - count = size; - while (count) - { - token = buffer[size - count]; // CHECK THE TOKEN - count--; - if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER - { - currentVertex = (int)buffer[size - count]; // WHAT VERTEX - count--; - } - else if (token == GL_POINT_TOKEN) - { - // THERE ARE THREE ELEMENTS TO A POINT TOKEN - for (loop = 0; loop < 3; loop++) - { - point[loop] = buffer[size - count]; - count--; - } - dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); - if (result == -1 || dist < nearest) - { - nearest = dist; - result = currentVertex; - } - } - } - - if (nearest < 50.0f) - { - if (m_Pick[0] == -1) - m_Pick[0] = result; - else if (m_Pick[1] == -1) - m_Pick[1] = result; - else - { - m_Pick[0] = result; - m_Pick[1] = -1; - } - } -} -////// CompareBuffer ////////////////////////////////////////////////////////// - -void CPhysEnv::SetWorldParticles(tTexturedVertex *coords,int particleCnt) -{ - tParticle *tempParticle; - - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - free(m_TempSys[i]); - } - if (m_Contact) - free(m_Contact); - // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - for (i = 0; i < 5; i++) - { - m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - } - m_ParticleCnt = particleCnt; - - // MULTIPLIED PARTICLE COUNT * 2 SINCE THEY CAN COLLIDE WITH MULTIPLE WALLS - m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt * 2); - m_ContactCnt = 0; - - tempParticle = m_CurrentSys; - for (int loop = 0; loop < particleCnt; loop++) - { - MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) - MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) - MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) - tempParticle->oneOverM = 1.0f; // MASS OF 1 - tempParticle++; - coords++; - } - - // COPY THE SYSTEM TO THE SECOND ONE ALSO - memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); - // COPY THE SYSTEM TO THE RESET BUFFER ALSO - memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); - - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: FreeSystem -// Purpose: Remove all particles and clear it out -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::FreeSystem() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - if (m_ParticleSys[0]) - { - m_ParticleSys[0] = NULL; - free(m_ParticleSys[0]); - } - if (m_ParticleSys[1]) - { - free(m_ParticleSys[1]); - m_ParticleSys[1] = NULL; - } - if (m_ParticleSys[2]) - { - free(m_ParticleSys[2]); - m_ParticleSys[2] = NULL; // RESET BUFFER - } - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - { - free(m_TempSys[i]); - m_TempSys[i] = NULL; // RESET BUFFER - } - } - if (m_Contact) - { - free(m_Contact); - m_Contact = NULL; - } - if (m_Spring) - { - free(m_Spring); - m_Spring = NULL; - } - m_SpringCnt = 0; - m_ParticleCnt = 0; -} -////// FreeSystem ////////////////////////////////////////////////////////////// - -void CPhysEnv::LoadData(FILE *fp) -{ - fread(&m_UseGravity,sizeof(BOOL),1,fp); - fread(&m_UseDamping,sizeof(BOOL),1,fp); - fread(&m_UserForceActive,sizeof(BOOL),1,fp); - fread(&m_Gravity,sizeof(tVector),1,fp); - fread(&m_UserForce,sizeof(tVector),1,fp); - fread(&m_UserForceMag,sizeof(float),1,fp); - fread(&m_Kd,sizeof(float),1,fp); - fread(&m_Kr,sizeof(float),1,fp); - fread(&m_Ksh,sizeof(float),1,fp); - fread(&m_Ksd,sizeof(float),1,fp); - fread(&m_ParticleCnt,sizeof(int),1,fp); - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - for (int i = 0; i < 5; i++) - { - m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - } - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; - m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); - fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fread(&m_SpringCnt,sizeof(int),1,fp); - m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); - fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fread(m_Pick,sizeof(int),2,fp); - fread(&m_SphereCnt,sizeof(int),1,fp); - m_Sphere = (tCollisionSphere *)malloc(sizeof(tCollisionSphere) * (m_SphereCnt)); - fread(m_Sphere,sizeof(tCollisionSphere),m_SphereCnt,fp); -} - -void CPhysEnv::SaveData(FILE *fp) -{ - fwrite(&m_UseGravity,sizeof(BOOL),1,fp); - fwrite(&m_UseDamping,sizeof(BOOL),1,fp); - fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); - fwrite(&m_Gravity,sizeof(tVector),1,fp); - fwrite(&m_UserForce,sizeof(tVector),1,fp); - fwrite(&m_UserForceMag,sizeof(float),1,fp); - fwrite(&m_Kd,sizeof(float),1,fp); - fwrite(&m_Kr,sizeof(float),1,fp); - fwrite(&m_Ksh,sizeof(float),1,fp); - fwrite(&m_Ksd,sizeof(float),1,fp); - fwrite(&m_ParticleCnt,sizeof(int),1,fp); - fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(&m_SpringCnt,sizeof(int),1,fp); - fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fwrite(m_Pick,sizeof(int),2,fp); - fwrite(&m_SphereCnt,sizeof(int),1,fp); - fwrite(m_Sphere,sizeof(tCollisionSphere),m_SphereCnt,fp); -} - -// RESET THE SIM TO INITIAL VALUES -void CPhysEnv::ResetWorld() -{ - memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); - memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); -} - -void CPhysEnv::SetWorldProperties() -{ - CSimProps dialog; - dialog.m_CoefRest = m_Kr; - dialog.m_Damping = m_Kd; - dialog.m_GravX = m_Gravity.x; - dialog.m_GravY = m_Gravity.y; - dialog.m_GravZ = m_Gravity.z; - dialog.m_SpringConst = m_Ksh; - dialog.m_SpringDamp = m_Ksd; - dialog.m_UserForceMag = m_UserForceMag; - if (dialog.DoModal() == IDOK) - { - m_Kr = dialog.m_CoefRest; - m_Kd = dialog.m_Damping; - m_Gravity.x = dialog.m_GravX; - m_Gravity.y = dialog.m_GravY; - m_Gravity.z = dialog.m_GravZ; - m_UserForceMag = dialog.m_UserForceMag; - m_Ksh = dialog.m_SpringConst; - m_Ksd = dialog.m_SpringDamp; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - m_Spring[loop].Ks = m_Ksh; - m_Spring[loop].Kd = m_Ksd; - } - } -} - -void CPhysEnv::SetVertexProperties() -{ - CSetVert dialog; - dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; - if (dialog.DoModal() == IDOK) - { - m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; - } -} - -void CPhysEnv::ApplyUserForce(tVector *force) -{ - ScaleVector(force, m_UserForceMag, &m_UserForce); - m_UserForceActive = TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetMouseForce -// Purpose: Allows the user to interact with selected points by dragging -// Arguments: Delta distance from clicked point, local x and y axes -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector tempX,tempY; -/////////////////////////////////////////////////////////////////////////////// - ScaleVector(localX, (float)deltaX * 0.03f, &tempX); - ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); - if (m_Pick[0] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); - VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); - VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); - } -} -/// SetMouseForce ///////////////////////////////////////////////////////////// - - -void CPhysEnv::AddSpring() -{ - tSpring *spring; - // MAKE SURE TWO PARTICLES ARE PICKED - if (m_Pick[0] > -1 && m_Pick[1] > -1) - { - spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); - if (m_Spring != NULL) - memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); - m_Spring = spring; - spring = &m_Spring[m_SpringCnt++]; - spring->Ks = m_Ksh; - spring->Kd = m_Ksd; - spring->p1 = m_Pick[0]; - spring->p2 = m_Pick[1]; - spring->restLen = - sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, - &m_CurrentSys[m_Pick[1]].pos)); - spring->type = MANUAL_SPRING; - } -} - -void CPhysEnv::AddSpring(int v1, int v2,float Ksh,float Ksd, int type) -{ - tSpring *spring; - // MAKE SURE TWO PARTICLES ARE PICKED - if (v1 > -1 && v2 > -1) - { - spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); - if (m_Spring != NULL) - { - memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); - free(m_Spring); - } - m_Spring = spring; - spring = &m_Spring[m_SpringCnt++]; - spring->type = type; - spring->Ks = Ksh; - spring->Kd = Ksd; - spring->p1 = v1; - spring->p2 = v2; - spring->restLen = - sqrt(VectorSquaredDistance(&m_CurrentSys[v1].pos, - &m_CurrentSys[v2].pos)); - } -} - -void CPhysEnv::ComputeForces( tParticle *system ) -{ - int loop; - tParticle *curParticle,*p1, *p2; - tSpring *spring; - float dist, Hterm, Dterm; - tVector springForce,deltaV,deltaP; - - curParticle = system; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR - - if (m_UseGravity && curParticle->oneOverM != 0) - { - curParticle->f.x += (m_Gravity.x / curParticle->oneOverM); - curParticle->f.y += (m_Gravity.y / curParticle->oneOverM); - curParticle->f.z += (m_Gravity.z / curParticle->oneOverM); - } - - if (m_UseDamping) - { - curParticle->f.x += (-m_Kd * curParticle->v.x); - curParticle->f.y += (-m_Kd * curParticle->v.y); - curParticle->f.z += (-m_Kd * curParticle->v.z); - } - else - { - curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); - curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); - curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); - } - curParticle++; - } - - // CHECK IF THERE IS A USER FORCE BEING APPLIED - if (m_UserForceActive) - { - if (m_Pick[0] != -1) - { - VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); - } - if (m_Pick[1] != -1) - { - VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); - } - MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE - } - - // NOW DO ALL THE SPRINGS - spring = m_Spring; - for (loop = 0; loop < m_SpringCnt; loop++) - { - p1 = &system[spring->p1]; - p2 = &system[spring->p2]; - VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) - - VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector - Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 - spring++; // DO THE NEXT SPRING - } - - // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE - if (m_MouseForceActive) - { - // APPLY TO EACH PICKED PARTICLE - if (m_Pick[0] > -1) - { - p1 = &system[m_Pick[0]]; - VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - if (m_Pick[1] > -1) - { - p1 = &system[m_Pick[1]]; - VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: IntegrateSysOverTime -// Purpose: Does the Integration for all the points in a system -// Arguments: Initial Position, Source and Target Particle Systems and Time -// Notes: Computes a single integration step -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float deltaTimeMass; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < m_ParticleCnt; loop++) - { - deltaTimeMass = deltaTime * initial->oneOverM; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = initial->v.x + (source->f.x * deltaTimeMass); - target->v.y = initial->v.y + (source->f.y * deltaTimeMass); - target->v.z = initial->v.z + (source->f.z * deltaTimeMass); - - target->oneOverM = initial->oneOverM; - - // SET THE NEW POSITION - target->pos.x = initial->pos.x + (deltaTime * source->v.x); - target->pos.y = initial->pos.y + (deltaTime * source->v.y); - target->pos.z = initial->pos.z + (deltaTime * source->v.z); - - initial++; - source++; - target++; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses Euler's method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::EulerIntegrate( float DeltaTime) -{ - // JUST TAKE A SINGLE STEP - IntegrateSysOverTime(m_CurrentSys,m_CurrentSys, m_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: MidPointIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Midpoint method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::MidPointIntegrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float halfDeltaT; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; - - // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION - IntegrateSysOverTime(m_CurrentSys,m_CurrentSys,m_TempSys[0],halfDeltaT); - - // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES - ComputeForces(m_TempSys[0]); - - // TAKE THE FULL STEP WITH THIS NEW INFORMATION - IntegrateSysOverTime(m_CurrentSys,m_TempSys[0],m_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RK4Integrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Runga-Kutta 4 method -// This could use a generic function 4 times instead of unrolled -// but it was easier for me to debug. Fun for you to optimize. -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::RK4Integrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float halfDeltaT,sixthDeltaT; - tParticle *source,*target,*accum1,*accum2,*accum3,*accum4; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; // SOME TIME VALUES I WILL NEED - sixthDeltaT = 1.0f / 6.0f; - - // FIRST STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[1]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - accum1->f.x = halfDeltaT * source->f.x * source->oneOverM; - accum1->f.y = halfDeltaT * source->f.y * source->oneOverM; - accum1->f.z = halfDeltaT * source->f.z * source->oneOverM; - - accum1->v.x = halfDeltaT * source->v.x; - accum1->v.y = halfDeltaT * source->v.y; - accum1->v.z = halfDeltaT * source->v.z; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE OVER 1/2 TIME - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES - - // SECOND STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[2]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - accum1->f.x = halfDeltaT * target->f.x * source->oneOverM; - accum1->f.y = halfDeltaT * target->f.y * source->oneOverM; - accum1->f.z = halfDeltaT * target->f.z * source->oneOverM; - accum1->v.x = halfDeltaT * target->v.x; - accum1->v.y = halfDeltaT * target->v.y; - accum1->v.z = halfDeltaT * target->v.z; - - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES - - // THIRD STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[3]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // NOTICE I USE THE FULL DELTATIME THIS STEP - accum1->f.x = DeltaTime * target->f.x * source->oneOverM; - accum1->f.y = DeltaTime * target->f.y * source->oneOverM; - accum1->f.z = DeltaTime * target->f.z * source->oneOverM; - accum1->v.x = DeltaTime * target->v.x; - accum1->v.y = DeltaTime * target->v.y; - accum1->v.z = DeltaTime * target->v.z; - - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES - - // FOURTH STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[4]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // NOTICE I USE THE FULL DELTATIME THIS STEP - accum1->f.x = DeltaTime * target->f.x * source->oneOverM; - accum1->f.y = DeltaTime * target->f.y * source->oneOverM; - accum1->f.z = DeltaTime * target->f.z * source->oneOverM; - - accum1->v.x = DeltaTime * target->v.x; - accum1->v.y = DeltaTime * target->v.y; - accum1->v.z = DeltaTime * target->v.z; - - // THIS TIME I DON'T NEED TO COMPUTE THE TEMPORARY POSITIONS - source++; - target++; - accum1++; - } - - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TargetSys; - accum1 = m_TempSys[1]; - accum2 = m_TempSys[2]; - accum3 = m_TempSys[3]; - accum4 = m_TempSys[4]; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE USING RK4 FORMULA - target->v.x = source->v.x + ((accum1->f.x + ((accum2->f.x + accum3->f.x) * 2.0f) + accum4->f.x) * sixthDeltaT); - target->v.y = source->v.y + ((accum1->f.y + ((accum2->f.y + accum3->f.y) * 2.0f) + accum4->f.y) * sixthDeltaT); - target->v.z = source->v.z + ((accum1->f.z + ((accum2->f.z + accum3->f.z) * 2.0f) + accum4->f.z) * sixthDeltaT); - // DETERMINE THE NEW POSITION FOR THE PARTICLE USING RK4 FORMULA - target->pos.x = source->pos.x + ((accum1->v.x + ((accum2->v.x + accum3->v.x) * 2.0f) + accum4->v.x) * sixthDeltaT); - target->pos.y = source->pos.y + ((accum1->v.y + ((accum2->v.y + accum3->v.y) * 2.0f) + accum4->v.y) * sixthDeltaT); - target->pos.z = source->pos.z + ((accum1->v.z + ((accum2->v.z + accum3->v.z) * 2.0f) + accum4->v.z) * sixthDeltaT); - - source++; - target++; - accum1++; - accum2++; - accum3++; - accum4++; - } - -} - -int CPhysEnv::CheckForCollisions( tParticle *system ) -{ - // be optimistic! - int collisionState = NOT_COLLIDING; - float const depthEpsilon = 0.001f; - - int loop; - tParticle *curParticle; - - m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS - - curParticle = system; - for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); - loop++,curParticle++) - { - // CHECK THE MAIN BOUNDARY PLANES FIRST - for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && - (collisionState != PENETRATING);planeIndex++) - { - tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; - - float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; - - if(axbyczd < -depthEpsilon) - { - // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(axbyczd < depthEpsilon) - { - float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); - - if(relativeVelocity < 0.0f) - { - collisionState = COLLIDING; - m_Contact[m_ContactCnt].particle = loop; - memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); - m_ContactCnt++; - } - } - } - if (m_CollisionActive) - { - // THIS IS NEW FROM MARCH - ADDED SPHERE BOUNDARIES - // CHECK ANY SPHERE BOUNDARIES - for(int sphereIndex = 0;(sphereIndex < m_SphereCnt) && - (collisionState != PENETRATING);sphereIndex++) - { - tCollisionSphere *sphere = &m_Sphere[sphereIndex]; - - tVector distVect; - - VectorDifference(&curParticle->pos, &sphere->pos, &distVect); - - float radius = VectorSquaredLength(&distVect); - // SINCE IT IS TESTING THE SQUARED DISTANCE, SQUARE THE RADIUS ALSO - float dist = radius - (sphere->radius * sphere->radius); - - if(dist < -depthEpsilon) - { - // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(dist < depthEpsilon) - { - // NORMALIZE THE VECTOR - NormalizeVector(&distVect); - - float relativeVelocity = DotProduct(&distVect,&curParticle->v); - - if(relativeVelocity < 0.0f) - { - collisionState = COLLIDING; - m_Contact[m_ContactCnt].particle = loop; - memcpy(&m_Contact[m_ContactCnt].normal,&distVect,sizeof(tVector)); - m_ContactCnt++; - } - } - } - } - - } - - return collisionState; -} - -void CPhysEnv::ResolveCollisions( tParticle *system ) -{ - tContact *contact; - tParticle *particle; // THE PARTICLE COLLIDING - float VdotN; - tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE - contact = m_Contact; - for (int loop = 0; loop < m_ContactCnt; loop++,contact++) - { - particle = &system[contact->particle]; - // CALCULATE Vn - VdotN = DotProduct(&contact->normal,&particle->v); - ScaleVector(&contact->normal, VdotN, &Vn); - // CALCULATE Vt - VectorDifference(&particle->v, &Vn, &Vt); - // SCALE Vn BY COEFFICIENT OF RESTITUTION - ScaleVector(&Vn, m_Kr, &Vn); - // SET THE VELOCITY TO BE THE NEW IMPULSE - VectorDifference(&Vt, &Vn, &particle->v); - } -} - -void CPhysEnv::Simulate(float DeltaTime, BOOL running) -{ - float CurrentTime = 0.0f; - float TargetTime = DeltaTime; - tParticle *tempSys; - int collisionState; - - while(CurrentTime < DeltaTime) - { - if (running) - { - ComputeForces(m_CurrentSys); - - // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK - // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, - // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. - // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY - if (m_CollisionRootFinding) - { - EulerIntegrate(TargetTime-CurrentTime); - } - else - { - switch (m_IntegratorType) - { - case EULER_INTEGRATOR: - EulerIntegrate(TargetTime-CurrentTime); - break; - case MIDPOINT_INTEGRATOR: - MidPointIntegrate(TargetTime-CurrentTime); - break; - case RK4_INTEGRATOR: - RK4Integrate(TargetTime-CurrentTime); - break; - } - } - } - - collisionState = CheckForCollisions(m_TargetSys); - - if(collisionState == PENETRATING) - { - // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER - m_CollisionRootFinding = TRUE; - // we simulated too far, so subdivide time and try again - TargetTime = (CurrentTime + TargetTime) / 2.0f; - - // blow up if we aren't moving forward each step, which is - // probably caused by interpenetration at the frame start - assert(fabs(TargetTime - CurrentTime) > EPSILON); - } - else - { - // either colliding or clear - if(collisionState == COLLIDING) - { - int Counter = 0; - do - { - ResolveCollisions(m_TargetSys); - Counter++; - } while((CheckForCollisions(m_TargetSys) == - COLLIDING) && (Counter < 100)); - - assert(Counter < 100); - m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT - } - - // we made a successful step, so swap configurations - // to "save" the data for the next step - - CurrentTime = TargetTime; - TargetTime = DeltaTime; - - // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN - tempSys = m_CurrentSys; - m_CurrentSys = m_TargetSys; - m_TargetSys = tempSys; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: AddCollisionSphere -// Purpose: Add a collision sphere to the system -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::AddCollisionSphere() -{ -/// Local Variables /////////////////////////////////////////////////////////// - tCollisionSphere *temparray; - CAddSpher dialog; -/////////////////////////////////////////////////////////////////////////////// - dialog.m_Radius = 2.0f; - dialog.m_XPos = 0.0f; - dialog.m_YPos = -3.0f; - dialog.m_ZPos = 0.0f; - if (dialog.DoModal()) - { - temparray = (tCollisionSphere *)malloc(sizeof(tCollisionSphere) * (m_SphereCnt+1)); - if (m_SphereCnt > 0) - { - memcpy(temparray,m_Sphere,sizeof(tCollisionSphere) * m_SphereCnt); - free(m_Sphere); - } - - MAKEVECTOR(temparray[m_SphereCnt].pos,dialog.m_XPos,dialog.m_YPos, dialog.m_ZPos) - temparray[m_SphereCnt].radius = dialog.m_Radius; - - m_Sphere = temparray; - m_SphereCnt++; - } +/////////////////////////////////////////////////////////////////////////////// +// +// PhysEnv.cpp : Physical World implementation file +// +// Purpose: Implementation of Particle Physics System +// +// Created: +// JL 2/10/99 Modified from Mass-Spring Particle demo to handle cloth +// Modified: +// JL 3/6/99 - FIXED GRAVITY FORCE CALCULATION BUG +// JL 3/8/99 - ADDED MORE POSSIBLE CONTACTS AS EACH VERTEX CAN CONTACT MORE +// THEN ONE COLLISION SURFACE (SHOULD IT BE DYNAMICALLY ALLOC'ED?) +// JL 3/20/99 - ADDED THE MIDPOINT AND RK INTEGRATOR NEEDED TO ALLOC 5 TEMP PARTICLE ARRAYS +// +// Notes: A bit of this along with the organization comes from Chris Hecker's +// Physics Articles from last year www.d6.com. Hopefully this will get +// everyone back up to speed before we dig deeper into the world of Dynamics. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998-1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include + +#include "Clothy.h" +#include "PhysEnv.h" +#include "SimProps.h" +#include "SetVert.h" +#include "AddSpher.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +///////////////////////////////////////////////////////////////////////////// +// CPhysEnv + +// INITIALIZE THE SIMULATION WORLD +CPhysEnv::CPhysEnv() +{ + m_IntegratorType = EULER_INTEGRATOR; + + m_Pick[0] = -1; + m_Pick[1] = -1; + m_ParticleSys[0] = NULL; + m_ParticleSys[1] = NULL; + m_ParticleSys[2] = NULL; // RESET BUFFER + // THESE TEMP PARTICLE BUFFERS ARE NEEDED FOR THE MIDPOINT AND RK4 INTEGRATOR + for (int i = 0; i < 5; i++) + m_TempSys[i] = NULL; + m_ParticleCnt = 0; + m_Contact = NULL; + m_Spring = NULL; + m_SpringCnt = 0; + m_MouseForceActive = FALSE; + + m_UseGravity = TRUE; + m_DrawSprings = TRUE; + m_DrawStructural = TRUE; // By default only draw structural springs + m_DrawBend = FALSE; + m_DrawShear = FALSE; + m_DrawVertices = TRUE; + m_CollisionActive = TRUE; + m_CollisionRootFinding = FALSE; // I AM NOT LOOKING FOR A COLLISION RIGHT AWAY + + MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) + m_UserForceMag = 100.0; + m_UserForceActive = FALSE; + m_MouseForceKs = 2.0f; // MOUSE SPRING CONSTANT + m_Kd = 0.04f; // DAMPING FACTOR + m_Kr = 0.1f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT + m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT + m_Ksd = 0.1f; // SPRING DAMPING CONSTANT + + // CREATE THE SIZE FOR THE SIMULATION WORLD + m_WorldSizeX = 15.0f; + m_WorldSizeY = 15.0f; + m_WorldSizeZ = 15.0f; + + m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); + m_CollisionPlaneCnt = 6; + + // MAKE THE TOP PLANE (CEILING) + MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) + m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; + + // MAKE THE BOTTOM PLANE (FLOOR) + MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) + m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; + + // MAKE THE LEFT PLANE + MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) + m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; + + // MAKE THE RIGHT PLANE + MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) + m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; + + // MAKE THE FRONT PLANE + MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) + m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; + + // MAKE THE BACK PLANE + MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) + m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; + + m_SphereCnt = 0; + +} + +CPhysEnv::~CPhysEnv() +{ + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + free(m_TempSys[i]); + } + if (m_Contact) + free(m_Contact); + free(m_CollisionPlane); + free(m_Spring); + + free(m_Sphere); +} + +void CPhysEnv::RenderWorld() +{ + tParticle *tempParticle; + tSpring *tempSpring; + + // FIRST DRAW THE WORLD CONTAINER + glColor3f(1.0f,1.0f,1.0f); + // do a big linestrip to get most of edges + glBegin(GL_LINE_STRIP); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glEnd(); + // fill in the stragglers + glBegin(GL_LINES); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + + // draw floor + glDisable(GL_CULL_FACE); + glBegin(GL_QUADS); + glColor3f(0.0f,0.0f,0.5f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + glEnable(GL_CULL_FACE); + + + if (m_ParticleSys) + { + if (m_Spring && m_DrawSprings) + { + glBegin(GL_LINES); + glColor3f(0.0f,0.8f,0.8f); + tempSpring = m_Spring; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + // Only draw normal springs or the cloth "structural" ones + if ((tempSpring->type == MANUAL_SPRING) || + (tempSpring->type == STRUCTURAL_SPRING && m_DrawStructural) || + (tempSpring->type == SHEAR_SPRING && m_DrawShear) || + (tempSpring->type == BEND_SPRING && m_DrawBend)) + { + glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); + glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); + } + tempSpring++; + } + if (m_MouseForceActive) // DRAW MOUSESPRING FORCE + { + if (m_Pick[0] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); + glVertex3fv((float *)&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); + glVertex3fv((float *)&m_MouseDragPos[1]); + } + } + glEnd(); + } + if (m_DrawVertices) + { + glBegin(GL_POINTS); + tempParticle = m_CurrentSys; + for (int loop = 0; loop < m_ParticleCnt; loop++) + { + if (loop == m_Pick[0]) + glColor3f(0.0f,0.8f,0.0f); + else if (loop == m_Pick[1]) + glColor3f(0.8f,0.0f,0.0f); + else + glColor3f(0.8f,0.8f,0.0f); + glVertex3fv((float *)&tempParticle->pos); + tempParticle++; + } + glEnd(); + } + } + + if (m_SphereCnt > 0 && m_CollisionActive) + { + glColor3f(0.5f,0.0f,0.0f); + for (int loop = 0; loop < m_SphereCnt; loop++) + { + glPushMatrix(); + glTranslatef(m_Sphere[loop].pos.x, m_Sphere[loop].pos.y, m_Sphere[loop].pos.z); + glScalef(m_Sphere[loop].radius,m_Sphere[loop].radius,m_Sphere[loop].radius); + glCallList(OGL_AXIS_DLIST); + glPopMatrix(); + } + } +} + +void CPhysEnv::GetNearestPoint(int x, int y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *feedBuffer; + int hitCount; + tParticle *tempParticle; + int loop; +/////////////////////////////////////////////////////////////////////////////// + // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) + feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); + // TELL OPENGL ABOUT THE BUFFER + glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); + (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE + + tempParticle = m_CurrentSys; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS + glPassThrough((float)loop); + // SEND THE VERTEX + glBegin(GL_POINTS); + glVertex3fv((float *)&tempParticle->pos); + glEnd(); + tempParticle++; + } + hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET + CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT + free(feedBuffer); // GET RID OF THE MEMORY +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: CompareBuffer +// Purpose: Check the feedback buffer to see if anything is hit +// Arguments: Number of hits, pointer to buffer, point to test +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLint count; + GLfloat token,point[3]; + int loop,currentVertex,result = -1; + long nearest = -1, dist; +/////////////////////////////////////////////////////////////////////////////// + count = size; + while (count) + { + token = buffer[size - count]; // CHECK THE TOKEN + count--; + if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER + { + currentVertex = (int)buffer[size - count]; // WHAT VERTEX + count--; + } + else if (token == GL_POINT_TOKEN) + { + // THERE ARE THREE ELEMENTS TO A POINT TOKEN + for (loop = 0; loop < 3; loop++) + { + point[loop] = buffer[size - count]; + count--; + } + dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); + if (result == -1 || dist < nearest) + { + nearest = dist; + result = currentVertex; + } + } + } + + if (nearest < 50.0f) + { + if (m_Pick[0] == -1) + m_Pick[0] = result; + else if (m_Pick[1] == -1) + m_Pick[1] = result; + else + { + m_Pick[0] = result; + m_Pick[1] = -1; + } + } +} +////// CompareBuffer ////////////////////////////////////////////////////////// + +void CPhysEnv::SetWorldParticles(tTexturedVertex *coords,int particleCnt) +{ + tParticle *tempParticle; + + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + free(m_TempSys[i]); + } + if (m_Contact) + free(m_Contact); + // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + for (i = 0; i < 5; i++) + { + m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + } + m_ParticleCnt = particleCnt; + + // MULTIPLIED PARTICLE COUNT * 2 SINCE THEY CAN COLLIDE WITH MULTIPLE WALLS + m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt * 2); + m_ContactCnt = 0; + + tempParticle = m_CurrentSys; + for (int loop = 0; loop < particleCnt; loop++) + { + MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) + MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) + MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) + tempParticle->oneOverM = 1.0f; // MASS OF 1 + tempParticle++; + coords++; + } + + // COPY THE SYSTEM TO THE SECOND ONE ALSO + memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); + // COPY THE SYSTEM TO THE RESET BUFFER ALSO + memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); + + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: FreeSystem +// Purpose: Remove all particles and clear it out +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::FreeSystem() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + if (m_ParticleSys[0]) + { + m_ParticleSys[0] = NULL; + free(m_ParticleSys[0]); + } + if (m_ParticleSys[1]) + { + free(m_ParticleSys[1]); + m_ParticleSys[1] = NULL; + } + if (m_ParticleSys[2]) + { + free(m_ParticleSys[2]); + m_ParticleSys[2] = NULL; // RESET BUFFER + } + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + { + free(m_TempSys[i]); + m_TempSys[i] = NULL; // RESET BUFFER + } + } + if (m_Contact) + { + free(m_Contact); + m_Contact = NULL; + } + if (m_Spring) + { + free(m_Spring); + m_Spring = NULL; + } + m_SpringCnt = 0; + m_ParticleCnt = 0; +} +////// FreeSystem ////////////////////////////////////////////////////////////// + +void CPhysEnv::LoadData(FILE *fp) +{ + fread(&m_UseGravity,sizeof(BOOL),1,fp); + fread(&m_UseDamping,sizeof(BOOL),1,fp); + fread(&m_UserForceActive,sizeof(BOOL),1,fp); + fread(&m_Gravity,sizeof(tVector),1,fp); + fread(&m_UserForce,sizeof(tVector),1,fp); + fread(&m_UserForceMag,sizeof(float),1,fp); + fread(&m_Kd,sizeof(float),1,fp); + fread(&m_Kr,sizeof(float),1,fp); + fread(&m_Ksh,sizeof(float),1,fp); + fread(&m_Ksd,sizeof(float),1,fp); + fread(&m_ParticleCnt,sizeof(int),1,fp); + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + for (int i = 0; i < 5; i++) + { + m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + } + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; + m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); + fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fread(&m_SpringCnt,sizeof(int),1,fp); + m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); + fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fread(m_Pick,sizeof(int),2,fp); + fread(&m_SphereCnt,sizeof(int),1,fp); + m_Sphere = (tCollisionSphere *)malloc(sizeof(tCollisionSphere) * (m_SphereCnt)); + fread(m_Sphere,sizeof(tCollisionSphere),m_SphereCnt,fp); +} + +void CPhysEnv::SaveData(FILE *fp) +{ + fwrite(&m_UseGravity,sizeof(BOOL),1,fp); + fwrite(&m_UseDamping,sizeof(BOOL),1,fp); + fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); + fwrite(&m_Gravity,sizeof(tVector),1,fp); + fwrite(&m_UserForce,sizeof(tVector),1,fp); + fwrite(&m_UserForceMag,sizeof(float),1,fp); + fwrite(&m_Kd,sizeof(float),1,fp); + fwrite(&m_Kr,sizeof(float),1,fp); + fwrite(&m_Ksh,sizeof(float),1,fp); + fwrite(&m_Ksd,sizeof(float),1,fp); + fwrite(&m_ParticleCnt,sizeof(int),1,fp); + fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(&m_SpringCnt,sizeof(int),1,fp); + fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fwrite(m_Pick,sizeof(int),2,fp); + fwrite(&m_SphereCnt,sizeof(int),1,fp); + fwrite(m_Sphere,sizeof(tCollisionSphere),m_SphereCnt,fp); +} + +// RESET THE SIM TO INITIAL VALUES +void CPhysEnv::ResetWorld() +{ + memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); + memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); +} + +void CPhysEnv::SetWorldProperties() +{ + CSimProps dialog; + dialog.m_CoefRest = m_Kr; + dialog.m_Damping = m_Kd; + dialog.m_GravX = m_Gravity.x; + dialog.m_GravY = m_Gravity.y; + dialog.m_GravZ = m_Gravity.z; + dialog.m_SpringConst = m_Ksh; + dialog.m_SpringDamp = m_Ksd; + dialog.m_UserForceMag = m_UserForceMag; + if (dialog.DoModal() == IDOK) + { + m_Kr = dialog.m_CoefRest; + m_Kd = dialog.m_Damping; + m_Gravity.x = dialog.m_GravX; + m_Gravity.y = dialog.m_GravY; + m_Gravity.z = dialog.m_GravZ; + m_UserForceMag = dialog.m_UserForceMag; + m_Ksh = dialog.m_SpringConst; + m_Ksd = dialog.m_SpringDamp; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + m_Spring[loop].Ks = m_Ksh; + m_Spring[loop].Kd = m_Ksd; + } + } +} + +void CPhysEnv::SetVertexProperties() +{ + CSetVert dialog; + dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; + if (dialog.DoModal() == IDOK) + { + m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; + } +} + +void CPhysEnv::ApplyUserForce(tVector *force) +{ + ScaleVector(force, m_UserForceMag, &m_UserForce); + m_UserForceActive = TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetMouseForce +// Purpose: Allows the user to interact with selected points by dragging +// Arguments: Delta distance from clicked point, local x and y axes +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector tempX,tempY; +/////////////////////////////////////////////////////////////////////////////// + ScaleVector(localX, (float)deltaX * 0.03f, &tempX); + ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); + if (m_Pick[0] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); + VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); + VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); + } +} +/// SetMouseForce ///////////////////////////////////////////////////////////// + + +void CPhysEnv::AddSpring() +{ + tSpring *spring; + // MAKE SURE TWO PARTICLES ARE PICKED + if (m_Pick[0] > -1 && m_Pick[1] > -1) + { + spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); + if (m_Spring != NULL) + memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); + m_Spring = spring; + spring = &m_Spring[m_SpringCnt++]; + spring->Ks = m_Ksh; + spring->Kd = m_Ksd; + spring->p1 = m_Pick[0]; + spring->p2 = m_Pick[1]; + spring->restLen = + sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, + &m_CurrentSys[m_Pick[1]].pos)); + spring->type = MANUAL_SPRING; + } +} + +void CPhysEnv::AddSpring(int v1, int v2,float Ksh,float Ksd, int type) +{ + tSpring *spring; + // MAKE SURE TWO PARTICLES ARE PICKED + if (v1 > -1 && v2 > -1) + { + spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); + if (m_Spring != NULL) + { + memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); + free(m_Spring); + } + m_Spring = spring; + spring = &m_Spring[m_SpringCnt++]; + spring->type = type; + spring->Ks = Ksh; + spring->Kd = Ksd; + spring->p1 = v1; + spring->p2 = v2; + spring->restLen = + sqrt(VectorSquaredDistance(&m_CurrentSys[v1].pos, + &m_CurrentSys[v2].pos)); + } +} + +void CPhysEnv::ComputeForces( tParticle *system ) +{ + int loop; + tParticle *curParticle,*p1, *p2; + tSpring *spring; + float dist, Hterm, Dterm; + tVector springForce,deltaV,deltaP; + + curParticle = system; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR + + if (m_UseGravity && curParticle->oneOverM != 0) + { + curParticle->f.x += (m_Gravity.x / curParticle->oneOverM); + curParticle->f.y += (m_Gravity.y / curParticle->oneOverM); + curParticle->f.z += (m_Gravity.z / curParticle->oneOverM); + } + + if (m_UseDamping) + { + curParticle->f.x += (-m_Kd * curParticle->v.x); + curParticle->f.y += (-m_Kd * curParticle->v.y); + curParticle->f.z += (-m_Kd * curParticle->v.z); + } + else + { + curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); + curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); + curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); + } + curParticle++; + } + + // CHECK IF THERE IS A USER FORCE BEING APPLIED + if (m_UserForceActive) + { + if (m_Pick[0] != -1) + { + VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); + } + if (m_Pick[1] != -1) + { + VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); + } + MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE + } + + // NOW DO ALL THE SPRINGS + spring = m_Spring; + for (loop = 0; loop < m_SpringCnt; loop++) + { + p1 = &system[spring->p1]; + p2 = &system[spring->p2]; + VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) + + VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector + Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 + spring++; // DO THE NEXT SPRING + } + + // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE + if (m_MouseForceActive) + { + // APPLY TO EACH PICKED PARTICLE + if (m_Pick[0] > -1) + { + p1 = &system[m_Pick[0]]; + VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + if (m_Pick[1] > -1) + { + p1 = &system[m_Pick[1]]; + VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: IntegrateSysOverTime +// Purpose: Does the Integration for all the points in a system +// Arguments: Initial Position, Source and Target Particle Systems and Time +// Notes: Computes a single integration step +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float deltaTimeMass; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < m_ParticleCnt; loop++) + { + deltaTimeMass = deltaTime * initial->oneOverM; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = initial->v.x + (source->f.x * deltaTimeMass); + target->v.y = initial->v.y + (source->f.y * deltaTimeMass); + target->v.z = initial->v.z + (source->f.z * deltaTimeMass); + + target->oneOverM = initial->oneOverM; + + // SET THE NEW POSITION + target->pos.x = initial->pos.x + (deltaTime * source->v.x); + target->pos.y = initial->pos.y + (deltaTime * source->v.y); + target->pos.z = initial->pos.z + (deltaTime * source->v.z); + + initial++; + source++; + target++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses Euler's method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::EulerIntegrate( float DeltaTime) +{ + // JUST TAKE A SINGLE STEP + IntegrateSysOverTime(m_CurrentSys,m_CurrentSys, m_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: MidPointIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Midpoint method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::MidPointIntegrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float halfDeltaT; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; + + // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION + IntegrateSysOverTime(m_CurrentSys,m_CurrentSys,m_TempSys[0],halfDeltaT); + + // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES + ComputeForces(m_TempSys[0]); + + // TAKE THE FULL STEP WITH THIS NEW INFORMATION + IntegrateSysOverTime(m_CurrentSys,m_TempSys[0],m_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RK4Integrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Runga-Kutta 4 method +// This could use a generic function 4 times instead of unrolled +// but it was easier for me to debug. Fun for you to optimize. +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::RK4Integrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float halfDeltaT,sixthDeltaT; + tParticle *source,*target,*accum1,*accum2,*accum3,*accum4; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; // SOME TIME VALUES I WILL NEED + sixthDeltaT = 1.0f / 6.0f; + + // FIRST STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[1]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + accum1->f.x = halfDeltaT * source->f.x * source->oneOverM; + accum1->f.y = halfDeltaT * source->f.y * source->oneOverM; + accum1->f.z = halfDeltaT * source->f.z * source->oneOverM; + + accum1->v.x = halfDeltaT * source->v.x; + accum1->v.y = halfDeltaT * source->v.y; + accum1->v.z = halfDeltaT * source->v.z; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE OVER 1/2 TIME + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES + + // SECOND STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[2]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + accum1->f.x = halfDeltaT * target->f.x * source->oneOverM; + accum1->f.y = halfDeltaT * target->f.y * source->oneOverM; + accum1->f.z = halfDeltaT * target->f.z * source->oneOverM; + accum1->v.x = halfDeltaT * target->v.x; + accum1->v.y = halfDeltaT * target->v.y; + accum1->v.z = halfDeltaT * target->v.z; + + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES + + // THIRD STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[3]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // NOTICE I USE THE FULL DELTATIME THIS STEP + accum1->f.x = DeltaTime * target->f.x * source->oneOverM; + accum1->f.y = DeltaTime * target->f.y * source->oneOverM; + accum1->f.z = DeltaTime * target->f.z * source->oneOverM; + accum1->v.x = DeltaTime * target->v.x; + accum1->v.y = DeltaTime * target->v.y; + accum1->v.z = DeltaTime * target->v.z; + + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES + + // FOURTH STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[4]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // NOTICE I USE THE FULL DELTATIME THIS STEP + accum1->f.x = DeltaTime * target->f.x * source->oneOverM; + accum1->f.y = DeltaTime * target->f.y * source->oneOverM; + accum1->f.z = DeltaTime * target->f.z * source->oneOverM; + + accum1->v.x = DeltaTime * target->v.x; + accum1->v.y = DeltaTime * target->v.y; + accum1->v.z = DeltaTime * target->v.z; + + // THIS TIME I DON'T NEED TO COMPUTE THE TEMPORARY POSITIONS + source++; + target++; + accum1++; + } + + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TargetSys; + accum1 = m_TempSys[1]; + accum2 = m_TempSys[2]; + accum3 = m_TempSys[3]; + accum4 = m_TempSys[4]; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE USING RK4 FORMULA + target->v.x = source->v.x + ((accum1->f.x + ((accum2->f.x + accum3->f.x) * 2.0f) + accum4->f.x) * sixthDeltaT); + target->v.y = source->v.y + ((accum1->f.y + ((accum2->f.y + accum3->f.y) * 2.0f) + accum4->f.y) * sixthDeltaT); + target->v.z = source->v.z + ((accum1->f.z + ((accum2->f.z + accum3->f.z) * 2.0f) + accum4->f.z) * sixthDeltaT); + // DETERMINE THE NEW POSITION FOR THE PARTICLE USING RK4 FORMULA + target->pos.x = source->pos.x + ((accum1->v.x + ((accum2->v.x + accum3->v.x) * 2.0f) + accum4->v.x) * sixthDeltaT); + target->pos.y = source->pos.y + ((accum1->v.y + ((accum2->v.y + accum3->v.y) * 2.0f) + accum4->v.y) * sixthDeltaT); + target->pos.z = source->pos.z + ((accum1->v.z + ((accum2->v.z + accum3->v.z) * 2.0f) + accum4->v.z) * sixthDeltaT); + + source++; + target++; + accum1++; + accum2++; + accum3++; + accum4++; + } + +} + +int CPhysEnv::CheckForCollisions( tParticle *system ) +{ + // be optimistic! + int collisionState = NOT_COLLIDING; + float const depthEpsilon = 0.001f; + + int loop; + tParticle *curParticle; + + m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS + + curParticle = system; + for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); + loop++,curParticle++) + { + // CHECK THE MAIN BOUNDARY PLANES FIRST + for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && + (collisionState != PENETRATING);planeIndex++) + { + tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; + + float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; + + if(axbyczd < -depthEpsilon) + { + // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(axbyczd < depthEpsilon) + { + float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); + + if(relativeVelocity < 0.0f) + { + collisionState = COLLIDING; + m_Contact[m_ContactCnt].particle = loop; + memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); + m_ContactCnt++; + } + } + } + if (m_CollisionActive) + { + // THIS IS NEW FROM MARCH - ADDED SPHERE BOUNDARIES + // CHECK ANY SPHERE BOUNDARIES + for(int sphereIndex = 0;(sphereIndex < m_SphereCnt) && + (collisionState != PENETRATING);sphereIndex++) + { + tCollisionSphere *sphere = &m_Sphere[sphereIndex]; + + tVector distVect; + + VectorDifference(&curParticle->pos, &sphere->pos, &distVect); + + float radius = VectorSquaredLength(&distVect); + // SINCE IT IS TESTING THE SQUARED DISTANCE, SQUARE THE RADIUS ALSO + float dist = radius - (sphere->radius * sphere->radius); + + if(dist < -depthEpsilon) + { + // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(dist < depthEpsilon) + { + // NORMALIZE THE VECTOR + NormalizeVector(&distVect); + + float relativeVelocity = DotProduct(&distVect,&curParticle->v); + + if(relativeVelocity < 0.0f) + { + collisionState = COLLIDING; + m_Contact[m_ContactCnt].particle = loop; + memcpy(&m_Contact[m_ContactCnt].normal,&distVect,sizeof(tVector)); + m_ContactCnt++; + } + } + } + } + + } + + return collisionState; +} + +void CPhysEnv::ResolveCollisions( tParticle *system ) +{ + tContact *contact; + tParticle *particle; // THE PARTICLE COLLIDING + float VdotN; + tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE + contact = m_Contact; + for (int loop = 0; loop < m_ContactCnt; loop++,contact++) + { + particle = &system[contact->particle]; + // CALCULATE Vn + VdotN = DotProduct(&contact->normal,&particle->v); + ScaleVector(&contact->normal, VdotN, &Vn); + // CALCULATE Vt + VectorDifference(&particle->v, &Vn, &Vt); + // SCALE Vn BY COEFFICIENT OF RESTITUTION + ScaleVector(&Vn, m_Kr, &Vn); + // SET THE VELOCITY TO BE THE NEW IMPULSE + VectorDifference(&Vt, &Vn, &particle->v); + } +} + +void CPhysEnv::Simulate(float DeltaTime, BOOL running) +{ + float CurrentTime = 0.0f; + float TargetTime = DeltaTime; + tParticle *tempSys; + int collisionState; + + while(CurrentTime < DeltaTime) + { + if (running) + { + ComputeForces(m_CurrentSys); + + // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK + // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, + // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. + // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY + if (m_CollisionRootFinding) + { + EulerIntegrate(TargetTime-CurrentTime); + } + else + { + switch (m_IntegratorType) + { + case EULER_INTEGRATOR: + EulerIntegrate(TargetTime-CurrentTime); + break; + case MIDPOINT_INTEGRATOR: + MidPointIntegrate(TargetTime-CurrentTime); + break; + case RK4_INTEGRATOR: + RK4Integrate(TargetTime-CurrentTime); + break; + } + } + } + + collisionState = CheckForCollisions(m_TargetSys); + + if(collisionState == PENETRATING) + { + // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER + m_CollisionRootFinding = TRUE; + // we simulated too far, so subdivide time and try again + TargetTime = (CurrentTime + TargetTime) / 2.0f; + + // blow up if we aren't moving forward each step, which is + // probably caused by interpenetration at the frame start + assert(fabs(TargetTime - CurrentTime) > EPSILON); + } + else + { + // either colliding or clear + if(collisionState == COLLIDING) + { + int Counter = 0; + do + { + ResolveCollisions(m_TargetSys); + Counter++; + } while((CheckForCollisions(m_TargetSys) == + COLLIDING) && (Counter < 100)); + + assert(Counter < 100); + m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT + } + + // we made a successful step, so swap configurations + // to "save" the data for the next step + + CurrentTime = TargetTime; + TargetTime = DeltaTime; + + // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN + tempSys = m_CurrentSys; + m_CurrentSys = m_TargetSys; + m_TargetSys = tempSys; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: AddCollisionSphere +// Purpose: Add a collision sphere to the system +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::AddCollisionSphere() +{ +/// Local Variables /////////////////////////////////////////////////////////// + tCollisionSphere *temparray; + CAddSpher dialog; +/////////////////////////////////////////////////////////////////////////////// + dialog.m_Radius = 2.0f; + dialog.m_XPos = 0.0f; + dialog.m_YPos = -3.0f; + dialog.m_ZPos = 0.0f; + if (dialog.DoModal()) + { + temparray = (tCollisionSphere *)malloc(sizeof(tCollisionSphere) * (m_SphereCnt+1)); + if (m_SphereCnt > 0) + { + memcpy(temparray,m_Sphere,sizeof(tCollisionSphere) * m_SphereCnt); + free(m_Sphere); + } + + MAKEVECTOR(temparray[m_SphereCnt].pos,dialog.m_XPos,dialog.m_YPos, dialog.m_ZPos) + temparray[m_SphereCnt].radius = dialog.m_Radius; + + m_Sphere = temparray; + m_SphereCnt++; + } } \ No newline at end of file diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.h index c1be084..d65aa0d 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/PhysEnv.h @@ -1,158 +1,158 @@ -#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) -#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// PhysEnv.h : header file -// -#include "MathDefs.h" - -#define EPSILON 0.00001f // ERROR TERM -#define DEFAULT_DAMPING 0.002f - -enum tCollisionTypes -{ - NOT_COLLIDING, - PENETRATING, - COLLIDING -}; - -enum tIntegratorTypes -{ - EULER_INTEGRATOR, - MIDPOINT_INTEGRATOR, - RK4_INTEGRATOR -}; - - -// CLASSIFY THE SPRINGS SO I CAN HANDLE THEM SEPARATELY -enum tSpringTypes -{ - MANUAL_SPRING, - STRUCTURAL_SPRING, - SHEAR_SPRING, - BEND_SPRING -}; - -// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH -struct tCollisionPlane -{ - tVector normal; // inward pointing - float d; // ax + by + cz + d = 0 -}; - -// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM -struct tParticle -{ - tVector pos; // Position of Particle - tVector v; // Velocity of Particle - tVector f; // Force Acting on Particle - float oneOverM; // 1 / Mass of Particle -}; - -// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM -struct tContact -{ - int particle; // Particle Index - tVector normal; // Normal of Collision plane -}; - -// TYPE FOR COLLISION SPHERES IN SYSTEM -struct tCollisionSphere -{ - float radius; // RADIUS OF SPHERE - tVector pos; // POSITION OF SPHERE -}; - -// TYPE FOR SPRINGS IN SYSTEM -struct tSpring -{ - int p1,p2; // PARTICLE INDEX FOR ENDS - float restLen; // LENGTH OF SPRING AT REST - float Ks; // SPRING CONSTANT - float Kd; // SPRING DAMPING - int type; // SPRING TYPE - USED FOR SPECIAL FEATURES -}; - -class CPhysEnv -{ -// Construction -public: - CPhysEnv(); - void RenderWorld(); - void SetWorldParticles(tTexturedVertex *coords,int particleCnt); - void ResetWorld(); - void Simulate(float DeltaTime,BOOL running); - void ApplyUserForce(tVector *force); - void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); - void GetNearestPoint(int x, int y); - void AddSpring(); - void AddSpring(int v1, int v2,float Ksh,float Ksd, int type); - void SetWorldProperties(); - void SetVertexProperties(); - void FreeSystem(); - void LoadData(FILE *fp); - void SaveData(FILE *fp); - void AddCollisionSphere(); - BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN - BOOL m_UseDamping; // SHOULD DAMPING BE ON - BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED - BOOL m_DrawSprings; // DRAW THE SPRING LINES - BOOL m_DrawVertices; // DRAW VERTICES - BOOL m_MouseForceActive; // MOUSE DRAG FORCE - BOOL m_CollisionActive; // COLLISION SPHERES ACTIVE - BOOL m_CollisionRootFinding; // AM I SEARCHING FOR A COLLISION - BOOL m_DrawStructural; // DRAW STRUCTURAL CLOTH SPRINGS - BOOL m_DrawShear; // DRAW SHEAR CLOTH SPRINGS - BOOL m_DrawBend; // DRAW BEND CLOTH SPRINGS - int m_IntegratorType; - -// Attributes -private: - float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; - tVector m_Gravity; // GRAVITY FORCE VECTOR - tVector m_UserForce; // USER FORCE VECTOR - float m_UserForceMag; // MAGNITUDE OF USER FORCE - float m_Kd; // DAMPING FACTOR - float m_Kr; // COEFFICIENT OF RESTITUTION - float m_Ksh; // HOOK'S SPRING CONSTANT - float m_Ksd; // SPRING DAMPING - float m_MouseForceKs; // MOUSE SPRING COEFFICIENT - tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES - int m_CollisionPlaneCnt; - tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS - int m_ContactCnt; // COLLISION COUNT - tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES - tParticle *m_CurrentSys,*m_TargetSys; - tParticle *m_TempSys[5]; // SETUP FOR TEMP PARTICLES USED WHILE INTEGRATING - int m_ParticleCnt; - tSpring *m_Spring; // VALID SPRINGS IN SYSTEM - int m_SpringCnt; - int m_Pick[2]; // INDEX COUNTERS FOR SELECTING - tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR - tCollisionSphere *m_Sphere; - int m_SphereCnt; -// Operations -private: - inline void IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime); - void RK4Integrate( float DeltaTime); - void MidPointIntegrate( float DeltaTime); - void EulerIntegrate( float DeltaTime); - void ComputeForces( tParticle *system ); - int CheckForCollisions( tParticle *system ); - void ResolveCollisions( tParticle *system ); - void CompareBuffer(int size, float *buffer,float x, float y); - -// Implementation -public: - virtual ~CPhysEnv(); - -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PhysEnv.h : header file +// +#include "MathDefs.h" + +#define EPSILON 0.00001f // ERROR TERM +#define DEFAULT_DAMPING 0.002f + +enum tCollisionTypes +{ + NOT_COLLIDING, + PENETRATING, + COLLIDING +}; + +enum tIntegratorTypes +{ + EULER_INTEGRATOR, + MIDPOINT_INTEGRATOR, + RK4_INTEGRATOR +}; + + +// CLASSIFY THE SPRINGS SO I CAN HANDLE THEM SEPARATELY +enum tSpringTypes +{ + MANUAL_SPRING, + STRUCTURAL_SPRING, + SHEAR_SPRING, + BEND_SPRING +}; + +// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH +struct tCollisionPlane +{ + tVector normal; // inward pointing + float d; // ax + by + cz + d = 0 +}; + +// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM +struct tParticle +{ + tVector pos; // Position of Particle + tVector v; // Velocity of Particle + tVector f; // Force Acting on Particle + float oneOverM; // 1 / Mass of Particle +}; + +// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM +struct tContact +{ + int particle; // Particle Index + tVector normal; // Normal of Collision plane +}; + +// TYPE FOR COLLISION SPHERES IN SYSTEM +struct tCollisionSphere +{ + float radius; // RADIUS OF SPHERE + tVector pos; // POSITION OF SPHERE +}; + +// TYPE FOR SPRINGS IN SYSTEM +struct tSpring +{ + int p1,p2; // PARTICLE INDEX FOR ENDS + float restLen; // LENGTH OF SPRING AT REST + float Ks; // SPRING CONSTANT + float Kd; // SPRING DAMPING + int type; // SPRING TYPE - USED FOR SPECIAL FEATURES +}; + +class CPhysEnv +{ +// Construction +public: + CPhysEnv(); + void RenderWorld(); + void SetWorldParticles(tTexturedVertex *coords,int particleCnt); + void ResetWorld(); + void Simulate(float DeltaTime,BOOL running); + void ApplyUserForce(tVector *force); + void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); + void GetNearestPoint(int x, int y); + void AddSpring(); + void AddSpring(int v1, int v2,float Ksh,float Ksd, int type); + void SetWorldProperties(); + void SetVertexProperties(); + void FreeSystem(); + void LoadData(FILE *fp); + void SaveData(FILE *fp); + void AddCollisionSphere(); + BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN + BOOL m_UseDamping; // SHOULD DAMPING BE ON + BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED + BOOL m_DrawSprings; // DRAW THE SPRING LINES + BOOL m_DrawVertices; // DRAW VERTICES + BOOL m_MouseForceActive; // MOUSE DRAG FORCE + BOOL m_CollisionActive; // COLLISION SPHERES ACTIVE + BOOL m_CollisionRootFinding; // AM I SEARCHING FOR A COLLISION + BOOL m_DrawStructural; // DRAW STRUCTURAL CLOTH SPRINGS + BOOL m_DrawShear; // DRAW SHEAR CLOTH SPRINGS + BOOL m_DrawBend; // DRAW BEND CLOTH SPRINGS + int m_IntegratorType; + +// Attributes +private: + float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; + tVector m_Gravity; // GRAVITY FORCE VECTOR + tVector m_UserForce; // USER FORCE VECTOR + float m_UserForceMag; // MAGNITUDE OF USER FORCE + float m_Kd; // DAMPING FACTOR + float m_Kr; // COEFFICIENT OF RESTITUTION + float m_Ksh; // HOOK'S SPRING CONSTANT + float m_Ksd; // SPRING DAMPING + float m_MouseForceKs; // MOUSE SPRING COEFFICIENT + tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES + int m_CollisionPlaneCnt; + tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS + int m_ContactCnt; // COLLISION COUNT + tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES + tParticle *m_CurrentSys,*m_TargetSys; + tParticle *m_TempSys[5]; // SETUP FOR TEMP PARTICLES USED WHILE INTEGRATING + int m_ParticleCnt; + tSpring *m_Spring; // VALID SPRINGS IN SYSTEM + int m_SpringCnt; + int m_Pick[2]; // INDEX COUNTERS FOR SELECTING + tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR + tCollisionSphere *m_Sphere; + int m_SphereCnt; +// Operations +private: + inline void IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime); + void RK4Integrate( float DeltaTime); + void MidPointIntegrate( float DeltaTime); + void EulerIntegrate( float DeltaTime); + void ComputeForces( tParticle *system ); + int CheckForCollisions( tParticle *system ); + void ResolveCollisions( tParticle *system ); + void CompareBuffer(int size, float *buffer,float x, float y); + +// Implementation +public: + virtual ~CPhysEnv(); + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/ReadMe.txt b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/ReadMe.txt index bea90a5..9439d28 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/ReadMe.txt +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/ReadMe.txt @@ -1,68 +1,68 @@ -3D Cloth Simulation Demonstration April 10, 1999 --------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the May 99 -Game Developer magazine. It is meant as a demonstration of -a method for 3D cloth simulation in OpenGL. - -Cloth simulation is a very complex process. This column and -demo just scratches the surface. It is simply a way of building -a form of cloth using the mass and spring system from last -month. It is sort of a macro function (CreateClothPatch in OGLView.cpp) -that builds all the various springs and attaches them. -There are many places it can be improved and modified. -Please read the article and check the references in the -"For Further Info" section if you are really interested -in cloth simulation. - -Ideas for Optimization and expansion: -1. Change the springs to work on the Squared distance to avoid -the sqrt for each spring. - -2. The collision detection really slows things down. The model -could be changed so that it didn't back up the sim for cloth->sphere -collisions. You could simply move the vertex outside the sphere. -I have tried this and it makes things a bunch faster at the expense -of some accuracy. - -3. Optimize the integration code. Especially the RK4 needs some -work. - -4. Add a fix to the "super-elastic" effect I described in the -article. - -5. Add an implicit integrator like in the Witkin and Baraff -reference. - -6. Add in cloth->box collision. - -Hopefully this will get you started. If you make any -improvements send them to me and I will post them with a -credit to you. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. -I hope to expand on this demo some more in the future. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - - -I compiled the code with Visual C++ 6.0. It has been tested -with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -Also, depending on how well GLlines are drawn on your system, the -sim should run too fast, too slow, or just right. I try to lock -it to the clock except to set the timesteps. If it is strange, -adjust COGLView::RunSim(). - +3D Cloth Simulation Demonstration April 10, 1999 +-------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the May 99 +Game Developer magazine. It is meant as a demonstration of +a method for 3D cloth simulation in OpenGL. + +Cloth simulation is a very complex process. This column and +demo just scratches the surface. It is simply a way of building +a form of cloth using the mass and spring system from last +month. It is sort of a macro function (CreateClothPatch in OGLView.cpp) +that builds all the various springs and attaches them. +There are many places it can be improved and modified. +Please read the article and check the references in the +"For Further Info" section if you are really interested +in cloth simulation. + +Ideas for Optimization and expansion: +1. Change the springs to work on the Squared distance to avoid +the sqrt for each spring. + +2. The collision detection really slows things down. The model +could be changed so that it didn't back up the sim for cloth->sphere +collisions. You could simply move the vertex outside the sphere. +I have tried this and it makes things a bunch faster at the expense +of some accuracy. + +3. Optimize the integration code. Especially the RK4 needs some +work. + +4. Add a fix to the "super-elastic" effect I described in the +article. + +5. Add an implicit integrator like in the Witkin and Baraff +reference. + +6. Add in cloth->box collision. + +Hopefully this will get you started. If you make any +improvements send them to me and I will post them with a +credit to you. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. +I hope to expand on this demo some more in the future. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + + +I compiled the code with Visual C++ 6.0. It has been tested +with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +Also, depending on how well GLlines are drawn on your system, the +sim should run too fast, too slow, or just right. I try to lock +it to the clock except to set the timesteps. If it is strange, +adjust COGLView::RunSim(). + diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.cpp index f6ba39f..da102e4 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.cpp @@ -1,43 +1,43 @@ -// SetVert.cpp : implementation file -// - -#include "stdafx.h" -#include "Clothy.h" -#include "SetVert.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSetVert dialog - - -CSetVert::CSetVert(CWnd* pParent /*=NULL*/) - : CDialog(CSetVert::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSetVert) - m_VertexMass = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSetVert::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSetVert) - DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSetVert, CDialog) - //{{AFX_MSG_MAP(CSetVert) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSetVert message handlers +// SetVert.cpp : implementation file +// + +#include "stdafx.h" +#include "Clothy.h" +#include "SetVert.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSetVert dialog + + +CSetVert::CSetVert(CWnd* pParent /*=NULL*/) + : CDialog(CSetVert::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSetVert) + m_VertexMass = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSetVert::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSetVert) + DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSetVert, CDialog) + //{{AFX_MSG_MAP(CSetVert) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSetVert message handlers diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.h index 2fd8b05..9870442 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SetVert.h @@ -1,46 +1,46 @@ -#if !defined(AFX_SETVERT_H__5F1BAAC0_BDD8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_SETVERT_H__5F1BAAC0_BDD8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// SetVert.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSetVert dialog - -class CSetVert : public CDialog -{ -// Construction -public: - CSetVert(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSetVert) - enum { IDD = IDD_VERTEXDIALOG }; - float m_VertexMass; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSetVert) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSetVert) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SETVERT_H__5F1BAAC0_BDD8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_SETVERT_H__5F1BAAC0_BDD8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_SETVERT_H__5F1BAAC0_BDD8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// SetVert.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSetVert dialog + +class CSetVert : public CDialog +{ +// Construction +public: + CSetVert(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSetVert) + enum { IDD = IDD_VERTEXDIALOG }; + float m_VertexMass; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSetVert) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSetVert) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SETVERT_H__5F1BAAC0_BDD8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.cpp index fcca4d1..0c27d6d 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.cpp @@ -1,56 +1,56 @@ -// SimProps.cpp : implementation file -// - -#include "stdafx.h" -#include "Clothy.h" -#include "SimProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - - -CSimProps::CSimProps(CWnd* pParent /*=NULL*/) - : CDialog(CSimProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSimProps) - m_CoefRest = 0.0f; - m_Damping = 0.0f; - m_GravX = 0.0f; - m_GravY = 0.0f; - m_GravZ = 0.0f; - m_SpringConst = 0.0f; - m_SpringDamp = 0.0f; - m_UserForceMag = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSimProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSimProps) - DDX_Text(pDX, IDC_COEFREST, m_CoefRest); - DDX_Text(pDX, IDC_Damping, m_Damping); - DDX_Text(pDX, IDC_GRAVX, m_GravX); - DDX_Text(pDX, IDC_GRAVY, m_GravY); - DDX_Text(pDX, IDC_GRAVZ, m_GravZ); - DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); - DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); - DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSimProps, CDialog) - //{{AFX_MSG_MAP(CSimProps) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSimProps message handlers +// SimProps.cpp : implementation file +// + +#include "stdafx.h" +#include "Clothy.h" +#include "SimProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + + +CSimProps::CSimProps(CWnd* pParent /*=NULL*/) + : CDialog(CSimProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSimProps) + m_CoefRest = 0.0f; + m_Damping = 0.0f; + m_GravX = 0.0f; + m_GravY = 0.0f; + m_GravZ = 0.0f; + m_SpringConst = 0.0f; + m_SpringDamp = 0.0f; + m_UserForceMag = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSimProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSimProps) + DDX_Text(pDX, IDC_COEFREST, m_CoefRest); + DDX_Text(pDX, IDC_Damping, m_Damping); + DDX_Text(pDX, IDC_GRAVX, m_GravX); + DDX_Text(pDX, IDC_GRAVY, m_GravY); + DDX_Text(pDX, IDC_GRAVZ, m_GravZ); + DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); + DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); + DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSimProps, CDialog) + //{{AFX_MSG_MAP(CSimProps) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSimProps message handlers diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.h index 4e10c68..7dbe14a 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/SimProps.h @@ -1,52 +1,52 @@ -#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) -#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// SimProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - -class CSimProps : public CDialog -{ -// Construction -public: - CSimProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSimProps) - enum { IDD = IDD_SIMPROP }; - float m_CoefRest; - float m_Damping; - float m_GravX; - float m_GravY; - float m_GravZ; - float m_SpringConst; - float m_SpringDamp; - float m_UserForceMag; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSimProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSimProps) - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// SimProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + +class CSimProps : public CDialog +{ +// Construction +public: + CSimProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSimProps) + enum { IDD = IDD_SIMPROP }; + float m_CoefRest; + float m_Damping; + float m_GravX; + float m_GravY; + float m_GravZ; + float m_SpringConst; + float m_SpringDamp; + float m_UserForceMag; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSimProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSimProps) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.cpp index 68cf8c4..ac13a71 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.cpp @@ -1,166 +1,166 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { -// free(child->primChannel); - child->primChannel = NULL; - } - if (child->visualCnt > 0) - { - free(child->visuals->vertexData); - if (child->visuals->faceIndex) - free(child->visuals->faceIndex); - free(child->visuals); - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - if (root->visualCnt > 0) - { - free(root->visuals->vertexData); - if (root->visuals->faceIndex) - free(root->visuals->faceIndex); - free(root->visuals); - } - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { +// free(child->primChannel); + child->primChannel = NULL; + } + if (child->visualCnt > 0) + { + free(child->visuals->vertexData); + if (child->visuals->faceIndex) + free(child->visuals->faceIndex); + free(child->visuals); + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + if (root->visualCnt > 0) + { + free(root->visuals->vertexData); + if (root->visuals->faceIndex) + free(root->visuals->faceIndex); + free(root->visuals); + } + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.h index 46b5d27..87139bd 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/Skeleton.h @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -#define ushort unsigned short -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "MathDefs.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS - ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED - int vSize; // NUMBER OF FLOATS IN A VERTEX - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *faceNormal; // POINTER TO FACE NORMALS - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tVector Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - int glTex; - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -}; - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +#define ushort unsigned short +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "MathDefs.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS + ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED + int vSize; // NUMBER OF FLOATS IN A VERTEX + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *faceNormal; // POINTER TO FACE NORMALS + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tVector Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + int glTex; + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +}; + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.cpp index 4758675..51f29bd 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Clothy.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Clothy.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.h index ddefdab..571c76c 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.cpp b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.cpp index 2418962..48121fa 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.cpp +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.cpp @@ -1,48 +1,48 @@ -// TimeProps.cpp : implementation file -// - -#include "stdafx.h" -#include "Clothy.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - - -CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) - : CDialog(CTimeProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CTimeProps) - m_FixedTimeSteps = FALSE; - m_Iterations = 0; - m_MaxTimeStep = 0.0f; - //}}AFX_DATA_INIT -} - - -void CTimeProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CTimeProps) - DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); - DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); - DDV_MinMaxInt(pDX, m_Iterations, 1, 100); - DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CTimeProps, CDialog) - //{{AFX_MSG_MAP(CTimeProps) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps message handlers +// TimeProps.cpp : implementation file +// + +#include "stdafx.h" +#include "Clothy.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + + +CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) + : CDialog(CTimeProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTimeProps) + m_FixedTimeSteps = FALSE; + m_Iterations = 0; + m_MaxTimeStep = 0.0f; + //}}AFX_DATA_INIT +} + + +void CTimeProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTimeProps) + DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); + DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); + DDV_MinMaxInt(pDX, m_Iterations, 1, 100); + DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CTimeProps, CDialog) + //{{AFX_MSG_MAP(CTimeProps) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps message handlers diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.h index 07041d8..2222823 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/TimeProps.h @@ -1,48 +1,48 @@ -#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// TimeProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - -class CTimeProps : public CDialog -{ -// Construction -public: - CTimeProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CTimeProps) - enum { IDD = IDD_SIMTIMING }; - BOOL m_FixedTimeSteps; - int m_Iterations; - float m_MaxTimeStep; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CTimeProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CTimeProps) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// TimeProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + +class CTimeProps : public CDialog +{ +// Construction +public: + CTimeProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTimeProps) + enum { IDD = IDD_SIMTIMING }; + BOOL m_FixedTimeSteps; + int m_Iterations; + float m_MaxTimeStep; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTimeProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CTimeProps) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/resource.h b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/resource.h index a2a5671..deb134a 100644 --- a/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/resource.h +++ b/Cloth Simulation using Mass and Spring System/Code/OGL/Clothy/resource.h @@ -1,104 +1,104 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Clothy.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_CLOTHYTYPE 129 -#define IDD_SETROTATE 130 -#define IDB_HUP 131 -#define IDB_HDN 132 -#define IDD_DIALOG1 132 -#define IDB_HUPP 133 -#define IDD_LOADOBJ 133 -#define IDD_PICKOBJ 133 -#define IDB_HDNP 134 -#define IDD_SIMPROP 134 -#define IDB_VDN 135 -#define IDD_VERTEXDIALOG 135 -#define IDD_VERTEXMASS 135 -#define IDB_VUP 136 -#define IDD_SIMTIMING 136 -#define IDB_VUPP 137 -#define IDD_MAKECLOTH 137 -#define IDB_VDNP 138 -#define IDD_ADDSPHERE 138 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_BUTTON1 1001 -#define IDC_BROWSE1 1001 -#define IDC_ZAXIS 1002 -#define IDC_BROWSE2 1002 -#define IDC_SLIDER1 1003 -#define IDC_EDIT1 1004 -#define IDC_GRAVX 1004 -#define IDC_MAXTIMESTEP 1004 -#define IDC_SHEARCOEF 1004 -#define IDC_XPOS 1004 -#define IDC_EDIT2 1005 -#define IDC_OBJLIST 1005 -#define IDC_GRAVY 1005 -#define IDC_ITERATIONS 1005 -#define IDC_STRUCTCOEF 1005 -#define IDC_YPOS 1005 -#define IDC_GRAVZ 1006 -#define IDC_ZPOS 1006 -#define IDC_COEFREST 1007 -#define IDC_VERTICAL 1007 -#define IDC_RADIUS 1007 -#define IDC_SPRINGCONST 1008 -#define IDC_BENDCOEF 1008 -#define IDC_Damping 1009 -#define IDC_SHEARDAMP 1009 -#define IDC_SPRINGDAMP 1010 -#define IDC_STRUCTDAMP 1010 -#define IDC_USERFORCEMAG 1011 -#define IDC_BENDDAMP 1011 -#define IDC_VERTEXMASS 1012 -#define IDC_USIZE 1012 -#define IDC_VSIZE 1013 -#define IDC_FIXEDTIME 1014 -#define IDC_USESTRUCT 1014 -#define IDC_USESHEAR 1015 -#define IDC_USEBEND 1016 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_METHOD_FASTBBOX 32775 -#define ID_VIEW_SHOWBBOX 32776 -#define ID_VIEW_SHOWOBBOX 32777 -#define ID_VIEW_SHOWSPRINGS 32778 -#define ID_VIEW_SHOWGEOMETRY 32779 -#define ID_SIMULATION_RUNNING 32780 -#define ID_SIMULATION_RESET 32781 -#define ID_SIMULATION_SETSIMPROPERTIES 32782 -#define ID_SIMULATION_USEGRAVITY 32783 -#define ID_VIEW_SHOWVERTICES 32785 -#define ID_FILE_CREATECLOTHPATCH 32786 -#define ID_SIMULATION_SETVERTEXPROPERTIES 32787 -#define ID_VIEW_COLLISIONACTIVE 32788 -#define ID_VIEW_SHOWSTRUCTURAL 32789 -#define ID_VIEW_SHOWSHEAR 32790 -#define ID_VIEW_SHOWBEND 32791 -#define ID_INTEULER 32792 -#define ID_INTMIDPOINT 32793 -#define ID_INTRK4 32794 -#define ID_FILE_NEWSYSTEM 32795 -#define ID_SIMULATION_SETTIMINGPROPERTIES 32796 -#define ID_SIMULATION_ADDCOLLISIONSPHERE 32797 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 139 -#define _APS_NEXT_COMMAND_VALUE 32798 -#define _APS_NEXT_CONTROL_VALUE 1015 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Clothy.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_CLOTHYTYPE 129 +#define IDD_SETROTATE 130 +#define IDB_HUP 131 +#define IDB_HDN 132 +#define IDD_DIALOG1 132 +#define IDB_HUPP 133 +#define IDD_LOADOBJ 133 +#define IDD_PICKOBJ 133 +#define IDB_HDNP 134 +#define IDD_SIMPROP 134 +#define IDB_VDN 135 +#define IDD_VERTEXDIALOG 135 +#define IDD_VERTEXMASS 135 +#define IDB_VUP 136 +#define IDD_SIMTIMING 136 +#define IDB_VUPP 137 +#define IDD_MAKECLOTH 137 +#define IDB_VDNP 138 +#define IDD_ADDSPHERE 138 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_BUTTON1 1001 +#define IDC_BROWSE1 1001 +#define IDC_ZAXIS 1002 +#define IDC_BROWSE2 1002 +#define IDC_SLIDER1 1003 +#define IDC_EDIT1 1004 +#define IDC_GRAVX 1004 +#define IDC_MAXTIMESTEP 1004 +#define IDC_SHEARCOEF 1004 +#define IDC_XPOS 1004 +#define IDC_EDIT2 1005 +#define IDC_OBJLIST 1005 +#define IDC_GRAVY 1005 +#define IDC_ITERATIONS 1005 +#define IDC_STRUCTCOEF 1005 +#define IDC_YPOS 1005 +#define IDC_GRAVZ 1006 +#define IDC_ZPOS 1006 +#define IDC_COEFREST 1007 +#define IDC_VERTICAL 1007 +#define IDC_RADIUS 1007 +#define IDC_SPRINGCONST 1008 +#define IDC_BENDCOEF 1008 +#define IDC_Damping 1009 +#define IDC_SHEARDAMP 1009 +#define IDC_SPRINGDAMP 1010 +#define IDC_STRUCTDAMP 1010 +#define IDC_USERFORCEMAG 1011 +#define IDC_BENDDAMP 1011 +#define IDC_VERTEXMASS 1012 +#define IDC_USIZE 1012 +#define IDC_VSIZE 1013 +#define IDC_FIXEDTIME 1014 +#define IDC_USESTRUCT 1014 +#define IDC_USESHEAR 1015 +#define IDC_USEBEND 1016 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_METHOD_FASTBBOX 32775 +#define ID_VIEW_SHOWBBOX 32776 +#define ID_VIEW_SHOWOBBOX 32777 +#define ID_VIEW_SHOWSPRINGS 32778 +#define ID_VIEW_SHOWGEOMETRY 32779 +#define ID_SIMULATION_RUNNING 32780 +#define ID_SIMULATION_RESET 32781 +#define ID_SIMULATION_SETSIMPROPERTIES 32782 +#define ID_SIMULATION_USEGRAVITY 32783 +#define ID_VIEW_SHOWVERTICES 32785 +#define ID_FILE_CREATECLOTHPATCH 32786 +#define ID_SIMULATION_SETVERTEXPROPERTIES 32787 +#define ID_VIEW_COLLISIONACTIVE 32788 +#define ID_VIEW_SHOWSTRUCTURAL 32789 +#define ID_VIEW_SHOWSHEAR 32790 +#define ID_VIEW_SHOWBEND 32791 +#define ID_INTEULER 32792 +#define ID_INTMIDPOINT 32793 +#define ID_INTRK4 32794 +#define ID_FILE_NEWSYSTEM 32795 +#define ID_SIMULATION_SETTIMINGPROPERTIES 32796 +#define ID_SIMULATION_ADDCOLLISIONSPHERE 32797 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 139 +#define _APS_NEXT_COMMAND_VALUE 32798 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/EXTERNS.h b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/EXTERNS.h index 17097ec..2fe4d0f 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/EXTERNS.h +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/EXTERNS.h @@ -1,204 +1,204 @@ -// Externs.h -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -#include "MathDefs.h" - -// This sets up the table position in the world -// TODO: Should load with the model....? -#define FFD_STARTY 4.20f // Height of the virtual table off ground - -// Physical Dimension of the Ball -#define BALL_DIAMETER 0.1875f // Diameter of Billiard Ball in feet 2.25 in - -#define EPSILON 0.00001f // ERROR TERM -#define DEFAULT_DAMPING 0.002f -#define DRAG_FORCE 5.0f // For Mouse interaction - -enum tCollisionTypes -{ - NOT_COLLIDING, - PENETRATING, - COLLIDING_WITH_WALL, - COLLIDING_WITH_BALL -}; - -enum tIntegratorTypes -{ - EULER_INTEGRATOR, - MIDPOINT_INTEGRATOR, - RK4_INTEGRATOR -}; - -// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM -typedef struct s_Contact -{ - int particle,particle2; - tVector normal; // Normal of Collision plane - int type; // COLLIDING OR CONTACT - float Kr; // Coefficient of restitution -} t_Contact; - -// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH -typedef struct s_CollisionPlane -{ - tVector normal; // inward pointing - float d; // ax + by + cz + d = 0 -} t_CollisionPlane; - -typedef struct s_Camera -{ - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - float fov; // FIELD OF VIEW -} t_Camera; - -// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM -typedef struct s_Particle -{ - tVector rest_pos; // Position of Particle - tVector pos; // Position of Particle - tVector v; // Velocity of Particle - tVector f; // Force Acting on Particle - tVector angMom; // Angular Momentum - tVector torque; // Torque - float oneOverM; // 1 / Mass of Particle - tQuaternion orientation; - int flags; // So I can track things -} t_Particle; - -// TYPE FOR SPRINGS IN SYSTEM -typedef struct s_Spring -{ - int p1,p2; // PARTICLE INDEX FOR ENDS - float restLen; // LENGTH OF SPRING AT REST - float Ks; // SPRING CONSTANT - float Kd; // SPRING DAMPING -} t_Spring; - -/// Model Definitions /////////////////////////////////////////////////////// -struct t_VWeight -{ - float *weight; -}; - -typedef struct -{ - long v[3],n[3],t[3]; - int mat; -} t_faceIndex; - -typedef struct -{ - int dataFormat; - tVector *vertex; // Vertex - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - tVector *normal; // Vertex - tVector *deformData; // DEFORMED VERTEX DATA - tVector *texture; // Vertex - t_faceIndex *index; - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *matColor; // POINTER TO VECTOR - int matCnt; - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tColor Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - uint glTex; - float *weightData; // - long normalCnt; // NUMBER OF VERTICES IN VISUAL - long uvCnt; // NUMBER OF VERTICES IN VISUAL - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -} t_ToonVisual; - -typedef struct -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - void *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - void *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - float min_rx, max_rx; // ROTATION X LIMITS - float min_ry, max_ry; // ROTATION Y LIMITS - float min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_ToonVisual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_select; // POINTER TO CONTROL VERTICES - void *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - tMatrix *curMatrix; // STORE THE CURRENT MATRIX -} t_Mesh; - -#define POLY_SELECTED 1 -#define POLY_TEXTURED 2 - -// Camera for View System -extern t_Camera g_POV; - -// Objects for the Game -extern t_Particle *g_CurrentSys; -extern int g_UseFriction; // Global to Select Friction -extern int g_UseGravity; // Global to Select Gravity -extern int g_DrawSprings; -extern int g_DrawCVs; -extern int g_DrawMesh; -extern int g_DrawInfluence; // For display of vertex weights -extern int g_MouseForceActive; -extern tMatrix g_ViewMatrix; -extern int g_Pick[2]; - -// External handles to all the windows, palettes, etc. -extern HWND hViewWnd; -extern HWND hMainWnd; -extern HPALETTE hPalette; -extern HDC g_hDC; - -// Other shared variables -extern double PI; - -///////////////////////// -// Functions declared in other source files -BOOL InitGame(void); // Defined in GameSim.c -void DrawSimWorld(void); // Defined in GameSim.c -void Simulate(float DeltaTime, BOOL running); // In GameSim.c -void InitRender(void); // Defined in RenderWorld.c -void RenderWorld(void); // Defined in RenderWorld.c -float GetTime( void ); -void GetNearestPoint(int x, int y); -void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); +// Externs.h +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +#include "MathDefs.h" + +// This sets up the table position in the world +// TODO: Should load with the model....? +#define FFD_STARTY 4.20f // Height of the virtual table off ground + +// Physical Dimension of the Ball +#define BALL_DIAMETER 0.1875f // Diameter of Billiard Ball in feet 2.25 in + +#define EPSILON 0.00001f // ERROR TERM +#define DEFAULT_DAMPING 0.002f +#define DRAG_FORCE 5.0f // For Mouse interaction + +enum tCollisionTypes +{ + NOT_COLLIDING, + PENETRATING, + COLLIDING_WITH_WALL, + COLLIDING_WITH_BALL +}; + +enum tIntegratorTypes +{ + EULER_INTEGRATOR, + MIDPOINT_INTEGRATOR, + RK4_INTEGRATOR +}; + +// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM +typedef struct s_Contact +{ + int particle,particle2; + tVector normal; // Normal of Collision plane + int type; // COLLIDING OR CONTACT + float Kr; // Coefficient of restitution +} t_Contact; + +// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH +typedef struct s_CollisionPlane +{ + tVector normal; // inward pointing + float d; // ax + by + cz + d = 0 +} t_CollisionPlane; + +typedef struct s_Camera +{ + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + float fov; // FIELD OF VIEW +} t_Camera; + +// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM +typedef struct s_Particle +{ + tVector rest_pos; // Position of Particle + tVector pos; // Position of Particle + tVector v; // Velocity of Particle + tVector f; // Force Acting on Particle + tVector angMom; // Angular Momentum + tVector torque; // Torque + float oneOverM; // 1 / Mass of Particle + tQuaternion orientation; + int flags; // So I can track things +} t_Particle; + +// TYPE FOR SPRINGS IN SYSTEM +typedef struct s_Spring +{ + int p1,p2; // PARTICLE INDEX FOR ENDS + float restLen; // LENGTH OF SPRING AT REST + float Ks; // SPRING CONSTANT + float Kd; // SPRING DAMPING +} t_Spring; + +/// Model Definitions /////////////////////////////////////////////////////// +struct t_VWeight +{ + float *weight; +}; + +typedef struct +{ + long v[3],n[3],t[3]; + int mat; +} t_faceIndex; + +typedef struct +{ + int dataFormat; + tVector *vertex; // Vertex + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + tVector *normal; // Vertex + tVector *deformData; // DEFORMED VERTEX DATA + tVector *texture; // Vertex + t_faceIndex *index; + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *matColor; // POINTER TO VECTOR + int matCnt; + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tColor Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + uint glTex; + float *weightData; // + long normalCnt; // NUMBER OF VERTICES IN VISUAL + long uvCnt; // NUMBER OF VERTICES IN VISUAL + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +} t_ToonVisual; + +typedef struct +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + void *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + void *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + float min_rx, max_rx; // ROTATION X LIMITS + float min_ry, max_ry; // ROTATION Y LIMITS + float min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_ToonVisual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_select; // POINTER TO CONTROL VERTICES + void *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + tMatrix *curMatrix; // STORE THE CURRENT MATRIX +} t_Mesh; + +#define POLY_SELECTED 1 +#define POLY_TEXTURED 2 + +// Camera for View System +extern t_Camera g_POV; + +// Objects for the Game +extern t_Particle *g_CurrentSys; +extern int g_UseFriction; // Global to Select Friction +extern int g_UseGravity; // Global to Select Gravity +extern int g_DrawSprings; +extern int g_DrawCVs; +extern int g_DrawMesh; +extern int g_DrawInfluence; // For display of vertex weights +extern int g_MouseForceActive; +extern tMatrix g_ViewMatrix; +extern int g_Pick[2]; + +// External handles to all the windows, palettes, etc. +extern HWND hViewWnd; +extern HWND hMainWnd; +extern HPALETTE hPalette; +extern HDC g_hDC; + +// Other shared variables +extern double PI; + +///////////////////////// +// Functions declared in other source files +BOOL InitGame(void); // Defined in GameSim.c +void DrawSimWorld(void); // Defined in GameSim.c +void Simulate(float DeltaTime, BOOL running); // In GameSim.c +void InitRender(void); // Defined in RenderWorld.c +void RenderWorld(void); // Defined in RenderWorld.c +float GetTime( void ); +void GetNearestPoint(int x, int y); +void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); void SetFFDWeights(t_ToonVisual *visual); \ No newline at end of file diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadOBJ.h b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadOBJ.h index 43eb2b0..ce2447c 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadOBJ.h +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadOBJ.h @@ -1,32 +1,32 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#include "MathDefs.h" - -#define MAX_STRINGLENGTH 2048 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -int LoadOBJ(char *filename,t_ToonVisual *visual); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#include "MathDefs.h" + +#define MAX_STRINGLENGTH 2048 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +int LoadOBJ(char *filename,t_ToonVisual *visual); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadTGA.h b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadTGA.h index 0999923..c36068c 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadTGA.h +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/LoadTGA.h @@ -1,27 +1,27 @@ -typedef struct -{ - unsigned char d_iif_size; // IIF size (after header), usually 0 - unsigned char d_cmap_type; // ignored - unsigned char d_image_type; // should be 2 - unsigned char pad[5]; - - unsigned short d_x_origin; - unsigned short d_y_origin; - unsigned short d_width; - unsigned short d_height; - - unsigned char d_pixel_size; // 16, 24, or 32 - unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) -} tTGAHeader_s; - -#define RGB16(r,g,b) ( ((r>>3) << 10) + ((g>>3) << 5) + (b >> 3) ) -#define RGB24(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) -#define GET16R(v) (v >> 10) -#define GET16G(v) ((v >> 5) & 0x1f) -#define GET16B(v) (v & 0x1f) - -unsigned char *LoadTGAFile( char* strFilename,tTGAHeader_s *header); - +typedef struct +{ + unsigned char d_iif_size; // IIF size (after header), usually 0 + unsigned char d_cmap_type; // ignored + unsigned char d_image_type; // should be 2 + unsigned char pad[5]; + + unsigned short d_x_origin; + unsigned short d_y_origin; + unsigned short d_width; + unsigned short d_height; + + unsigned char d_pixel_size; // 16, 24, or 32 + unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) +} tTGAHeader_s; + +#define RGB16(r,g,b) ( ((r>>3) << 10) + ((g>>3) << 5) + (b >> 3) ) +#define RGB24(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) +#define GET16R(v) (v >> 10) +#define GET16G(v) ((v >> 5) & 0x1f) +#define GET16B(v) (v & 0x1f) + +unsigned char *LoadTGAFile( char* strFilename,tTGAHeader_s *header); + diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/MathDefs.h b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/MathDefs.h index bc56266..32faf60 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/MathDefs.h +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/MathDefs.h @@ -1,122 +1,122 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// -typedef unsigned char uchar; - -typedef int BOOL; -typedef unsigned int uint; -typedef unsigned short ushort; -typedef unsigned char byte; - -typedef struct -{ - float u,v; -} t2DCoord; - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -typedef struct -{ - float r; - float g; - float b; - float a; -} tColor; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); -void IdentityMatrix(tMatrix *mat); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// +typedef unsigned char uchar; + +typedef int BOOL; +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned char byte; + +typedef struct +{ + float u,v; +} t2DCoord; + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +typedef struct +{ + float r; + float g; + float b; + float a; +} tColor; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); +void IdentityMatrix(tMatrix *mat); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/Readme.txt b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/Readme.txt index f1729af..335c1ec 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/Readme.txt +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/Readme.txt @@ -1,63 +1,63 @@ -Accelerated FFD deformation May 2000 --------------------------------------------------------- -v. 1.0 - -This is a demonstration of how skeletal deformation techniques can be -used to accelerate arbitrary deformation functions such as a cubic FFD. - -A lattice of control points is created around an object and those control -points are connected with springs. Any movement of these control points -will deform the mesh. - -This demo also uses the cartoon rendering shader from January. - -How it works. - - Click and drag the Left Mouse Button on one or two control points to - change the deformation lattice. - - Click and drag the Right Mouse Button to rotate the view around. - - Menu options to turn on/off gravity. - - View options: - Draw Springs - Draw Control Vertices (CVs) - Draw Mesh - Draw Vertex Influences (This displays the rough weighting on the mesh of the - first selected CV) - -Problems for you to explore: - - The physical simulation is a simple spring system. It is easy to collapse - the mesh on itself. The physical sim really needs a mesh deformation technique - that preserves volume. - - Collision occurs with the control vertices right now. They really show collide with - the base mesh points. One idea is to store offsets from the CV into the mesh and only - collide then. Thanks to Casey of RAD Game Tools for that idea. - - Convert this whole thing to be hardware accelerated with both vertex and pixel shaders - once DX8 hardware is available to do this. (How about it IHVs??) - - -Any questions email: - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I compiled the code with Visual C++ 6.0. It has been tested -with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 2 OpenGL -Drivers, Riva 128, TNT, TNT2, AccelGalaxy, ATI Rage LT Pro, -and Matrox G400. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX Voodoo series. -3DFX OpenGL that does not support OpenGL in a window will not work -with this application. - -The Spring and Particle display make use of line drawing. Some cards -are slow when displaying lines (ATI Rage LT Pro is an example). Performance +Accelerated FFD deformation May 2000 +-------------------------------------------------------- +v. 1.0 + +This is a demonstration of how skeletal deformation techniques can be +used to accelerate arbitrary deformation functions such as a cubic FFD. + +A lattice of control points is created around an object and those control +points are connected with springs. Any movement of these control points +will deform the mesh. + +This demo also uses the cartoon rendering shader from January. + +How it works. + + Click and drag the Left Mouse Button on one or two control points to + change the deformation lattice. + + Click and drag the Right Mouse Button to rotate the view around. + + Menu options to turn on/off gravity. + + View options: + Draw Springs + Draw Control Vertices (CVs) + Draw Mesh + Draw Vertex Influences (This displays the rough weighting on the mesh of the + first selected CV) + +Problems for you to explore: + + The physical simulation is a simple spring system. It is easy to collapse + the mesh on itself. The physical sim really needs a mesh deformation technique + that preserves volume. + + Collision occurs with the control vertices right now. They really show collide with + the base mesh points. One idea is to store offsets from the CV into the mesh and only + collide then. Thanks to Casey of RAD Game Tools for that idea. + + Convert this whole thing to be hardware accelerated with both vertex and pixel shaders + once DX8 hardware is available to do this. (How about it IHVs??) + + +Any questions email: + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I compiled the code with Visual C++ 6.0. It has been tested +with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 2 OpenGL +Drivers, Riva 128, TNT, TNT2, AccelGalaxy, ATI Rage LT Pro, +and Matrox G400. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX Voodoo series. +3DFX OpenGL that does not support OpenGL in a window will not work +with this application. + +The Spring and Particle display make use of line drawing. Some cards +are slow when displaying lines (ATI Rage LT Pro is an example). Performance will increase greatly when line drawing is off. \ No newline at end of file diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/ToonTown.mak b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/ToonTown.mak index ecacba4..dbb154b 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/ToonTown.mak +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/ToonTown.mak @@ -1,469 +1,469 @@ -# Microsoft Developer Studio Generated NMAKE File, Format Version 40001 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -!IF "$(CFG)" == "" -CFG=Pool - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Pool - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Pool - Win32 Release" && "$(CFG)" != "Pool - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE on this makefile -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Pool.mak" CFG="Pool - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Pool - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Pool - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF -################################################################################ -# Begin Project -# PROP Target_Last_Scanned "Pool - Win32 Debug" -CPP=cl.exe -RSC=rc.exe -MTL=mktyplib.exe - -!IF "$(CFG)" == "Pool - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -OUTDIR=.\Release -INTDIR=.\Release - -ALL : "$(OUTDIR)\Pool.exe" - -CLEAN : - -@erase ".\Release\vc40.pdb" - -@erase ".\Release\Pool.exe" - -@erase ".\Release\glutils.obj" - -@erase ".\Release\initworld.obj" - -@erase ".\Release\CenterWnd.obj" - -@erase ".\Release\Pool.obj" - -@erase ".\Release\CompassWnd.obj" - -@erase ".\Release\ViewWnd.obj" - -@erase ".\Release\RadarWnd.obj" - -@erase ".\Release\RESOURCE.res" - -@erase ".\Release\RenderWorld.obj" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -CPP_PROJ=/nologo /ML /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)/Pool.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c -CPP_OBJS=.\Release/ -CPP_SBRS= -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /win32 -MTL_PROJ=/nologo /D "NDEBUG" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -RSC_PROJ=/l 0x409 /fo"$(INTDIR)/RESOURCE.res" /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/Pool.bsc" -BSC32_SBRS= -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /machine:I386 -# SUBTRACT LINK32 /debug -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:no /pdb:"$(OUTDIR)/Pool.pdb" /machine:I386\ - /out:"$(OUTDIR)/Pool.exe" -LINK32_OBJS= \ - ".\Release\glutils.obj" \ - ".\Release\initworld.obj" \ - ".\Release\CenterWnd.obj" \ - ".\Release\Pool.obj" \ - ".\Release\CompassWnd.obj" \ - ".\Release\ViewWnd.obj" \ - ".\Release\RadarWnd.obj" \ - ".\Release\RenderWorld.obj" \ - ".\Release\RESOURCE.res" - -"$(OUTDIR)\Pool.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -OUTDIR=.\Debug -INTDIR=.\Debug - -ALL : "$(OUTDIR)\Pool.exe" "$(OUTDIR)\Pool.bsc" - -CLEAN : - -@erase ".\Debug\vc40.pdb" - -@erase ".\Debug\vc40.idb" - -@erase ".\Debug\Pool.bsc" - -@erase ".\Debug\CompassWnd.sbr" - -@erase ".\Debug\ViewWnd.sbr" - -@erase ".\Debug\glutils.sbr" - -@erase ".\Debug\RadarWnd.sbr" - -@erase ".\Debug\Pool.sbr" - -@erase ".\Debug\initworld.sbr" - -@erase ".\Debug\CenterWnd.sbr" - -@erase ".\Debug\RenderWorld.sbr" - -@erase ".\Debug\Pool.exe" - -@erase ".\Debug\CompassWnd.obj" - -@erase ".\Debug\ViewWnd.obj" - -@erase ".\Debug\glutils.obj" - -@erase ".\Debug\RadarWnd.obj" - -@erase ".\Debug\Pool.obj" - -@erase ".\Debug\initworld.obj" - -@erase ".\Debug\CenterWnd.obj" - -@erase ".\Debug\RESOURCE.res" - -@erase ".\Debug\RenderWorld.obj" - -@erase ".\Debug\Pool.pdb" - -@erase ".\Debug\Pool.map" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fr /YX /c -CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /Fr"$(INTDIR)/" /Fp"$(INTDIR)/Pool.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c -CPP_OBJS=.\Debug/ -CPP_SBRS=.\Debug/ -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /win32 -MTL_PROJ=/nologo /D "_DEBUG" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -RSC_PROJ=/l 0x409 /fo"$(INTDIR)/RESOURCE.res" /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/Pool.bsc" -BSC32_SBRS= \ - ".\Debug\CompassWnd.sbr" \ - ".\Debug\ViewWnd.sbr" \ - ".\Debug\glutils.sbr" \ - ".\Debug\RadarWnd.sbr" \ - ".\Debug\Pool.sbr" \ - ".\Debug\initworld.sbr" \ - ".\Debug\CenterWnd.sbr" \ - ".\Debug\RenderWorld.sbr" - -"$(OUTDIR)\Pool.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /map /debug /debugtype:both /machine:I386 -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:no /pdb:"$(OUTDIR)/Pool.pdb" /map:"$(INTDIR)/Pool.map" /debug\ - /debugtype:both /machine:I386 /out:"$(OUTDIR)/Pool.exe" -LINK32_OBJS= \ - ".\Debug\CompassWnd.obj" \ - ".\Debug\ViewWnd.obj" \ - ".\Debug\glutils.obj" \ - ".\Debug\RadarWnd.obj" \ - ".\Debug\Pool.obj" \ - ".\Debug\initworld.obj" \ - ".\Debug\CenterWnd.obj" \ - ".\Debug\RenderWorld.obj" \ - ".\Debug\RESOURCE.res" - -"$(OUTDIR)\Pool.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -################################################################################ -# Begin Target - -# Name "Pool - Win32 Release" -# Name "Pool - Win32 Debug" - -!IF "$(CFG)" == "Pool - Win32 Release" - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - -!ENDIF - -################################################################################ -# Begin Source File - -SOURCE=.\Pool.c -DEP_CPP_Pool_=\ - ".\glutils.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\Pool.obj" : $(SOURCE) $(DEP_CPP_Pool_) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\Pool.obj" : $(SOURCE) $(DEP_CPP_Pool_) "$(INTDIR)" - -"$(INTDIR)\Pool.sbr" : $(SOURCE) $(DEP_CPP_Pool_) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\RESOURCE.RC - -"$(INTDIR)\RESOURCE.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\glutils.c -DEP_CPP_GLUTI=\ - ".\glutils.h"\ - ".\externs.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\glutils.obj" : $(SOURCE) $(DEP_CPP_GLUTI) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\glutils.obj" : $(SOURCE) $(DEP_CPP_GLUTI) "$(INTDIR)" - -"$(INTDIR)\glutils.sbr" : $(SOURCE) $(DEP_CPP_GLUTI) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\CenterWnd.c -DEP_CPP_CENTE=\ - ".\externs.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\CenterWnd.obj" : $(SOURCE) $(DEP_CPP_CENTE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\CenterWnd.obj" : $(SOURCE) $(DEP_CPP_CENTE) "$(INTDIR)" - -"$(INTDIR)\CenterWnd.sbr" : $(SOURCE) $(DEP_CPP_CENTE) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ViewWnd.c -DEP_CPP_VIEWW=\ - {$(INCLUDE)}"\gl\GL.H"\ - {$(INCLUDE)}"\gl\GLU.H"\ - {$(INCLUDE)}"\gl\glaux.h"\ - ".\externs.h"\ - ".\glutils.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\ViewWnd.obj" : $(SOURCE) $(DEP_CPP_VIEWW) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\ViewWnd.obj" : $(SOURCE) $(DEP_CPP_VIEWW) "$(INTDIR)" - -"$(INTDIR)\ViewWnd.sbr" : $(SOURCE) $(DEP_CPP_VIEWW) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\RadarWnd.c -DEP_CPP_RADAR=\ - ".\glutils.h"\ - ".\externs.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\RadarWnd.obj" : $(SOURCE) $(DEP_CPP_RADAR) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\RadarWnd.obj" : $(SOURCE) $(DEP_CPP_RADAR) "$(INTDIR)" - -"$(INTDIR)\RadarWnd.sbr" : $(SOURCE) $(DEP_CPP_RADAR) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\CompassWnd.c -DEP_CPP_COMPA=\ - ".\externs.h"\ - ".\glutils.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\CompassWnd.obj" : $(SOURCE) $(DEP_CPP_COMPA) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\CompassWnd.obj" : $(SOURCE) $(DEP_CPP_COMPA) "$(INTDIR)" - -"$(INTDIR)\CompassWnd.sbr" : $(SOURCE) $(DEP_CPP_COMPA) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\initworld.c -DEP_CPP_INITW=\ - ".\glutils.h"\ - ".\externs.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\initworld.obj" : $(SOURCE) $(DEP_CPP_INITW) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\initworld.obj" : $(SOURCE) $(DEP_CPP_INITW) "$(INTDIR)" - -"$(INTDIR)\initworld.sbr" : $(SOURCE) $(DEP_CPP_INITW) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\RenderWorld.c -DEP_CPP_RENDE=\ - {$(INCLUDE)}"\gl\GL.H"\ - {$(INCLUDE)}"\gl\GLU.H"\ - {$(INCLUDE)}"\gl\glaux.h"\ - ".\externs.h"\ - ".\glutils.h"\ - - -!IF "$(CFG)" == "Pool - Win32 Release" - - -"$(INTDIR)\RenderWorld.obj" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "Pool - Win32 Debug" - - -"$(INTDIR)\RenderWorld.obj" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)" - -"$(INTDIR)\RenderWorld.sbr" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)" - - -!ENDIF - -# End Source File -# End Target -# End Project -################################################################################ +# Microsoft Developer Studio Generated NMAKE File, Format Version 40001 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=Pool - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Pool - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Pool - Win32 Release" && "$(CFG)" != "Pool - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Pool.mak" CFG="Pool - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Pool - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Pool - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Pool - Win32 Debug" +CPP=cl.exe +RSC=rc.exe +MTL=mktyplib.exe + +!IF "$(CFG)" == "Pool - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\Pool.exe" + +CLEAN : + -@erase ".\Release\vc40.pdb" + -@erase ".\Release\Pool.exe" + -@erase ".\Release\glutils.obj" + -@erase ".\Release\initworld.obj" + -@erase ".\Release\CenterWnd.obj" + -@erase ".\Release\Pool.obj" + -@erase ".\Release\CompassWnd.obj" + -@erase ".\Release\ViewWnd.obj" + -@erase ".\Release\RadarWnd.obj" + -@erase ".\Release\RESOURCE.res" + -@erase ".\Release\RenderWorld.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/Pool.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/RESOURCE.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Pool.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /machine:I386 +# SUBTRACT LINK32 /debug +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/Pool.pdb" /machine:I386\ + /out:"$(OUTDIR)/Pool.exe" +LINK32_OBJS= \ + ".\Release\glutils.obj" \ + ".\Release\initworld.obj" \ + ".\Release\CenterWnd.obj" \ + ".\Release\Pool.obj" \ + ".\Release\CompassWnd.obj" \ + ".\Release\ViewWnd.obj" \ + ".\Release\RadarWnd.obj" \ + ".\Release\RenderWorld.obj" \ + ".\Release\RESOURCE.res" + +"$(OUTDIR)\Pool.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Pool.exe" "$(OUTDIR)\Pool.bsc" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Debug\Pool.bsc" + -@erase ".\Debug\CompassWnd.sbr" + -@erase ".\Debug\ViewWnd.sbr" + -@erase ".\Debug\glutils.sbr" + -@erase ".\Debug\RadarWnd.sbr" + -@erase ".\Debug\Pool.sbr" + -@erase ".\Debug\initworld.sbr" + -@erase ".\Debug\CenterWnd.sbr" + -@erase ".\Debug\RenderWorld.sbr" + -@erase ".\Debug\Pool.exe" + -@erase ".\Debug\CompassWnd.obj" + -@erase ".\Debug\ViewWnd.obj" + -@erase ".\Debug\glutils.obj" + -@erase ".\Debug\RadarWnd.obj" + -@erase ".\Debug\Pool.obj" + -@erase ".\Debug\initworld.obj" + -@erase ".\Debug\CenterWnd.obj" + -@erase ".\Debug\RESOURCE.res" + -@erase ".\Debug\RenderWorld.obj" + -@erase ".\Debug\Pool.pdb" + -@erase ".\Debug\Pool.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fr /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fr"$(INTDIR)/" /Fp"$(INTDIR)/Pool.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\Debug/ +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo"$(INTDIR)/RESOURCE.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Pool.bsc" +BSC32_SBRS= \ + ".\Debug\CompassWnd.sbr" \ + ".\Debug\ViewWnd.sbr" \ + ".\Debug\glutils.sbr" \ + ".\Debug\RadarWnd.sbr" \ + ".\Debug\Pool.sbr" \ + ".\Debug\initworld.sbr" \ + ".\Debug\CenterWnd.sbr" \ + ".\Debug\RenderWorld.sbr" + +"$(OUTDIR)\Pool.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /map /debug /debugtype:both /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)/Pool.pdb" /map:"$(INTDIR)/Pool.map" /debug\ + /debugtype:both /machine:I386 /out:"$(OUTDIR)/Pool.exe" +LINK32_OBJS= \ + ".\Debug\CompassWnd.obj" \ + ".\Debug\ViewWnd.obj" \ + ".\Debug\glutils.obj" \ + ".\Debug\RadarWnd.obj" \ + ".\Debug\Pool.obj" \ + ".\Debug\initworld.obj" \ + ".\Debug\CenterWnd.obj" \ + ".\Debug\RenderWorld.obj" \ + ".\Debug\RESOURCE.res" + +"$(OUTDIR)\Pool.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "Pool - Win32 Release" +# Name "Pool - Win32 Debug" + +!IF "$(CFG)" == "Pool - Win32 Release" + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\Pool.c +DEP_CPP_Pool_=\ + ".\glutils.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\Pool.obj" : $(SOURCE) $(DEP_CPP_Pool_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\Pool.obj" : $(SOURCE) $(DEP_CPP_Pool_) "$(INTDIR)" + +"$(INTDIR)\Pool.sbr" : $(SOURCE) $(DEP_CPP_Pool_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\RESOURCE.RC + +"$(INTDIR)\RESOURCE.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\glutils.c +DEP_CPP_GLUTI=\ + ".\glutils.h"\ + ".\externs.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\glutils.obj" : $(SOURCE) $(DEP_CPP_GLUTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\glutils.obj" : $(SOURCE) $(DEP_CPP_GLUTI) "$(INTDIR)" + +"$(INTDIR)\glutils.sbr" : $(SOURCE) $(DEP_CPP_GLUTI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\CenterWnd.c +DEP_CPP_CENTE=\ + ".\externs.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\CenterWnd.obj" : $(SOURCE) $(DEP_CPP_CENTE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\CenterWnd.obj" : $(SOURCE) $(DEP_CPP_CENTE) "$(INTDIR)" + +"$(INTDIR)\CenterWnd.sbr" : $(SOURCE) $(DEP_CPP_CENTE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ViewWnd.c +DEP_CPP_VIEWW=\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + {$(INCLUDE)}"\gl\glaux.h"\ + ".\externs.h"\ + ".\glutils.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\ViewWnd.obj" : $(SOURCE) $(DEP_CPP_VIEWW) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\ViewWnd.obj" : $(SOURCE) $(DEP_CPP_VIEWW) "$(INTDIR)" + +"$(INTDIR)\ViewWnd.sbr" : $(SOURCE) $(DEP_CPP_VIEWW) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\RadarWnd.c +DEP_CPP_RADAR=\ + ".\glutils.h"\ + ".\externs.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\RadarWnd.obj" : $(SOURCE) $(DEP_CPP_RADAR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\RadarWnd.obj" : $(SOURCE) $(DEP_CPP_RADAR) "$(INTDIR)" + +"$(INTDIR)\RadarWnd.sbr" : $(SOURCE) $(DEP_CPP_RADAR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\CompassWnd.c +DEP_CPP_COMPA=\ + ".\externs.h"\ + ".\glutils.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\CompassWnd.obj" : $(SOURCE) $(DEP_CPP_COMPA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\CompassWnd.obj" : $(SOURCE) $(DEP_CPP_COMPA) "$(INTDIR)" + +"$(INTDIR)\CompassWnd.sbr" : $(SOURCE) $(DEP_CPP_COMPA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\initworld.c +DEP_CPP_INITW=\ + ".\glutils.h"\ + ".\externs.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\initworld.obj" : $(SOURCE) $(DEP_CPP_INITW) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\initworld.obj" : $(SOURCE) $(DEP_CPP_INITW) "$(INTDIR)" + +"$(INTDIR)\initworld.sbr" : $(SOURCE) $(DEP_CPP_INITW) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\RenderWorld.c +DEP_CPP_RENDE=\ + {$(INCLUDE)}"\gl\GL.H"\ + {$(INCLUDE)}"\gl\GLU.H"\ + {$(INCLUDE)}"\gl\glaux.h"\ + ".\externs.h"\ + ".\glutils.h"\ + + +!IF "$(CFG)" == "Pool - Win32 Release" + + +"$(INTDIR)\RenderWorld.obj" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "Pool - Win32 Debug" + + +"$(INTDIR)\RenderWorld.obj" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)" + +"$(INTDIR)\RenderWorld.sbr" : $(SOURCE) $(DEP_CPP_RENDE) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/resource.h b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/resource.h index 6fb2598..9293459 100644 --- a/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/resource.h +++ b/Hardware Accelerated Free Form Deformation/Code/OGL/ToonTown/resource.h @@ -1,39 +1,39 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by RESOURCE.RC -// -#define IDR_MENU 101 -#define IDD_DIALOG_ABOUT 102 -#define IDR_TOOLBAR1 104 -#define IDC_OPENGL_VENDOR 1000 -#define IDC_OPENGL_RENDERER 1001 -#define IDC_OPENGL_VERSION 1002 -#define IDC_OPENGL_EXTENSIONS 1003 -#define IDC_GLU_VERSION 1005 -#define IDC_GLU_EXTENSIONS 1006 -#define IDC_ERROR1 1007 -#define IDC_ERROR2 1008 -#define IDC_ERROR3 1009 -#define IDC_ERROR4 1010 -#define IDC_ERROR5 1011 -#define IDC_ERROR6 1012 -#define ID_FILE_EXIT 40001 -#define ID_HELP_ABOUT 40002 -#define ID_BUTTON40003 40003 -#define ID_USE_FRICTION 40004 -#define ID_USE_GRAVITY 40011 -#define ID_VIEW_SPRINGS 40012 -#define ID_VIEW_CVS 40013 -#define ID_VIEW_MESH 40014 -#define ID_VIEW_VERTEXINFLUENCES 40015 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40016 -#define _APS_NEXT_CONTROL_VALUE 1013 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by RESOURCE.RC +// +#define IDR_MENU 101 +#define IDD_DIALOG_ABOUT 102 +#define IDR_TOOLBAR1 104 +#define IDC_OPENGL_VENDOR 1000 +#define IDC_OPENGL_RENDERER 1001 +#define IDC_OPENGL_VERSION 1002 +#define IDC_OPENGL_EXTENSIONS 1003 +#define IDC_GLU_VERSION 1005 +#define IDC_GLU_EXTENSIONS 1006 +#define IDC_ERROR1 1007 +#define IDC_ERROR2 1008 +#define IDC_ERROR3 1009 +#define IDC_ERROR4 1010 +#define IDC_ERROR5 1011 +#define IDC_ERROR6 1012 +#define ID_FILE_EXIT 40001 +#define ID_HELP_ABOUT 40002 +#define ID_BUTTON40003 40003 +#define ID_USE_FRICTION 40004 +#define ID_USE_GRAVITY 40011 +#define ID_VIEW_SPRINGS 40012 +#define ID_VIEW_CVS 40013 +#define ID_VIEW_MESH 40014 +#define ID_VIEW_VERTEXINFLUENCES 40015 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40016 +#define _APS_NEXT_CONTROL_VALUE 1013 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/More Kine/Code/OGL/KineChain/Bitmap.cpp b/More Kine/Code/OGL/KineChain/Bitmap.cpp index adf2983..7cfcaa0 100644 --- a/More Kine/Code/OGL/KineChain/Bitmap.cpp +++ b/More Kine/Code/OGL/KineChain/Bitmap.cpp @@ -1,197 +1,197 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Bitmap.cpp : implementation file -// -// Purpose: Implementation of Windows BMP Loader -// -// Created: -// JL 7/1/98 -// -// Notes: This code was originally from the OpenGL SuperBible -// by Richard Wright Jr. and Michael Sweet -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "bitmap.h" - - -/* - * 'LoadDIBitmap()' - Load a DIB/BMP file from disk. - * - * Returns a pointer to the bitmap if successful, NULL otherwise... - */ - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadDIBitmap -// Purpose: Load texture images for the bone -// Arguments: Name of the file to load, bitmap info -void *LoadDIBitmap(char *filename,BITMAPINFO **info) -{ - FILE *fp; /* Open file pointer */ - void *bits; /* Bitmap pixel bits */ - long bitsize, /* Size of bitmap */ - infosize; /* Size of header information */ - BITMAPFILEHEADER header; /* File header */ - - - /* - * Try opening the file; use "rb" mode to read this *binary* file. - */ - - if ((fp = fopen(filename, "rb")) == NULL) - return (NULL); - - /* - * Read the file header and any following bitmap information... - */ - - if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1) - { - /* - * Couldn't read the file header - return NULL... - */ - - fclose(fp); - return (NULL); - }; - - if (header.bfType != 'MB') /* Check for BM reversed... */ - { - /* - * Not a bitmap file - return NULL... - */ - - fclose(fp); - return (NULL); - }; - - infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER); - if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL) - { - /* - * Couldn't allocate memory for bitmap info - return NULL... - */ - - fclose(fp); - return (NULL); - }; - - if (fread(*info, 1, infosize, fp) < infosize) - { - /* - * Couldn't read the bitmap header - return NULL... - */ - - free(*info); - fclose(fp); - return (NULL); - }; - - /* - * Now that we have all the header info read in, allocate memory for the - * bitmap and read *it* in... - */ - - if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0) - bitsize = ((*info)->bmiHeader.biWidth * - (*info)->bmiHeader.biBitCount + 7) / 8 * - abs((*info)->bmiHeader.biHeight); - - if ((bits = malloc(bitsize)) == NULL) - { - /* - * Couldn't allocate memory - return NULL! - */ - - free(*info); - fclose(fp); - return (NULL); - }; - - if (fread(bits, 1, bitsize, fp) < bitsize) - { - /* - * Couldn't read bitmap - free memory and return NULL! - */ - - free(*info); - free(bits); - fclose(fp); - return (NULL); - }; - - /* - * OK, everything went fine - return the allocated bitmap... - */ - - fclose(fp); - return (bits); -} - - -/* - * 'ConvertRGB()' - Convert a DIB/BMP image to 24-bit RGB pixels. - * - * Returns an RGB pixel array if successful and NULL otherwise. - */ - -GLubyte * ConvertBitsToGL(BITMAPINFO *info,void *bits) -{ - int i, j, /* Looping vars */ - bitsize, /* Total size of bitmap */ - width; /* Aligned width of bitmap */ - GLubyte *newbits; /* New RGB bits */ - GLubyte *from, *to, /* RGB looping vars */ - temp; /* Temporary var for swapping */ - - - /* - * Allocate memory for the RGB bitmap... - */ - - width = 3 * info->bmiHeader.biWidth; - width = (width + 3) & ~3; - bitsize = width * info->bmiHeader.biHeight; - if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL) - return (NULL); - - /* - * Copy the original bitmap to the new array, converting as necessary. - */ - - switch (info->bmiHeader.biCompression) - { - case BI_RGB : - if (info->bmiHeader.biBitCount == 24) - { - /* - * Swap red & blue in a 24-bit image... - */ - - for (i = 0; i < info->bmiHeader.biHeight; i ++) - for (j = 0, from = ((GLubyte *)bits) + i * width, - to = newbits + i * width; - j < info->bmiHeader.biWidth; - j ++, from += 3, to += 3) - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - }; - }; - break; - case BI_RLE4 : - case BI_RLE8 : - case BI_BITFIELDS : - break; - }; - - return (newbits); -} +/////////////////////////////////////////////////////////////////////////////// +// +// Bitmap.cpp : implementation file +// +// Purpose: Implementation of Windows BMP Loader +// +// Created: +// JL 7/1/98 +// +// Notes: This code was originally from the OpenGL SuperBible +// by Richard Wright Jr. and Michael Sweet +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "bitmap.h" + + +/* + * 'LoadDIBitmap()' - Load a DIB/BMP file from disk. + * + * Returns a pointer to the bitmap if successful, NULL otherwise... + */ + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadDIBitmap +// Purpose: Load texture images for the bone +// Arguments: Name of the file to load, bitmap info +void *LoadDIBitmap(char *filename,BITMAPINFO **info) +{ + FILE *fp; /* Open file pointer */ + void *bits; /* Bitmap pixel bits */ + long bitsize, /* Size of bitmap */ + infosize; /* Size of header information */ + BITMAPFILEHEADER header; /* File header */ + + + /* + * Try opening the file; use "rb" mode to read this *binary* file. + */ + + if ((fp = fopen(filename, "rb")) == NULL) + return (NULL); + + /* + * Read the file header and any following bitmap information... + */ + + if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1) + { + /* + * Couldn't read the file header - return NULL... + */ + + fclose(fp); + return (NULL); + }; + + if (header.bfType != 'MB') /* Check for BM reversed... */ + { + /* + * Not a bitmap file - return NULL... + */ + + fclose(fp); + return (NULL); + }; + + infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER); + if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL) + { + /* + * Couldn't allocate memory for bitmap info - return NULL... + */ + + fclose(fp); + return (NULL); + }; + + if (fread(*info, 1, infosize, fp) < infosize) + { + /* + * Couldn't read the bitmap header - return NULL... + */ + + free(*info); + fclose(fp); + return (NULL); + }; + + /* + * Now that we have all the header info read in, allocate memory for the + * bitmap and read *it* in... + */ + + if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0) + bitsize = ((*info)->bmiHeader.biWidth * + (*info)->bmiHeader.biBitCount + 7) / 8 * + abs((*info)->bmiHeader.biHeight); + + if ((bits = malloc(bitsize)) == NULL) + { + /* + * Couldn't allocate memory - return NULL! + */ + + free(*info); + fclose(fp); + return (NULL); + }; + + if (fread(bits, 1, bitsize, fp) < bitsize) + { + /* + * Couldn't read bitmap - free memory and return NULL! + */ + + free(*info); + free(bits); + fclose(fp); + return (NULL); + }; + + /* + * OK, everything went fine - return the allocated bitmap... + */ + + fclose(fp); + return (bits); +} + + +/* + * 'ConvertRGB()' - Convert a DIB/BMP image to 24-bit RGB pixels. + * + * Returns an RGB pixel array if successful and NULL otherwise. + */ + +GLubyte * ConvertBitsToGL(BITMAPINFO *info,void *bits) +{ + int i, j, /* Looping vars */ + bitsize, /* Total size of bitmap */ + width; /* Aligned width of bitmap */ + GLubyte *newbits; /* New RGB bits */ + GLubyte *from, *to, /* RGB looping vars */ + temp; /* Temporary var for swapping */ + + + /* + * Allocate memory for the RGB bitmap... + */ + + width = 3 * info->bmiHeader.biWidth; + width = (width + 3) & ~3; + bitsize = width * info->bmiHeader.biHeight; + if ((newbits = (GLubyte *)calloc(bitsize, 1)) == NULL) + return (NULL); + + /* + * Copy the original bitmap to the new array, converting as necessary. + */ + + switch (info->bmiHeader.biCompression) + { + case BI_RGB : + if (info->bmiHeader.biBitCount == 24) + { + /* + * Swap red & blue in a 24-bit image... + */ + + for (i = 0; i < info->bmiHeader.biHeight; i ++) + for (j = 0, from = ((GLubyte *)bits) + i * width, + to = newbits + i * width; + j < info->bmiHeader.biWidth; + j ++, from += 3, to += 3) + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + }; + }; + break; + case BI_RLE4 : + case BI_RLE8 : + case BI_BITFIELDS : + break; + }; + + return (newbits); +} diff --git a/More Kine/Code/OGL/KineChain/Bitmap.h b/More Kine/Code/OGL/KineChain/Bitmap.h index 5dc7064..8e78eb6 100644 --- a/More Kine/Code/OGL/KineChain/Bitmap.h +++ b/More Kine/Code/OGL/KineChain/Bitmap.h @@ -1,24 +1,24 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Bitmap.h : Header file -// -// Purpose: Implementation of Windows BMP Loader -// -// Created: -// JL 7/1/98 -// -// Notes: This code was originally from the OpenGL SuperBible -// by Richard Wright Jr. and Michael Sweet -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include -#include - -extern void *LoadDIBitmap(char *filename, BITMAPINFO **info); -GLubyte * ConvertBitsToGL(BITMAPINFO *info,void *bits); +/////////////////////////////////////////////////////////////////////////////// +// +// Bitmap.h : Header file +// +// Purpose: Implementation of Windows BMP Loader +// +// Created: +// JL 7/1/98 +// +// Notes: This code was originally from the OpenGL SuperBible +// by Richard Wright Jr. and Michael Sweet +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include +#include + +extern void *LoadDIBitmap(char *filename, BITMAPINFO **info); +GLubyte * ConvertBitsToGL(BITMAPINFO *info,void *bits); diff --git a/More Kine/Code/OGL/KineChain/KineChain.cpp b/More Kine/Code/OGL/KineChain/KineChain.cpp index db84c8b..13c67e2 100644 --- a/More Kine/Code/OGL/KineChain/KineChain.cpp +++ b/More Kine/Code/OGL/KineChain/KineChain.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// KineChain.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "KineChain.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CKineChainApp - -BEGIN_MESSAGE_MAP(CKineChainApp, CWinApp) - //{{AFX_MSG_MAP(CKineChainApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CKineChainApp construction - -CKineChainApp::CKineChainApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CKineChainApp object - -CKineChainApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CKineChainApp initialization - -BOOL CKineChainApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CKineChainApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CKineChainApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// KineChain.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "KineChain.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CKineChainApp + +BEGIN_MESSAGE_MAP(CKineChainApp, CWinApp) + //{{AFX_MSG_MAP(CKineChainApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CKineChainApp construction + +CKineChainApp::CKineChainApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CKineChainApp object + +CKineChainApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CKineChainApp initialization + +BOOL CKineChainApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CKineChainApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CKineChainApp commands diff --git a/More Kine/Code/OGL/KineChain/KineChain.h b/More Kine/Code/OGL/KineChain/KineChain.h index fd64599..afda25b 100644 --- a/More Kine/Code/OGL/KineChain/KineChain.h +++ b/More Kine/Code/OGL/KineChain/KineChain.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// KineChain.h : main header file for the KineChain application -// -// Purpose: header of Main Application of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_KineChain_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_KineChain_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CKineChainApp: -// See KineChain.cpp for the implementation of this class -// - -class CKineChainApp : public CWinApp -{ -public: - CKineChainApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CKineChainApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CKineChainApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_KineChain_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// KineChain.h : main header file for the KineChain application +// +// Purpose: header of Main Application of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_KineChain_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_KineChain_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CKineChainApp: +// See KineChain.cpp for the implementation of this class +// + +class CKineChainApp : public CWinApp +{ +public: + CKineChainApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CKineChainApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CKineChainApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_KineChain_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/KineChain.mak b/More Kine/Code/OGL/KineChain/KineChain.mak index 2961509..99d6ce5 100644 --- a/More Kine/Code/OGL/KineChain/KineChain.mak +++ b/More Kine/Code/OGL/KineChain/KineChain.mak @@ -1,458 +1,458 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on KineChain.dsp -!IF "$(CFG)" == "" -CFG=KineChain - Win32 Debug -!MESSAGE No configuration specified. Defaulting to KineChain - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "KineChain - Win32 Release" && "$(CFG)" != "KineChain - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "KineChain.mak" CFG="KineChain - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "KineChain - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "KineChain - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "KineChain - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\KineChain.exe" - -!ELSE - -ALL : "$(OUTDIR)\KineChain.exe" - -!ENDIF - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\KineChain.obj" - -@erase "$(INTDIR)\KineChain.pch" - -@erase "$(INTDIR)\KineChain.res" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Quatern.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc50.idb" - -@erase "$(OUTDIR)\KineChain.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\KineChain.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ - /c -CPP_OBJS=.\Release/ -CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\KineChain.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\KineChain.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:no /pdb:"$(OUTDIR)\KineChain.pdb" /machine:I386\ - /out:"$(OUTDIR)\KineChain.exe" -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\KineChain.obj" \ - "$(INTDIR)\KineChain.res" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Quatern.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\KineChain.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\KineChain.exe" - -!ELSE - -ALL : "$(OUTDIR)\KineChain.exe" - -!ENDIF - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\KineChain.obj" - -@erase "$(INTDIR)\KineChain.pch" - -@erase "$(INTDIR)\KineChain.res" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Quatern.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc50.idb" - -@erase "$(INTDIR)\vc50.pdb" - -@erase "$(OUTDIR)\KineChain.exe" - -@erase "$(OUTDIR)\KineChain.ilk" - -@erase "$(OUTDIR)\KineChain.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\KineChain.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ - /c -CPP_OBJS=.\Debug/ -CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\KineChain.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\KineChain.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:yes /pdb:"$(OUTDIR)\KineChain.pdb" /debug /machine:I386\ - /out:"$(OUTDIR)\KineChain.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\KineChain.obj" \ - "$(INTDIR)\KineChain.res" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Quatern.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\KineChain.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(CFG)" == "KineChain - Win32 Release" || "$(CFG)" == "KineChain - Win32 Debug" -SOURCE=.\Bitmap.cpp -DEP_CPP_BITMA=\ - ".\Bitmap.h"\ - - -"$(INTDIR)\Bitmap.obj" : $(SOURCE) $(DEP_CPP_BITMA) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -SOURCE=.\KineChain.cpp - -!IF "$(CFG)" == "KineChain - Win32 Release" - -DEP_CPP_KINE3=\ - ".\KineChain.h"\ - ".\MainFrm.h"\ - ".\MathDefs.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\KineChain.obj" : $(SOURCE) $(DEP_CPP_KINE3) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -DEP_CPP_KINE3=\ - ".\KineChain.h"\ - ".\MainFrm.h"\ - ".\MathDefs.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\KineChain.obj" : $(SOURCE) $(DEP_CPP_KINE3) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ENDIF - -SOURCE=.\KineChain.rc -DEP_RSC_KineChain=\ - ".\res\KineChain.ico"\ - ".\res\KineChain.rc2"\ - - -"$(INTDIR)\KineChain.res" : $(SOURCE) $(DEP_RSC_KineChain) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\MainFrm.cpp - -!IF "$(CFG)" == "KineChain - Win32 Release" - -DEP_CPP_MAINF=\ - ".\KineChain.h"\ - ".\MainFrm.h"\ - ".\MathDefs.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -DEP_CPP_MAINF=\ - ".\KineChain.h"\ - ".\MainFrm.h"\ - ".\MathDefs.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ENDIF - -SOURCE=.\MathDefs.cpp -DEP_CPP_MATHD=\ - ".\MathDefs.h"\ - - -"$(INTDIR)\MathDefs.obj" : $(SOURCE) $(DEP_CPP_MATHD) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -SOURCE=.\OGLView.cpp - -!IF "$(CFG)" == "KineChain - Win32 Release" - -DEP_CPP_OGLVI=\ - ".\Bitmap.h"\ - ".\KineChain.h"\ - ".\MathDefs.h"\ - ".\Model.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -DEP_CPP_OGLVI=\ - ".\Bitmap.h"\ - ".\KineChain.h"\ - ".\MathDefs.h"\ - ".\Model.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ENDIF - -SOURCE=.\Quatern.cpp - -!IF "$(CFG)" == "KineChain - Win32 Release" - -DEP_CPP_QUATE=\ - ".\MathDefs.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -DEP_CPP_QUATE=\ - ".\MathDefs.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ENDIF - -SOURCE=.\Skeleton.cpp - -!IF "$(CFG)" == "KineChain - Win32 Release" - -DEP_CPP_SKELE=\ - ".\MathDefs.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -DEP_CPP_SKELE=\ - ".\MathDefs.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ - "$(INTDIR)\KineChain.pch" - - -!ENDIF - -SOURCE=.\StdAfx.cpp -DEP_CPP_STDAF=\ - ".\StdAfx.h"\ - - -!IF "$(CFG)" == "KineChain - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\KineChain.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ - /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\KineChain.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ - "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D\ - "_WINDOWS" /Fp"$(INTDIR)\KineChain.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\"\ - /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\KineChain.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ - "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on KineChain.dsp +!IF "$(CFG)" == "" +CFG=KineChain - Win32 Debug +!MESSAGE No configuration specified. Defaulting to KineChain - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "KineChain - Win32 Release" && "$(CFG)" != "KineChain - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "KineChain.mak" CFG="KineChain - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "KineChain - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "KineChain - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "KineChain - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\KineChain.exe" + +!ELSE + +ALL : "$(OUTDIR)\KineChain.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\KineChain.obj" + -@erase "$(INTDIR)\KineChain.pch" + -@erase "$(INTDIR)\KineChain.res" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Quatern.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(OUTDIR)\KineChain.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\KineChain.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c +CPP_OBJS=.\Release/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\KineChain.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\KineChain.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\KineChain.pdb" /machine:I386\ + /out:"$(OUTDIR)\KineChain.exe" +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\KineChain.obj" \ + "$(INTDIR)\KineChain.res" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Quatern.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\KineChain.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\KineChain.exe" + +!ELSE + +ALL : "$(OUTDIR)\KineChain.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\KineChain.obj" + -@erase "$(INTDIR)\KineChain.pch" + -@erase "$(INTDIR)\KineChain.res" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Quatern.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(OUTDIR)\KineChain.exe" + -@erase "$(OUTDIR)\KineChain.ilk" + -@erase "$(OUTDIR)\KineChain.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\KineChain.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c +CPP_OBJS=.\Debug/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\KineChain.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\KineChain.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:yes /pdb:"$(OUTDIR)\KineChain.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)\KineChain.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\KineChain.obj" \ + "$(INTDIR)\KineChain.res" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Quatern.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\KineChain.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(CFG)" == "KineChain - Win32 Release" || "$(CFG)" == "KineChain - Win32 Debug" +SOURCE=.\Bitmap.cpp +DEP_CPP_BITMA=\ + ".\Bitmap.h"\ + + +"$(INTDIR)\Bitmap.obj" : $(SOURCE) $(DEP_CPP_BITMA) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +SOURCE=.\KineChain.cpp + +!IF "$(CFG)" == "KineChain - Win32 Release" + +DEP_CPP_KINE3=\ + ".\KineChain.h"\ + ".\MainFrm.h"\ + ".\MathDefs.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\KineChain.obj" : $(SOURCE) $(DEP_CPP_KINE3) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +DEP_CPP_KINE3=\ + ".\KineChain.h"\ + ".\MainFrm.h"\ + ".\MathDefs.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\KineChain.obj" : $(SOURCE) $(DEP_CPP_KINE3) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ENDIF + +SOURCE=.\KineChain.rc +DEP_RSC_KineChain=\ + ".\res\KineChain.ico"\ + ".\res\KineChain.rc2"\ + + +"$(INTDIR)\KineChain.res" : $(SOURCE) $(DEP_RSC_KineChain) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\MainFrm.cpp + +!IF "$(CFG)" == "KineChain - Win32 Release" + +DEP_CPP_MAINF=\ + ".\KineChain.h"\ + ".\MainFrm.h"\ + ".\MathDefs.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +DEP_CPP_MAINF=\ + ".\KineChain.h"\ + ".\MainFrm.h"\ + ".\MathDefs.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ENDIF + +SOURCE=.\MathDefs.cpp +DEP_CPP_MATHD=\ + ".\MathDefs.h"\ + + +"$(INTDIR)\MathDefs.obj" : $(SOURCE) $(DEP_CPP_MATHD) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +SOURCE=.\OGLView.cpp + +!IF "$(CFG)" == "KineChain - Win32 Release" + +DEP_CPP_OGLVI=\ + ".\Bitmap.h"\ + ".\KineChain.h"\ + ".\MathDefs.h"\ + ".\Model.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +DEP_CPP_OGLVI=\ + ".\Bitmap.h"\ + ".\KineChain.h"\ + ".\MathDefs.h"\ + ".\Model.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ENDIF + +SOURCE=.\Quatern.cpp + +!IF "$(CFG)" == "KineChain - Win32 Release" + +DEP_CPP_QUATE=\ + ".\MathDefs.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +DEP_CPP_QUATE=\ + ".\MathDefs.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ENDIF + +SOURCE=.\Skeleton.cpp + +!IF "$(CFG)" == "KineChain - Win32 Release" + +DEP_CPP_SKELE=\ + ".\MathDefs.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +DEP_CPP_SKELE=\ + ".\MathDefs.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ + "$(INTDIR)\KineChain.pch" + + +!ENDIF + +SOURCE=.\StdAfx.cpp +DEP_CPP_STDAF=\ + ".\StdAfx.h"\ + + +!IF "$(CFG)" == "KineChain - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\KineChain.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\KineChain.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ + "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "KineChain - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /Fp"$(INTDIR)\KineChain.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\KineChain.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ + "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/More Kine/Code/OGL/KineChain/MainFrm.cpp b/More Kine/Code/OGL/KineChain/MainFrm.cpp index 033679e..ed4c9a1 100644 --- a/More Kine/Code/OGL/KineChain/MainFrm.cpp +++ b/More Kine/Code/OGL/KineChain/MainFrm.cpp @@ -1,222 +1,222 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "KineChain.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_OPTIONS_DAMPING, OnOptionsDamping) - ON_UPDATE_COMMAND_UI(ID_OPTIONS_DAMPING, OnUpdateOptionsDamping) - ON_COMMAND(ID_OPTIONS_DOF, OnOptionsDof) - ON_UPDATE_COMMAND_UI(ID_OPTIONS_DOF, OnUpdateOptionsDof) - ON_COMMAND(ID_OPTIONS_SETRESTRICTIONS, OnOptionsSetrestrictions) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_BASEROT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(TRUE); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case 'Q': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(TRUE); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnOptionsDamping() -{ - m_OGLView.m_Damping = !m_OGLView.m_Damping; - m_OGLView.drawScene(TRUE); -} - -void CMainFrame::OnUpdateOptionsDamping(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_Damping ); -} - -void CMainFrame::OnOptionsDof() -{ - m_OGLView.m_DOF_Restrict = !m_OGLView.m_DOF_Restrict; - m_OGLView.drawScene(TRUE); -} - -void CMainFrame::OnUpdateOptionsDof(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DOF_Restrict ); -} - -void CMainFrame::OnOptionsSetrestrictions() -{ - m_OGLView.SetRestrictions(); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "KineChain.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_OPTIONS_DAMPING, OnOptionsDamping) + ON_UPDATE_COMMAND_UI(ID_OPTIONS_DAMPING, OnUpdateOptionsDamping) + ON_COMMAND(ID_OPTIONS_DOF, OnOptionsDof) + ON_UPDATE_COMMAND_UI(ID_OPTIONS_DOF, OnUpdateOptionsDof) + ON_COMMAND(ID_OPTIONS_SETRESTRICTIONS, OnOptionsSetrestrictions) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_BASEROT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(TRUE); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case 'Q': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(TRUE); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnOptionsDamping() +{ + m_OGLView.m_Damping = !m_OGLView.m_Damping; + m_OGLView.drawScene(TRUE); +} + +void CMainFrame::OnUpdateOptionsDamping(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_Damping ); +} + +void CMainFrame::OnOptionsDof() +{ + m_OGLView.m_DOF_Restrict = !m_OGLView.m_DOF_Restrict; + m_OGLView.drawScene(TRUE); +} + +void CMainFrame::OnUpdateOptionsDof(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DOF_Restrict ); +} + +void CMainFrame::OnOptionsSetrestrictions() +{ + m_OGLView.SetRestrictions(); +} diff --git a/More Kine/Code/OGL/KineChain/MainFrm.h b/More Kine/Code/OGL/KineChain/MainFrm.h index d17976e..c5140f0 100644 --- a/More Kine/Code/OGL/KineChain/MainFrm.h +++ b/More Kine/Code/OGL/KineChain/MainFrm.h @@ -1,88 +1,88 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "MathDefs.h" -#include "Skeleton.h" -#include "OGLView.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnOptionsDamping(); - afx_msg void OnUpdateOptionsDamping(CCmdUI* pCmdUI); - afx_msg void OnOptionsDof(); - afx_msg void OnUpdateOptionsDof(CCmdUI* pCmdUI); - afx_msg void OnOptionsSetrestrictions(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "MathDefs.h" +#include "Skeleton.h" +#include "OGLView.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnOptionsDamping(); + afx_msg void OnUpdateOptionsDamping(CCmdUI* pCmdUI); + afx_msg void OnOptionsDof(); + afx_msg void OnUpdateOptionsDof(CCmdUI* pCmdUI); + afx_msg void OnOptionsSetrestrictions(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/MathDefs.cpp b/More Kine/Code/OGL/KineChain/MathDefs.cpp index e72e718..e01737f 100644 --- a/More Kine/Code/OGL/KineChain/MathDefs.cpp +++ b/More Kine/Code/OGL/KineChain/MathDefs.cpp @@ -1,91 +1,91 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z + v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z + v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} diff --git a/More Kine/Code/OGL/KineChain/MathDefs.h b/More Kine/Code/OGL/KineChain/MathDefs.h index 5e2eb67..5395912 100644 --- a/More Kine/Code/OGL/KineChain/MathDefs.h +++ b/More Kine/Code/OGL/KineChain/MathDefs.h @@ -1,90 +1,90 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - float x,y,z; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); - -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + float x,y,z; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); + +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/More Kine/Code/OGL/KineChain/Matrix.h b/More Kine/Code/OGL/KineChain/Matrix.h index cffcc97..99d5cde 100644 --- a/More Kine/Code/OGL/KineChain/Matrix.h +++ b/More Kine/Code/OGL/KineChain/Matrix.h @@ -1,39 +1,39 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Matrix.h : Matrix Structure Header File -// -// Purpose: Declare Basic Matrix Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATRIX_H__INCLUDED_) -#define MATRIX_H__INCLUDED_ - -#include "MathDefs.h" // MATH SYSTEM HEADER - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); - -#endif // !defined(MATRIX_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// Matrix.h : Matrix Structure Header File +// +// Purpose: Declare Basic Matrix Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATRIX_H__INCLUDED_) +#define MATRIX_H__INCLUDED_ + +#include "MathDefs.h" // MATH SYSTEM HEADER + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); + +#endif // !defined(MATRIX_H__INCLUDED_) + diff --git a/More Kine/Code/OGL/KineChain/Model.h b/More Kine/Code/OGL/KineChain/Model.h index 081c2a8..15bbcde 100644 --- a/More Kine/Code/OGL/KineChain/Model.h +++ b/More Kine/Code/OGL/KineChain/Model.h @@ -1,143 +1,143 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// d:\snake.ogl : Geometry Header File -// 1 Frames of 44 Triangles -// Purpose: Auto-Generated from Softimage -// -/////////////////////////////////////////////////////////////////////////////// - -#define SNAKEPOLYCNT 44 -float SNAKE[] = { - 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, - 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, - 0.0000f, 0.8333f, 0.3569f, 0.3569f, 0.3569f, -0.5000f, 0.0000f, 0.1500f, - 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, - 0.0000f, 0.8333f, 0.3569f, 0.3569f, 0.3569f, -0.5000f, 0.0000f, 0.1500f, - 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, - 0.3500f, 0.1667f, 0.6902f, 0.6902f, 0.6902f, -0.1500f, -0.8000f, 0.2000f, - 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, - 0.7500f, 0.8333f, 0.7529f, 0.7529f, 0.7529f, 0.2500f, 0.0000f, 0.4000f, - 0.3500f, 0.1667f, 0.6902f, 0.6902f, 0.6902f, -0.1500f, -0.8000f, 0.2000f, - 0.7500f, 0.8333f, 0.7529f, 0.7529f, 0.7529f, 0.2500f, 0.0000f, 0.4000f, - 0.2500f, 0.8333f, 0.7451f, 0.7451f, 0.7451f, -0.2500f, 0.0000f, 0.4000f, - 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, - 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, - 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, - 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, - 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, - 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, - 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, - 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, - 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, - 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, - 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, - 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, - 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, - 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, - 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, - 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, - 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, - 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, - 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, - 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, - 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, - 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, - 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, - 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, - 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, - 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, - 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, - 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, - 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, - 0.0000f, 0.8333f, 0.3569f, 0.3569f, 0.3569f, -0.5000f, 0.0000f, 0.1500f, - 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, - 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, - 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, - 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, - 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, - 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, - 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, - 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, - 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, - 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, - 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, - 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, - 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, - 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, - 0.0000f, 0.8333f, 0.3608f, 0.3608f, 0.3608f, -0.5000f, 0.0000f, 0.1500f, - 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, - 0.0000f, 0.8333f, 0.3608f, 0.3608f, 0.3608f, -0.5000f, 0.0000f, 0.1500f, - 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, - 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, - 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, - 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, - 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, - 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, - 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, - 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, - 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, - 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, - 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, - 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, - 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, - 0.9000f, 0.2500f, 0.3490f, 0.3490f, 0.3490f, 0.4000f, -0.7000f, 0.0500f, - 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, - 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, - 0.9000f, 0.2500f, 0.3490f, 0.3490f, 0.3490f, 0.4000f, -0.7000f, 0.0500f, - 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, - 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, - 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, - 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, - 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, - 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, - 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, - 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, - 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, - 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, - 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, - 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, - 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, - 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, - 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, - 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, - 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, - 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, - 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, - 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, - 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, - 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, - 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, - 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, - 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, - 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, - 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, - 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, - 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, - 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, - 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, - 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, - 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, - 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, - 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, - 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, - 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, - 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, - 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, - 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, - 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, - 0.0000f, 0.8333f, 0.3608f, 0.3608f, 0.3608f, -0.5000f, 0.0000f, 0.1500f, - 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, - 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, - 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, - 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, - 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, - 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, - 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, - 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, - 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, - 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, - 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, - 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, - 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, - 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, -}; +/////////////////////////////////////////////////////////////////////////////// +// +// d:\snake.ogl : Geometry Header File +// 1 Frames of 44 Triangles +// Purpose: Auto-Generated from Softimage +// +/////////////////////////////////////////////////////////////////////////////// + +#define SNAKEPOLYCNT 44 +float SNAKE[] = { + 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, + 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, + 0.0000f, 0.8333f, 0.3569f, 0.3569f, 0.3569f, -0.5000f, 0.0000f, 0.1500f, + 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, + 0.0000f, 0.8333f, 0.3569f, 0.3569f, 0.3569f, -0.5000f, 0.0000f, 0.1500f, + 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, + 0.3500f, 0.1667f, 0.6902f, 0.6902f, 0.6902f, -0.1500f, -0.8000f, 0.2000f, + 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, + 0.7500f, 0.8333f, 0.7529f, 0.7529f, 0.7529f, 0.2500f, 0.0000f, 0.4000f, + 0.3500f, 0.1667f, 0.6902f, 0.6902f, 0.6902f, -0.1500f, -0.8000f, 0.2000f, + 0.7500f, 0.8333f, 0.7529f, 0.7529f, 0.7529f, 0.2500f, 0.0000f, 0.4000f, + 0.2500f, 0.8333f, 0.7451f, 0.7451f, 0.7451f, -0.2500f, 0.0000f, 0.4000f, + 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, + 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, + 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, + 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, + 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, + 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, + 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, + 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, + 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, + 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, + 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, + 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, + 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, + 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, + 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, + 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, + 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, + 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, + 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, + 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, + 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, + 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, + 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, + 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, + 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, + 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, + 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, + 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, + 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, + 0.0000f, 0.8333f, 0.3569f, 0.3569f, 0.3569f, -0.5000f, 0.0000f, 0.1500f, + 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, + 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, + 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, + 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, + 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, + 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, + 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, + 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, + 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, + 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, + 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, + 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, + 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, + 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, + 0.0000f, 0.8333f, 0.3608f, 0.3608f, 0.3608f, -0.5000f, 0.0000f, 0.1500f, + 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, + 0.0000f, 0.8333f, 0.3608f, 0.3608f, 0.3608f, -0.5000f, 0.0000f, 0.1500f, + 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, + 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, + 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, + 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, + 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, + 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, + 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, + 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, + 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, + 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, + 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, + 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, + 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, + 0.9000f, 0.2500f, 0.3490f, 0.3490f, 0.3490f, 0.4000f, -0.7000f, 0.0500f, + 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, + 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, + 0.9000f, 0.2500f, 0.3490f, 0.3490f, 0.3490f, 0.4000f, -0.7000f, 0.0500f, + 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, + 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, + 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, + 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, + 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, + 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, + 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, + 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, + 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, + 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, + 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, + 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, + 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, + 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, + 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, + 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, + 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, + 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, + 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, + 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, + 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, + 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, + 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, + 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, + 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, + 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, + 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, + 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, + 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, + 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, + 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, + 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, + 0.1000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, -0.4000f, -0.7000f, -0.0500f, + 0.3500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, -0.1500f, -0.8000f, -0.2000f, + 0.4500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, -0.0500f, -1.0000f, -0.0500f, + 0.3500f, 0.1667f, 0.6863f, 0.6863f, 0.6863f, -0.1500f, -0.8000f, 0.2000f, + 0.1000f, 0.2500f, 0.3294f, 0.3294f, 0.3294f, -0.4000f, -0.7000f, 0.0500f, + 0.4500f, 0.0000f, 0.3412f, 0.3412f, 0.3412f, -0.0500f, -1.0000f, 0.0500f, + 0.2500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.0000f, -0.4000f, + 0.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, -0.5000f, 0.0000f, -0.1500f, + 0.2500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, -0.2500f, 0.2000f, -0.1500f, + 0.0000f, 0.8333f, 0.3608f, 0.3608f, 0.3608f, -0.5000f, 0.0000f, 0.1500f, + 0.2500f, 0.8333f, 0.7412f, 0.7412f, 0.7412f, -0.2500f, 0.0000f, 0.4000f, + 0.2500f, 1.0000f, 0.3137f, 0.3137f, 0.3137f, -0.2500f, 0.2000f, 0.1500f, + 0.6500f, 0.1667f, 0.1490f, 0.1490f, 0.1490f, 0.1500f, -0.8000f, -0.2000f, + 0.9000f, 0.2500f, 0.1490f, 0.1490f, 0.1490f, 0.4000f, -0.7000f, -0.0500f, + 0.5500f, 0.0000f, 0.1490f, 0.1490f, 0.1490f, 0.0500f, -1.0000f, -0.0500f, + 0.9000f, 0.2500f, 0.3451f, 0.3451f, 0.3451f, 0.4000f, -0.7000f, 0.0500f, + 0.6500f, 0.1667f, 0.6941f, 0.6941f, 0.6941f, 0.1500f, -0.8000f, 0.2000f, + 0.5500f, 0.0000f, 0.3490f, 0.3490f, 0.3490f, 0.0500f, -1.0000f, 0.0500f, + 1.0000f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.5000f, 0.0000f, -0.1500f, + 0.7500f, 0.8333f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.0000f, -0.4000f, + 0.7500f, 1.0000f, 0.1490f, 0.1490f, 0.1490f, 0.2500f, 0.2000f, -0.1500f, + 0.7500f, 0.8333f, 0.7490f, 0.7490f, 0.7490f, 0.2500f, 0.0000f, 0.4000f, + 1.0000f, 0.8333f, 0.3765f, 0.3765f, 0.3765f, 0.5000f, 0.0000f, 0.1500f, + 0.7500f, 1.0000f, 0.3216f, 0.3216f, 0.3216f, 0.2500f, 0.2000f, 0.1500f, +}; diff --git a/More Kine/Code/OGL/KineChain/OGLView.cpp b/More Kine/Code/OGL/KineChain/OGLView.cpp index c2904e1..8686843 100644 --- a/More Kine/Code/OGL/KineChain/OGLView.cpp +++ b/More Kine/Code/OGL/KineChain/OGLView.cpp @@ -1,982 +1,982 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Inverse Kinematics System -// -// Created: -// JL 7/1/98 -// -// Notes: The meat of this application is the last routine in this file. -// "ComputeIK" takes a target point and solves the two bone system. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "math.h" -#include "KineChain.h" -#include "MathDefs.h" -#include "OGLView.h" -#include "Quatern.h" -#include "Model.h" // SOFTIMAGE MODEL DATA -#include "Restrict.h" // DOF RESTRICTIONS DIALOG -#include "Bitmap.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 99 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -#define EFFECTOR_POS 5 // THIS CHAIN HAS 5 LINKS -#define MAX_IK_TRIES 100 // TIMES THROUGH THE CCD LOOP (TRIES = # / LINKS) -#define IK_POS_THRESH 1.0f // THRESHOLD FOR SUCCESS -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - - // INITIALIZE SOME OF THE SKELETON VARIABLES - ResetBone(&m_Link[0], NULL); - m_Link[0].id = 1; - m_Link[0].trans.x = 4.8f; - m_Link[0].trans.y = 6.0f; - strcpy(m_Link[0].name,"Base"); - m_Link[0].childCnt = 1; - m_Link[0].children = &m_Link[1]; - - - ResetBone(&m_Link[1], NULL); - m_Link[1].id = 2; - strcpy(m_Link[1].name,"Link1"); - m_Link[1].trans.y = -1.0f; - m_Link[1].childCnt = 1; - m_Link[1].children = &m_Link[2]; - - ResetBone(&m_Link[2], NULL); - m_Link[2].id = 3; - strcpy(m_Link[2].name,"Link2"); - m_Link[2].trans.y = -1.0f; - m_Link[2].childCnt = 1; - m_Link[2].children = &m_Link[3]; - - ResetBone(&m_Link[3], NULL); - m_Link[3].id = 4; - strcpy(m_Link[3].name,"Link3"); - m_Link[3].trans.y = -1.0f; - m_Link[3].childCnt = 1; - m_Link[3].children = &m_Link[4]; - - ResetBone(&m_Link[4], NULL); - m_Link[4].id = 5; - strcpy(m_Link[4].name,"Link4"); - m_Link[4].trans.y = -1.0f; - m_Link[4].childCnt = 1; - m_Link[4].children = &m_Link[5]; - - // SET UP END EFFECTOR - ResetBone(&m_Link[5], NULL); - m_Link[5].id = 6; - strcpy(m_Link[5].name,"Effector"); - m_Link[5].trans.y = -1.0f; - - // SET UP DEFAULT SETTINGS FOR THE DAMPING FOR SIX JOINTS - m_Link[0].damp_width = 10.0f; - m_Link[1].damp_width = 10.0f; - m_Link[2].damp_width = 10.0f; - m_Link[3].damp_width = 10.0f; - m_Link[4].damp_width = 10.0f; - m_Link[5].damp_width = 10.0f; // END EFFECTOR, NOT USED REALLY - - // SET UP DEFAULT SETTINGS FOR THE DOF RESTRICTIONS - m_Link[0].min_rz = -30; - m_Link[1].min_rz = -30; - m_Link[2].min_rz = -30; - m_Link[3].min_rz = -30; - m_Link[4].min_rz = -30; - m_Link[5].min_rz = -30; // END EFFECTOR, NOT USED REALLY - - m_Link[0].max_rz = 30; - m_Link[1].max_rz = 30; - m_Link[2].max_rz = 30; - m_Link[3].max_rz = 30; - m_Link[4].max_rz = 30; - m_Link[5].max_rz = 30; // END EFFECTOR, NOT USED REALLY - - // BY DEFAULT NO DAMPING OR DOF RESTRICTION - m_Damping = FALSE; - m_DOF_Restrict = FALSE; -} - -COGLView::~COGLView() -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: UpdateStatus -// Purpose: Update the status bar with orientation info -/////////////////////////////////////////////////////////////////////////////// -void COGLView::UpdateStatus() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - - // WRITE THE ORIENTATIONS OF THE BONES IN THE WINDOW STATUS AREA - sprintf(message,"Joint Rot Values (%.2f,%.2f,%.2f,%.2f,%.2f)", - m_Link[0].rot.z,m_Link[1].rot.z,m_Link[2].rot.z,m_Link[3].rot.z, - m_Link[4].rot.z); - m_ptrStatusBar->SetPaneText(1,message); - -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ - UpdateStatus(); // DRAW INITIAL STATUS BAR - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_MBUTTONDOWN() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(2.0,2.0,2.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - CreateBoneDLists(&m_Link[0]); - - // LOAD THE TEXTURE MAPS FOR THE OBJECT - LoadBoneTexture(&m_Link[0], "snake.bmp"); - m_Link[1].visuals = m_Link[0].visuals; // BONES 1 - 3 USE INSTANCED TEXTURES - m_Link[2].visuals = m_Link[0].visuals; - m_Link[3].visuals = m_Link[0].visuals; - LoadBoneTexture(&m_Link[4], "head.bmp"); - - drawScene(TRUE); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - m_Width = width; - m_Height = height; - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // FOR THIS APP, I WANT A 2D Ortho View - gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS -// gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - m_ModelScale = (float)height / 6.0f; - glScalef(m_ModelScale,m_ModelScale,0.0f); - - m_Link[0].trans.x = ((float)width / 2.0f) / m_ModelScale; -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadBoneTexture -// Purpose: Load texture images for the bone -// Notes: Some of this code was originally from the OpenGL SuperBible -// by Richard Wright Jr. and Michael Sweet -// THIS SHOULD LOOK THROUGH ALL BONES AND SEE IF TEXTURE IS -// ALREADY LOADED. -GLvoid COGLView::LoadBoneTexture(t_Bone *curBone, char *name) -{ - BITMAPINFO *info; /* Bitmap information */ - void *bits; /* Bitmap pixel bits */ - GLubyte *glbits; /* Bitmap RGB pixels */ - - // GENERATE THE OPENGL TEXTURE ID - glGenTextures(1,(unsigned int *)&curBone->visuals); - curBone->visualCnt++; - - // LOAD THE BITMAP - bits = LoadDIBitmap(name, &info); - if (bits == NULL) - { - ::MessageBox(NULL,"Unable to Open File...",name,MB_OK); - curBone->visuals = 0; - return; - } - - // CONVERT IT TO AN RGB TEXTURE - glbits = ConvertBitsToGL(info, bits); - if (glbits == NULL) - { - free(info); - free(bits); - - return; - }; - - glBindTexture(GL_TEXTURE_2D, (unsigned int)curBone->visuals); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - /* - * Define the 2D texture image. - */ - - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); /* Force 4-byte alignment */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - - glTexImage2D(GL_TEXTURE_2D, 0, 3, info->bmiHeader.biWidth, info->bmiHeader.biHeight, 0, - GL_RGB, GL_UNSIGNED_BYTE, glbits); - - /* - *Free the bitmap and RGB images, then return 0 (no errors). - */ - - free(glbits); - free(info); - free(bits); -} - - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - // FOR THIS APP, I WANT A 2D Ortho View - gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS -// gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // WAS MODULATE - glEnable(GL_TEXTURE_2D); - - glShadeModel(GL_SMOOTH); - glDisable(GL_LIGHTING); -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: CreateBoneDLists -// Purpose: Creates the Drawlists for the Bones in a Skeleton -// Arguments: Pointer to a bone hierarchy -/////////////////////////////////////////////////////////////////////////////// -void COGLView::CreateBoneDLists(t_Bone *bone) -{ - // ONLY MAKE A BONE IF THERE IS A CHILD - if (bone->childCnt > 0) - { - // CREATE THE DISPLAY LIST FOR A BONE - glNewList(bone->id,GL_COMPILE); - glBegin(GL_LINE_STRIP); - glColor3f(1.0f, 1.0f, 0.0f); // YELLOW - glVertex3f( 0.0f, 0.4f, 0.0f); // 0 - glVertex3f(-0.4f, 0.0f,-0.4f); // 1 - glVertex3f( 0.4f, 0.0f,-0.4f); // 2 - glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base - glVertex3f(-0.4f, 0.0f,-0.4f); // 1 - glVertex3f(-0.4f, 0.0f, 0.4f); // 4 - glVertex3f( 0.0f, 0.4f, 0.0f); // 0 - glVertex3f( 0.4f, 0.0f,-0.4f); // 2 - glVertex3f( 0.4f, 0.0f, 0.4f); // 3 - glVertex3f( 0.0f, 0.4f, 0.0f); // 0 - glVertex3f(-0.4f, 0.0f, 0.4f); // 4 - glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base - glVertex3f( 0.4f, 0.0f, 0.4f); // 3 - glVertex3f(-0.4f, 0.0f, 0.4f); // 4 - glEnd(); - glEndList(); - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (bone->childCnt > 0) - CreateBoneDLists(bone->children); - } -} - -GLvoid COGLView::drawModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (curBone->visuals > 0) - { - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, (unsigned int)curBone->visuals); - } - glInterleavedArrays(GL_T2F_C3F_V3F,0,(GLvoid *)SNAKE); - - glDrawArrays(GL_TRIANGLES,0,SNAKEPOLYCNT * 3); - glDisable(GL_TEXTURE_2D); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawSkeleton -// Purpose: Actually draws the Skeleton it is recursive -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawSkeleton(t_Bone *rootBone,BOOL actuallyDraw) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - // Set base orientation and position - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - - // THE SCALE IS LOCAL SO I PUSH AND POP - glPushMatrix(); - glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); - - if (actuallyDraw) - { - if (m_DrawGeometry) - { - if (curBone->childCnt > 0) - { - drawModel(curBone); - } - } - else - { - // DRAW THE AXIS OGL OBJECT - glCallList(OGL_AXIS_DLIST); - // DRAW THE ACTUAL BONE STRUCTURE - // ONLY MAKE A BONE IF THERE IS A CHILD - if (curBone->childCnt > 0) - { - glColor3f(1.0f, 1.0f, 0.0f); // Selected bone is bright Yellow - // DRAW THE BONE STRUCTURE - glCallList(curBone->id); - } - } - } - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,curBone->matrix.m); - - glPopMatrix(); // THIS POP IS JUST FOR THE SCALE - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - drawSkeleton(curBone,actuallyDraw); - - glPopMatrix(); // THIS POPS THE WHOLE MATRIX - - curBone++; - } -} -//// drawSkeleton ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(BOOL actuallyDraw) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (actuallyDraw) - { - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - } - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Link[0].trans.x, m_Link[0].trans.y, m_Link[0].trans.z); - - // ROTATE THE ROOT - glRotatef(m_Link[0].rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_Link[0].rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Link[0].rot.x, 1.0f, 0.0f, 0.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m_Link[0].matrix.m); - - if (actuallyDraw) - { - if (m_DrawGeometry) - { - drawModel(m_Link); - } - else - { - glCallList(m_Link[0].id); - glCallList(OGL_AXIS_DLIST); - } - } - - drawSkeleton(&m_Link[0],actuallyDraw); - - glPopMatrix(); - glFinish(); - - if (actuallyDraw) - { - SwapBuffers(m_hDC); - - // DRAW THE STATS AT THE BOTTOM OF THE SCREEN - UpdateStatus(); - } -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(TRUE); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CPoint joint1,joint2,effector; -/////////////////////////////////////////////////////////////////////////////// - m_mousepos = point; - - point.y = m_Height - point.y - 1; - - // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM - if ((nFlags & MK_CONTROL) == 0) - { - ComputeCCDLink(point); - drawScene(TRUE); - } - else - { - ComputeOneCCDLink(point,2); - drawScene(TRUE); - } - m_Grab_Rot_X = m_Link[2].rot.x; - m_Grab_Rot_Y = m_Link[2].rot.y; - m_Grab_Rot_Z = m_Link[2].rot.z; - m_Grab_Trans_X = m_Link[2].trans.x; - m_Grab_Trans_Y = m_Link[2].trans.y; - m_Grab_Trans_Z = m_Link[2].trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - point.y = m_Height - point.y - 1; - - // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM - if ((nFlags & MK_CONTROL) == 0) - { - ComputeCCDLink(point); - drawScene(TRUE); - } - else - { - ComputeOneCCDLink(point,4); - drawScene(TRUE); - } - m_Grab_Rot_X = m_Link[4].rot.x; - m_Grab_Rot_Y = m_Link[4].rot.y; - m_Grab_Rot_Z = m_Link[4].rot.z; - m_Grab_Trans_X = m_Link[4].trans.x; - m_Grab_Trans_Y = m_Link[4].trans.y; - m_Grab_Trans_Z = m_Link[4].trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnMButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - point.y = m_Height - point.y - 1; - - // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM - if ((nFlags & MK_CONTROL) == 0) - { - ComputeCCDLink(point); - drawScene(TRUE); - } - else - { - ComputeOneCCDLink(point,3); - drawScene(TRUE); - } - m_Grab_Rot_X = m_Link[3].rot.x; - m_Grab_Rot_Y = m_Link[3].rot.y; - m_Grab_Rot_Z = m_Link[3].rot.z; - m_Grab_Trans_X = m_Link[3].trans.x; - m_Grab_Trans_Y = m_Link[3].trans.y; - m_Grab_Trans_Z = m_Link[3].trans.z; - CWnd::OnMButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case 'G': - m_DrawGeometry = !m_DrawGeometry; - break; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (nFlags & MK_LBUTTON > 0) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { -// m_Link[3].rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(TRUE); - } - } - else - { - point.y = m_Height - point.y - 1; - ComputeCCDLink(point); - drawScene(TRUE); - } - - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { -// m_Link[4].rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(TRUE); - } - } - } - else if ((nFlags & MK_MBUTTON) == MK_MBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { -// m_Link[2].rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(TRUE); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: SetRestrictions -// Purpose: Open Dialog to set up restrictions -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SetRestrictions() -{ - CRestrict dialog; - dialog.m_Damp0 = m_Link[0].damp_width; - dialog.m_Damp1 = m_Link[1].damp_width; - dialog.m_Damp2 = m_Link[2].damp_width; - dialog.m_Damp3 = m_Link[3].damp_width; - dialog.m_Damp4 = m_Link[4].damp_width; - dialog.m_MinRot0 = m_Link[0].min_rz; - dialog.m_MinRot1 = m_Link[1].min_rz; - dialog.m_MinRot2 = m_Link[2].min_rz; - dialog.m_MinRot3 = m_Link[3].min_rz; - dialog.m_MinRot4 = m_Link[4].min_rz; - dialog.m_MaxRot0 = m_Link[0].max_rz; - dialog.m_MaxRot1 = m_Link[1].max_rz; - dialog.m_MaxRot2 = m_Link[2].max_rz; - dialog.m_MaxRot3 = m_Link[3].max_rz; - dialog.m_MaxRot4 = m_Link[4].max_rz; - if (dialog.DoModal()) - { - m_Link[0].damp_width = dialog.m_Damp0; - m_Link[1].damp_width = dialog.m_Damp1; - m_Link[2].damp_width = dialog.m_Damp2; - m_Link[3].damp_width = dialog.m_Damp3; - m_Link[4].damp_width = dialog.m_Damp4; - m_Link[0].min_rz = dialog.m_MinRot0; - m_Link[1].min_rz = dialog.m_MinRot1; - m_Link[2].min_rz = dialog.m_MinRot2; - m_Link[3].min_rz = dialog.m_MinRot3; - m_Link[4].min_rz = dialog.m_MinRot4; - m_Link[0].max_rz = dialog.m_MaxRot0; - m_Link[1].max_rz = dialog.m_MaxRot1; - m_Link[2].max_rz = dialog.m_MaxRot2; - m_Link[3].max_rz = dialog.m_MaxRot3; - m_Link[4].max_rz = dialog.m_MaxRot4; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: ComputeOneCCDLink -// Purpose: Compute an IK Solution to an end effector position -// Arguments: End Target (x,y) -// Returns: TRUE if a solution exists, FALSE if the position isn't in reach -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::ComputeOneCCDLink(CPoint endPos,int link) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector rootPos,curEnd,desiredEnd,targetVector,curVector,crossResult; - double cosAngle,turnAngle,turnDeg; -/////////////////////////////////////////////////////////////////////////////// - - rootPos.x = m_Link[link].matrix.m[12]; - rootPos.y = m_Link[link].matrix.m[13]; - rootPos.z = m_Link[link].matrix.m[14]; - - curEnd.x = m_Link[EFFECTOR_POS].matrix.m[12]; - curEnd.y = m_Link[EFFECTOR_POS].matrix.m[13]; - curEnd.z = m_Link[EFFECTOR_POS].matrix.m[14]; - - desiredEnd.x = (float)endPos.x; - desiredEnd.y = (float)endPos.y; - desiredEnd.z = 0.0f; // ONLY DOING 2D NOW - if (VectorSquaredDistance(&curEnd, &desiredEnd) > 1.0f) - { - curVector.x = curEnd.x - rootPos.x; - curVector.y = curEnd.y - rootPos.y; - curVector.z = curEnd.z - rootPos.z; - - targetVector.x = endPos.x - rootPos.x; - targetVector.y = endPos.y - rootPos.y; - targetVector.z = 0.0f; // ONLY DOING 2D NOW - - NormalizeVector(&curVector); - NormalizeVector(&targetVector); - - cosAngle = DotProduct(&targetVector,&curVector); - - if (cosAngle < 0.99999) - { - CrossProduct(&targetVector, &curVector, &crossResult); - - if (crossResult.z > 0.0f) - { - turnAngle = acos((float)cosAngle); - turnDeg = RADTODEG(turnAngle); - m_Link[link].rot.z -= (float)turnDeg; - } - else if (crossResult.z < 0.0f) - { - turnAngle = acos((float)cosAngle); - turnDeg = RADTODEG(turnAngle); - m_Link[link].rot.z += (float)turnDeg; - } - drawScene(FALSE); // CHANGE THIS TO TRUE IF YOU WANT TO SEE THE ITERATION - } - } - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: ComputeCCDLink -// Purpose: Compute an IK Solution to an end effector position -// Arguments: End Target (x,y) -// Returns: TRUE if a solution exists, FALSE if the position isn't in reach -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::ComputeCCDLink(CPoint endPos) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector rootPos,curEnd,desiredEnd,targetVector,curVector,crossResult; - double cosAngle,turnAngle,turnDeg; - int link,tries; -/////////////////////////////////////////////////////////////////////////////// - // START AT THE LAST LINK IN THE CHAIN - link = EFFECTOR_POS - 1; - tries = 0; // LOOP COUNTER SO I KNOW WHEN TO QUIT - do - { - // THE COORDS OF THE X,Y,Z POSITION OF THE ROOT OF THIS BONE IS IN THE MATRIX - // TRANSLATION PART WHICH IS IN THE 12,13,14 POSITION OF THE MATRIX - rootPos.x = m_Link[link].matrix.m[12]; - rootPos.y = m_Link[link].matrix.m[13]; - rootPos.z = m_Link[link].matrix.m[14]; - - // POSITION OF THE END EFFECTOR - curEnd.x = m_Link[EFFECTOR_POS].matrix.m[12]; - curEnd.y = m_Link[EFFECTOR_POS].matrix.m[13]; - curEnd.z = m_Link[EFFECTOR_POS].matrix.m[14]; - - // DESIRED END EFFECTOR POSITION - desiredEnd.x = (float)endPos.x; - desiredEnd.y = (float)endPos.y; - desiredEnd.z = 0.0f; // ONLY DOING 2D NOW - - // SEE IF I AM ALREADY CLOSE ENOUGH - if (VectorSquaredDistance(&curEnd, &desiredEnd) > IK_POS_THRESH) - { - // CREATE THE VECTOR TO THE CURRENT EFFECTOR POS - curVector.x = curEnd.x - rootPos.x; - curVector.y = curEnd.y - rootPos.y; - curVector.z = curEnd.z - rootPos.z; - // CREATE THE DESIRED EFFECTOR POSITION VECTOR - targetVector.x = endPos.x - rootPos.x; - targetVector.y = endPos.y - rootPos.y; - targetVector.z = 0.0f; // ONLY DOING 2D NOW - - // NORMALIZE THE VECTORS (EXPENSIVE, REQUIRES A SQRT) - NormalizeVector(&curVector); - NormalizeVector(&targetVector); - - // THE DOT PRODUCT GIVES ME THE COSINE OF THE DESIRED ANGLE - cosAngle = DotProduct(&targetVector,&curVector); - - // IF THE DOT PRODUCT RETURNS 1.0, I DON'T NEED TO ROTATE AS IT IS 0 DEGREES - if (cosAngle < 0.99999) - { - // USE THE CROSS PRODUCT TO CHECK WHICH WAY TO ROTATE - CrossProduct(&targetVector, &curVector, &crossResult); - if (crossResult.z > 0.0f) // IF THE Z ELEMENT IS POSITIVE, ROTATE CLOCKWISE - { - turnAngle = acos((float)cosAngle); // GET THE ANGLE - turnDeg = RADTODEG(turnAngle); // COVERT TO DEGREES - // DAMPING - if (m_Damping && turnDeg > m_Link[link].damp_width) - turnDeg = m_Link[link].damp_width; - m_Link[link].rot.z -= (float)turnDeg; // ACTUALLY TURN THE LINK - // DOF RESTRICTIONS - if (m_DOF_Restrict && - m_Link[link].rot.z < (float)m_Link[link].min_rz) - m_Link[link].rot.z = (float)m_Link[link].min_rz; - } - else if (crossResult.z < 0.0f) // ROTATE COUNTER CLOCKWISE - { - turnAngle = acos((float)cosAngle); - turnDeg = RADTODEG(turnAngle); - // DAMPING - if (m_Damping && turnDeg > m_Link[link].damp_width) - turnDeg = m_Link[link].damp_width; - m_Link[link].rot.z += (float)turnDeg; // ACTUALLY TURN THE LINK - // DOF RESTRICTIONS - if (m_DOF_Restrict && - m_Link[link].rot.z > (float)m_Link[link].max_rz) - m_Link[link].rot.z = (float)m_Link[link].max_rz; - } - // RECALC ALL THE MATRICES WITHOUT DRAWING ANYTHING - drawScene(FALSE); // CHANGE THIS TO TRUE IF YOU WANT TO SEE THE ITERATION - } - if (--link < 0) link = EFFECTOR_POS - 1; // START OF THE CHAIN, RESTART - } - // QUIT IF I AM CLOSE ENOUGH OR BEEN RUNNING LONG ENOUGH - } while (tries++ < MAX_IK_TRIES && - VectorSquaredDistance(&curEnd, &desiredEnd) > IK_POS_THRESH); - return TRUE; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Inverse Kinematics System +// +// Created: +// JL 7/1/98 +// +// Notes: The meat of this application is the last routine in this file. +// "ComputeIK" takes a target point and solves the two bone system. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "math.h" +#include "KineChain.h" +#include "MathDefs.h" +#include "OGLView.h" +#include "Quatern.h" +#include "Model.h" // SOFTIMAGE MODEL DATA +#include "Restrict.h" // DOF RESTRICTIONS DIALOG +#include "Bitmap.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 99 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +#define EFFECTOR_POS 5 // THIS CHAIN HAS 5 LINKS +#define MAX_IK_TRIES 100 // TIMES THROUGH THE CCD LOOP (TRIES = # / LINKS) +#define IK_POS_THRESH 1.0f // THRESHOLD FOR SUCCESS +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + + // INITIALIZE SOME OF THE SKELETON VARIABLES + ResetBone(&m_Link[0], NULL); + m_Link[0].id = 1; + m_Link[0].trans.x = 4.8f; + m_Link[0].trans.y = 6.0f; + strcpy(m_Link[0].name,"Base"); + m_Link[0].childCnt = 1; + m_Link[0].children = &m_Link[1]; + + + ResetBone(&m_Link[1], NULL); + m_Link[1].id = 2; + strcpy(m_Link[1].name,"Link1"); + m_Link[1].trans.y = -1.0f; + m_Link[1].childCnt = 1; + m_Link[1].children = &m_Link[2]; + + ResetBone(&m_Link[2], NULL); + m_Link[2].id = 3; + strcpy(m_Link[2].name,"Link2"); + m_Link[2].trans.y = -1.0f; + m_Link[2].childCnt = 1; + m_Link[2].children = &m_Link[3]; + + ResetBone(&m_Link[3], NULL); + m_Link[3].id = 4; + strcpy(m_Link[3].name,"Link3"); + m_Link[3].trans.y = -1.0f; + m_Link[3].childCnt = 1; + m_Link[3].children = &m_Link[4]; + + ResetBone(&m_Link[4], NULL); + m_Link[4].id = 5; + strcpy(m_Link[4].name,"Link4"); + m_Link[4].trans.y = -1.0f; + m_Link[4].childCnt = 1; + m_Link[4].children = &m_Link[5]; + + // SET UP END EFFECTOR + ResetBone(&m_Link[5], NULL); + m_Link[5].id = 6; + strcpy(m_Link[5].name,"Effector"); + m_Link[5].trans.y = -1.0f; + + // SET UP DEFAULT SETTINGS FOR THE DAMPING FOR SIX JOINTS + m_Link[0].damp_width = 10.0f; + m_Link[1].damp_width = 10.0f; + m_Link[2].damp_width = 10.0f; + m_Link[3].damp_width = 10.0f; + m_Link[4].damp_width = 10.0f; + m_Link[5].damp_width = 10.0f; // END EFFECTOR, NOT USED REALLY + + // SET UP DEFAULT SETTINGS FOR THE DOF RESTRICTIONS + m_Link[0].min_rz = -30; + m_Link[1].min_rz = -30; + m_Link[2].min_rz = -30; + m_Link[3].min_rz = -30; + m_Link[4].min_rz = -30; + m_Link[5].min_rz = -30; // END EFFECTOR, NOT USED REALLY + + m_Link[0].max_rz = 30; + m_Link[1].max_rz = 30; + m_Link[2].max_rz = 30; + m_Link[3].max_rz = 30; + m_Link[4].max_rz = 30; + m_Link[5].max_rz = 30; // END EFFECTOR, NOT USED REALLY + + // BY DEFAULT NO DAMPING OR DOF RESTRICTION + m_Damping = FALSE; + m_DOF_Restrict = FALSE; +} + +COGLView::~COGLView() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: UpdateStatus +// Purpose: Update the status bar with orientation info +/////////////////////////////////////////////////////////////////////////////// +void COGLView::UpdateStatus() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + + // WRITE THE ORIENTATIONS OF THE BONES IN THE WINDOW STATUS AREA + sprintf(message,"Joint Rot Values (%.2f,%.2f,%.2f,%.2f,%.2f)", + m_Link[0].rot.z,m_Link[1].rot.z,m_Link[2].rot.z,m_Link[3].rot.z, + m_Link[4].rot.z); + m_ptrStatusBar->SetPaneText(1,message); + +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ + UpdateStatus(); // DRAW INITIAL STATUS BAR + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_MBUTTONDOWN() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(2.0,2.0,2.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + CreateBoneDLists(&m_Link[0]); + + // LOAD THE TEXTURE MAPS FOR THE OBJECT + LoadBoneTexture(&m_Link[0], "snake.bmp"); + m_Link[1].visuals = m_Link[0].visuals; // BONES 1 - 3 USE INSTANCED TEXTURES + m_Link[2].visuals = m_Link[0].visuals; + m_Link[3].visuals = m_Link[0].visuals; + LoadBoneTexture(&m_Link[4], "head.bmp"); + + drawScene(TRUE); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + m_Width = width; + m_Height = height; + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // FOR THIS APP, I WANT A 2D Ortho View + gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS +// gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + m_ModelScale = (float)height / 6.0f; + glScalef(m_ModelScale,m_ModelScale,0.0f); + + m_Link[0].trans.x = ((float)width / 2.0f) / m_ModelScale; +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadBoneTexture +// Purpose: Load texture images for the bone +// Notes: Some of this code was originally from the OpenGL SuperBible +// by Richard Wright Jr. and Michael Sweet +// THIS SHOULD LOOK THROUGH ALL BONES AND SEE IF TEXTURE IS +// ALREADY LOADED. +GLvoid COGLView::LoadBoneTexture(t_Bone *curBone, char *name) +{ + BITMAPINFO *info; /* Bitmap information */ + void *bits; /* Bitmap pixel bits */ + GLubyte *glbits; /* Bitmap RGB pixels */ + + // GENERATE THE OPENGL TEXTURE ID + glGenTextures(1,(unsigned int *)&curBone->visuals); + curBone->visualCnt++; + + // LOAD THE BITMAP + bits = LoadDIBitmap(name, &info); + if (bits == NULL) + { + ::MessageBox(NULL,"Unable to Open File...",name,MB_OK); + curBone->visuals = 0; + return; + } + + // CONVERT IT TO AN RGB TEXTURE + glbits = ConvertBitsToGL(info, bits); + if (glbits == NULL) + { + free(info); + free(bits); + + return; + }; + + glBindTexture(GL_TEXTURE_2D, (unsigned int)curBone->visuals); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + /* + * Define the 2D texture image. + */ + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); /* Force 4-byte alignment */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + + glTexImage2D(GL_TEXTURE_2D, 0, 3, info->bmiHeader.biWidth, info->bmiHeader.biHeight, 0, + GL_RGB, GL_UNSIGNED_BYTE, glbits); + + /* + *Free the bitmap and RGB images, then return 0 (no errors). + */ + + free(glbits); + free(info); + free(bits); +} + + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + // FOR THIS APP, I WANT A 2D Ortho View + gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS +// gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // WAS MODULATE + glEnable(GL_TEXTURE_2D); + + glShadeModel(GL_SMOOTH); + glDisable(GL_LIGHTING); +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: CreateBoneDLists +// Purpose: Creates the Drawlists for the Bones in a Skeleton +// Arguments: Pointer to a bone hierarchy +/////////////////////////////////////////////////////////////////////////////// +void COGLView::CreateBoneDLists(t_Bone *bone) +{ + // ONLY MAKE A BONE IF THERE IS A CHILD + if (bone->childCnt > 0) + { + // CREATE THE DISPLAY LIST FOR A BONE + glNewList(bone->id,GL_COMPILE); + glBegin(GL_LINE_STRIP); + glColor3f(1.0f, 1.0f, 0.0f); // YELLOW + glVertex3f( 0.0f, 0.4f, 0.0f); // 0 + glVertex3f(-0.4f, 0.0f,-0.4f); // 1 + glVertex3f( 0.4f, 0.0f,-0.4f); // 2 + glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base + glVertex3f(-0.4f, 0.0f,-0.4f); // 1 + glVertex3f(-0.4f, 0.0f, 0.4f); // 4 + glVertex3f( 0.0f, 0.4f, 0.0f); // 0 + glVertex3f( 0.4f, 0.0f,-0.4f); // 2 + glVertex3f( 0.4f, 0.0f, 0.4f); // 3 + glVertex3f( 0.0f, 0.4f, 0.0f); // 0 + glVertex3f(-0.4f, 0.0f, 0.4f); // 4 + glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base + glVertex3f( 0.4f, 0.0f, 0.4f); // 3 + glVertex3f(-0.4f, 0.0f, 0.4f); // 4 + glEnd(); + glEndList(); + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (bone->childCnt > 0) + CreateBoneDLists(bone->children); + } +} + +GLvoid COGLView::drawModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (curBone->visuals > 0) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, (unsigned int)curBone->visuals); + } + glInterleavedArrays(GL_T2F_C3F_V3F,0,(GLvoid *)SNAKE); + + glDrawArrays(GL_TRIANGLES,0,SNAKEPOLYCNT * 3); + glDisable(GL_TEXTURE_2D); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawSkeleton +// Purpose: Actually draws the Skeleton it is recursive +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawSkeleton(t_Bone *rootBone,BOOL actuallyDraw) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + // Set base orientation and position + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + + // THE SCALE IS LOCAL SO I PUSH AND POP + glPushMatrix(); + glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); + + if (actuallyDraw) + { + if (m_DrawGeometry) + { + if (curBone->childCnt > 0) + { + drawModel(curBone); + } + } + else + { + // DRAW THE AXIS OGL OBJECT + glCallList(OGL_AXIS_DLIST); + // DRAW THE ACTUAL BONE STRUCTURE + // ONLY MAKE A BONE IF THERE IS A CHILD + if (curBone->childCnt > 0) + { + glColor3f(1.0f, 1.0f, 0.0f); // Selected bone is bright Yellow + // DRAW THE BONE STRUCTURE + glCallList(curBone->id); + } + } + } + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,curBone->matrix.m); + + glPopMatrix(); // THIS POP IS JUST FOR THE SCALE + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + drawSkeleton(curBone,actuallyDraw); + + glPopMatrix(); // THIS POPS THE WHOLE MATRIX + + curBone++; + } +} +//// drawSkeleton ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(BOOL actuallyDraw) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (actuallyDraw) + { + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + } + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Link[0].trans.x, m_Link[0].trans.y, m_Link[0].trans.z); + + // ROTATE THE ROOT + glRotatef(m_Link[0].rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_Link[0].rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Link[0].rot.x, 1.0f, 0.0f, 0.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m_Link[0].matrix.m); + + if (actuallyDraw) + { + if (m_DrawGeometry) + { + drawModel(m_Link); + } + else + { + glCallList(m_Link[0].id); + glCallList(OGL_AXIS_DLIST); + } + } + + drawSkeleton(&m_Link[0],actuallyDraw); + + glPopMatrix(); + glFinish(); + + if (actuallyDraw) + { + SwapBuffers(m_hDC); + + // DRAW THE STATS AT THE BOTTOM OF THE SCREEN + UpdateStatus(); + } +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(TRUE); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CPoint joint1,joint2,effector; +/////////////////////////////////////////////////////////////////////////////// + m_mousepos = point; + + point.y = m_Height - point.y - 1; + + // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM + if ((nFlags & MK_CONTROL) == 0) + { + ComputeCCDLink(point); + drawScene(TRUE); + } + else + { + ComputeOneCCDLink(point,2); + drawScene(TRUE); + } + m_Grab_Rot_X = m_Link[2].rot.x; + m_Grab_Rot_Y = m_Link[2].rot.y; + m_Grab_Rot_Z = m_Link[2].rot.z; + m_Grab_Trans_X = m_Link[2].trans.x; + m_Grab_Trans_Y = m_Link[2].trans.y; + m_Grab_Trans_Z = m_Link[2].trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + point.y = m_Height - point.y - 1; + + // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM + if ((nFlags & MK_CONTROL) == 0) + { + ComputeCCDLink(point); + drawScene(TRUE); + } + else + { + ComputeOneCCDLink(point,4); + drawScene(TRUE); + } + m_Grab_Rot_X = m_Link[4].rot.x; + m_Grab_Rot_Y = m_Link[4].rot.y; + m_Grab_Rot_Z = m_Link[4].rot.z; + m_Grab_Trans_X = m_Link[4].trans.x; + m_Grab_Trans_Y = m_Link[4].trans.y; + m_Grab_Trans_Z = m_Link[4].trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnMButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + point.y = m_Height - point.y - 1; + + // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM + if ((nFlags & MK_CONTROL) == 0) + { + ComputeCCDLink(point); + drawScene(TRUE); + } + else + { + ComputeOneCCDLink(point,3); + drawScene(TRUE); + } + m_Grab_Rot_X = m_Link[3].rot.x; + m_Grab_Rot_Y = m_Link[3].rot.y; + m_Grab_Rot_Z = m_Link[3].rot.z; + m_Grab_Trans_X = m_Link[3].trans.x; + m_Grab_Trans_Y = m_Link[3].trans.y; + m_Grab_Trans_Z = m_Link[3].trans.z; + CWnd::OnMButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case 'G': + m_DrawGeometry = !m_DrawGeometry; + break; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (nFlags & MK_LBUTTON > 0) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { +// m_Link[3].rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(TRUE); + } + } + else + { + point.y = m_Height - point.y - 1; + ComputeCCDLink(point); + drawScene(TRUE); + } + + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { +// m_Link[4].rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(TRUE); + } + } + } + else if ((nFlags & MK_MBUTTON) == MK_MBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { +// m_Link[2].rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(TRUE); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: SetRestrictions +// Purpose: Open Dialog to set up restrictions +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SetRestrictions() +{ + CRestrict dialog; + dialog.m_Damp0 = m_Link[0].damp_width; + dialog.m_Damp1 = m_Link[1].damp_width; + dialog.m_Damp2 = m_Link[2].damp_width; + dialog.m_Damp3 = m_Link[3].damp_width; + dialog.m_Damp4 = m_Link[4].damp_width; + dialog.m_MinRot0 = m_Link[0].min_rz; + dialog.m_MinRot1 = m_Link[1].min_rz; + dialog.m_MinRot2 = m_Link[2].min_rz; + dialog.m_MinRot3 = m_Link[3].min_rz; + dialog.m_MinRot4 = m_Link[4].min_rz; + dialog.m_MaxRot0 = m_Link[0].max_rz; + dialog.m_MaxRot1 = m_Link[1].max_rz; + dialog.m_MaxRot2 = m_Link[2].max_rz; + dialog.m_MaxRot3 = m_Link[3].max_rz; + dialog.m_MaxRot4 = m_Link[4].max_rz; + if (dialog.DoModal()) + { + m_Link[0].damp_width = dialog.m_Damp0; + m_Link[1].damp_width = dialog.m_Damp1; + m_Link[2].damp_width = dialog.m_Damp2; + m_Link[3].damp_width = dialog.m_Damp3; + m_Link[4].damp_width = dialog.m_Damp4; + m_Link[0].min_rz = dialog.m_MinRot0; + m_Link[1].min_rz = dialog.m_MinRot1; + m_Link[2].min_rz = dialog.m_MinRot2; + m_Link[3].min_rz = dialog.m_MinRot3; + m_Link[4].min_rz = dialog.m_MinRot4; + m_Link[0].max_rz = dialog.m_MaxRot0; + m_Link[1].max_rz = dialog.m_MaxRot1; + m_Link[2].max_rz = dialog.m_MaxRot2; + m_Link[3].max_rz = dialog.m_MaxRot3; + m_Link[4].max_rz = dialog.m_MaxRot4; + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: ComputeOneCCDLink +// Purpose: Compute an IK Solution to an end effector position +// Arguments: End Target (x,y) +// Returns: TRUE if a solution exists, FALSE if the position isn't in reach +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::ComputeOneCCDLink(CPoint endPos,int link) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector rootPos,curEnd,desiredEnd,targetVector,curVector,crossResult; + double cosAngle,turnAngle,turnDeg; +/////////////////////////////////////////////////////////////////////////////// + + rootPos.x = m_Link[link].matrix.m[12]; + rootPos.y = m_Link[link].matrix.m[13]; + rootPos.z = m_Link[link].matrix.m[14]; + + curEnd.x = m_Link[EFFECTOR_POS].matrix.m[12]; + curEnd.y = m_Link[EFFECTOR_POS].matrix.m[13]; + curEnd.z = m_Link[EFFECTOR_POS].matrix.m[14]; + + desiredEnd.x = (float)endPos.x; + desiredEnd.y = (float)endPos.y; + desiredEnd.z = 0.0f; // ONLY DOING 2D NOW + if (VectorSquaredDistance(&curEnd, &desiredEnd) > 1.0f) + { + curVector.x = curEnd.x - rootPos.x; + curVector.y = curEnd.y - rootPos.y; + curVector.z = curEnd.z - rootPos.z; + + targetVector.x = endPos.x - rootPos.x; + targetVector.y = endPos.y - rootPos.y; + targetVector.z = 0.0f; // ONLY DOING 2D NOW + + NormalizeVector(&curVector); + NormalizeVector(&targetVector); + + cosAngle = DotProduct(&targetVector,&curVector); + + if (cosAngle < 0.99999) + { + CrossProduct(&targetVector, &curVector, &crossResult); + + if (crossResult.z > 0.0f) + { + turnAngle = acos((float)cosAngle); + turnDeg = RADTODEG(turnAngle); + m_Link[link].rot.z -= (float)turnDeg; + } + else if (crossResult.z < 0.0f) + { + turnAngle = acos((float)cosAngle); + turnDeg = RADTODEG(turnAngle); + m_Link[link].rot.z += (float)turnDeg; + } + drawScene(FALSE); // CHANGE THIS TO TRUE IF YOU WANT TO SEE THE ITERATION + } + } + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: ComputeCCDLink +// Purpose: Compute an IK Solution to an end effector position +// Arguments: End Target (x,y) +// Returns: TRUE if a solution exists, FALSE if the position isn't in reach +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::ComputeCCDLink(CPoint endPos) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector rootPos,curEnd,desiredEnd,targetVector,curVector,crossResult; + double cosAngle,turnAngle,turnDeg; + int link,tries; +/////////////////////////////////////////////////////////////////////////////// + // START AT THE LAST LINK IN THE CHAIN + link = EFFECTOR_POS - 1; + tries = 0; // LOOP COUNTER SO I KNOW WHEN TO QUIT + do + { + // THE COORDS OF THE X,Y,Z POSITION OF THE ROOT OF THIS BONE IS IN THE MATRIX + // TRANSLATION PART WHICH IS IN THE 12,13,14 POSITION OF THE MATRIX + rootPos.x = m_Link[link].matrix.m[12]; + rootPos.y = m_Link[link].matrix.m[13]; + rootPos.z = m_Link[link].matrix.m[14]; + + // POSITION OF THE END EFFECTOR + curEnd.x = m_Link[EFFECTOR_POS].matrix.m[12]; + curEnd.y = m_Link[EFFECTOR_POS].matrix.m[13]; + curEnd.z = m_Link[EFFECTOR_POS].matrix.m[14]; + + // DESIRED END EFFECTOR POSITION + desiredEnd.x = (float)endPos.x; + desiredEnd.y = (float)endPos.y; + desiredEnd.z = 0.0f; // ONLY DOING 2D NOW + + // SEE IF I AM ALREADY CLOSE ENOUGH + if (VectorSquaredDistance(&curEnd, &desiredEnd) > IK_POS_THRESH) + { + // CREATE THE VECTOR TO THE CURRENT EFFECTOR POS + curVector.x = curEnd.x - rootPos.x; + curVector.y = curEnd.y - rootPos.y; + curVector.z = curEnd.z - rootPos.z; + // CREATE THE DESIRED EFFECTOR POSITION VECTOR + targetVector.x = endPos.x - rootPos.x; + targetVector.y = endPos.y - rootPos.y; + targetVector.z = 0.0f; // ONLY DOING 2D NOW + + // NORMALIZE THE VECTORS (EXPENSIVE, REQUIRES A SQRT) + NormalizeVector(&curVector); + NormalizeVector(&targetVector); + + // THE DOT PRODUCT GIVES ME THE COSINE OF THE DESIRED ANGLE + cosAngle = DotProduct(&targetVector,&curVector); + + // IF THE DOT PRODUCT RETURNS 1.0, I DON'T NEED TO ROTATE AS IT IS 0 DEGREES + if (cosAngle < 0.99999) + { + // USE THE CROSS PRODUCT TO CHECK WHICH WAY TO ROTATE + CrossProduct(&targetVector, &curVector, &crossResult); + if (crossResult.z > 0.0f) // IF THE Z ELEMENT IS POSITIVE, ROTATE CLOCKWISE + { + turnAngle = acos((float)cosAngle); // GET THE ANGLE + turnDeg = RADTODEG(turnAngle); // COVERT TO DEGREES + // DAMPING + if (m_Damping && turnDeg > m_Link[link].damp_width) + turnDeg = m_Link[link].damp_width; + m_Link[link].rot.z -= (float)turnDeg; // ACTUALLY TURN THE LINK + // DOF RESTRICTIONS + if (m_DOF_Restrict && + m_Link[link].rot.z < (float)m_Link[link].min_rz) + m_Link[link].rot.z = (float)m_Link[link].min_rz; + } + else if (crossResult.z < 0.0f) // ROTATE COUNTER CLOCKWISE + { + turnAngle = acos((float)cosAngle); + turnDeg = RADTODEG(turnAngle); + // DAMPING + if (m_Damping && turnDeg > m_Link[link].damp_width) + turnDeg = m_Link[link].damp_width; + m_Link[link].rot.z += (float)turnDeg; // ACTUALLY TURN THE LINK + // DOF RESTRICTIONS + if (m_DOF_Restrict && + m_Link[link].rot.z > (float)m_Link[link].max_rz) + m_Link[link].rot.z = (float)m_Link[link].max_rz; + } + // RECALC ALL THE MATRICES WITHOUT DRAWING ANYTHING + drawScene(FALSE); // CHANGE THIS TO TRUE IF YOU WANT TO SEE THE ITERATION + } + if (--link < 0) link = EFFECTOR_POS - 1; // START OF THE CHAIN, RESTART + } + // QUIT IF I AM CLOSE ENOUGH OR BEEN RUNNING LONG ENOUGH + } while (tries++ < MAX_IK_TRIES && + VectorSquaredDistance(&curEnd, &desiredEnd) > IK_POS_THRESH); + return TRUE; +} + diff --git a/More Kine/Code/OGL/KineChain/OGLView.h b/More Kine/Code/OGL/KineChain/OGLView.h index 503d9fc..b27c851 100644 --- a/More Kine/Code/OGL/KineChain/OGLView.h +++ b/More Kine/Code/OGL/KineChain/OGLView.h @@ -1,106 +1,106 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ - // Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry; - BOOL m_UseQuat; - BOOL m_Damping; - BOOL m_DOF_Restrict; - -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(BOOL actuallyDraw); - VOID CreateBoneDLists(t_Bone *bone); - GLvoid COGLView::LoadBoneTexture(t_Bone *curBone, char *name); - GLvoid COGLView::drawModel(t_Bone *curBone); - GLvoid drawSkeleton(t_Bone *rootBone,BOOL actuallyDraw); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void SetRestrictions(); - BOOL ComputeOneCCDLink(CPoint endPos,int link); - BOOL ComputeCCDLink(CPoint endPos); - void GetGLInfo(); - void UpdateStatus(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Link[6]; - float m_ModelScale; - int m_Width,m_Height; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnMButtonDown(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ + // Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry; + BOOL m_UseQuat; + BOOL m_Damping; + BOOL m_DOF_Restrict; + +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(BOOL actuallyDraw); + VOID CreateBoneDLists(t_Bone *bone); + GLvoid COGLView::LoadBoneTexture(t_Bone *curBone, char *name); + GLvoid COGLView::drawModel(t_Bone *curBone); + GLvoid drawSkeleton(t_Bone *rootBone,BOOL actuallyDraw); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void SetRestrictions(); + BOOL ComputeOneCCDLink(CPoint endPos,int link); + BOOL ComputeCCDLink(CPoint endPos); + void GetGLInfo(); + void UpdateStatus(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Link[6]; + float m_ModelScale; + int m_Width,m_Height; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/Quatern.cpp b/More Kine/Code/OGL/KineChain/Quatern.cpp index 358b487..989a244 100644 --- a/More Kine/Code/OGL/KineChain/Quatern.cpp +++ b/More Kine/Code/OGL/KineChain/Quatern.cpp @@ -1,366 +1,366 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.cpp : Quaternion System structure implementation file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY -// -// Created: -// JL 9/1/97 -// -// Sources: -// Shoemake, Ken, "Animating Rotations with Quaternion Curves" -// Computer Graphics 85, pp. 245-254 -// Watt and Watt, Advanced Animation and Rendering Techniques -// Addison Wesley, pp. 360-368 -// Shoemake, Graphic Gems II. -// -// Notes: -// There are a couple of methods of conversion here so it -// can be played around with a bit. One is more clear and the other -// is a bit faster. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include "MathDefs.h" -#include "skeleton.h" -#include "quatern.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: CopyVector -// Purpose: Copy a vector -// Arguments: pointer to destination and source -/////////////////////////////////////////////////////////////////////////////// -void CopyVector(tVector *dest, tVector *src) -{ - dest->x = src->x; - dest->y = src->y; - dest->z = src->z; -} -//// CopyVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ScaleVector -// Purpose: Scale a vector -// Arguments: pointer to vector and scale factor -/////////////////////////////////////////////////////////////////////////////// -void ScaleVector(tVector *vect, float scale) -{ - vect->x *= scale; - vect->y *= scale; - vect->z *= scale; -} -//// ScaleVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: AddVectors -// Purpose: Add two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - dest->x = vect1->x + vect2->x; - dest->y = vect1->y + vect2->y; - dest->z = vect1->z + vect2->z; -} -//// AddVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DotVectors -// Purpose: Compute the dot product of two vectors -// Arguments: pointer to vectors -// Returns: Dot product -/////////////////////////////////////////////////////////////////////////////// -float DotVectors(tVector *vect1, tVector *vect2) -{ - return (vect1->x * vect2->x) + - (vect1->y * vect2->y) + - (vect1->z * vect2->z); -} -//// DotVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossVectors -// Purpose: Computes the cross product of two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - // COMPUTE THE CROSS PRODUCT - dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); - dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); - dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); -} -//// CrossVectors ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion v1,v2,v3,vf; -/////////////////////////////////////////////////////////////////////////////// - - CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); - - AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); - AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); - - vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); - - dest->x = vf.x; - dest->y = vf.y; - dest->z = vf.z; - dest->w = vf.w; -} -//// MultQuaternions ////////////////////////////////////////////////////////// - -/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR - I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY - THE MATH CHECKS OUT THOUGH */ -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions2 -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ - tQuaternion tmp; - tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + - quat2->y * quat1->z - quat2->z * quat1->y; - tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + - quat2->z * quat1->x - quat2->x * quat1->z; - tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + - quat2->x * quat1->y - quat2->y * quat1->x; - tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - - quat2->y * quat1->y - quat2->z * quat1->z; - dest->x = tmp.x; dest->y = tmp.y; - dest->z = tmp.z; dest->w = tmp.w; -} -//// MultQuaternions2 ////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeQuaternion -// Purpose: Normalize a Quaternion -// Arguments: a quaternion to set -// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 -// This function insures this -/////////////////////////////////////////////////////////////////////////////// -void NormalizeQuaternion(tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float magnitude; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, FIND THE MAGNITUDE - magnitude = (quat->x * quat->x) + - (quat->y * quat->y) + - (quat->z * quat->z) + - (quat->w * quat->w); - - // DIVIDE BY THE MAGNITUDE TO NORMALIZE - quat->x = quat->x / magnitude; - quat->y = quat->y / magnitude; - quat->z = quat->z / magnitude; - quat->w = quat->w / magnitude; -} -// NormalizeQuaternion /////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT -// A SERIES OF ROTATIONS TO QUATERNIONS. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted. It is more efficient this way though. -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - tx = rx * (float)0.5; - ty = ry * (float)0.5; - tz = rz * (float)0.5; - cx = (float)cos(tx); - cy = (float)cos(ty); - cz = (float)cos(tz); - sx = (float)sin(tx); - sy = (float)sin(ty); - sz = (float)sin(tz); - - cc = cx * cz; - cs = cx * sz; - sc = sx * cz; - ss = sx * sz; - - quat->x = (cy * sc) - (sy * cs); - quat->y = (cy * ss) + (sy * cc); - quat->z = (cy * cs) - (sy * sc); - quat->w = (cy * cc) + (sy * ss); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(quat); -} -// EulerToQuaternion ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: This is a second variation. It creates a -// Series of quaternions and multiplies them together -// It would be easier to extend this for other rotation orders -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,ti,tj,tk; - tQuaternion qx,qy,qz,qf; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - ti = rx * (float)0.5; - tj = ry * (float)0.5; - tk = rz * (float)0.5; - - qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); - qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); - qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); - - MultQuaternions(&qx,&qy,&qf); - MultQuaternions(&qf,&qz,&qf); - -// ANOTHER TEST VARIATION -// MultQuaternions2(&qx,&qy,&qf); -// MultQuaternions2(&qf,&qz,&qf); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(&qf); - - quat->x = qf.x; - quat->y = qf.y; - quat->z = qf.z; - quat->w = qf.w; - -} -// EulerToQuaternion2 ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float scale,tw; -/////////////////////////////////////////////////////////////////////////////// - tw = (float)acos(quat->w) * 2; - scale = (float)sin(tw / 2.0); - axisAngle->x = quat->x / scale; - axisAngle->y = quat->y / scale; - axisAngle->z = quat->z / scale; - - // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES - axisAngle->w = (tw * (360 / 2)) / (float)M_PI; -} -// QuatToAxisAngle ///////////////////////////////////////////////////////// - -// THIS ROUTINE IS REALLY FOR THE APRIL ARTICLE BUT IF YOU WANT TO PLAY -// AROUND WITH IT, HERE IT IS. - -#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -// Notes: The comments explain the handling of the special cases. -// The comments in the magazine were wrong. Adjust the -// DELTA constant to play with the LERP vs. SLERP level -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // CHECK A COUPLE OF SPECIAL CASES. - // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) - if ((1.0 + cosom) > DELTA) - { - // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT - if ((1.0 - cosom) > DELTA) { - // YES, DO A SLERP - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1.0 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - // NOT A VERY BIG DIFFERENCE, DO A LERP - scale0 = 1.0 - slerp; - scale1 = slerp; - } - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; - } else { - // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR - // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION - result->x = -quat2->y; - result->y = quat2->x; - result->z = -quat2->w; - result->w = quat2->z; - scale0 = sin((1.0 - slerp) * (float)HALF_PI); - scale1 = sin(slerp * (float)HALF_PI); - result->x = scale0 * quat1->x + scale1 * result->x; - result->y = scale0 * quat1->y + scale1 * result->y; - result->z = scale0 * quat1->z + scale1 * result->z; - result->w = scale0 * quat1->w + scale1 * result->w; - } - -} -// SlerpQuat ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.cpp : Quaternion System structure implementation file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY +// +// Created: +// JL 9/1/97 +// +// Sources: +// Shoemake, Ken, "Animating Rotations with Quaternion Curves" +// Computer Graphics 85, pp. 245-254 +// Watt and Watt, Advanced Animation and Rendering Techniques +// Addison Wesley, pp. 360-368 +// Shoemake, Graphic Gems II. +// +// Notes: +// There are a couple of methods of conversion here so it +// can be played around with a bit. One is more clear and the other +// is a bit faster. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include "MathDefs.h" +#include "skeleton.h" +#include "quatern.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: CopyVector +// Purpose: Copy a vector +// Arguments: pointer to destination and source +/////////////////////////////////////////////////////////////////////////////// +void CopyVector(tVector *dest, tVector *src) +{ + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} +//// CopyVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ScaleVector +// Purpose: Scale a vector +// Arguments: pointer to vector and scale factor +/////////////////////////////////////////////////////////////////////////////// +void ScaleVector(tVector *vect, float scale) +{ + vect->x *= scale; + vect->y *= scale; + vect->z *= scale; +} +//// ScaleVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: AddVectors +// Purpose: Add two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + dest->x = vect1->x + vect2->x; + dest->y = vect1->y + vect2->y; + dest->z = vect1->z + vect2->z; +} +//// AddVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DotVectors +// Purpose: Compute the dot product of two vectors +// Arguments: pointer to vectors +// Returns: Dot product +/////////////////////////////////////////////////////////////////////////////// +float DotVectors(tVector *vect1, tVector *vect2) +{ + return (vect1->x * vect2->x) + + (vect1->y * vect2->y) + + (vect1->z * vect2->z); +} +//// DotVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossVectors +// Purpose: Computes the cross product of two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + // COMPUTE THE CROSS PRODUCT + dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); + dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); + dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); +} +//// CrossVectors ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion v1,v2,v3,vf; +/////////////////////////////////////////////////////////////////////////////// + + CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); + + AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); + AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); + + vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); + + dest->x = vf.x; + dest->y = vf.y; + dest->z = vf.z; + dest->w = vf.w; +} +//// MultQuaternions ////////////////////////////////////////////////////////// + +/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR + I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY + THE MATH CHECKS OUT THOUGH */ +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions2 +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ + tQuaternion tmp; + tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + + quat2->y * quat1->z - quat2->z * quat1->y; + tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + + quat2->z * quat1->x - quat2->x * quat1->z; + tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + + quat2->x * quat1->y - quat2->y * quat1->x; + tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - + quat2->y * quat1->y - quat2->z * quat1->z; + dest->x = tmp.x; dest->y = tmp.y; + dest->z = tmp.z; dest->w = tmp.w; +} +//// MultQuaternions2 ////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeQuaternion +// Purpose: Normalize a Quaternion +// Arguments: a quaternion to set +// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 +// This function insures this +/////////////////////////////////////////////////////////////////////////////// +void NormalizeQuaternion(tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float magnitude; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, FIND THE MAGNITUDE + magnitude = (quat->x * quat->x) + + (quat->y * quat->y) + + (quat->z * quat->z) + + (quat->w * quat->w); + + // DIVIDE BY THE MAGNITUDE TO NORMALIZE + quat->x = quat->x / magnitude; + quat->y = quat->y / magnitude; + quat->z = quat->z / magnitude; + quat->w = quat->w / magnitude; +} +// NormalizeQuaternion /////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT +// A SERIES OF ROTATIONS TO QUATERNIONS. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted. It is more efficient this way though. +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + tx = rx * (float)0.5; + ty = ry * (float)0.5; + tz = rz * (float)0.5; + cx = (float)cos(tx); + cy = (float)cos(ty); + cz = (float)cos(tz); + sx = (float)sin(tx); + sy = (float)sin(ty); + sz = (float)sin(tz); + + cc = cx * cz; + cs = cx * sz; + sc = sx * cz; + ss = sx * sz; + + quat->x = (cy * sc) - (sy * cs); + quat->y = (cy * ss) + (sy * cc); + quat->z = (cy * cs) - (sy * sc); + quat->w = (cy * cc) + (sy * ss); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(quat); +} +// EulerToQuaternion ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: This is a second variation. It creates a +// Series of quaternions and multiplies them together +// It would be easier to extend this for other rotation orders +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,ti,tj,tk; + tQuaternion qx,qy,qz,qf; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + ti = rx * (float)0.5; + tj = ry * (float)0.5; + tk = rz * (float)0.5; + + qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); + qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); + qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); + + MultQuaternions(&qx,&qy,&qf); + MultQuaternions(&qf,&qz,&qf); + +// ANOTHER TEST VARIATION +// MultQuaternions2(&qx,&qy,&qf); +// MultQuaternions2(&qf,&qz,&qf); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(&qf); + + quat->x = qf.x; + quat->y = qf.y; + quat->z = qf.z; + quat->w = qf.w; + +} +// EulerToQuaternion2 ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float scale,tw; +/////////////////////////////////////////////////////////////////////////////// + tw = (float)acos(quat->w) * 2; + scale = (float)sin(tw / 2.0); + axisAngle->x = quat->x / scale; + axisAngle->y = quat->y / scale; + axisAngle->z = quat->z / scale; + + // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES + axisAngle->w = (tw * (360 / 2)) / (float)M_PI; +} +// QuatToAxisAngle ///////////////////////////////////////////////////////// + +// THIS ROUTINE IS REALLY FOR THE APRIL ARTICLE BUT IF YOU WANT TO PLAY +// AROUND WITH IT, HERE IT IS. + +#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +// Notes: The comments explain the handling of the special cases. +// The comments in the magazine were wrong. Adjust the +// DELTA constant to play with the LERP vs. SLERP level +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // CHECK A COUPLE OF SPECIAL CASES. + // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) + if ((1.0 + cosom) > DELTA) + { + // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT + if ((1.0 - cosom) > DELTA) { + // YES, DO A SLERP + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1.0 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + // NOT A VERY BIG DIFFERENCE, DO A LERP + scale0 = 1.0 - slerp; + scale1 = slerp; + } + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; + } else { + // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR + // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION + result->x = -quat2->y; + result->y = quat2->x; + result->z = -quat2->w; + result->w = quat2->z; + scale0 = sin((1.0 - slerp) * (float)HALF_PI); + scale1 = sin(slerp * (float)HALF_PI); + result->x = scale0 * quat1->x + scale1 * result->x; + result->y = scale0 * quat1->y + scale1 * result->y; + result->z = scale0 * quat1->z + scale1 * result->z; + result->w = scale0 * quat1->w + scale1 * result->w; + } + +} +// SlerpQuat ///////////////////////////////////////////////////////////////// diff --git a/More Kine/Code/OGL/KineChain/Quatern.h b/More Kine/Code/OGL/KineChain/Quatern.h index 0ebb65a..667eaa9 100644 --- a/More Kine/Code/OGL/KineChain/Quatern.h +++ b/More Kine/Code/OGL/KineChain/Quatern.h @@ -1,59 +1,59 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.h : Quaternion System structure definition file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(QUATERN_H__INCLUDED_) -#define QUATERN_H__INCLUDED_ - -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); - -#endif // !defined(QUATERN_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.h : Quaternion System structure definition file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(QUATERN_H__INCLUDED_) +#define QUATERN_H__INCLUDED_ + +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); + +#endif // !defined(QUATERN_H__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/ReadMe.txt b/More Kine/Code/OGL/KineChain/ReadMe.txt index 12a3e1d..10ba6bd 100644 --- a/More Kine/Code/OGL/KineChain/ReadMe.txt +++ b/More Kine/Code/OGL/KineChain/ReadMe.txt @@ -1,37 +1,37 @@ -Inverse Kinematics in OpenGL Demonstration Program Oct 1, 1998 ----------------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the November 98 -Game Developer magazine. It is meant as a demonstration of -an general inverse kinematics solution. The main function -is in OGLView.cpp at the very bottom. The function is called -"ComputeCCDLink" and it takes a point on the screen for the -articulated arm to try and reach. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128, Riva TNT, and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -There are instructions in the Help/About dialog. - +Inverse Kinematics in OpenGL Demonstration Program Oct 1, 1998 +---------------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the November 98 +Game Developer magazine. It is meant as a demonstration of +an general inverse kinematics solution. The main function +is in OGLView.cpp at the very bottom. The function is called +"ComputeCCDLink" and it takes a point on the screen for the +articulated arm to try and reach. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128, Riva TNT, and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +There are instructions in the Help/About dialog. + Jeff \ No newline at end of file diff --git a/More Kine/Code/OGL/KineChain/Restrict.cpp b/More Kine/Code/OGL/KineChain/Restrict.cpp index 0eba3a2..2ef09f1 100644 --- a/More Kine/Code/OGL/KineChain/Restrict.cpp +++ b/More Kine/Code/OGL/KineChain/Restrict.cpp @@ -1,76 +1,76 @@ -// Restrict.cpp : implementation file -// - -#include "stdafx.h" -#include "kinechain.h" -#include "Restrict.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CRestrict dialog - - -CRestrict::CRestrict(CWnd* pParent /*=NULL*/) - : CDialog(CRestrict::IDD, pParent) -{ - //{{AFX_DATA_INIT(CRestrict) - m_MinRot0 = 0; - m_MinRot1 = 0; - m_MinRot2 = 0; - m_MinRot3 = 0; - m_MinRot4 = 0; - m_MaxRot0 = 0; - m_MaxRot1 = 0; - m_MaxRot2 = 0; - m_MaxRot3 = 0; - m_MaxRot4 = 0; - m_Damp0 = 0.0f; - m_Damp1 = 0.0f; - m_Damp2 = 0.0f; - m_Damp3 = 0.0f; - m_Damp4 = 0.0f; - //}}AFX_DATA_INIT -} - - -void CRestrict::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CRestrict) - DDX_Text(pDX, IDC_MINROT0, m_MinRot0); - DDX_Text(pDX, IDC_MINROT1, m_MinRot1); - DDX_Text(pDX, IDC_MINROT2, m_MinRot2); - DDX_Text(pDX, IDC_MINROT3, m_MinRot3); - DDX_Text(pDX, IDC_MINROT4, m_MinRot4); - DDX_Text(pDX, IDC_MAXROT0, m_MaxRot0); - DDX_Text(pDX, IDC_MAXROT1, m_MaxRot1); - DDX_Text(pDX, IDC_MAXROT2, m_MaxRot2); - DDX_Text(pDX, IDC_MAXROT3, m_MaxRot3); - DDX_Text(pDX, IDC_MAXROT4, m_MaxRot4); - DDX_Text(pDX, IDC_DAMP0, m_Damp0); - DDX_Text(pDX, IDC_DAMP1, m_Damp1); - DDX_Text(pDX, IDC_DAMP2, m_Damp2); - DDX_Text(pDX, IDC_DAMP3, m_Damp3); - DDX_Text(pDX, IDC_DAMP4, m_Damp4); - DDV_MinMaxFloat(pDX, m_Damp0, 0.0f, 359.0f); - DDV_MinMaxFloat(pDX, m_Damp1, 0.0f, 359.0f); - DDV_MinMaxFloat(pDX, m_Damp2, 0.0f, 359.0f); - DDV_MinMaxFloat(pDX, m_Damp3, 0.0f, 359.0f); - DDV_MinMaxFloat(pDX, m_Damp4, 0.0f, 359.0f); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CRestrict, CDialog) - //{{AFX_MSG_MAP(CRestrict) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CRestrict message handlers +// Restrict.cpp : implementation file +// + +#include "stdafx.h" +#include "kinechain.h" +#include "Restrict.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CRestrict dialog + + +CRestrict::CRestrict(CWnd* pParent /*=NULL*/) + : CDialog(CRestrict::IDD, pParent) +{ + //{{AFX_DATA_INIT(CRestrict) + m_MinRot0 = 0; + m_MinRot1 = 0; + m_MinRot2 = 0; + m_MinRot3 = 0; + m_MinRot4 = 0; + m_MaxRot0 = 0; + m_MaxRot1 = 0; + m_MaxRot2 = 0; + m_MaxRot3 = 0; + m_MaxRot4 = 0; + m_Damp0 = 0.0f; + m_Damp1 = 0.0f; + m_Damp2 = 0.0f; + m_Damp3 = 0.0f; + m_Damp4 = 0.0f; + //}}AFX_DATA_INIT +} + + +void CRestrict::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CRestrict) + DDX_Text(pDX, IDC_MINROT0, m_MinRot0); + DDX_Text(pDX, IDC_MINROT1, m_MinRot1); + DDX_Text(pDX, IDC_MINROT2, m_MinRot2); + DDX_Text(pDX, IDC_MINROT3, m_MinRot3); + DDX_Text(pDX, IDC_MINROT4, m_MinRot4); + DDX_Text(pDX, IDC_MAXROT0, m_MaxRot0); + DDX_Text(pDX, IDC_MAXROT1, m_MaxRot1); + DDX_Text(pDX, IDC_MAXROT2, m_MaxRot2); + DDX_Text(pDX, IDC_MAXROT3, m_MaxRot3); + DDX_Text(pDX, IDC_MAXROT4, m_MaxRot4); + DDX_Text(pDX, IDC_DAMP0, m_Damp0); + DDX_Text(pDX, IDC_DAMP1, m_Damp1); + DDX_Text(pDX, IDC_DAMP2, m_Damp2); + DDX_Text(pDX, IDC_DAMP3, m_Damp3); + DDX_Text(pDX, IDC_DAMP4, m_Damp4); + DDV_MinMaxFloat(pDX, m_Damp0, 0.0f, 359.0f); + DDV_MinMaxFloat(pDX, m_Damp1, 0.0f, 359.0f); + DDV_MinMaxFloat(pDX, m_Damp2, 0.0f, 359.0f); + DDV_MinMaxFloat(pDX, m_Damp3, 0.0f, 359.0f); + DDV_MinMaxFloat(pDX, m_Damp4, 0.0f, 359.0f); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CRestrict, CDialog) + //{{AFX_MSG_MAP(CRestrict) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CRestrict message handlers diff --git a/More Kine/Code/OGL/KineChain/Restrict.h b/More Kine/Code/OGL/KineChain/Restrict.h index a196f21..5a77ca0 100644 --- a/More Kine/Code/OGL/KineChain/Restrict.h +++ b/More Kine/Code/OGL/KineChain/Restrict.h @@ -1,60 +1,60 @@ -#if !defined(AFX_RESTRICT_H__2023DCA0_611E_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_RESTRICT_H__2023DCA0_611E_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// Restrict.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CRestrict dialog - -class CRestrict : public CDialog -{ -// Construction -public: - CRestrict(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CRestrict) - enum { IDD = IDD_SETRESTRICT }; - int m_MinRot0; - int m_MinRot1; - int m_MinRot2; - int m_MinRot3; - int m_MinRot4; - int m_MaxRot0; - int m_MaxRot1; - int m_MaxRot2; - int m_MaxRot3; - int m_MaxRot4; - float m_Damp0; - float m_Damp1; - float m_Damp2; - float m_Damp3; - float m_Damp4; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CRestrict) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CRestrict) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_RESTRICT_H__2023DCA0_611E_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_RESTRICT_H__2023DCA0_611E_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_RESTRICT_H__2023DCA0_611E_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// Restrict.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CRestrict dialog + +class CRestrict : public CDialog +{ +// Construction +public: + CRestrict(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CRestrict) + enum { IDD = IDD_SETRESTRICT }; + int m_MinRot0; + int m_MinRot1; + int m_MinRot2; + int m_MinRot3; + int m_MinRot4; + int m_MaxRot0; + int m_MaxRot1; + int m_MaxRot2; + int m_MaxRot3; + int m_MaxRot4; + float m_Damp0; + float m_Damp1; + float m_Damp2; + float m_Damp3; + float m_Damp4; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CRestrict) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CRestrict) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_RESTRICT_H__2023DCA0_611E_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/Skeleton.cpp b/More Kine/Code/OGL/KineChain/Skeleton.cpp index c17c60f..3c2ddfa 100644 --- a/More Kine/Code/OGL/KineChain/Skeleton.cpp +++ b/More Kine/Code/OGL/KineChain/Skeleton.cpp @@ -1,153 +1,153 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "mathdefs.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "mathdefs.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/More Kine/Code/OGL/KineChain/Skeleton.h b/More Kine/Code/OGL/KineChain/Skeleton.h index 69b96ec..3a8cc50 100644 --- a/More Kine/Code/OGL/KineChain/Skeleton.h +++ b/More Kine/Code/OGL/KineChain/Skeleton.h @@ -1,134 +1,134 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "Quatern.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - long *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "Quatern.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + long *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/StdAfx.cpp b/More Kine/Code/OGL/KineChain/StdAfx.cpp index 32d5921..f80f8c9 100644 --- a/More Kine/Code/OGL/KineChain/StdAfx.cpp +++ b/More Kine/Code/OGL/KineChain/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Kine.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Kine.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/More Kine/Code/OGL/KineChain/StdAfx.h b/More Kine/Code/OGL/KineChain/StdAfx.h index ddefdab..571c76c 100644 --- a/More Kine/Code/OGL/KineChain/StdAfx.h +++ b/More Kine/Code/OGL/KineChain/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/More Kine/Code/OGL/KineChain/resource.h b/More Kine/Code/OGL/KineChain/resource.h index 074be6f..a1f0356 100644 --- a/More Kine/Code/OGL/KineChain/resource.h +++ b/More Kine/Code/OGL/KineChain/resource.h @@ -1,52 +1,52 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by KineChain.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDD_SETROTATE 130 -#define IDD_SETRESTRICT 130 -#define IDC_XAXIS 1000 -#define IDC_DAMP0 1000 -#define IDC_YAXIS 1001 -#define IDC_MINROT0 1001 -#define IDC_ZAXIS 1002 -#define IDC_MAXROT0 1002 -#define IDC_DAMP1 1003 -#define IDC_MINROT1 1004 -#define IDC_MAXROT1 1005 -#define IDC_DAMP2 1006 -#define IDC_MINROT2 1007 -#define IDC_MAXROT2 1008 -#define IDC_DAMP3 1009 -#define IDC_MINROT3 1010 -#define IDC_MAXROT3 1011 -#define IDC_DAMP4 1012 -#define IDC_MINROT4 1013 -#define IDC_MAXROT4 1014 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_OPTIONS_DAMPING 32775 -#define ID_OPTIONS_DOFRESTRICTIONS 32776 -#define ID_OPTIONS_DOF 32777 -#define ID_OPTIONS_SETRESTRICTIONS 32778 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_LOWROT 59144 -#define ID_INDICATOR_STATUS 59145 -#define ID_INDICATOR_UPROT 59145 -#define ID_INDICATOR_BASEROT 59146 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32779 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by KineChain.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDD_SETROTATE 130 +#define IDD_SETRESTRICT 130 +#define IDC_XAXIS 1000 +#define IDC_DAMP0 1000 +#define IDC_YAXIS 1001 +#define IDC_MINROT0 1001 +#define IDC_ZAXIS 1002 +#define IDC_MAXROT0 1002 +#define IDC_DAMP1 1003 +#define IDC_MINROT1 1004 +#define IDC_MAXROT1 1005 +#define IDC_DAMP2 1006 +#define IDC_MINROT2 1007 +#define IDC_MAXROT2 1008 +#define IDC_DAMP3 1009 +#define IDC_MINROT3 1010 +#define IDC_MAXROT3 1011 +#define IDC_DAMP4 1012 +#define IDC_MINROT4 1013 +#define IDC_MAXROT4 1014 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_OPTIONS_DAMPING 32775 +#define ID_OPTIONS_DOFRESTRICTIONS 32776 +#define ID_OPTIONS_DOF 32777 +#define ID_OPTIONS_SETRESTRICTIONS 32778 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_LOWROT 59144 +#define ID_INDICATOR_STATUS 59145 +#define ID_INDICATOR_UPROT 59145 +#define ID_INDICATOR_BASEROT 59146 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 131 +#define _APS_NEXT_COMMAND_VALUE 32779 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.cpp b/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.cpp index 1de9585..5e76b16 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.cpp +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Kine.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Kine.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CKineApp - -BEGIN_MESSAGE_MAP(CKineApp, CWinApp) - //{{AFX_MSG_MAP(CKineApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CKineApp construction - -CKineApp::CKineApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CKineApp object - -CKineApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CKineApp initialization - -BOOL CKineApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CKineApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CKineApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Kine.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Kine.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CKineApp + +BEGIN_MESSAGE_MAP(CKineApp, CWinApp) + //{{AFX_MSG_MAP(CKineApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CKineApp construction + +CKineApp::CKineApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CKineApp object + +CKineApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CKineApp initialization + +BOOL CKineApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CKineApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CKineApp commands diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.h index 5c3d07a..f71f204 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Kine.h : main header file for the Kine application -// -// Purpose: header of Main Application of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Kine_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Kine_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CKineApp: -// See Kine.cpp for the implementation of this class -// - -class CKineApp : public CWinApp -{ -public: - CKineApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CKineApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CKineApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Kine_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Kine.h : main header file for the Kine application +// +// Purpose: header of Main Application of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Kine_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Kine_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CKineApp: +// See Kine.cpp for the implementation of this class +// + +class CKineApp : public CWinApp +{ +public: + CKineApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CKineApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CKineApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Kine_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.mak b/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.mak index 47b33fe..627abf7 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.mak +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Kine.mak @@ -1,359 +1,359 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Kine.dsp -!IF "$(CFG)" == "" -CFG=Kine - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Kine - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Kine - Win32 Release" && "$(CFG)" != "Kine - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Kine.mak" CFG="Kine - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Kine - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Kine - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Kine - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\Kine.exe" - -!ELSE - -ALL : "$(OUTDIR)\Kine.exe" - -!ENDIF - -CLEAN : - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Quatern.obj" - -@erase "$(INTDIR)\SetRot.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Kine.obj" - -@erase "$(INTDIR)\Kine.pch" - -@erase "$(INTDIR)\Kine.res" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc50.idb" - -@erase "$(OUTDIR)\Kine.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\Kine.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ - -CPP_OBJS=.\Release/ -CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Kine.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Kine.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:no /pdb:"$(OUTDIR)\Kine.pdb" /machine:I386\ - /out:"$(OUTDIR)\Kine.exe" -LINK32_OBJS= \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Quatern.obj" \ - "$(INTDIR)\SetRot.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\Kine.obj" \ - "$(INTDIR)\Kine.res" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\Kine.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Kine - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\Kine.exe" - -!ELSE - -ALL : "$(OUTDIR)\Kine.exe" - -!ENDIF - -CLEAN : - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Quatern.obj" - -@erase "$(INTDIR)\SetRot.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Kine.obj" - -@erase "$(INTDIR)\Kine.pch" - -@erase "$(INTDIR)\Kine.res" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc50.idb" - -@erase "$(INTDIR)\vc50.pdb" - -@erase "$(OUTDIR)\Kine.exe" - -@erase "$(OUTDIR)\Kine.ilk" - -@erase "$(OUTDIR)\Kine.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\Kine.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ - -CPP_OBJS=.\Debug/ -CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Kine.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Kine.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:yes /pdb:"$(OUTDIR)\Kine.pdb" /debug /machine:I386\ - /out:"$(OUTDIR)\Kine.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Quatern.obj" \ - "$(INTDIR)\SetRot.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\Kine.obj" \ - "$(INTDIR)\Kine.res" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\Kine.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(CFG)" == "Kine - Win32 Release" || "$(CFG)" == "Kine - Win32 Debug" -SOURCE=.\MainFrm.cpp -DEP_CPP_MAINF=\ - ".\MainFrm.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\Kine.h"\ - ".\StdAfx.h"\ - {$(INCLUDE)}"GL\gl.h"\ - {$(INCLUDE)}"GL\glu.h"\ - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ - "$(INTDIR)\Kine.pch" - - -SOURCE=.\OGLView.cpp -DEP_CPP_OGLVI=\ - ".\Model.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\SetRot.h"\ - ".\Skeleton.h"\ - ".\Kine.h"\ - ".\StdAfx.h"\ - {$(INCLUDE)}"GL\gl.h"\ - {$(INCLUDE)}"GL\glu.h"\ - - -"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ - "$(INTDIR)\Kine.pch" - - -SOURCE=.\Quatern.cpp -DEP_CPP_QUATE=\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ - "$(INTDIR)\Kine.pch" - - -SOURCE=.\SetRot.cpp -DEP_CPP_SETRO=\ - ".\SetRot.h"\ - ".\Kine.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\SetRot.obj" : $(SOURCE) $(DEP_CPP_SETRO) "$(INTDIR)"\ - "$(INTDIR)\Kine.pch" - - -SOURCE=.\Skeleton.cpp -DEP_CPP_SKELE=\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ - "$(INTDIR)\Kine.pch" - - -SOURCE=.\Kine.cpp -DEP_CPP_Kine=\ - ".\MainFrm.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\Kine.h"\ - ".\StdAfx.h"\ - {$(INCLUDE)}"GL\gl.h"\ - {$(INCLUDE)}"GL\glu.h"\ - - -"$(INTDIR)\Kine.obj" : $(SOURCE) $(DEP_CPP_Kine) "$(INTDIR)"\ - "$(INTDIR)\Kine.pch" - - -SOURCE=.\Kine.rc -DEP_RSC_Kine_=\ - ".\res\Kine.ico"\ - ".\res\Kine.rc2"\ - ".\res\KineDoc.ico"\ - - -"$(INTDIR)\Kine.res" : $(SOURCE) $(DEP_RSC_Kine_) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\StdAfx.cpp -DEP_CPP_STDAF=\ - ".\StdAfx.h"\ - - -!IF "$(CFG)" == "Kine - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\Kine.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ - - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Kine.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ - "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Kine - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D\ - "_WINDOWS" /Fp"$(INTDIR)\Kine.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\"\ - /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Kine.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ - "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Kine.dsp +!IF "$(CFG)" == "" +CFG=Kine - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Kine - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Kine - Win32 Release" && "$(CFG)" != "Kine - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Kine.mak" CFG="Kine - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Kine - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Kine - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Kine - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Kine.exe" + +!ELSE + +ALL : "$(OUTDIR)\Kine.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Quatern.obj" + -@erase "$(INTDIR)\SetRot.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Kine.obj" + -@erase "$(INTDIR)\Kine.pch" + -@erase "$(INTDIR)\Kine.res" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(OUTDIR)\Kine.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\Kine.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ + +CPP_OBJS=.\Release/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Kine.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Kine.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Kine.pdb" /machine:I386\ + /out:"$(OUTDIR)\Kine.exe" +LINK32_OBJS= \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Quatern.obj" \ + "$(INTDIR)\SetRot.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\Kine.obj" \ + "$(INTDIR)\Kine.res" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\Kine.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Kine - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Kine.exe" + +!ELSE + +ALL : "$(OUTDIR)\Kine.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Quatern.obj" + -@erase "$(INTDIR)\SetRot.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Kine.obj" + -@erase "$(INTDIR)\Kine.pch" + -@erase "$(INTDIR)\Kine.res" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(OUTDIR)\Kine.exe" + -@erase "$(OUTDIR)\Kine.ilk" + -@erase "$(OUTDIR)\Kine.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\Kine.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ + +CPP_OBJS=.\Debug/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Kine.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Kine.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:yes /pdb:"$(OUTDIR)\Kine.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)\Kine.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Quatern.obj" \ + "$(INTDIR)\SetRot.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\Kine.obj" \ + "$(INTDIR)\Kine.res" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\Kine.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(CFG)" == "Kine - Win32 Release" || "$(CFG)" == "Kine - Win32 Debug" +SOURCE=.\MainFrm.cpp +DEP_CPP_MAINF=\ + ".\MainFrm.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\Kine.h"\ + ".\StdAfx.h"\ + {$(INCLUDE)}"GL\gl.h"\ + {$(INCLUDE)}"GL\glu.h"\ + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ + "$(INTDIR)\Kine.pch" + + +SOURCE=.\OGLView.cpp +DEP_CPP_OGLVI=\ + ".\Model.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\SetRot.h"\ + ".\Skeleton.h"\ + ".\Kine.h"\ + ".\StdAfx.h"\ + {$(INCLUDE)}"GL\gl.h"\ + {$(INCLUDE)}"GL\glu.h"\ + + +"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ + "$(INTDIR)\Kine.pch" + + +SOURCE=.\Quatern.cpp +DEP_CPP_QUATE=\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ + "$(INTDIR)\Kine.pch" + + +SOURCE=.\SetRot.cpp +DEP_CPP_SETRO=\ + ".\SetRot.h"\ + ".\Kine.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\SetRot.obj" : $(SOURCE) $(DEP_CPP_SETRO) "$(INTDIR)"\ + "$(INTDIR)\Kine.pch" + + +SOURCE=.\Skeleton.cpp +DEP_CPP_SKELE=\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ + "$(INTDIR)\Kine.pch" + + +SOURCE=.\Kine.cpp +DEP_CPP_Kine=\ + ".\MainFrm.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\Kine.h"\ + ".\StdAfx.h"\ + {$(INCLUDE)}"GL\gl.h"\ + {$(INCLUDE)}"GL\glu.h"\ + + +"$(INTDIR)\Kine.obj" : $(SOURCE) $(DEP_CPP_Kine) "$(INTDIR)"\ + "$(INTDIR)\Kine.pch" + + +SOURCE=.\Kine.rc +DEP_RSC_Kine_=\ + ".\res\Kine.ico"\ + ".\res\Kine.rc2"\ + ".\res\KineDoc.ico"\ + + +"$(INTDIR)\Kine.res" : $(SOURCE) $(DEP_RSC_Kine_) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\StdAfx.cpp +DEP_CPP_STDAF=\ + ".\StdAfx.h"\ + + +!IF "$(CFG)" == "Kine - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\Kine.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ + + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Kine.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ + "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Kine - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /Fp"$(INTDIR)\Kine.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Kine.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ + "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.cpp b/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.cpp index 1523994..ef6e662 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.cpp +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.cpp @@ -1,191 +1,191 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Kine.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_UPROT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_LOWROT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case 'Q': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Kine.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_UPROT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_LOWROT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case 'Q': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.h index d58df3a..c9d6a4c 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/MainFrm.h @@ -1,82 +1,82 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Model.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/Model.h index a0d13d3..c008fbc 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Model.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Model.h @@ -1,310 +1,310 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// e:\kinemodel.h : Geometry Header File -// 1 Frames of 75 Triangles -// Purpose: Auto-Generated from Softimage -// -/////////////////////////////////////////////////////////////////////////////// - -#define BODYFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define BODYPOLYCNT 75 -float BODY[] = { - 0.0000f, 0.4902f, 0.0000f, 1.2356f, 4.8287f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.0500f, 5.0982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.0781f, 3.1332f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.0000f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.7500f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3000f, 2.0500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8354f, 5.3011f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 5.4654f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 5.4654f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 5.5839f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 5.0982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4000f, 3.5982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.2000f, 3.3982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4000f, 3.5982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 5.0982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 4.8982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.0000f, 4.8982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.0000f, 4.4982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.2000f, 4.4982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1500f, 3.8982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2000f, 3.9482f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.2000f, 3.3982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.4000f, 3.5982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.1000f, 3.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4352f, 4.3974f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.0482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4352f, 4.3974f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9482f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1770f, 2.7830f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.5566f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0768f, 3.0371f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9500f, 2.4500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.5566f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.0000f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3000f, 2.0500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9500f, 2.4500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.0781f, 3.1332f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.2664f, 3.5040f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3721f, 3.8540f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3721f, 3.8540f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.4203f, 4.2126f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3721f, 4.5748f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.0500f, 5.0982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 5.0982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 5.4654f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.3000f, 4.6982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4352f, 4.3974f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 4.8982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.3000f, 4.6982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4352f, 4.3974f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4352f, 4.3974f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4000f, 3.5982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 3.2982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0534f, 3.1139f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.2000f, 3.3982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0868f, 3.1273f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.1000f, 3.4982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.0000f, 3.4982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.0000f, 3.2982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4000f, 3.5982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 3.9482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4000f, 3.5982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4000f, 3.5982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 3.9482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2043f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 3.9482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.0482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2043f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.0482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.4352f, 4.3974f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 4.0482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 4.0482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.0982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2000f, 4.0482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1500f, 4.0982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 4.0482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2043f, 3.9982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2000f, 4.0482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 4.0482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2000f, 4.0482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2043f, 3.9982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2000f, 3.9482f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.2043f, 3.9982f, 0.0000f, - 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9482f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.2000f, 4.4982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.4352f, 4.3974f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.3000f, 4.6982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.2000f, 4.4982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.3000f, 4.6982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.0000f, 4.8982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9500f, 2.4500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.5566f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.0000f, -0.0000f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.0000f, 3.2982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.2000f, 3.3982f, 0.0000f, - 1.0000f, 0.6667f, 0.5412f, 0.1000f, 3.4982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9982f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.1000f, 4.0482f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0868f, 3.1273f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.2000f, 3.3982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 3.2982f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0000f, 3.2982f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0534f, 3.1139f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0868f, 3.1273f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0534f, 3.1139f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0768f, 3.0371f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0868f, 3.1273f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0534f, 3.1139f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0768f, 3.0371f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0868f, 3.1273f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0768f, 3.0371f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.1135f, 3.0504f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1770f, 2.7830f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1135f, 3.0504f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.1603f, 2.7362f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.1770f, 2.7830f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.1135f, 3.0504f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.1603f, 2.7362f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.1135f, 3.0504f, 0.0000f, - 0.0667f, 0.0667f, 0.0667f, 0.0768f, 3.0371f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1603f, 2.7362f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0768f, 3.0371f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1603f, 2.7362f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1770f, 2.7830f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.1603f, 2.7362f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.0868f, 3.1273f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.1135f, 3.0504f, 0.0000f, - 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.0500f, 5.0982f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8354f, 5.3011f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3721f, 4.5748f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.2356f, 4.8287f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.4203f, 4.2126f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3721f, 4.5748f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.2664f, 3.5040f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 1.3721f, 3.8540f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, -}; - -#define UPARMFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define UPARMPOLYCNT 4 -float UPARM[] = { - 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 4.0000f, 0.4500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.0000f, 0.7500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.0000f, 0.7500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.4500f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.4500f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.7500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.7500f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 4.0000f, -0.5000f, 0.0000f, -}; - -#define LOWARMFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define LOWARMPOLYCNT 17 -float LOWARM[] = { - 0.0000f, 0.4902f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.0000f, 0.4620f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.3351f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, -0.3351f, -0.0000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.4620f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.4620f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 2.0500f, -0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.0500f, 0.4000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.0000f, 0.5000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.7500f, 0.4000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.0500f, -0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.4500f, -0.2000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.5000f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.0500f, 0.4000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.7500f, 0.4000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.7500f, 0.4000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.5000f, 0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.5000f, 0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.5000f, -0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.5000f, -0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.0500f, -0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.5000f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.4000f, 0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.0500f, -0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 3.5000f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.5000f, 0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 2.0500f, -0.3000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.0500f, -0.3000f, 0.0000f, - 0.0000f, 0.4902f, 0.0000f, 2.1000f, -0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.1000f, -0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.5000f, -0.2500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, - 0.0000f, 0.2745f, 0.0000f, 2.1000f, -0.3500f, 0.0000f, -}; +/////////////////////////////////////////////////////////////////////////////// +// +// e:\kinemodel.h : Geometry Header File +// 1 Frames of 75 Triangles +// Purpose: Auto-Generated from Softimage +// +/////////////////////////////////////////////////////////////////////////////// + +#define BODYFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define BODYPOLYCNT 75 +float BODY[] = { + 0.0000f, 0.4902f, 0.0000f, 1.2356f, 4.8287f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.0500f, 5.0982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.0781f, 3.1332f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.0000f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.7500f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3000f, 2.0500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8354f, 5.3011f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 5.4654f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 5.4654f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 5.5839f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 5.0982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4000f, 3.5982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.2000f, 3.3982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4000f, 3.5982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 5.0982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 4.8982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.0000f, 4.8982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.0000f, 4.4982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.2000f, 4.4982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1500f, 3.8982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2000f, 3.9482f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.2000f, 3.3982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.4000f, 3.5982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.1000f, 3.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4352f, 4.3974f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.0482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4352f, 4.3974f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9482f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1770f, 2.7830f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.5566f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0768f, 3.0371f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9500f, 2.4500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.5566f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.0000f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3000f, 2.0500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9500f, 2.4500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.0781f, 3.1332f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.2664f, 3.5040f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3721f, 3.8540f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3721f, 3.8540f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.4203f, 4.2126f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3721f, 4.5748f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.0500f, 5.0982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 5.0982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 5.4654f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.3000f, 4.6982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4352f, 4.3974f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 4.8982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.3000f, 4.6982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4352f, 4.3974f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4352f, 4.3974f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4000f, 3.5982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 3.2982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0534f, 3.1139f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.2000f, 3.3982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0868f, 3.1273f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.1000f, 3.4982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.0000f, 3.4982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.0000f, 3.2982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4000f, 3.5982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 3.9482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4000f, 3.5982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4000f, 3.5982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 3.9482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2043f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 3.9482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.0482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2043f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.0482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4900f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.4352f, 4.3974f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.2000f, 4.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 4.0482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 4.0482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 4.0982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2000f, 4.0482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1500f, 4.0982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 4.0482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2043f, 3.9982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2000f, 4.0482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 4.0482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2000f, 4.0482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2043f, 3.9982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2000f, 3.9482f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.2043f, 3.9982f, 0.0000f, + 0.0510f, 0.0471f, 0.0431f, 0.1000f, 3.9482f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1500f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.2000f, 4.4982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.4352f, 4.3974f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.3000f, 4.6982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.2000f, 4.4982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.3000f, 4.6982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.0000f, 4.8982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.9982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9500f, 2.4500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, 2.5566f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.0000f, -0.0000f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.0000f, 3.2982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.2000f, 3.3982f, 0.0000f, + 1.0000f, 0.6667f, 0.5412f, 0.1000f, 3.4982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 3.8982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 3.9982f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.1000f, 4.0482f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0868f, 3.1273f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.2000f, 3.3982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 3.2982f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0000f, 3.2982f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0534f, 3.1139f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0868f, 3.1273f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0534f, 3.1139f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0000f, 2.9982f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0768f, 3.0371f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0868f, 3.1273f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0534f, 3.1139f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0768f, 3.0371f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0868f, 3.1273f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0768f, 3.0371f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.1135f, 3.0504f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1770f, 2.7830f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1135f, 3.0504f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.1603f, 2.7362f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.1770f, 2.7830f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.1135f, 3.0504f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.1603f, 2.7362f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.1135f, 3.0504f, 0.0000f, + 0.0667f, 0.0667f, 0.0667f, 0.0768f, 3.0371f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1603f, 2.7362f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0768f, 3.0371f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1603f, 2.7362f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1500f, 2.5982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1770f, 2.7830f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.1603f, 2.7362f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.4900f, 2.7007f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.0868f, 3.1273f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.1135f, 3.0504f, 0.0000f, + 0.0000f, 0.2275f, 0.0000f, 0.4900f, 3.1982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.5070f, 4.8904f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.0500f, 5.0982f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8354f, 5.3011f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8354f, 4.4796f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3721f, 4.5748f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.2356f, 4.8287f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.4203f, 4.2126f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3721f, 4.5748f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.9688f, 4.0894f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.2664f, 3.5040f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 1.3721f, 3.8540f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.8821f, 3.7098f, 0.0000f, +}; + +#define UPARMFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define UPARMPOLYCNT 4 +float UPARM[] = { + 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 4.0000f, 0.4500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.0000f, 0.7500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.0000f, 0.7500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.4500f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.4500f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.7500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 4.4500f, -0.0500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.7500f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 4.0000f, -0.5000f, 0.0000f, +}; + +#define LOWARMFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define LOWARMPOLYCNT 17 +float LOWARM[] = { + 0.0000f, 0.4902f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.0000f, 0.4620f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.3351f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, -0.3351f, -0.0000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.4620f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 0.0000f, -0.4620f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 2.0500f, -0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.0500f, 0.4000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.0000f, 0.5000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.7500f, 0.4000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.0500f, -0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.4500f, -0.2000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.5000f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.0500f, 0.4000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.7500f, 0.4000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.7500f, 0.4000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.5000f, 0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.5000f, 0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.5000f, -0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.5000f, -0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.0500f, -0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.5000f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.4000f, 0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.9500f, 0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.0500f, -0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 3.5000f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.5000f, 0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.0500f, 0.3000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 2.0500f, -0.3000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.0500f, -0.3000f, 0.0000f, + 0.0000f, 0.4902f, 0.0000f, 2.1000f, -0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.1000f, -0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.5000f, -0.2500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.4500f, 0.0000f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.1000f, 0.3500f, 0.0000f, + 0.0000f, 0.2745f, 0.0000f, 2.1000f, -0.3500f, 0.0000f, +}; diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.cpp b/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.cpp index 4c351e1..93bfd70 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.cpp +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.cpp @@ -1,647 +1,647 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Inverse Kinematics System -// -// Created: -// JL 7/1/98 -// JL 9/20/98 FIXED A BUG IN THE IK CALCULATIONS -// -// Notes: The meat of this application is the last routine in this file. -// "ComputeIK" takes a target point and solves the two bone system. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "math.h" -#include "Kine.h" -#include "OGLView.h" -#include "Quatern.h" -#include "Model.h" // SOFTIMAGE MODEL DATA - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - - // INITIALIZE SOME OF THE SKELETON VARIABLES - ResetBone(&m_Body, NULL); - m_Body.id = -1; - strcpy(m_Body.name,"Body"); - - ResetBone(&m_UpArm, NULL); - m_UpArm.id = -1; - strcpy(m_UpArm.name,"UpArm"); - m_UpArm.trans.x = 0.7f; - m_UpArm.trans.y = 1.7f; - - ResetBone(&m_LowArm, NULL); - m_LowArm.id = -1; - strcpy(m_LowArm.name,"LowArm"); - m_LowArm.trans.x = 4.0f; - - // SET UP END EFFECTOR - ResetBone(&m_Effector, NULL); - m_Effector.id = -1; - strcpy(m_Effector.name,"Effector"); - m_Effector.trans.x = 3.0f; - -} - -COGLView::~COGLView() -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: UpdateStatus -// Purpose: Update the status bar with orientation info -/////////////////////////////////////////////////////////////////////////////// -void COGLView::UpdateStatus() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - - // WRITE THE ORIENTATIONS OF THE TWO BONES IN THE WINDOW STATUS AREA - sprintf(message,"UpArm Rot (%.2f)", - m_UpArm.rot.z); - m_ptrStatusBar->SetPaneText(1,message); - - sprintf(message,"LowArm Rot (%.2f)", - m_LowArm.rot.z); - m_ptrStatusBar->SetPaneText(2,message); -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ - UpdateStatus(); // DRAW INITIAL STATUS BAR - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(2.0,2.0,2.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - m_Width = width; - m_Height = height; - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // FOR THIS APP, I WANT A 2D Ortho View - gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS -// gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - m_ModelScale = (float)height / 6.0f; - glScalef(m_ModelScale,m_ModelScale,0.0f); - -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - // FOR THIS APP, I WANT A 2D Ortho View - gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS -// gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - // Declare the Array of Data - glInterleavedArrays(UPARMFORMAT,0,(GLvoid *)&UPARM); - // Draw all the Quads at once - glDrawArrays(GL_TRIANGLES,0,UPARMPOLYCNT * 3); - -} -// drawModel - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Body.trans.x, m_Body.trans.y, m_Body.trans.z); - - // ROTATE THE ROOT - glRotatef(m_Body.rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_Body.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Body.rot.x, 1.0f, 0.0f, 0.0f); - - // Declare the Array of Data - glInterleavedArrays(BODYFORMAT,0,(GLvoid *)&BODY); - // Draw all the Quads at once - glDrawArrays(GL_TRIANGLES,0,BODYPOLYCNT * 3); - - - // Set root skeleton's orientation and position - glTranslatef(m_UpArm.trans.x, m_UpArm.trans.y, m_UpArm.trans.z); - - // ROTATE THE ROOT - glRotatef(m_UpArm.rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_UpArm.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_UpArm.rot.x, 1.0f, 0.0f, 0.0f); - - // Declare the Array of Data - glInterleavedArrays(UPARMFORMAT,0,(GLvoid *)&UPARM); - // Draw all the Quads at once - glDrawArrays(GL_TRIANGLES,0,UPARMPOLYCNT * 3); - - // DRAW THE AXIS - glCallList(OGL_AXIS_DLIST); - - // Set root skeleton's orientation and position - glTranslatef(m_LowArm.trans.x, m_LowArm.trans.y, m_LowArm.trans.z); - - // ROTATE THE ROOT - glRotatef(m_LowArm.rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_LowArm.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_LowArm.rot.x, 1.0f, 0.0f, 0.0f); - - // Declare the Array of Data - glInterleavedArrays(LOWARMFORMAT,0,(GLvoid *)&LOWARM); - // Draw all the Quads at once - glDrawArrays(GL_TRIANGLES,0,LOWARMPOLYCNT * 3); - - // DRAW THE AXIS - glCallList(OGL_AXIS_DLIST); - - // Set root skeleton's orientation and position - glTranslatef(m_Effector.trans.x, m_Effector.trans.y, m_Effector.trans.z); - - // DRAW THE AXIS - glCallList(OGL_AXIS_DLIST); - - glPopMatrix(); - glFinish(); - - SwapBuffers(m_hDC); - - // DRAW THE STATS AT THE BOTTOM OF THE SCREEN - UpdateStatus(); -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ -/// Local Variables /////////////////////////////////////////////////////////// - char mess[80]; - float radZ; - CPoint joint1,joint2,effector; -/////////////////////////////////////////////////////////////////////////////// - m_mousepos = point; - - point.y = m_Height - point.y - 1; - - // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM - if ((nFlags & MK_CONTROL) == 0) - { - // COMPUTE THE ROTATIONS NEEDED TO REACH THE POINT - if (ComputeIK(point)) - drawScene(); - else // COULDN'T REACH IT, GIVE AN ERROR - MessageBox("Point is not reachable","ERROR",MB_OK); - } - m_Grab_Rot_X = m_UpArm.rot.x; - m_Grab_Rot_Y = m_UpArm.rot.y; - m_Grab_Rot_Z = m_UpArm.rot.z; - m_Grab_Trans_X = m_UpArm.trans.x; - m_Grab_Trans_Y = m_UpArm.trans.y; - m_Grab_Trans_Z = m_UpArm.trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Grab_Rot_X = m_UpArm.rot.x; - m_Grab_Rot_Y = m_UpArm.rot.y; - m_Grab_Rot_Z = m_UpArm.rot.z; - m_Grab_Trans_X = m_LowArm.trans.x; - m_Grab_Trans_Y = m_LowArm.trans.y; - m_Grab_Trans_Z = m_LowArm.trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case 'G': - m_DrawGeometry = !m_DrawGeometry; - break; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (nFlags & MK_LBUTTON > 0) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_UpArm.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - point.y = m_Height - point.y - 1; - if (ComputeIK(point)) - drawScene(); - } - - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_LowArm.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -double FASTATAN (double z) -{ - // All approximations valid for |z| <= 1. To compute ATAN(z) - // for z > 1, use ATAN(z) = PI/2 - ATAN(1/z). For z < -1, use - // ATAN(z) = -PI/2 - ATAN(1/z). - - // Speed-ups based on executions on an Intel Pentium 90Mhz chip - // running under Microsoft Visual C++ 4.0 with optimization set - // for "maximum speed". Comparison is made to the run-time - // library routine atan(double). - - double z2 = z*z; - double tmp; - -#if 1 - // Polynomial approximation of degree 9, P(z). - // |ATAN(z)-P(z)| <= 1e-05 - // Speed-up is 1.94 - - tmp = 0.0208351; - tmp *= z2; - tmp -= 0.0851330; - tmp *= z2; - tmp += 0.1801410; - tmp *= z2; - tmp -= 0.3302995; - tmp *= z2; - tmp += 0.9998660; - tmp *= z; -#endif - -#if 0 - // Rational approximation, R(z). - // |ATAN(z)-R(z)| <= 5e-03 - // Speed-up is 1.64 - - tmp = z/(1.0+0.28*z2); -#endif - -#if 0 - // Polynomial approximation of degree 16, Q(z) - // |ATAN(z)-Q(z)| <= 2e-08 - // Speed-up is 1.54 - - tmp = 0.0028662257; - tmp *= z2; - tmp -= 0.0161657367; - tmp *= z2; - tmp += 0.0429096138; - tmp *= z2; - tmp -= 0.0752896400; - tmp *= z2; - tmp += 0.1065626393; - tmp *= z2; - tmp -= 0.1420889944; - tmp *= z2; - tmp += 0.1999355085; - tmp *= z2; - tmp -= 0.3333314528; - tmp *= z2; - tmp += 1.0; - tmp *= z; -#endif - - return tmp; -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: ComputeIK -// Purpose: Compute an IK Solution to an end effector position -// Arguments: End Target (x,y) -// Returns: TRUE if a solution exists, FALSE if the position isn't in reach -// Notes: There was a bug in this in the Sept Game Developer source -// for this in the final angle calculation -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::ComputeIK(CPoint endPos) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float l1,l2; // BONE LENGTH FOR BONE 1 AND 2 - float ex,ey; // ADJUSTED TARGET POSITION - float sin2,cos2; // SINE AND COSINE OF ANGLE 2 - float angle1,angle2;// ANGLE 1 AND 2 IN RADIANS - float tan1; // TAN OF ANGLE 1 -/////////////////////////////////////////////////////////////////////////////// - - // SUBTRACT THE INITIAL OFFSET FROM THE TARGET POS - ex = endPos.x - (m_UpArm.trans.x * m_ModelScale); - ey = endPos.y - (m_UpArm.trans.y * m_ModelScale); - - // MULTIPLY THE BONE LENGTHS BY THE WINDOW SCALE - l1 = m_LowArm.trans.x * m_ModelScale; - l2 = m_Effector.trans.x * m_ModelScale; - - // CALCULATE THE COSINE OF ANGLE 2 - cos2 = ((ex * ex) + (ey * ey) - (l1 * l1) - (l2 * l2)) / (2 * l1 * l2); - - // IF IT IS NOT IN THIS RANGE, IT IS UNREACHABLE - if (cos2 >= -1.0 && cos2 <= 1.0) - { - angle2 = (float)acos(cos2); // GET THE ANGLE WITH AN ARCCOSINE - m_LowArm.rot.z = RADTODEG(angle2); // CONVERT IT TO DEGREES - - sin2 = (float)sin(angle2); // CALC THE SINE OF ANGLE 2 - - // COMPUTE ANGLE 1 - // HERE IS WHERE THE BUG WAS SEE THE README.TXT FOR MORE INFO - // CALCULATE THE TAN OF ANGLE 1 - tan1 = (-(l2 * sin2 * ex) + ((l1 + (l2 * cos2)) * ey)) / - ((l2 * sin2 * ey) + ((l1 + (l2 * cos2)) * ex)); - // GET THE ACTUAL ANGLE - angle1 = FASTATAN(tan1); -// angle1 = atan(tan1); - m_UpArm.rot.z = RADTODEG(angle1); // CONVERT IT TO DEGREES - return TRUE; - } - else - return FALSE; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Inverse Kinematics System +// +// Created: +// JL 7/1/98 +// JL 9/20/98 FIXED A BUG IN THE IK CALCULATIONS +// +// Notes: The meat of this application is the last routine in this file. +// "ComputeIK" takes a target point and solves the two bone system. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "math.h" +#include "Kine.h" +#include "OGLView.h" +#include "Quatern.h" +#include "Model.h" // SOFTIMAGE MODEL DATA + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + + // INITIALIZE SOME OF THE SKELETON VARIABLES + ResetBone(&m_Body, NULL); + m_Body.id = -1; + strcpy(m_Body.name,"Body"); + + ResetBone(&m_UpArm, NULL); + m_UpArm.id = -1; + strcpy(m_UpArm.name,"UpArm"); + m_UpArm.trans.x = 0.7f; + m_UpArm.trans.y = 1.7f; + + ResetBone(&m_LowArm, NULL); + m_LowArm.id = -1; + strcpy(m_LowArm.name,"LowArm"); + m_LowArm.trans.x = 4.0f; + + // SET UP END EFFECTOR + ResetBone(&m_Effector, NULL); + m_Effector.id = -1; + strcpy(m_Effector.name,"Effector"); + m_Effector.trans.x = 3.0f; + +} + +COGLView::~COGLView() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: UpdateStatus +// Purpose: Update the status bar with orientation info +/////////////////////////////////////////////////////////////////////////////// +void COGLView::UpdateStatus() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + + // WRITE THE ORIENTATIONS OF THE TWO BONES IN THE WINDOW STATUS AREA + sprintf(message,"UpArm Rot (%.2f)", + m_UpArm.rot.z); + m_ptrStatusBar->SetPaneText(1,message); + + sprintf(message,"LowArm Rot (%.2f)", + m_LowArm.rot.z); + m_ptrStatusBar->SetPaneText(2,message); +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ + UpdateStatus(); // DRAW INITIAL STATUS BAR + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(2.0,2.0,2.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + m_Width = width; + m_Height = height; + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // FOR THIS APP, I WANT A 2D Ortho View + gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS +// gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + m_ModelScale = (float)height / 6.0f; + glScalef(m_ModelScale,m_ModelScale,0.0f); + +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + // FOR THIS APP, I WANT A 2D Ortho View + gluOrtho2D(0.0f,(GLfloat)width,0.0f,(GLfloat)height); // USE WINDOW SETTINGS +// gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + // Declare the Array of Data + glInterleavedArrays(UPARMFORMAT,0,(GLvoid *)&UPARM); + // Draw all the Quads at once + glDrawArrays(GL_TRIANGLES,0,UPARMPOLYCNT * 3); + +} +// drawModel + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Body.trans.x, m_Body.trans.y, m_Body.trans.z); + + // ROTATE THE ROOT + glRotatef(m_Body.rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_Body.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Body.rot.x, 1.0f, 0.0f, 0.0f); + + // Declare the Array of Data + glInterleavedArrays(BODYFORMAT,0,(GLvoid *)&BODY); + // Draw all the Quads at once + glDrawArrays(GL_TRIANGLES,0,BODYPOLYCNT * 3); + + + // Set root skeleton's orientation and position + glTranslatef(m_UpArm.trans.x, m_UpArm.trans.y, m_UpArm.trans.z); + + // ROTATE THE ROOT + glRotatef(m_UpArm.rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_UpArm.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_UpArm.rot.x, 1.0f, 0.0f, 0.0f); + + // Declare the Array of Data + glInterleavedArrays(UPARMFORMAT,0,(GLvoid *)&UPARM); + // Draw all the Quads at once + glDrawArrays(GL_TRIANGLES,0,UPARMPOLYCNT * 3); + + // DRAW THE AXIS + glCallList(OGL_AXIS_DLIST); + + // Set root skeleton's orientation and position + glTranslatef(m_LowArm.trans.x, m_LowArm.trans.y, m_LowArm.trans.z); + + // ROTATE THE ROOT + glRotatef(m_LowArm.rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_LowArm.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_LowArm.rot.x, 1.0f, 0.0f, 0.0f); + + // Declare the Array of Data + glInterleavedArrays(LOWARMFORMAT,0,(GLvoid *)&LOWARM); + // Draw all the Quads at once + glDrawArrays(GL_TRIANGLES,0,LOWARMPOLYCNT * 3); + + // DRAW THE AXIS + glCallList(OGL_AXIS_DLIST); + + // Set root skeleton's orientation and position + glTranslatef(m_Effector.trans.x, m_Effector.trans.y, m_Effector.trans.z); + + // DRAW THE AXIS + glCallList(OGL_AXIS_DLIST); + + glPopMatrix(); + glFinish(); + + SwapBuffers(m_hDC); + + // DRAW THE STATS AT THE BOTTOM OF THE SCREEN + UpdateStatus(); +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ +/// Local Variables /////////////////////////////////////////////////////////// + char mess[80]; + float radZ; + CPoint joint1,joint2,effector; +/////////////////////////////////////////////////////////////////////////////// + m_mousepos = point; + + point.y = m_Height - point.y - 1; + + // IF YOU CLICK ANYWHERE, SOLVE THE SYSTEM + if ((nFlags & MK_CONTROL) == 0) + { + // COMPUTE THE ROTATIONS NEEDED TO REACH THE POINT + if (ComputeIK(point)) + drawScene(); + else // COULDN'T REACH IT, GIVE AN ERROR + MessageBox("Point is not reachable","ERROR",MB_OK); + } + m_Grab_Rot_X = m_UpArm.rot.x; + m_Grab_Rot_Y = m_UpArm.rot.y; + m_Grab_Rot_Z = m_UpArm.rot.z; + m_Grab_Trans_X = m_UpArm.trans.x; + m_Grab_Trans_Y = m_UpArm.trans.y; + m_Grab_Trans_Z = m_UpArm.trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Grab_Rot_X = m_UpArm.rot.x; + m_Grab_Rot_Y = m_UpArm.rot.y; + m_Grab_Rot_Z = m_UpArm.rot.z; + m_Grab_Trans_X = m_LowArm.trans.x; + m_Grab_Trans_Y = m_LowArm.trans.y; + m_Grab_Trans_Z = m_LowArm.trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case 'G': + m_DrawGeometry = !m_DrawGeometry; + break; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (nFlags & MK_LBUTTON > 0) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_UpArm.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + point.y = m_Height - point.y - 1; + if (ComputeIK(point)) + drawScene(); + } + + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_LowArm.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +double FASTATAN (double z) +{ + // All approximations valid for |z| <= 1. To compute ATAN(z) + // for z > 1, use ATAN(z) = PI/2 - ATAN(1/z). For z < -1, use + // ATAN(z) = -PI/2 - ATAN(1/z). + + // Speed-ups based on executions on an Intel Pentium 90Mhz chip + // running under Microsoft Visual C++ 4.0 with optimization set + // for "maximum speed". Comparison is made to the run-time + // library routine atan(double). + + double z2 = z*z; + double tmp; + +#if 1 + // Polynomial approximation of degree 9, P(z). + // |ATAN(z)-P(z)| <= 1e-05 + // Speed-up is 1.94 + + tmp = 0.0208351; + tmp *= z2; + tmp -= 0.0851330; + tmp *= z2; + tmp += 0.1801410; + tmp *= z2; + tmp -= 0.3302995; + tmp *= z2; + tmp += 0.9998660; + tmp *= z; +#endif + +#if 0 + // Rational approximation, R(z). + // |ATAN(z)-R(z)| <= 5e-03 + // Speed-up is 1.64 + + tmp = z/(1.0+0.28*z2); +#endif + +#if 0 + // Polynomial approximation of degree 16, Q(z) + // |ATAN(z)-Q(z)| <= 2e-08 + // Speed-up is 1.54 + + tmp = 0.0028662257; + tmp *= z2; + tmp -= 0.0161657367; + tmp *= z2; + tmp += 0.0429096138; + tmp *= z2; + tmp -= 0.0752896400; + tmp *= z2; + tmp += 0.1065626393; + tmp *= z2; + tmp -= 0.1420889944; + tmp *= z2; + tmp += 0.1999355085; + tmp *= z2; + tmp -= 0.3333314528; + tmp *= z2; + tmp += 1.0; + tmp *= z; +#endif + + return tmp; +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: ComputeIK +// Purpose: Compute an IK Solution to an end effector position +// Arguments: End Target (x,y) +// Returns: TRUE if a solution exists, FALSE if the position isn't in reach +// Notes: There was a bug in this in the Sept Game Developer source +// for this in the final angle calculation +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::ComputeIK(CPoint endPos) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float l1,l2; // BONE LENGTH FOR BONE 1 AND 2 + float ex,ey; // ADJUSTED TARGET POSITION + float sin2,cos2; // SINE AND COSINE OF ANGLE 2 + float angle1,angle2;// ANGLE 1 AND 2 IN RADIANS + float tan1; // TAN OF ANGLE 1 +/////////////////////////////////////////////////////////////////////////////// + + // SUBTRACT THE INITIAL OFFSET FROM THE TARGET POS + ex = endPos.x - (m_UpArm.trans.x * m_ModelScale); + ey = endPos.y - (m_UpArm.trans.y * m_ModelScale); + + // MULTIPLY THE BONE LENGTHS BY THE WINDOW SCALE + l1 = m_LowArm.trans.x * m_ModelScale; + l2 = m_Effector.trans.x * m_ModelScale; + + // CALCULATE THE COSINE OF ANGLE 2 + cos2 = ((ex * ex) + (ey * ey) - (l1 * l1) - (l2 * l2)) / (2 * l1 * l2); + + // IF IT IS NOT IN THIS RANGE, IT IS UNREACHABLE + if (cos2 >= -1.0 && cos2 <= 1.0) + { + angle2 = (float)acos(cos2); // GET THE ANGLE WITH AN ARCCOSINE + m_LowArm.rot.z = RADTODEG(angle2); // CONVERT IT TO DEGREES + + sin2 = (float)sin(angle2); // CALC THE SINE OF ANGLE 2 + + // COMPUTE ANGLE 1 + // HERE IS WHERE THE BUG WAS SEE THE README.TXT FOR MORE INFO + // CALCULATE THE TAN OF ANGLE 1 + tan1 = (-(l2 * sin2 * ex) + ((l1 + (l2 * cos2)) * ey)) / + ((l2 * sin2 * ey) + ((l1 + (l2 * cos2)) * ex)); + // GET THE ACTUAL ANGLE + angle1 = FASTATAN(tan1); +// angle1 = atan(tan1); + m_UpArm.rot.z = RADTODEG(angle1); // CONVERT IT TO DEGREES + return TRUE; + } + else + return FALSE; +} + diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.h index b899f35..3b5aee5 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/OGLView.h @@ -1,97 +1,97 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Inverse Kinematic System -// -// Created: -// JL 7/1/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry; - BOOL m_UseQuat; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - BOOL ComputeIK(CPoint endPos); - void GetGLInfo(); - void UpdateStatus(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Body,m_UpArm,m_LowArm,m_Effector; - float m_ModelScale; - int m_Width,m_Height; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Inverse Kinematic System +// +// Created: +// JL 7/1/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry; + BOOL m_UseQuat; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + BOOL ComputeIK(CPoint endPos); + void GetGLInfo(); + void UpdateStatus(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Body,m_UpArm,m_LowArm,m_Effector; + float m_ModelScale; + int m_Width,m_Height; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.cpp b/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.cpp index 4b9de36..8c437a3 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.cpp +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.cpp @@ -1,365 +1,365 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.cpp : Quaternion System structure implementation file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY -// -// Created: -// JL 9/1/97 -// -// Sources: -// Shoemake, Ken, "Animating Rotations with Quaternion Curves" -// Computer Graphics 85, pp. 245-254 -// Watt and Watt, Advanced Animation and Rendering Techniques -// Addison Wesley, pp. 360-368 -// Shoemake, Graphic Gems II. -// -// Notes: -// There are a couple of methods of conversion here so it -// can be played around with a bit. One is more clear and the other -// is a bit faster. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include "skeleton.h" -#include "quatern.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: CopyVector -// Purpose: Copy a vector -// Arguments: pointer to destination and source -/////////////////////////////////////////////////////////////////////////////// -void CopyVector(tVector *dest, tVector *src) -{ - dest->x = src->x; - dest->y = src->y; - dest->z = src->z; -} -//// CopyVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ScaleVector -// Purpose: Scale a vector -// Arguments: pointer to vector and scale factor -/////////////////////////////////////////////////////////////////////////////// -void ScaleVector(tVector *vect, float scale) -{ - vect->x *= scale; - vect->y *= scale; - vect->z *= scale; -} -//// ScaleVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: AddVectors -// Purpose: Add two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - dest->x = vect1->x + vect2->x; - dest->y = vect1->y + vect2->y; - dest->z = vect1->z + vect2->z; -} -//// AddVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DotVectors -// Purpose: Compute the dot product of two vectors -// Arguments: pointer to vectors -// Returns: Dot product -/////////////////////////////////////////////////////////////////////////////// -float DotVectors(tVector *vect1, tVector *vect2) -{ - return (vect1->x * vect2->x) + - (vect1->y * vect2->y) + - (vect1->z * vect2->z); -} -//// DotVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossVectors -// Purpose: Computes the cross product of two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - // COMPUTE THE CROSS PRODUCT - dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); - dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); - dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); -} -//// CrossVectors ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion v1,v2,v3,vf; -/////////////////////////////////////////////////////////////////////////////// - - CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); - - AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); - AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); - - vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); - - dest->x = vf.x; - dest->y = vf.y; - dest->z = vf.z; - dest->w = vf.w; -} -//// MultQuaternions ////////////////////////////////////////////////////////// - -/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR - I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY - THE MATH CHECKS OUT THOUGH */ -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions2 -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ - tQuaternion tmp; - tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + - quat2->y * quat1->z - quat2->z * quat1->y; - tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + - quat2->z * quat1->x - quat2->x * quat1->z; - tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + - quat2->x * quat1->y - quat2->y * quat1->x; - tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - - quat2->y * quat1->y - quat2->z * quat1->z; - dest->x = tmp.x; dest->y = tmp.y; - dest->z = tmp.z; dest->w = tmp.w; -} -//// MultQuaternions2 ////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeQuaternion -// Purpose: Normalize a Quaternion -// Arguments: a quaternion to set -// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 -// This function insures this -/////////////////////////////////////////////////////////////////////////////// -void NormalizeQuaternion(tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float magnitude; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, FIND THE MAGNITUDE - magnitude = (quat->x * quat->x) + - (quat->y * quat->y) + - (quat->z * quat->z) + - (quat->w * quat->w); - - // DIVIDE BY THE MAGNITUDE TO NORMALIZE - quat->x = quat->x / magnitude; - quat->y = quat->y / magnitude; - quat->z = quat->z / magnitude; - quat->w = quat->w / magnitude; -} -// NormalizeQuaternion /////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT -// A SERIES OF ROTATIONS TO QUATERNIONS. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted. It is more efficient this way though. -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - tx = rx * (float)0.5; - ty = ry * (float)0.5; - tz = rz * (float)0.5; - cx = (float)cos(tx); - cy = (float)cos(ty); - cz = (float)cos(tz); - sx = (float)sin(tx); - sy = (float)sin(ty); - sz = (float)sin(tz); - - cc = cx * cz; - cs = cx * sz; - sc = sx * cz; - ss = sx * sz; - - quat->x = (cy * sc) - (sy * cs); - quat->y = (cy * ss) + (sy * cc); - quat->z = (cy * cs) - (sy * sc); - quat->w = (cy * cc) + (sy * ss); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(quat); -} -// EulerToQuaternion ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: This is a second variation. It creates a -// Series of quaternions and multiplies them together -// It would be easier to extend this for other rotation orders -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,ti,tj,tk; - tQuaternion qx,qy,qz,qf; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - ti = rx * (float)0.5; - tj = ry * (float)0.5; - tk = rz * (float)0.5; - - qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); - qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); - qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); - - MultQuaternions(&qx,&qy,&qf); - MultQuaternions(&qf,&qz,&qf); - -// ANOTHER TEST VARIATION -// MultQuaternions2(&qx,&qy,&qf); -// MultQuaternions2(&qf,&qz,&qf); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(&qf); - - quat->x = qf.x; - quat->y = qf.y; - quat->z = qf.z; - quat->w = qf.w; - -} -// EulerToQuaternion2 ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float scale,tw; -/////////////////////////////////////////////////////////////////////////////// - tw = (float)acos(quat->w) * 2; - scale = (float)sin(tw / 2.0); - axisAngle->x = quat->x / scale; - axisAngle->y = quat->y / scale; - axisAngle->z = quat->z / scale; - - // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES - axisAngle->w = (tw * (360 / 2)) / (float)M_PI; -} -// QuatToAxisAngle ///////////////////////////////////////////////////////// - -// THIS ROUTINE IS REALLY FOR THE APRIL ARTICLE BUT IF YOU WANT TO PLAY -// AROUND WITH IT, HERE IT IS. - -#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -// Notes: The comments explain the handling of the special cases. -// The comments in the magazine were wrong. Adjust the -// DELTA constant to play with the LERP vs. SLERP level -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // CHECK A COUPLE OF SPECIAL CASES. - // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) - if ((1.0 + cosom) > DELTA) - { - // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT - if ((1.0 - cosom) > DELTA) { - // YES, DO A SLERP - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1.0 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - // NOT A VERY BIG DIFFERENCE, DO A LERP - scale0 = 1.0 - slerp; - scale1 = slerp; - } - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; - } else { - // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR - // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION - result->x = -quat2->y; - result->y = quat2->x; - result->z = -quat2->w; - result->w = quat2->z; - scale0 = sin((1.0 - slerp) * (float)HALF_PI); - scale1 = sin(slerp * (float)HALF_PI); - result->x = scale0 * quat1->x + scale1 * result->x; - result->y = scale0 * quat1->y + scale1 * result->y; - result->z = scale0 * quat1->z + scale1 * result->z; - result->w = scale0 * quat1->w + scale1 * result->w; - } - -} -// SlerpQuat ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.cpp : Quaternion System structure implementation file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY +// +// Created: +// JL 9/1/97 +// +// Sources: +// Shoemake, Ken, "Animating Rotations with Quaternion Curves" +// Computer Graphics 85, pp. 245-254 +// Watt and Watt, Advanced Animation and Rendering Techniques +// Addison Wesley, pp. 360-368 +// Shoemake, Graphic Gems II. +// +// Notes: +// There are a couple of methods of conversion here so it +// can be played around with a bit. One is more clear and the other +// is a bit faster. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include "skeleton.h" +#include "quatern.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: CopyVector +// Purpose: Copy a vector +// Arguments: pointer to destination and source +/////////////////////////////////////////////////////////////////////////////// +void CopyVector(tVector *dest, tVector *src) +{ + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} +//// CopyVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ScaleVector +// Purpose: Scale a vector +// Arguments: pointer to vector and scale factor +/////////////////////////////////////////////////////////////////////////////// +void ScaleVector(tVector *vect, float scale) +{ + vect->x *= scale; + vect->y *= scale; + vect->z *= scale; +} +//// ScaleVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: AddVectors +// Purpose: Add two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + dest->x = vect1->x + vect2->x; + dest->y = vect1->y + vect2->y; + dest->z = vect1->z + vect2->z; +} +//// AddVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DotVectors +// Purpose: Compute the dot product of two vectors +// Arguments: pointer to vectors +// Returns: Dot product +/////////////////////////////////////////////////////////////////////////////// +float DotVectors(tVector *vect1, tVector *vect2) +{ + return (vect1->x * vect2->x) + + (vect1->y * vect2->y) + + (vect1->z * vect2->z); +} +//// DotVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossVectors +// Purpose: Computes the cross product of two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + // COMPUTE THE CROSS PRODUCT + dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); + dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); + dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); +} +//// CrossVectors ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion v1,v2,v3,vf; +/////////////////////////////////////////////////////////////////////////////// + + CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); + + AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); + AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); + + vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); + + dest->x = vf.x; + dest->y = vf.y; + dest->z = vf.z; + dest->w = vf.w; +} +//// MultQuaternions ////////////////////////////////////////////////////////// + +/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR + I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY + THE MATH CHECKS OUT THOUGH */ +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions2 +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ + tQuaternion tmp; + tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + + quat2->y * quat1->z - quat2->z * quat1->y; + tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + + quat2->z * quat1->x - quat2->x * quat1->z; + tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + + quat2->x * quat1->y - quat2->y * quat1->x; + tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - + quat2->y * quat1->y - quat2->z * quat1->z; + dest->x = tmp.x; dest->y = tmp.y; + dest->z = tmp.z; dest->w = tmp.w; +} +//// MultQuaternions2 ////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeQuaternion +// Purpose: Normalize a Quaternion +// Arguments: a quaternion to set +// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 +// This function insures this +/////////////////////////////////////////////////////////////////////////////// +void NormalizeQuaternion(tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float magnitude; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, FIND THE MAGNITUDE + magnitude = (quat->x * quat->x) + + (quat->y * quat->y) + + (quat->z * quat->z) + + (quat->w * quat->w); + + // DIVIDE BY THE MAGNITUDE TO NORMALIZE + quat->x = quat->x / magnitude; + quat->y = quat->y / magnitude; + quat->z = quat->z / magnitude; + quat->w = quat->w / magnitude; +} +// NormalizeQuaternion /////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT +// A SERIES OF ROTATIONS TO QUATERNIONS. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted. It is more efficient this way though. +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + tx = rx * (float)0.5; + ty = ry * (float)0.5; + tz = rz * (float)0.5; + cx = (float)cos(tx); + cy = (float)cos(ty); + cz = (float)cos(tz); + sx = (float)sin(tx); + sy = (float)sin(ty); + sz = (float)sin(tz); + + cc = cx * cz; + cs = cx * sz; + sc = sx * cz; + ss = sx * sz; + + quat->x = (cy * sc) - (sy * cs); + quat->y = (cy * ss) + (sy * cc); + quat->z = (cy * cs) - (sy * sc); + quat->w = (cy * cc) + (sy * ss); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(quat); +} +// EulerToQuaternion ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: This is a second variation. It creates a +// Series of quaternions and multiplies them together +// It would be easier to extend this for other rotation orders +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,ti,tj,tk; + tQuaternion qx,qy,qz,qf; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + ti = rx * (float)0.5; + tj = ry * (float)0.5; + tk = rz * (float)0.5; + + qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); + qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); + qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); + + MultQuaternions(&qx,&qy,&qf); + MultQuaternions(&qf,&qz,&qf); + +// ANOTHER TEST VARIATION +// MultQuaternions2(&qx,&qy,&qf); +// MultQuaternions2(&qf,&qz,&qf); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(&qf); + + quat->x = qf.x; + quat->y = qf.y; + quat->z = qf.z; + quat->w = qf.w; + +} +// EulerToQuaternion2 ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float scale,tw; +/////////////////////////////////////////////////////////////////////////////// + tw = (float)acos(quat->w) * 2; + scale = (float)sin(tw / 2.0); + axisAngle->x = quat->x / scale; + axisAngle->y = quat->y / scale; + axisAngle->z = quat->z / scale; + + // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES + axisAngle->w = (tw * (360 / 2)) / (float)M_PI; +} +// QuatToAxisAngle ///////////////////////////////////////////////////////// + +// THIS ROUTINE IS REALLY FOR THE APRIL ARTICLE BUT IF YOU WANT TO PLAY +// AROUND WITH IT, HERE IT IS. + +#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +// Notes: The comments explain the handling of the special cases. +// The comments in the magazine were wrong. Adjust the +// DELTA constant to play with the LERP vs. SLERP level +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // CHECK A COUPLE OF SPECIAL CASES. + // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) + if ((1.0 + cosom) > DELTA) + { + // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT + if ((1.0 - cosom) > DELTA) { + // YES, DO A SLERP + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1.0 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + // NOT A VERY BIG DIFFERENCE, DO A LERP + scale0 = 1.0 - slerp; + scale1 = slerp; + } + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; + } else { + // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR + // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION + result->x = -quat2->y; + result->y = quat2->x; + result->z = -quat2->w; + result->w = quat2->z; + scale0 = sin((1.0 - slerp) * (float)HALF_PI); + scale1 = sin(slerp * (float)HALF_PI); + result->x = scale0 * quat1->x + scale1 * result->x; + result->y = scale0 * quat1->y + scale1 * result->y; + result->z = scale0 * quat1->z + scale1 * result->z; + result->w = scale0 * quat1->w + scale1 * result->w; + } + +} +// SlerpQuat ///////////////////////////////////////////////////////////////// diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.h index e48f890..96189ae 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Quatern.h @@ -1,68 +1,68 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.h : Quaternion System structure definition file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(QUATERN_H__INCLUDED_) -#define QUATERN_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; - -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); - -#endif // !defined(QUATERN_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.h : Quaternion System structure definition file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(QUATERN_H__INCLUDED_) +#define QUATERN_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; + +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); + +#endif // !defined(QUATERN_H__INCLUDED_) diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/RESOURCE.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/RESOURCE.h index 361541c..239420c 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/RESOURCE.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/RESOURCE.h @@ -1,31 +1,31 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Kine.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDD_SETROTATE 130 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_ZAXIS 1002 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_LOWROT 59144 -#define ID_INDICATOR_STATUS 59145 -#define ID_INDICATOR_UPROT 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32775 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Kine.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDD_SETROTATE 130 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_ZAXIS 1002 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_LOWROT 59144 +#define ID_INDICATOR_STATUS 59145 +#define ID_INDICATOR_UPROT 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 131 +#define _APS_NEXT_COMMAND_VALUE 32775 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/ReadMe.txt b/Oh my God, I inverted Kine!/Code/OGL/Kine/ReadMe.txt index 288dd52..68dc659 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/ReadMe.txt +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/ReadMe.txt @@ -1,122 +1,122 @@ -Inverse Kinematics in OpenGL Demonstration Program July 1, 1998 ----------------------------------------------------------------- -v. 1.1 Sept 20, 1998 - -There were a couple of typos in the magazine. -Eq.1 should have been a Point P2. There was also an error -in Equation 6. It should have reflected the equation in the code - - y(L2 cos(O2) + L1) - x(L2 sin(O2)) -O1 = ----------------------------------- - x(L2 cos(O2) + L1) + y(L2 sin(O2)) - -However, Eran Gottlieb sent me a message saying that the source -in the Watt & Watt Advanced Animation book had an error. -The result should have been the tan(O1). As in: - - b(L2 cos(O2) + L1) - a(L2 sin(O2)) -O1 = atan ---------------------------------- - a(L2 cos(O2) + L1) + b(L2 sin(O2)) - -Eran offered a pretty long algebraic proof but we can work out -an easier geometric proof of this also. - -I am working from my Figure 4 in the article. - -tan(O4) = L2 sin(O2) / L2 cos(O2) + L1 - -tan(O3) = b/a - -O1 = O3 - O4 - -Using the Tan identity - -tan(O3 - O4) = tan(O3) - tan (O4) / (1 + tan(O3)tan(O4) - - (b/a) - (L2 sin(O2) / (L2 cos(O2) + L1) -tan(O1) = ----------------------------------------- - 1 + (b/a)((L2 sin(O2) / (L2 cos(O2) + L1)) - -Multiply out the a - - b - a((L2 sin(O2) / (L2 cos(O2) + L1)) -tan(O1) = -------------------------------------- - a + b((L2 sin(O2) / (L2 cos(O2) + L1)) - -Multiply out the tan(O4) - - b(L2 cos(O2) + L1) - a(L2 sin(O2)) -tan(O1) = -------------------------------------- - a(L2 cos(O2) + L1) + b(L2 sin(O2)) - - - b(L2 cos(O2) + L1) - a(L2 sin(O2)) -O1 = atan -------------------------------------- - a(L2 cos(O2) + L1) + b(L2 sin(O2)) - - -What was most interesting to me was that my application seemed to -work. There is a very easy reason why. It turns out that we were -working in radians. If you compare the radian graph to the tan graph -you will see that for angle from -30 to 30 degrees or so, the values -are almost equivalent. - -Since my application by the shear restrictions of the screen never -really showed the problem with the approximation. You could see -the points diverge as the hand reached the bottom of the screen a bit. - -This brings up an interesting optimization. You can skip the ATAN under -certain circumstances. Because of the repeating nature of TAN it would be -something like if you joint has a DOF restriction that it stays in the -range of 0-90 degrees. When the value of tan(O1) is < 0.5 then use that -value directly and skip the ATAN call. Similar steps can be used in -other quadrants. - -Thanks to Eran Gottlieb for pointing this out. I am continually impressed -by the amount I am learning from the readers of Game Developer. - -Also, thanks to Alan Watt for confirming the problem in the book. - - ----------------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the September 98 -Game Developer magazine. It is meant as a demonstration of -an analytical 2D inverse kinematics solution. The main function -is in OGLView.cpp at the very bottom. The function is called -"ComputeIK" and it takes a point on the screen for the articulated -arm to try and reach. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm July 1, 1998 ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128, Riva TNT, and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -There are instructions in the Help/About dialog. - -It also has an example of working with Vertex Arrays as well as -Display Lists. I have been playing around with different variations -of interleaved arrays and found this a pretty good way to do things. - -Have some fun. - +Inverse Kinematics in OpenGL Demonstration Program July 1, 1998 +---------------------------------------------------------------- +v. 1.1 Sept 20, 1998 + +There were a couple of typos in the magazine. +Eq.1 should have been a Point P2. There was also an error +in Equation 6. It should have reflected the equation in the code + + y(L2 cos(O2) + L1) - x(L2 sin(O2)) +O1 = ----------------------------------- + x(L2 cos(O2) + L1) + y(L2 sin(O2)) + +However, Eran Gottlieb sent me a message saying that the source +in the Watt & Watt Advanced Animation book had an error. +The result should have been the tan(O1). As in: + + b(L2 cos(O2) + L1) - a(L2 sin(O2)) +O1 = atan ---------------------------------- + a(L2 cos(O2) + L1) + b(L2 sin(O2)) + +Eran offered a pretty long algebraic proof but we can work out +an easier geometric proof of this also. + +I am working from my Figure 4 in the article. + +tan(O4) = L2 sin(O2) / L2 cos(O2) + L1 + +tan(O3) = b/a + +O1 = O3 - O4 + +Using the Tan identity + +tan(O3 - O4) = tan(O3) - tan (O4) / (1 + tan(O3)tan(O4) + + (b/a) - (L2 sin(O2) / (L2 cos(O2) + L1) +tan(O1) = ----------------------------------------- + 1 + (b/a)((L2 sin(O2) / (L2 cos(O2) + L1)) + +Multiply out the a + + b - a((L2 sin(O2) / (L2 cos(O2) + L1)) +tan(O1) = -------------------------------------- + a + b((L2 sin(O2) / (L2 cos(O2) + L1)) + +Multiply out the tan(O4) + + b(L2 cos(O2) + L1) - a(L2 sin(O2)) +tan(O1) = -------------------------------------- + a(L2 cos(O2) + L1) + b(L2 sin(O2)) + + + b(L2 cos(O2) + L1) - a(L2 sin(O2)) +O1 = atan -------------------------------------- + a(L2 cos(O2) + L1) + b(L2 sin(O2)) + + +What was most interesting to me was that my application seemed to +work. There is a very easy reason why. It turns out that we were +working in radians. If you compare the radian graph to the tan graph +you will see that for angle from -30 to 30 degrees or so, the values +are almost equivalent. + +Since my application by the shear restrictions of the screen never +really showed the problem with the approximation. You could see +the points diverge as the hand reached the bottom of the screen a bit. + +This brings up an interesting optimization. You can skip the ATAN under +certain circumstances. Because of the repeating nature of TAN it would be +something like if you joint has a DOF restriction that it stays in the +range of 0-90 degrees. When the value of tan(O1) is < 0.5 then use that +value directly and skip the ATAN call. Similar steps can be used in +other quadrants. + +Thanks to Eran Gottlieb for pointing this out. I am continually impressed +by the amount I am learning from the readers of Game Developer. + +Also, thanks to Alan Watt for confirming the problem in the book. + + +---------------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the September 98 +Game Developer magazine. It is meant as a demonstration of +an analytical 2D inverse kinematics solution. The main function +is in OGLView.cpp at the very bottom. The function is called +"ComputeIK" and it takes a point on the screen for the articulated +arm to try and reach. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm July 1, 1998 +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128, Riva TNT, and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +There are instructions in the Help/About dialog. + +It also has an example of working with Vertex Arrays as well as +Display Lists. I have been playing around with different variations +of interleaved arrays and found this a pretty good way to do things. + +Have some fun. + Jeff \ No newline at end of file diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.cpp b/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.cpp index 562f27a..a75a9c7 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.cpp +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.cpp @@ -1,152 +1,152 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.h index 1a687b3..3cc2f8c 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/Skeleton.h @@ -1,138 +1,138 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -typedef struct -{ - float x,y,z; -} tVector; - -#include "Quatern.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - long *visuals; // POINTER TO VISUALS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +typedef struct +{ + float x,y,z; +} tVector; + +#include "Quatern.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + long *visuals; // POINTER TO VISUALS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.cpp b/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.cpp index 32d5921..f80f8c9 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.cpp +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Kine.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Kine.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.h b/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.h index ddefdab..571c76c 100644 --- a/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.h +++ b/Oh my God, I inverted Kine!/Code/OGL/Kine/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.cpp index 144fb4e..29c273c 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.cpp @@ -1,376 +1,376 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = (float)atof(words.GetAt(1)); - visual->Ka.g = (float)atof(words.GetAt(2)); - visual->Ka.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = (float)atof(words.GetAt(1)); - visual->Kd.g = (float)atof(words.GetAt(2)); - visual->Kd.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = (float)atof(words.GetAt(1)); - visual->Ks.g = (float)atof(words.GetAt(2)); - visual->Ks.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = (float)atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle anything other than -// 3-4 vertex polygons. -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loopcnt; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - loopcnt = words->GetSize(); - - // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < loopcnt; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } - face->flags = 0; - if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; - if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; - if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; - else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; - else - { - ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); - face->flags |= FACE_TYPE_TRI; - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone, flags of what to load -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; - unsigned short *indexData; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = (float)atof(words.GetAt(1)); - normal[nPos].y = (float)atof(words.GetAt(2)); - normal[nPos].z = (float)atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = (float)atof(words.GetAt(1)); - texture[tPos].v = (float)atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = (float)atof(words.GetAt(1)); - vertex[vPos].y = (float)atof(words.GetAt(2)); - vertex[vPos].z = (float)atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 5) - { - sprintf(buffer,"Face %d has more than 4 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS - // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF - // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER - if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; - else visual->vPerFace = 4; - - if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - } - visual->faceCnt = fPos; - if ((flags & LOADOBJ_REUSEVERTICES) > 0) - { - visual->reuseVertices = TRUE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); - visual->vertexCnt = vPos; - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); - if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA - { - memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); - } - else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS - { - visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT - } - } - else - { - visual->reuseVertices = FALSE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->vertexCnt = fPos * visual->vPerFace; - visual->faceIndex = NULL; - } - - data = visual->vertexData; - indexData = visual->faceIndex; - for (loop = 0; loop < fPos; loop++) - { - // ERROR CHECKING TO MAKE SURE - if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - - for (loop2 = 0; loop2 < visual->vPerFace; loop2++) - { - // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT - if ((flags & LOADOBJ_REUSEVERTICES) == 0) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - } - else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE - { - *indexData++ = face[loop].v[loop2] - 1; - } - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = (float)atof(words.GetAt(1)); + visual->Ka.g = (float)atof(words.GetAt(2)); + visual->Ka.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = (float)atof(words.GetAt(1)); + visual->Kd.g = (float)atof(words.GetAt(2)); + visual->Kd.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = (float)atof(words.GetAt(1)); + visual->Ks.g = (float)atof(words.GetAt(2)); + visual->Ks.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = (float)atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle anything other than +// 3-4 vertex polygons. +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loopcnt; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + loopcnt = words->GetSize(); + + // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < loopcnt; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } + face->flags = 0; + if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; + if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; + if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; + else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; + else + { + ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); + face->flags |= FACE_TYPE_TRI; + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone, flags of what to load +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; + unsigned short *indexData; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = (float)atof(words.GetAt(1)); + normal[nPos].y = (float)atof(words.GetAt(2)); + normal[nPos].z = (float)atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = (float)atof(words.GetAt(1)); + texture[tPos].v = (float)atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = (float)atof(words.GetAt(1)); + vertex[vPos].y = (float)atof(words.GetAt(2)); + vertex[vPos].z = (float)atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 5) + { + sprintf(buffer,"Face %d has more than 4 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS + // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF + // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER + if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; + else visual->vPerFace = 4; + + if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + } + visual->faceCnt = fPos; + if ((flags & LOADOBJ_REUSEVERTICES) > 0) + { + visual->reuseVertices = TRUE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); + visual->vertexCnt = vPos; + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); + if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA + { + memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); + } + else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS + { + visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT + } + } + else + { + visual->reuseVertices = FALSE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->vertexCnt = fPos * visual->vPerFace; + visual->faceIndex = NULL; + } + + data = visual->vertexData; + indexData = visual->faceIndex; + for (loop = 0; loop < fPos; loop++) + { + // ERROR CHECKING TO MAKE SURE + if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + + for (loop2 = 0; loop2 < visual->vPerFace; loop2++) + { + // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT + if ((flags & LOADOBJ_REUSEVERTICES) == 0) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + } + else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE + { + *indexData++ = face[loop].v[loop2] - 1; + } + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.h index 2b75bb3..8184168 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/LoadOBJ.h @@ -1,46 +1,46 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -enum LOAD_OBJFLAGS -{ - LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO - LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA - LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS -}; - -// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS -typedef struct -{ - long v[4],n[4],t[4]; - int flags; // FACE TYPES -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +enum LOAD_OBJFLAGS +{ + LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO + LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA + LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS +}; + +// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS +typedef struct +{ + long v[4],n[4],t[4]; + int flags; // FACE TYPES +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.cpp index ff96540..72f5ef1 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.cpp @@ -1,369 +1,369 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Squashy.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) - ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) - ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) - ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) - ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) - ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) - ON_WM_CLOSE() - ON_COMMAND(ID_SIMULATION_SETVERTEXMASS, OnSimulationSetvertexmass) - ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) - ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) - ON_COMMAND(ID_INTEGRATOR_EULER, OnIntegratorEuler) - ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_EULER, OnUpdateIntegratorEuler) - ON_COMMAND(ID_INTEGRATOR_MIDPOINT, OnIntegratorMidpoint) - ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_MIDPOINT, OnUpdateIntegratorMidpoint) - ON_COMMAND(ID_INTEGRATOR_RUNGEKUTTA4, OnIntegratorRungekutta4) - ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_RUNGEKUTTA4, OnUpdateIntegratorRungekutta4) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom - - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case ' ': - break; - } - m_OGLView.HandleKeyUp(nChar); -// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -} - - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - - -void CMainFrame::OnFileNewsystem() -{ - m_OGLView.NewSystem(); -} - -void CMainFrame::OnFileOpen() -{ - char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnFileSave() -{ - char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnSimulationRunning() -{ - m_OGLView.HandleKeyUp('R'); // FORCE SYSTEM TO START RUNNING THROUGH KEYPRESS -} - -void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_SimRunning ); -} - -void CMainFrame::OnSimulationReset() -{ - m_OGLView.m_PhysEnv.ResetWorld(); - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnSimulationSetsimproperties() -{ - m_OGLView.OnSimulationSetsimproperties(); -} - -void CMainFrame::OnSimulationSettimingproperties() -{ - m_OGLView.OnSetTimeProperties(); -} - -void CMainFrame::OnSimulationSetvertexmass() -{ - m_OGLView.OnSimulationSetVertexMass(); -} - -void CMainFrame::OnSimulationUsegravity() -{ - m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); -} - - -void CMainFrame::OnViewShowgeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnViewShowsprings() -{ - m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); -} - -void CMainFrame::OnViewShowvertices() -{ - m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); -} - -void CMainFrame::OnClose() -{ - m_OGLView.m_SimRunning = FALSE; - - CFrameWnd::OnClose(); -} - -BOOL CMainFrame::DestroyWindow() -{ - - return CFrameWnd::DestroyWindow(); -} - -void CMainFrame::OnIntegratorEuler() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = EULER_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntegratorEuler(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == EULER_INTEGRATOR ); -} - -void CMainFrame::OnIntegratorMidpoint() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = MIDPOINT_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == MIDPOINT_INTEGRATOR ); -} - -void CMainFrame::OnIntegratorRungekutta4() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = RK4_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == RK4_INTEGRATOR ); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Squashy.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) + ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) + ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) + ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) + ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) + ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) + ON_WM_CLOSE() + ON_COMMAND(ID_SIMULATION_SETVERTEXMASS, OnSimulationSetvertexmass) + ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) + ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) + ON_COMMAND(ID_INTEGRATOR_EULER, OnIntegratorEuler) + ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_EULER, OnUpdateIntegratorEuler) + ON_COMMAND(ID_INTEGRATOR_MIDPOINT, OnIntegratorMidpoint) + ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_MIDPOINT, OnUpdateIntegratorMidpoint) + ON_COMMAND(ID_INTEGRATOR_RUNGEKUTTA4, OnIntegratorRungekutta4) + ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_RUNGEKUTTA4, OnUpdateIntegratorRungekutta4) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom + + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case ' ': + break; + } + m_OGLView.HandleKeyUp(nChar); +// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +} + + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + + +void CMainFrame::OnFileNewsystem() +{ + m_OGLView.NewSystem(); +} + +void CMainFrame::OnFileOpen() +{ + char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnFileSave() +{ + char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnSimulationRunning() +{ + m_OGLView.HandleKeyUp('R'); // FORCE SYSTEM TO START RUNNING THROUGH KEYPRESS +} + +void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_SimRunning ); +} + +void CMainFrame::OnSimulationReset() +{ + m_OGLView.m_PhysEnv.ResetWorld(); + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnSimulationSetsimproperties() +{ + m_OGLView.OnSimulationSetsimproperties(); +} + +void CMainFrame::OnSimulationSettimingproperties() +{ + m_OGLView.OnSetTimeProperties(); +} + +void CMainFrame::OnSimulationSetvertexmass() +{ + m_OGLView.OnSimulationSetVertexMass(); +} + +void CMainFrame::OnSimulationUsegravity() +{ + m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); +} + + +void CMainFrame::OnViewShowgeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnViewShowsprings() +{ + m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); +} + +void CMainFrame::OnViewShowvertices() +{ + m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); +} + +void CMainFrame::OnClose() +{ + m_OGLView.m_SimRunning = FALSE; + + CFrameWnd::OnClose(); +} + +BOOL CMainFrame::DestroyWindow() +{ + + return CFrameWnd::DestroyWindow(); +} + +void CMainFrame::OnIntegratorEuler() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = EULER_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntegratorEuler(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == EULER_INTEGRATOR ); +} + +void CMainFrame::OnIntegratorMidpoint() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = MIDPOINT_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == MIDPOINT_INTEGRATOR ); +} + +void CMainFrame::OnIntegratorRungekutta4() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = RK4_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == RK4_INTEGRATOR ); +} diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.h index aa6b86d..1c350b8 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MainFrm.h @@ -1,109 +1,109 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual BOOL DestroyWindow(); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileOpen(); - afx_msg void OnSimulationRunning(); - afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); - afx_msg void OnSimulationReset(); - afx_msg void OnSimulationSetsimproperties(); - afx_msg void OnSimulationUsegravity(); - afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); - afx_msg void OnFileSave(); - afx_msg void OnViewShowgeometry(); - afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); - afx_msg void OnViewShowsprings(); - afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); - afx_msg void OnViewShowvertices(); - afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); - afx_msg void OnClose(); - afx_msg void OnSimulationSetvertexmass(); - afx_msg void OnFileNewsystem(); - afx_msg void OnSimulationSettimingproperties(); - afx_msg void OnIntegratorEuler(); - afx_msg void OnUpdateIntegratorEuler(CCmdUI* pCmdUI); - afx_msg void OnIntegratorMidpoint(); - afx_msg void OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI); - afx_msg void OnIntegratorRungekutta4(); - afx_msg void OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL DestroyWindow(); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileOpen(); + afx_msg void OnSimulationRunning(); + afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); + afx_msg void OnSimulationReset(); + afx_msg void OnSimulationSetsimproperties(); + afx_msg void OnSimulationUsegravity(); + afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); + afx_msg void OnFileSave(); + afx_msg void OnViewShowgeometry(); + afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); + afx_msg void OnViewShowsprings(); + afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); + afx_msg void OnViewShowvertices(); + afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); + afx_msg void OnClose(); + afx_msg void OnSimulationSetvertexmass(); + afx_msg void OnFileNewsystem(); + afx_msg void OnSimulationSettimingproperties(); + afx_msg void OnIntegratorEuler(); + afx_msg void OnUpdateIntegratorEuler(CCmdUI* pCmdUI); + afx_msg void OnIntegratorMidpoint(); + afx_msg void OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI); + afx_msg void OnIntegratorRungekutta4(); + afx_msg void OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.cpp index 849dbc4..5f58c91 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: IdentityMatrix -// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void IdentityMatrix(tMatrix *mat) -{ -///// Local Variables ///////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < 16; loop++) - mat->m[loop] = 0.0f; - mat->m[0] = - mat->m[5] = - mat->m[10] = - mat->m[15] = - 1.0f; -} -//// IdentityMatrix /////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByRotMatrix -// Purpose: Multiplies a vector by a 4x4 Rotation Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z); - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z); - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z); -} -//// MultVectorByRotMatrix /////////////////////////////////////////////////// - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void ScaleVector(tVector *v, float scale, tVector *result) -{ - result->x = v->x * scale; - result->y = v->y * scale; - result->z = v->z * scale; -} - -void VectorSum(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x + v2->x; - result->y = v1->y + v2->y; - result->z = v1->z + v2->z; -} - -void VectorDifference(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: IdentityMatrix +// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void IdentityMatrix(tMatrix *mat) +{ +///// Local Variables ///////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < 16; loop++) + mat->m[loop] = 0.0f; + mat->m[0] = + mat->m[5] = + mat->m[10] = + mat->m[15] = + 1.0f; +} +//// IdentityMatrix /////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByRotMatrix +// Purpose: Multiplies a vector by a 4x4 Rotation Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z); + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z); + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z); +} +//// MultVectorByRotMatrix /////////////////////////////////////////////////// + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void ScaleVector(tVector *v, float scale, tVector *result) +{ + result->x = v->x * scale; + result->y = v->y * scale; + result->z = v->z * scale; +} + +void VectorSum(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x + v2->x; + result->y = v1->y + v2->y; + result->z = v1->z + v2->z; +} + +void VectorDifference(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.h index 60a8d95..efd75ea 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/MathDefs.h @@ -1,117 +1,117 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float nx,ny,nz; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void IdentityMatrix(tMatrix *mat); -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float nx,ny,nz; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void IdentityMatrix(tMatrix *mat); +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.cpp index 70f6d78..466caff 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.cpp @@ -1,857 +1,857 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "Squashy.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION - -#define LERP(a,b,c) (a + ((b - a) * c)) -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_SimRunning = FALSE; - m_CurBone = NULL; - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.b_trans.z = -100.0f; - m_Skeleton.trans.z = -100.0f; - - m_FrameCnt = 0; - - m_TimeIterations = 10; - m_UseFixedTimeStep = FALSE; - m_MaxTimeStep = 0.01f; - - m_hDC = NULL; - - m_PickX = -1; - m_PickY = -1; -} - -COGLView::~COGLView() -{ - DestroySkeleton(&m_Skeleton); -} - - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual = NULL; -/////////////////////////////////////////////////////////////////////////////// - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_CLOSE() - ON_WM_LBUTTONUP() - ON_WM_MBUTTONDOWN() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -float COGLView::GetTime( void ) -{ - static DWORD StartMilliseconds; - if(!StartMilliseconds) - { - // yes, the first time through will be a 0 timestep - StartMilliseconds = timeGetTime(); - } - - DWORD CurrentMilliseconds = timeGetTime(); - return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; -} - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glDisable(GL_TEXTURE_2D); - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 - GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); -// glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); -// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - glLineWidth(2.0f); - glPointSize(8.0f); - glDisable(GL_LINE_SMOOTH); - glDepthFunc(GL_LEQUAL); - glDisable(GL_CULL_FACE); - -// glShadeModel(GL_SMOOTH); -// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - -// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); -// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); -// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); -// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 -// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glDisable(GL_LIGHTING); -// glEnable(GL_LIGHT0); - -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: RunSim -// Purpose: Actual simulation loop -// Notes: Allows you to adjust the rate of simulation or to change it -// to fixed time steps or actual timesteps. -/////////////////////////////////////////////////////////////////////////////// -void COGLView::RunSim() -{ -/// Local Variables /////////////////////////////////////////////////////////// - float Time; - float DeltaTime; -/////////////////////////////////////////////////////////////////////////////// - - if (m_UseFixedTimeStep) - Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); - else - Time = GetTime() * m_TimeIterations; - - if (m_SimRunning) - { - while(m_LastTime < Time) - { - DeltaTime = Time - m_LastTime; - if(DeltaTime > m_MaxTimeStep) - { - DeltaTime = m_MaxTimeStep; - } - - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - m_LastTime += DeltaTime; - } - m_LastTime = Time; - } - else - { - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - } -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ - if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) - { - glColor3f(1.0f,1.0f,1.0f); - // Declare the Array of Data - glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); - if (curBone->visuals[0].reuseVertices) - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - else - glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - } - else - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); - else - glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); - } - } -} -// drawModel - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; - if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; - if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; - - // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); - - // ROTATE THE ROOT - glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); - - if (m_PickX > -1) - m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); - - RunSim(); - - m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION - - glPopMatrix(); - glFinish(); - - if (m_hDC) - SwapBuffers(m_hDC); - -// PLAYING WITH CHECKING FRAMETIMING -/* if (m_SimRunning) - { - m_FrameCnt++; - char message[80]; - DWORD end = timeGetTime(); - float diff = (float)(m_FrameCnt * 1000)/(float)(end - m_StartTime); - - sprintf(message,"%.2f",diff); - m_ptrStatusBar->SetPaneText(0,message); - }*/ - m_PickX = -1; - m_PickY = -1; -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - m_ScreenWidth = cx; - m_ScreenHeight = cy; - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - if ((nFlags & MK_SHIFT) == 0) - { - m_PickX = point.x; - m_PickY = m_ScreenHeight - point.y; - drawScene(); - } - SetCapture( ); - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE - ReleaseCapture(); - CWnd::OnLButtonUp(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - tVector userforce; - switch (nChar) - { - case 13: - m_PhysEnv.AddSpring(); - break; - case 'G': - m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; - break; - case '1': m_curVisual = 0; - break; - case '2': m_curVisual = 1; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - break; - case 'F': - glPolygonMode(GL_FRONT,GL_FILL); - break; - case 'R': - m_SimRunning = !m_SimRunning; - if (m_SimRunning) - m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM - m_StartTime = timeGetTime(); - m_FrameCnt = 0; - break; - case 'T': - m_PhysEnv.ResetWorld(); - break; - case VK_HOME: - userforce.x = m_Skeleton.matrix.m[1]; - userforce.y = m_Skeleton.matrix.m[5]; - userforce.z = m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_END: - userforce.x = -m_Skeleton.matrix.m[1]; - userforce.y = -m_Skeleton.matrix.m[5]; - userforce.z = -m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_RIGHT: - userforce.x = m_Skeleton.matrix.m[0]; - userforce.y = m_Skeleton.matrix.m[4]; - userforce.z = m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_LEFT: - userforce.x = -m_Skeleton.matrix.m[0]; - userforce.y = -m_Skeleton.matrix.m[4]; - userforce.z = -m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_UP: - userforce.x = -m_Skeleton.matrix.m[2]; - userforce.y = -m_Skeleton.matrix.m[6]; - userforce.z = -m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_DOWN: - userforce.x = m_Skeleton.matrix.m[2]; - userforce.y = m_Skeleton.matrix.m[6]; - userforce.z = m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - } - - MSG msg; - - if (m_SimRunning) - { - while (m_SimRunning == TRUE) - { - while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - m_SimRunning = FALSE; - m_hDC = NULL; - PostQuitMessage(0); - break; - } - if (msg.message == WM_CLOSE) - { - m_SimRunning = FALSE; - } - - // Dispatch any messages as needed - if (!AfxGetApp()->PreTranslateMessage(&msg)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - // Give the Idle system some time - AfxGetApp()->OnIdle(0); - AfxGetApp()->OnIdle(1); - - } - if (m_SimRunning) drawScene(); - } - } - else - Invalidate(TRUE); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - tVector localX,localY; - - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CONTROL' BUTTON ROTATE - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - // ELSE ROTATE THE BONE - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS - { - // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES - localY.x = m_Skeleton.matrix.m[1]; - localY.y = m_Skeleton.matrix.m[5]; - localY.z = m_Skeleton.matrix.m[9]; - - localX.x = m_Skeleton.matrix.m[0]; - localX.y = m_Skeleton.matrix.m[4]; - localX.z = m_Skeleton.matrix.m[8]; - - m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); - m_PhysEnv.m_MouseForceActive = TRUE; - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: NewSystem -// Purpose: Clears the Simulation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::NewSystem() -{ - m_PhysEnv.FreeSystem(); - m_SimRunning = FALSE; - if (m_Skeleton.childCnt > 0) - { - if (m_Skeleton.children->visuals->vertexData) - free(m_Skeleton.children->visuals->vertexData); - if (m_Skeleton.children->visuals->faceIndex) - free(m_Skeleton.children->visuals->faceIndex); - free(m_Skeleton.children->visuals); - free(m_Skeleton.children); - m_Skeleton.childCnt = 0; - } - drawScene(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadFiles -// Purpose: Loads the OBJ files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadFile(CString file1,CString baseName,CString ext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *children; - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - ext.MakeUpper(); - if (ext == "OBJ") - { - visual = (t_Visual *)malloc(sizeof(t_Visual)); - NewSystem(); // CLEAR WHAT DATA IS THERE - // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT - if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, - LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) - { - // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SetWorldParticles((tVector *)visual->vertexData,visual->vertexCnt); - - children = (t_Bone *)malloc(sizeof(t_Bone)); - m_CurBone = &children[m_Skeleton.childCnt]; - ResetBone(m_CurBone,&m_Skeleton); - strcpy(m_CurBone->name,(LPCTSTR)baseName); - m_CurBone->visuals = visual; - m_CurBone->visualCnt = 1; - m_Skeleton.childCnt = 1; - m_Skeleton.children = children; - } - else - { - MessageBox("Must Be A Valid OBJ File","Error",MB_OK); - free(visual); - } - } - else // LOAD SIM SYSTEM - { - if (file1.GetLength()) - { - fp = fopen(file1,"rb"); - if (fp != NULL) - { - NewSystem(); // CLEAR WHAT DATA IS THERE - fread(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); - fread(m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); - visual = m_Skeleton.children->visuals; - fread(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); - fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.LoadData(fp); - } - } - fclose(fp); - } - } - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: SaveFiles -// Purpose: Saves the Particle System -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SaveFile(CString file1,CString baseName) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - if (file1.GetLength() > 0) - { - fp = fopen(file1,"wb"); - if (fp != NULL) - { - fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - fwrite(&m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - visual = m_Skeleton.children->visuals; - fwrite(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SaveData(fp); - } - } - fclose(fp); - } - } -} - -void COGLView::OnClose() -{ - - CWnd::OnClose(); -} - -void COGLView::OnSimulationSetsimproperties() -{ - m_PhysEnv.SetWorldProperties(); -} - -void COGLView::OnSimulationSetVertexMass() -{ - m_PhysEnv.SetVertexMass(); -} - -void COGLView::OnSetTimeProperties() -{ - CTimeProps dialog; - dialog.m_Iterations = m_TimeIterations; - dialog.m_FixedTimeSteps = m_UseFixedTimeStep; - dialog.m_MaxTimeStep = m_MaxTimeStep; - if (dialog.DoModal()) - { - m_TimeIterations = dialog.m_Iterations; - m_UseFixedTimeStep = dialog.m_FixedTimeSteps; - m_MaxTimeStep = dialog.m_MaxTimeStep; - } -} - - -void COGLView::OnMButtonDown(UINT nFlags, CPoint point) -{ - - CWnd::OnMButtonDown(nFlags, point); -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "Squashy.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION + +#define LERP(a,b,c) (a + ((b - a) * c)) +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_SimRunning = FALSE; + m_CurBone = NULL; + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.b_trans.z = -100.0f; + m_Skeleton.trans.z = -100.0f; + + m_FrameCnt = 0; + + m_TimeIterations = 10; + m_UseFixedTimeStep = FALSE; + m_MaxTimeStep = 0.01f; + + m_hDC = NULL; + + m_PickX = -1; + m_PickY = -1; +} + +COGLView::~COGLView() +{ + DestroySkeleton(&m_Skeleton); +} + + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual = NULL; +/////////////////////////////////////////////////////////////////////////////// + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_CLOSE() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONDOWN() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +float COGLView::GetTime( void ) +{ + static DWORD StartMilliseconds; + if(!StartMilliseconds) + { + // yes, the first time through will be a 0 timestep + StartMilliseconds = timeGetTime(); + } + + DWORD CurrentMilliseconds = timeGetTime(); + return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; +} + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glDisable(GL_TEXTURE_2D); + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 + GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); +// glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); +// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glLineWidth(2.0f); + glPointSize(8.0f); + glDisable(GL_LINE_SMOOTH); + glDepthFunc(GL_LEQUAL); + glDisable(GL_CULL_FACE); + +// glShadeModel(GL_SMOOTH); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); +// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); +// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); +// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 +// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_LIGHTING); +// glEnable(GL_LIGHT0); + +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: RunSim +// Purpose: Actual simulation loop +// Notes: Allows you to adjust the rate of simulation or to change it +// to fixed time steps or actual timesteps. +/////////////////////////////////////////////////////////////////////////////// +void COGLView::RunSim() +{ +/// Local Variables /////////////////////////////////////////////////////////// + float Time; + float DeltaTime; +/////////////////////////////////////////////////////////////////////////////// + + if (m_UseFixedTimeStep) + Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); + else + Time = GetTime() * m_TimeIterations; + + if (m_SimRunning) + { + while(m_LastTime < Time) + { + DeltaTime = Time - m_LastTime; + if(DeltaTime > m_MaxTimeStep) + { + DeltaTime = m_MaxTimeStep; + } + + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + m_LastTime += DeltaTime; + } + m_LastTime = Time; + } + else + { + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + } +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ + if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) + { + glColor3f(1.0f,1.0f,1.0f); + // Declare the Array of Data + glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); + if (curBone->visuals[0].reuseVertices) + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + else + glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + } + else + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); + else + glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); + } + } +} +// drawModel + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; + if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; + if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; + + // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); + + // ROTATE THE ROOT + glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); + + if (m_PickX > -1) + m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); + + RunSim(); + + m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION + + glPopMatrix(); + glFinish(); + + if (m_hDC) + SwapBuffers(m_hDC); + +// PLAYING WITH CHECKING FRAMETIMING +/* if (m_SimRunning) + { + m_FrameCnt++; + char message[80]; + DWORD end = timeGetTime(); + float diff = (float)(m_FrameCnt * 1000)/(float)(end - m_StartTime); + + sprintf(message,"%.2f",diff); + m_ptrStatusBar->SetPaneText(0,message); + }*/ + m_PickX = -1; + m_PickY = -1; +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + m_ScreenWidth = cx; + m_ScreenHeight = cy; + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + if ((nFlags & MK_SHIFT) == 0) + { + m_PickX = point.x; + m_PickY = m_ScreenHeight - point.y; + drawScene(); + } + SetCapture( ); + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE + ReleaseCapture(); + CWnd::OnLButtonUp(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + tVector userforce; + switch (nChar) + { + case 13: + m_PhysEnv.AddSpring(); + break; + case 'G': + m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; + break; + case '1': m_curVisual = 0; + break; + case '2': m_curVisual = 1; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + break; + case 'F': + glPolygonMode(GL_FRONT,GL_FILL); + break; + case 'R': + m_SimRunning = !m_SimRunning; + if (m_SimRunning) + m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM + m_StartTime = timeGetTime(); + m_FrameCnt = 0; + break; + case 'T': + m_PhysEnv.ResetWorld(); + break; + case VK_HOME: + userforce.x = m_Skeleton.matrix.m[1]; + userforce.y = m_Skeleton.matrix.m[5]; + userforce.z = m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_END: + userforce.x = -m_Skeleton.matrix.m[1]; + userforce.y = -m_Skeleton.matrix.m[5]; + userforce.z = -m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_RIGHT: + userforce.x = m_Skeleton.matrix.m[0]; + userforce.y = m_Skeleton.matrix.m[4]; + userforce.z = m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_LEFT: + userforce.x = -m_Skeleton.matrix.m[0]; + userforce.y = -m_Skeleton.matrix.m[4]; + userforce.z = -m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_UP: + userforce.x = -m_Skeleton.matrix.m[2]; + userforce.y = -m_Skeleton.matrix.m[6]; + userforce.z = -m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_DOWN: + userforce.x = m_Skeleton.matrix.m[2]; + userforce.y = m_Skeleton.matrix.m[6]; + userforce.z = m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + } + + MSG msg; + + if (m_SimRunning) + { + while (m_SimRunning == TRUE) + { + while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + m_SimRunning = FALSE; + m_hDC = NULL; + PostQuitMessage(0); + break; + } + if (msg.message == WM_CLOSE) + { + m_SimRunning = FALSE; + } + + // Dispatch any messages as needed + if (!AfxGetApp()->PreTranslateMessage(&msg)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + // Give the Idle system some time + AfxGetApp()->OnIdle(0); + AfxGetApp()->OnIdle(1); + + } + if (m_SimRunning) drawScene(); + } + } + else + Invalidate(TRUE); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + tVector localX,localY; + + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CONTROL' BUTTON ROTATE + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + // ELSE ROTATE THE BONE + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS + { + // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES + localY.x = m_Skeleton.matrix.m[1]; + localY.y = m_Skeleton.matrix.m[5]; + localY.z = m_Skeleton.matrix.m[9]; + + localX.x = m_Skeleton.matrix.m[0]; + localX.y = m_Skeleton.matrix.m[4]; + localX.z = m_Skeleton.matrix.m[8]; + + m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); + m_PhysEnv.m_MouseForceActive = TRUE; + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: NewSystem +// Purpose: Clears the Simulation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::NewSystem() +{ + m_PhysEnv.FreeSystem(); + m_SimRunning = FALSE; + if (m_Skeleton.childCnt > 0) + { + if (m_Skeleton.children->visuals->vertexData) + free(m_Skeleton.children->visuals->vertexData); + if (m_Skeleton.children->visuals->faceIndex) + free(m_Skeleton.children->visuals->faceIndex); + free(m_Skeleton.children->visuals); + free(m_Skeleton.children); + m_Skeleton.childCnt = 0; + } + drawScene(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadFiles +// Purpose: Loads the OBJ files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadFile(CString file1,CString baseName,CString ext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *children; + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + ext.MakeUpper(); + if (ext == "OBJ") + { + visual = (t_Visual *)malloc(sizeof(t_Visual)); + NewSystem(); // CLEAR WHAT DATA IS THERE + // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT + if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, + LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) + { + // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SetWorldParticles((tVector *)visual->vertexData,visual->vertexCnt); + + children = (t_Bone *)malloc(sizeof(t_Bone)); + m_CurBone = &children[m_Skeleton.childCnt]; + ResetBone(m_CurBone,&m_Skeleton); + strcpy(m_CurBone->name,(LPCTSTR)baseName); + m_CurBone->visuals = visual; + m_CurBone->visualCnt = 1; + m_Skeleton.childCnt = 1; + m_Skeleton.children = children; + } + else + { + MessageBox("Must Be A Valid OBJ File","Error",MB_OK); + free(visual); + } + } + else // LOAD SIM SYSTEM + { + if (file1.GetLength()) + { + fp = fopen(file1,"rb"); + if (fp != NULL) + { + NewSystem(); // CLEAR WHAT DATA IS THERE + fread(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); + fread(m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); + visual = m_Skeleton.children->visuals; + fread(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); + fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.LoadData(fp); + } + } + fclose(fp); + } + } + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: SaveFiles +// Purpose: Saves the Particle System +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SaveFile(CString file1,CString baseName) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + if (file1.GetLength() > 0) + { + fp = fopen(file1,"wb"); + if (fp != NULL) + { + fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + fwrite(&m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + visual = m_Skeleton.children->visuals; + fwrite(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SaveData(fp); + } + } + fclose(fp); + } + } +} + +void COGLView::OnClose() +{ + + CWnd::OnClose(); +} + +void COGLView::OnSimulationSetsimproperties() +{ + m_PhysEnv.SetWorldProperties(); +} + +void COGLView::OnSimulationSetVertexMass() +{ + m_PhysEnv.SetVertexMass(); +} + +void COGLView::OnSetTimeProperties() +{ + CTimeProps dialog; + dialog.m_Iterations = m_TimeIterations; + dialog.m_FixedTimeSteps = m_UseFixedTimeStep; + dialog.m_MaxTimeStep = m_MaxTimeStep; + if (dialog.DoModal()) + { + m_TimeIterations = dialog.m_Iterations; + m_UseFixedTimeStep = dialog.m_FixedTimeSteps; + m_MaxTimeStep = dialog.m_MaxTimeStep; + } +} + + +void COGLView::OnMButtonDown(UINT nFlags, CPoint point) +{ + + CWnd::OnMButtonDown(nFlags, point); +} diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.h index 3c7df6d..504ef50 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/OGLView.h @@ -1,124 +1,124 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -#include "PhysEnv.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry,m_SimRunning; - int m_curVisual; - float m_MorphPos; - DWORD m_StartTime; - DWORD m_FrameCnt; - int m_TimeIterations; - BOOL m_UseFixedTimeStep; - float m_MaxTimeStep; - float m_LastTime; - - - CPhysEnv m_PhysEnv; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - void OnSimulationSetVertexMass(); - void OnSimulationSetsimproperties(); - void OnSetTimeProperties(); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - GLvoid morphModel(t_Bone *curBone); - GLvoid LoadBoneTexture(t_Bone *curBone); - void NewSystem(); - void LoadFile(CString file1,CString baseName,CString ext); - void SaveFile(CString file1,CString baseName); - void RunSim(); - float GetTime( void ); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Skeleton,*m_CurBone; - int m_PickX, m_PickY; - int m_ScreenWidth; - int m_ScreenHeight; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnClose(); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnMButtonDown(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +#include "PhysEnv.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry,m_SimRunning; + int m_curVisual; + float m_MorphPos; + DWORD m_StartTime; + DWORD m_FrameCnt; + int m_TimeIterations; + BOOL m_UseFixedTimeStep; + float m_MaxTimeStep; + float m_LastTime; + + + CPhysEnv m_PhysEnv; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + void OnSimulationSetVertexMass(); + void OnSimulationSetsimproperties(); + void OnSetTimeProperties(); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + GLvoid morphModel(t_Bone *curBone); + GLvoid LoadBoneTexture(t_Bone *curBone); + void NewSystem(); + void LoadFile(CString file1,CString baseName,CString ext); + void SaveFile(CString file1,CString baseName); + void RunSim(); + float GetTime( void ); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Skeleton,*m_CurBone; + int m_PickX, m_PickY; + int m_ScreenWidth; + int m_ScreenHeight; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnClose(); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.cpp index a5571e9..ab96ed2 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.cpp @@ -1,1105 +1,1105 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// PhysEnv.cpp : Physical World implementation file -// -// Purpose: Implementation of Particle Physics System -// -// Created: -// JL 12/1/98 -// Modified: -// JL 3/6/99 - FIXED GRAVITY FORCE CALCULATION BUG -// JL 3/8/99 - ADDED MORE POSSIBLE CONTACTS AS EACH VERTEX CAN CONTACT MORE -// THEN ONE COLLISION SURFACE (SHOULD IT BE DYNAMICALLY ALLOC'ED?) -// JL 3/20/99 - ADDED THE MIDPOINT AND RK INTEGRATOR NEEDED TO ALLOC 5 TEMP PARTICLE ARRAYS -// -// Notes: A bit of this along with the organization comes from Chris Hecker's -// Physics Articles from last year. Hopefully this will get everyone -// back up to speed before we dig deeper into the world of Dynamics. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998-1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include -#include - -#include "Squashy.h" -#include "PhysEnv.h" -#include "SimProps.h" -#include "VertMass.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -///////////////////////////////////////////////////////////////////////////// -// CPhysEnv - -// INITIALIZE THE SIMULATION WORLD -CPhysEnv::CPhysEnv() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - m_ParticleSys[0] = NULL; - m_ParticleSys[1] = NULL; - m_ParticleSys[2] = NULL; // RESET BUFFER - - // THESE TEMP PARTICLE BUFFERS ARE NEEDED FOR THE MIDPOINT AND RK4 INTEGRATOR - for (int i = 0; i < 5; i++) - m_TempSys[i] = NULL; - m_ParticleCnt = 0; - m_Contact = NULL; - m_Spring = NULL; - m_SpringCnt = 0; - - m_UseGravity = TRUE; - m_DrawSprings = TRUE; - m_DrawVertices = TRUE; - m_MouseForceActive = FALSE; - - MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) - m_UserForceMag = 100.0; - m_UserForceActive = FALSE; - m_Kd = 0.04f; // DAMPING FACTOR - m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT - m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT - m_Ksd = 0.1f; // SPRING DAMPING CONSTANT - - m_Csf = 0.2f; // Default Static Friction - m_Ckf = 0.15f; // Default Kinetic Friction - m_MouseForceKs = 0.08f; // MOUSE SPRING CONSTANT - - // CREATE THE SIZE FOR THE SIMULATION WORLD - m_WorldSizeX = 15.0f; - m_WorldSizeY = 15.0f; - m_WorldSizeZ = 15.0f; - - m_IntegratorType = EULER_INTEGRATOR; - - m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); - m_CollisionPlaneCnt = 6; - - // MAKE THE TOP PLANE (CEILING) - MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) - m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; - - // MAKE THE BOTTOM PLANE (FLOOR) - MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) - m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; - - // MAKE THE LEFT PLANE - MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) - m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; - - // MAKE THE RIGHT PLANE - MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) - m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; - - // MAKE THE FRONT PLANE - MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) - m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; - - // MAKE THE BACK PLANE - MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) - m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; - - m_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION -} - -CPhysEnv::~CPhysEnv() -{ - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - free(m_TempSys[i]); - } - if (m_Contact) - free(m_Contact); - if (m_Spring) - free(m_Spring); - free(m_CollisionPlane); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RenderWorld -// Purpose: Draw the current system (particles, springs, userforces) -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::RenderWorld() -{ - tParticle *tempParticle; - tSpring *tempSpring; - - // FIRST DRAW THE WORLD CONTAINER - glColor3f(1.0f,1.0f,1.0f); - // do a big linestrip to get most of edges - glBegin(GL_LINE_STRIP); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glEnd(); - // fill in the stragglers - glBegin(GL_LINES); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - - // draw floor - glDisable(GL_CULL_FACE); - glBegin(GL_QUADS); - glColor3f(0.0f,0.0f,0.5f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - glEnable(GL_CULL_FACE); - - - if (m_ParticleSys) - { - if (m_Spring && m_DrawSprings) - { - glBegin(GL_LINES); - glColor3f(0.0f,0.8f,0.8f); - tempSpring = m_Spring; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); - glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); - tempSpring++; - } - if (m_MouseForceActive) // DRAW MOUSESPRING FORCE - { - if (m_Pick[0] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); - glVertex3fv((float *)&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); - glVertex3fv((float *)&m_MouseDragPos[1]); - } - } - glEnd(); - } - if (m_DrawVertices) - { - glBegin(GL_POINTS); - tempParticle = m_CurrentSys; - for (int loop = 0; loop < m_ParticleCnt; loop++) - { - if (loop == m_Pick[0]) - glColor3f(0.0f,0.8f,0.0f); - else if (loop == m_Pick[1]) - glColor3f(0.8f,0.0f,0.0f); - else - glColor3f(0.8f,0.8f,0.0f); - - glVertex3fv((float *)&tempParticle->pos); - tempParticle++; - } - glEnd(); - } - } - -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetNearestPoint -// Purpose: Use OpenGL Feedback to find the closest point to a mouseclick -// Arguments: Screen coordinates of the hit -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::GetNearestPoint(int x, int y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *feedBuffer; - int hitCount; - tParticle *tempParticle; - int loop; -/////////////////////////////////////////////////////////////////////////////// - // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) - feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); - // TELL OPENGL ABOUT THE BUFFER - glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); - (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE - - tempParticle = m_CurrentSys; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS - glPassThrough((float)loop); - // SEND THE VERTEX - glBegin(GL_POINTS); - glVertex3fv((float *)&tempParticle->pos); - glEnd(); - tempParticle++; - } - hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET - CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT - free(feedBuffer); // GET RID OF THE MEMORY -} -////// GetNearestPoint //////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CompareBuffer -// Purpose: Check the feedback buffer to see if anything is hit -// Arguments: Number of hits, pointer to buffer, point to test -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLint count; - GLfloat token,point[3]; - int loop,currentVertex,result = -1; - long nearest = -1, dist; -/////////////////////////////////////////////////////////////////////////////// - count = size; - while (count) - { - token = buffer[size - count]; // CHECK THE TOKEN - count--; - if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER - { - currentVertex = (int)buffer[size - count]; // WHAT VERTEX - count--; - } - else if (token == GL_POINT_TOKEN) - { - // THERE ARE THREE ELEMENTS TO A POINT TOKEN - for (loop = 0; loop < 3; loop++) - { - point[loop] = buffer[size - count]; - count--; - } - dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); - if (result == -1 || dist < nearest) - { - nearest = dist; - result = currentVertex; - } - } - } - - if (nearest < 50.0f) - { - if (m_Pick[0] == -1) - m_Pick[0] = result; - else if (m_Pick[1] == -1) - m_Pick[1] = result; - else - { - m_Pick[0] = result; - m_Pick[1] = -1; - } - } -} -////// CompareBuffer ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetWorldParticles -// Purpose: Inform the System of the particles under control -// Arguments: List of vertices and count -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetWorldParticles(tVector *coords,int particleCnt) -{ - tParticle *tempParticle; - - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - free(m_TempSys[i]); - } - if (m_Contact) - free(m_Contact); - // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - for (i = 0; i < 5; i++) - { - m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - } - m_ParticleCnt = particleCnt; - - // MULTIPLIED PARTICLE COUNT * 2 SINCE THEY CAN COLLIDE WITH MULTIPLE WALLS - m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt * 2); - m_ContactCnt = 0; - - tempParticle = m_CurrentSys; - for (int loop = 0; loop < particleCnt; loop++) - { - MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) - MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) - MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) - tempParticle->oneOverM = 1.0f; // MASS OF 1 - tempParticle++; - coords++; - } - - // COPY THE SYSTEM TO THE SECOND ONE ALSO - memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); - // COPY THE SYSTEM TO THE RESET BUFFER ALSO - memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); - - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; -} -////// SetWorldParticles ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: FreeSystem -// Purpose: Remove all particles and clear it out -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::FreeSystem() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - if (m_ParticleSys[0]) - { - m_ParticleSys[0] = NULL; - free(m_ParticleSys[0]); - } - if (m_ParticleSys[1]) - { - free(m_ParticleSys[1]); - m_ParticleSys[1] = NULL; - } - if (m_ParticleSys[2]) - { - free(m_ParticleSys[2]); - m_ParticleSys[2] = NULL; // RESET BUFFER - } - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - { - free(m_TempSys[i]); - m_TempSys[i] = NULL; // RESET BUFFER - } - } - if (m_Contact) - { - free(m_Contact); - m_Contact = NULL; - } - if (m_Spring) - { - free(m_Spring); - m_Spring = NULL; - } - m_SpringCnt = 0; - m_ParticleCnt = 0; -} -////// FreeSystem ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadData -// Purpose: Load a simulation system -// Arguments: File pointer -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::LoadData(FILE *fp) -{ - fread(&m_UseGravity,sizeof(BOOL),1,fp); - fread(&m_UseDamping,sizeof(BOOL),1,fp); - fread(&m_UserForceActive,sizeof(BOOL),1,fp); - fread(&m_Gravity,sizeof(tVector),1,fp); - fread(&m_UserForce,sizeof(tVector),1,fp); - fread(&m_UserForceMag,sizeof(float),1,fp); - fread(&m_Kd,sizeof(float),1,fp); - fread(&m_Kr,sizeof(float),1,fp); - fread(&m_Ksh,sizeof(float),1,fp); - fread(&m_Ksd,sizeof(float),1,fp); - fread(&m_ParticleCnt,sizeof(int),1,fp); - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - for (int i = 0; i < 5; i++) - { - m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - } - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; - m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); - fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fread(&m_SpringCnt,sizeof(int),1,fp); - m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); - fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fread(m_Pick,sizeof(int),2,fp); -} -////// LoadData ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SaveData -// Purpose: Save a simulation system -// Arguments: File pointer -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SaveData(FILE *fp) -{ - fwrite(&m_UseGravity,sizeof(BOOL),1,fp); - fwrite(&m_UseDamping,sizeof(BOOL),1,fp); - fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); - fwrite(&m_Gravity,sizeof(tVector),1,fp); - fwrite(&m_UserForce,sizeof(tVector),1,fp); - fwrite(&m_UserForceMag,sizeof(float),1,fp); - fwrite(&m_Kd,sizeof(float),1,fp); - fwrite(&m_Kr,sizeof(float),1,fp); - fwrite(&m_Ksh,sizeof(float),1,fp); - fwrite(&m_Ksd,sizeof(float),1,fp); - fwrite(&m_ParticleCnt,sizeof(int),1,fp); - fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(&m_SpringCnt,sizeof(int),1,fp); - fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fwrite(m_Pick,sizeof(int),2,fp); -} -////// SaveData ////////////////////////////////////////////////////////////// - -// RESET THE SIM TO INITIAL VALUES -void CPhysEnv::ResetWorld() -{ - memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); - memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); -} - -void CPhysEnv::SetWorldProperties() -{ - CSimProps dialog; - dialog.m_CoefRest = m_Kr; - dialog.m_Damping = m_Kd; - dialog.m_GravX = m_Gravity.x; - dialog.m_GravY = m_Gravity.y; - dialog.m_GravZ = m_Gravity.z; - dialog.m_SpringConst = m_Ksh; - dialog.m_SpringDamp = m_Ksd; - dialog.m_UserForceMag = m_UserForceMag; - dialog.m_MouseSpring = m_MouseForceKs; - if (dialog.DoModal() == IDOK) - { - m_Kr = dialog.m_CoefRest; - m_Kd = dialog.m_Damping; - m_Gravity.x = dialog.m_GravX; - m_Gravity.y = dialog.m_GravY; - m_Gravity.z = dialog.m_GravZ; - m_UserForceMag = dialog.m_UserForceMag; - m_Ksh = dialog.m_SpringConst; - m_Ksd = dialog.m_SpringDamp; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - m_Spring[loop].Ks = m_Ksh; - m_Spring[loop].Kd = m_Ksd; - } - - // GET THE NEW MOUSESPRING FORCE - m_MouseForceKs = dialog.m_MouseSpring; - } -} - - -void CPhysEnv::SetVertexMass() -{ - CVertMass dialog; - dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; - if (dialog.DoModal() == IDOK) - { - m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; - } -} - -void CPhysEnv::ApplyUserForce(tVector *force) -{ - ScaleVector(force, m_UserForceMag, &m_UserForce); - m_UserForceActive = TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetMouseForce -// Purpose: Allows the user to interact with selected points by dragging -// Arguments: Delta distance from clicked point, local x and y axes -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector tempX,tempY; -/////////////////////////////////////////////////////////////////////////////// - ScaleVector(localX, (float)deltaX * 0.03f, &tempX); - ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); - if (m_Pick[0] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); - VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); - VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); - } -} -/// SetMouseForce ///////////////////////////////////////////////////////////// - -void CPhysEnv::AddSpring() -{ - tSpring *spring; - // MAKE SURE TWO PARTICLES ARE PICKED - if (m_Pick[0] > -1 && m_Pick[1] > -1) - { - spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); - if (m_Spring != NULL) - memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); - m_Spring = spring; - spring = &m_Spring[m_SpringCnt++]; - spring->Ks = m_Ksh; - spring->Kd = m_Ksd; - spring->p1 = m_Pick[0]; - spring->p2 = m_Pick[1]; - spring->restLen = - sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, - &m_CurrentSys[m_Pick[1]].pos)); - } -} - -void CPhysEnv::ComputeForces( tParticle *system ) -{ - int loop; - tParticle *curParticle,*p1, *p2; - tSpring *spring; - float dist, Hterm, Dterm; - tVector springForce,deltaV,deltaP; - - curParticle = system; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR - - // BUG (3/8/99): THERE WAS A BUG HERE, I FORGOT YOU NEED TO DIVIDE - // BY 1/M TO GET THE TRUE FORCE ACTING ON THE PARTICLE INSTEAD OF A MULTIPLY - // THANKS TO ED POVAZ FOR THE SPOT... - if (m_UseGravity && curParticle->oneOverM != 0) // && curParticle->type != CONTACTING) - { - curParticle->f.x += (m_Gravity.x / curParticle->oneOverM); - curParticle->f.y += (m_Gravity.y / curParticle->oneOverM); - curParticle->f.z += (m_Gravity.z / curParticle->oneOverM); - } - - if (m_UseDamping) - { - curParticle->f.x += (-m_Kd * curParticle->v.x); - curParticle->f.y += (-m_Kd * curParticle->v.y); - curParticle->f.z += (-m_Kd * curParticle->v.z); - } - else - { - curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); - curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); - curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); - } - curParticle++; - } - - // CHECK IF THERE IS A USER FORCE BEING APPLIED - if (m_UserForceActive) - { - if (m_Pick[0] != -1) - { - VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); - } - if (m_Pick[1] != -1) - { - VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); - } - MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE - } - - // NOW DO ALL THE SPRINGS - spring = m_Spring; - for (loop = 0; loop < m_SpringCnt; loop++) - { - p1 = &system[spring->p1]; - p2 = &system[spring->p2]; - VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) - - VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector - Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force -// if (p1->type != CONTACTING) - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 -// if (p2->type != CONTACTING) - VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 - spring++; // DO THE NEXT SPRING - } - - // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE - if (m_MouseForceActive) - { - // APPLY TO EACH PICKED PARTICLE - if (m_Pick[0] > -1) - { - p1 = &system[m_Pick[0]]; - VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - if (m_Pick[1] > -1) - { - p1 = &system[m_Pick[1]]; - VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - } - -} - - - -/////////////////////////////////////////////////////////////////////////////// -// Function: IntegrateSysOverTime -// Purpose: Does the Integration for all the points in a system -// Arguments: Initial Position, Source and Target Particle Systems and Time -// Notes: Computes a single integration step -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float deltaTimeMass; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < m_ParticleCnt; loop++) - { - deltaTimeMass = deltaTime * initial->oneOverM; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = initial->v.x + (source->f.x * deltaTimeMass); - target->v.y = initial->v.y + (source->f.y * deltaTimeMass); - target->v.z = initial->v.z + (source->f.z * deltaTimeMass); - - target->oneOverM = initial->oneOverM; - - // SET THE NEW POSITION - target->pos.x = initial->pos.x + (deltaTime * source->v.x); - target->pos.y = initial->pos.y + (deltaTime * source->v.y); - target->pos.z = initial->pos.z + (deltaTime * source->v.z); - - initial++; - source++; - target++; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses Euler's method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::EulerIntegrate( float DeltaTime) -{ - // JUST TAKE A SINGLE STEP - IntegrateSysOverTime(m_CurrentSys,m_CurrentSys, m_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: MidPointIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Midpoint method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::MidPointIntegrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float halfDeltaT; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; - - // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION - IntegrateSysOverTime(m_CurrentSys,m_CurrentSys,m_TempSys[0],halfDeltaT); - - // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES - ComputeForces(m_TempSys[0]); - - // TAKE THE FULL STEP WITH THIS NEW INFORMATION - IntegrateSysOverTime(m_CurrentSys,m_TempSys[0],m_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RK4Integrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Runga-Kutta 4 method -// This could use a generic function 4 times instead of unrolled -// but it was easier for me to debug. Fun for you to optimize. -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::RK4Integrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float halfDeltaT,sixthDeltaT; - tParticle *source,*target,*accum1,*accum2,*accum3,*accum4; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; // SOME TIME VALUES I WILL NEED - sixthDeltaT = 1.0f / 6.0f; - - // FIRST STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[1]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - accum1->f.x = halfDeltaT * source->f.x * source->oneOverM; - accum1->f.y = halfDeltaT * source->f.y * source->oneOverM; - accum1->f.z = halfDeltaT * source->f.z * source->oneOverM; - - accum1->v.x = halfDeltaT * source->v.x; - accum1->v.y = halfDeltaT * source->v.y; - accum1->v.z = halfDeltaT * source->v.z; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE OVER 1/2 TIME - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES - - // SECOND STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[2]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - accum1->f.x = halfDeltaT * target->f.x * source->oneOverM; - accum1->f.y = halfDeltaT * target->f.y * source->oneOverM; - accum1->f.z = halfDeltaT * target->f.z * source->oneOverM; - accum1->v.x = halfDeltaT * target->v.x; - accum1->v.y = halfDeltaT * target->v.y; - accum1->v.z = halfDeltaT * target->v.z; - - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES - - // THIRD STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[3]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // NOTICE I USE THE FULL DELTATIME THIS STEP - accum1->f.x = DeltaTime * target->f.x * source->oneOverM; - accum1->f.y = DeltaTime * target->f.y * source->oneOverM; - accum1->f.z = DeltaTime * target->f.z * source->oneOverM; - accum1->v.x = DeltaTime * target->v.x; - accum1->v.y = DeltaTime * target->v.y; - accum1->v.z = DeltaTime * target->v.z; - - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES - - // FOURTH STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[4]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // NOTICE I USE THE FULL DELTATIME THIS STEP - accum1->f.x = DeltaTime * target->f.x * source->oneOverM; - accum1->f.y = DeltaTime * target->f.y * source->oneOverM; - accum1->f.z = DeltaTime * target->f.z * source->oneOverM; - - accum1->v.x = DeltaTime * target->v.x; - accum1->v.y = DeltaTime * target->v.y; - accum1->v.z = DeltaTime * target->v.z; - - // THIS TIME I DON'T NEED TO COMPUTE THE TEMPORARY POSITIONS - source++; - target++; - accum1++; - } - - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TargetSys; - accum1 = m_TempSys[1]; - accum2 = m_TempSys[2]; - accum3 = m_TempSys[3]; - accum4 = m_TempSys[4]; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE USING RK4 FORMULA - target->v.x = source->v.x + ((accum1->f.x + ((accum2->f.x + accum3->f.x) * 2.0f) + accum4->f.x) * sixthDeltaT); - target->v.y = source->v.y + ((accum1->f.y + ((accum2->f.y + accum3->f.y) * 2.0f) + accum4->f.y) * sixthDeltaT); - target->v.z = source->v.z + ((accum1->f.z + ((accum2->f.z + accum3->f.z) * 2.0f) + accum4->f.z) * sixthDeltaT); - // DETERMINE THE NEW POSITION FOR THE PARTICLE USING RK4 FORMULA - target->pos.x = source->pos.x + ((accum1->v.x + ((accum2->v.x + accum3->v.x) * 2.0f) + accum4->v.x) * sixthDeltaT); - target->pos.y = source->pos.y + ((accum1->v.y + ((accum2->v.y + accum3->v.y) * 2.0f) + accum4->v.y) * sixthDeltaT); - target->pos.z = source->pos.z + ((accum1->v.z + ((accum2->v.z + accum3->v.z) * 2.0f) + accum4->v.z) * sixthDeltaT); - - source++; - target++; - accum1++; - accum2++; - accum3++; - accum4++; - } - -} - -int CPhysEnv::CheckForCollisions( tParticle *system ) -{ - // be optimistic! - int collisionState = NOT_COLLIDING; - float const depthEpsilon = 0.001f; - - int loop; - tParticle *curParticle; - - m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS - - curParticle = system; - for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); - loop++,curParticle++) - { - for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && - (collisionState != PENETRATING);planeIndex++) - { - tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; - - float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; - - if(axbyczd < -depthEpsilon) - { - // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(axbyczd < depthEpsilon) - { - float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); -/* if(relativeVelocity < 0.01f && relativeVelocity > -0.01f) - { - collisionState = CONTACTING; - curParticle->v.x = curParticle->v.y = curParticle->v.z = 0.0f; - curParticle->type = CONTACTING; - } - else */ - if(relativeVelocity < 0.0f) - { - collisionState = COLLIDING; - m_Contact[m_ContactCnt].type = COLLIDING; - m_Contact[m_ContactCnt].particle = loop; - memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); - m_ContactCnt++; - } - } - } - } - - return collisionState; -} - -void CPhysEnv::ResolveCollisions( tParticle *system ) -{ - tContact *contact; - tParticle *particle; // THE PARTICLE COLLIDING - float VdotN; - tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE - contact = m_Contact; - for (int loop = 0; loop < m_ContactCnt; loop++,contact++) - { - particle = &system[contact->particle]; - // CALCULATE Vn - VdotN = DotProduct(&contact->normal,&particle->v); - ScaleVector(&contact->normal, VdotN, &Vn); - // CALCULATE Vt - VectorDifference(&particle->v, &Vn, &Vt); - // SCALE Vn BY COEFFICIENT OF RESTITUTION - ScaleVector(&Vn, m_Kr, &Vn); - // SET THE VELOCITY TO BE THE NEW IMPULSE - VectorDifference(&Vt, &Vn, &particle->v); - } -} - -void CPhysEnv::Simulate(float DeltaTime, BOOL running) -{ - float CurrentTime = 0.0f; - float TargetTime = DeltaTime; - tParticle *tempSys; - int collisionState; - - while(CurrentTime < DeltaTime) - { - if (running) - { - ComputeForces(m_CurrentSys); - - // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK - // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, - // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. - // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY - if (m_CollisionRootFinding) - { - EulerIntegrate(TargetTime-CurrentTime); - } - else - { - switch (m_IntegratorType) - { - case EULER_INTEGRATOR: - EulerIntegrate(TargetTime-CurrentTime); - break; - case MIDPOINT_INTEGRATOR: - MidPointIntegrate(TargetTime-CurrentTime); - break; - case RK4_INTEGRATOR: - RK4Integrate(TargetTime-CurrentTime); - break; - } - } - } - - collisionState = CheckForCollisions(m_TargetSys); - - if(collisionState == PENETRATING) - { - // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER - m_CollisionRootFinding = TRUE; - // we simulated too far, so subdivide time and try again - TargetTime = (CurrentTime + TargetTime) / 2.0f; - - // blow up if we aren't moving forward each step, which is - // probably caused by interpenetration at the frame start - assert(fabs(TargetTime - CurrentTime) > EPSILON); - } - else - { - // either colliding or clear - if(collisionState == COLLIDING) - { - int Counter = 0; - do - { - ResolveCollisions(m_TargetSys); - Counter++; - } while((CheckForCollisions(m_TargetSys) == - COLLIDING) && (Counter < 100)); - - assert(Counter < 100); - m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT BACK TO NORMAL - } - - // we made a successful step, so swap configurations - // to "save" the data for the next step - - CurrentTime = TargetTime; - TargetTime = DeltaTime; - - // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN - tempSys = m_CurrentSys; - m_CurrentSys = m_TargetSys; - m_TargetSys = tempSys; - } - } -} +/////////////////////////////////////////////////////////////////////////////// +// +// PhysEnv.cpp : Physical World implementation file +// +// Purpose: Implementation of Particle Physics System +// +// Created: +// JL 12/1/98 +// Modified: +// JL 3/6/99 - FIXED GRAVITY FORCE CALCULATION BUG +// JL 3/8/99 - ADDED MORE POSSIBLE CONTACTS AS EACH VERTEX CAN CONTACT MORE +// THEN ONE COLLISION SURFACE (SHOULD IT BE DYNAMICALLY ALLOC'ED?) +// JL 3/20/99 - ADDED THE MIDPOINT AND RK INTEGRATOR NEEDED TO ALLOC 5 TEMP PARTICLE ARRAYS +// +// Notes: A bit of this along with the organization comes from Chris Hecker's +// Physics Articles from last year. Hopefully this will get everyone +// back up to speed before we dig deeper into the world of Dynamics. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998-1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include + +#include "Squashy.h" +#include "PhysEnv.h" +#include "SimProps.h" +#include "VertMass.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +///////////////////////////////////////////////////////////////////////////// +// CPhysEnv + +// INITIALIZE THE SIMULATION WORLD +CPhysEnv::CPhysEnv() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + m_ParticleSys[0] = NULL; + m_ParticleSys[1] = NULL; + m_ParticleSys[2] = NULL; // RESET BUFFER + + // THESE TEMP PARTICLE BUFFERS ARE NEEDED FOR THE MIDPOINT AND RK4 INTEGRATOR + for (int i = 0; i < 5; i++) + m_TempSys[i] = NULL; + m_ParticleCnt = 0; + m_Contact = NULL; + m_Spring = NULL; + m_SpringCnt = 0; + + m_UseGravity = TRUE; + m_DrawSprings = TRUE; + m_DrawVertices = TRUE; + m_MouseForceActive = FALSE; + + MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) + m_UserForceMag = 100.0; + m_UserForceActive = FALSE; + m_Kd = 0.04f; // DAMPING FACTOR + m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT + m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT + m_Ksd = 0.1f; // SPRING DAMPING CONSTANT + + m_Csf = 0.2f; // Default Static Friction + m_Ckf = 0.15f; // Default Kinetic Friction + m_MouseForceKs = 0.08f; // MOUSE SPRING CONSTANT + + // CREATE THE SIZE FOR THE SIMULATION WORLD + m_WorldSizeX = 15.0f; + m_WorldSizeY = 15.0f; + m_WorldSizeZ = 15.0f; + + m_IntegratorType = EULER_INTEGRATOR; + + m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); + m_CollisionPlaneCnt = 6; + + // MAKE THE TOP PLANE (CEILING) + MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) + m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; + + // MAKE THE BOTTOM PLANE (FLOOR) + MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) + m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; + + // MAKE THE LEFT PLANE + MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) + m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; + + // MAKE THE RIGHT PLANE + MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) + m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; + + // MAKE THE FRONT PLANE + MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) + m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; + + // MAKE THE BACK PLANE + MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) + m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; + + m_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION +} + +CPhysEnv::~CPhysEnv() +{ + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + free(m_TempSys[i]); + } + if (m_Contact) + free(m_Contact); + if (m_Spring) + free(m_Spring); + free(m_CollisionPlane); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RenderWorld +// Purpose: Draw the current system (particles, springs, userforces) +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::RenderWorld() +{ + tParticle *tempParticle; + tSpring *tempSpring; + + // FIRST DRAW THE WORLD CONTAINER + glColor3f(1.0f,1.0f,1.0f); + // do a big linestrip to get most of edges + glBegin(GL_LINE_STRIP); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glEnd(); + // fill in the stragglers + glBegin(GL_LINES); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + + // draw floor + glDisable(GL_CULL_FACE); + glBegin(GL_QUADS); + glColor3f(0.0f,0.0f,0.5f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + glEnable(GL_CULL_FACE); + + + if (m_ParticleSys) + { + if (m_Spring && m_DrawSprings) + { + glBegin(GL_LINES); + glColor3f(0.0f,0.8f,0.8f); + tempSpring = m_Spring; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); + glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); + tempSpring++; + } + if (m_MouseForceActive) // DRAW MOUSESPRING FORCE + { + if (m_Pick[0] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); + glVertex3fv((float *)&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); + glVertex3fv((float *)&m_MouseDragPos[1]); + } + } + glEnd(); + } + if (m_DrawVertices) + { + glBegin(GL_POINTS); + tempParticle = m_CurrentSys; + for (int loop = 0; loop < m_ParticleCnt; loop++) + { + if (loop == m_Pick[0]) + glColor3f(0.0f,0.8f,0.0f); + else if (loop == m_Pick[1]) + glColor3f(0.8f,0.0f,0.0f); + else + glColor3f(0.8f,0.8f,0.0f); + + glVertex3fv((float *)&tempParticle->pos); + tempParticle++; + } + glEnd(); + } + } + +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetNearestPoint +// Purpose: Use OpenGL Feedback to find the closest point to a mouseclick +// Arguments: Screen coordinates of the hit +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::GetNearestPoint(int x, int y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *feedBuffer; + int hitCount; + tParticle *tempParticle; + int loop; +/////////////////////////////////////////////////////////////////////////////// + // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) + feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); + // TELL OPENGL ABOUT THE BUFFER + glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); + (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE + + tempParticle = m_CurrentSys; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS + glPassThrough((float)loop); + // SEND THE VERTEX + glBegin(GL_POINTS); + glVertex3fv((float *)&tempParticle->pos); + glEnd(); + tempParticle++; + } + hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET + CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT + free(feedBuffer); // GET RID OF THE MEMORY +} +////// GetNearestPoint //////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CompareBuffer +// Purpose: Check the feedback buffer to see if anything is hit +// Arguments: Number of hits, pointer to buffer, point to test +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLint count; + GLfloat token,point[3]; + int loop,currentVertex,result = -1; + long nearest = -1, dist; +/////////////////////////////////////////////////////////////////////////////// + count = size; + while (count) + { + token = buffer[size - count]; // CHECK THE TOKEN + count--; + if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER + { + currentVertex = (int)buffer[size - count]; // WHAT VERTEX + count--; + } + else if (token == GL_POINT_TOKEN) + { + // THERE ARE THREE ELEMENTS TO A POINT TOKEN + for (loop = 0; loop < 3; loop++) + { + point[loop] = buffer[size - count]; + count--; + } + dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); + if (result == -1 || dist < nearest) + { + nearest = dist; + result = currentVertex; + } + } + } + + if (nearest < 50.0f) + { + if (m_Pick[0] == -1) + m_Pick[0] = result; + else if (m_Pick[1] == -1) + m_Pick[1] = result; + else + { + m_Pick[0] = result; + m_Pick[1] = -1; + } + } +} +////// CompareBuffer ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetWorldParticles +// Purpose: Inform the System of the particles under control +// Arguments: List of vertices and count +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetWorldParticles(tVector *coords,int particleCnt) +{ + tParticle *tempParticle; + + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + free(m_TempSys[i]); + } + if (m_Contact) + free(m_Contact); + // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + for (i = 0; i < 5; i++) + { + m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + } + m_ParticleCnt = particleCnt; + + // MULTIPLIED PARTICLE COUNT * 2 SINCE THEY CAN COLLIDE WITH MULTIPLE WALLS + m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt * 2); + m_ContactCnt = 0; + + tempParticle = m_CurrentSys; + for (int loop = 0; loop < particleCnt; loop++) + { + MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) + MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) + MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) + tempParticle->oneOverM = 1.0f; // MASS OF 1 + tempParticle++; + coords++; + } + + // COPY THE SYSTEM TO THE SECOND ONE ALSO + memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); + // COPY THE SYSTEM TO THE RESET BUFFER ALSO + memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); + + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; +} +////// SetWorldParticles ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: FreeSystem +// Purpose: Remove all particles and clear it out +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::FreeSystem() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + if (m_ParticleSys[0]) + { + m_ParticleSys[0] = NULL; + free(m_ParticleSys[0]); + } + if (m_ParticleSys[1]) + { + free(m_ParticleSys[1]); + m_ParticleSys[1] = NULL; + } + if (m_ParticleSys[2]) + { + free(m_ParticleSys[2]); + m_ParticleSys[2] = NULL; // RESET BUFFER + } + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + { + free(m_TempSys[i]); + m_TempSys[i] = NULL; // RESET BUFFER + } + } + if (m_Contact) + { + free(m_Contact); + m_Contact = NULL; + } + if (m_Spring) + { + free(m_Spring); + m_Spring = NULL; + } + m_SpringCnt = 0; + m_ParticleCnt = 0; +} +////// FreeSystem ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadData +// Purpose: Load a simulation system +// Arguments: File pointer +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::LoadData(FILE *fp) +{ + fread(&m_UseGravity,sizeof(BOOL),1,fp); + fread(&m_UseDamping,sizeof(BOOL),1,fp); + fread(&m_UserForceActive,sizeof(BOOL),1,fp); + fread(&m_Gravity,sizeof(tVector),1,fp); + fread(&m_UserForce,sizeof(tVector),1,fp); + fread(&m_UserForceMag,sizeof(float),1,fp); + fread(&m_Kd,sizeof(float),1,fp); + fread(&m_Kr,sizeof(float),1,fp); + fread(&m_Ksh,sizeof(float),1,fp); + fread(&m_Ksd,sizeof(float),1,fp); + fread(&m_ParticleCnt,sizeof(int),1,fp); + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + for (int i = 0; i < 5; i++) + { + m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + } + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; + m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); + fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fread(&m_SpringCnt,sizeof(int),1,fp); + m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); + fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fread(m_Pick,sizeof(int),2,fp); +} +////// LoadData ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SaveData +// Purpose: Save a simulation system +// Arguments: File pointer +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SaveData(FILE *fp) +{ + fwrite(&m_UseGravity,sizeof(BOOL),1,fp); + fwrite(&m_UseDamping,sizeof(BOOL),1,fp); + fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); + fwrite(&m_Gravity,sizeof(tVector),1,fp); + fwrite(&m_UserForce,sizeof(tVector),1,fp); + fwrite(&m_UserForceMag,sizeof(float),1,fp); + fwrite(&m_Kd,sizeof(float),1,fp); + fwrite(&m_Kr,sizeof(float),1,fp); + fwrite(&m_Ksh,sizeof(float),1,fp); + fwrite(&m_Ksd,sizeof(float),1,fp); + fwrite(&m_ParticleCnt,sizeof(int),1,fp); + fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(&m_SpringCnt,sizeof(int),1,fp); + fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fwrite(m_Pick,sizeof(int),2,fp); +} +////// SaveData ////////////////////////////////////////////////////////////// + +// RESET THE SIM TO INITIAL VALUES +void CPhysEnv::ResetWorld() +{ + memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); + memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); +} + +void CPhysEnv::SetWorldProperties() +{ + CSimProps dialog; + dialog.m_CoefRest = m_Kr; + dialog.m_Damping = m_Kd; + dialog.m_GravX = m_Gravity.x; + dialog.m_GravY = m_Gravity.y; + dialog.m_GravZ = m_Gravity.z; + dialog.m_SpringConst = m_Ksh; + dialog.m_SpringDamp = m_Ksd; + dialog.m_UserForceMag = m_UserForceMag; + dialog.m_MouseSpring = m_MouseForceKs; + if (dialog.DoModal() == IDOK) + { + m_Kr = dialog.m_CoefRest; + m_Kd = dialog.m_Damping; + m_Gravity.x = dialog.m_GravX; + m_Gravity.y = dialog.m_GravY; + m_Gravity.z = dialog.m_GravZ; + m_UserForceMag = dialog.m_UserForceMag; + m_Ksh = dialog.m_SpringConst; + m_Ksd = dialog.m_SpringDamp; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + m_Spring[loop].Ks = m_Ksh; + m_Spring[loop].Kd = m_Ksd; + } + + // GET THE NEW MOUSESPRING FORCE + m_MouseForceKs = dialog.m_MouseSpring; + } +} + + +void CPhysEnv::SetVertexMass() +{ + CVertMass dialog; + dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; + if (dialog.DoModal() == IDOK) + { + m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; + } +} + +void CPhysEnv::ApplyUserForce(tVector *force) +{ + ScaleVector(force, m_UserForceMag, &m_UserForce); + m_UserForceActive = TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetMouseForce +// Purpose: Allows the user to interact with selected points by dragging +// Arguments: Delta distance from clicked point, local x and y axes +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector tempX,tempY; +/////////////////////////////////////////////////////////////////////////////// + ScaleVector(localX, (float)deltaX * 0.03f, &tempX); + ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); + if (m_Pick[0] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); + VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); + VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); + } +} +/// SetMouseForce ///////////////////////////////////////////////////////////// + +void CPhysEnv::AddSpring() +{ + tSpring *spring; + // MAKE SURE TWO PARTICLES ARE PICKED + if (m_Pick[0] > -1 && m_Pick[1] > -1) + { + spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); + if (m_Spring != NULL) + memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); + m_Spring = spring; + spring = &m_Spring[m_SpringCnt++]; + spring->Ks = m_Ksh; + spring->Kd = m_Ksd; + spring->p1 = m_Pick[0]; + spring->p2 = m_Pick[1]; + spring->restLen = + sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, + &m_CurrentSys[m_Pick[1]].pos)); + } +} + +void CPhysEnv::ComputeForces( tParticle *system ) +{ + int loop; + tParticle *curParticle,*p1, *p2; + tSpring *spring; + float dist, Hterm, Dterm; + tVector springForce,deltaV,deltaP; + + curParticle = system; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR + + // BUG (3/8/99): THERE WAS A BUG HERE, I FORGOT YOU NEED TO DIVIDE + // BY 1/M TO GET THE TRUE FORCE ACTING ON THE PARTICLE INSTEAD OF A MULTIPLY + // THANKS TO ED POVAZ FOR THE SPOT... + if (m_UseGravity && curParticle->oneOverM != 0) // && curParticle->type != CONTACTING) + { + curParticle->f.x += (m_Gravity.x / curParticle->oneOverM); + curParticle->f.y += (m_Gravity.y / curParticle->oneOverM); + curParticle->f.z += (m_Gravity.z / curParticle->oneOverM); + } + + if (m_UseDamping) + { + curParticle->f.x += (-m_Kd * curParticle->v.x); + curParticle->f.y += (-m_Kd * curParticle->v.y); + curParticle->f.z += (-m_Kd * curParticle->v.z); + } + else + { + curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); + curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); + curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); + } + curParticle++; + } + + // CHECK IF THERE IS A USER FORCE BEING APPLIED + if (m_UserForceActive) + { + if (m_Pick[0] != -1) + { + VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); + } + if (m_Pick[1] != -1) + { + VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); + } + MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE + } + + // NOW DO ALL THE SPRINGS + spring = m_Spring; + for (loop = 0; loop < m_SpringCnt; loop++) + { + p1 = &system[spring->p1]; + p2 = &system[spring->p2]; + VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) + + VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector + Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force +// if (p1->type != CONTACTING) + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 +// if (p2->type != CONTACTING) + VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 + spring++; // DO THE NEXT SPRING + } + + // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE + if (m_MouseForceActive) + { + // APPLY TO EACH PICKED PARTICLE + if (m_Pick[0] > -1) + { + p1 = &system[m_Pick[0]]; + VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + if (m_Pick[1] > -1) + { + p1 = &system[m_Pick[1]]; + VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + } + +} + + + +/////////////////////////////////////////////////////////////////////////////// +// Function: IntegrateSysOverTime +// Purpose: Does the Integration for all the points in a system +// Arguments: Initial Position, Source and Target Particle Systems and Time +// Notes: Computes a single integration step +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float deltaTimeMass; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < m_ParticleCnt; loop++) + { + deltaTimeMass = deltaTime * initial->oneOverM; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = initial->v.x + (source->f.x * deltaTimeMass); + target->v.y = initial->v.y + (source->f.y * deltaTimeMass); + target->v.z = initial->v.z + (source->f.z * deltaTimeMass); + + target->oneOverM = initial->oneOverM; + + // SET THE NEW POSITION + target->pos.x = initial->pos.x + (deltaTime * source->v.x); + target->pos.y = initial->pos.y + (deltaTime * source->v.y); + target->pos.z = initial->pos.z + (deltaTime * source->v.z); + + initial++; + source++; + target++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses Euler's method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::EulerIntegrate( float DeltaTime) +{ + // JUST TAKE A SINGLE STEP + IntegrateSysOverTime(m_CurrentSys,m_CurrentSys, m_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: MidPointIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Midpoint method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::MidPointIntegrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float halfDeltaT; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; + + // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION + IntegrateSysOverTime(m_CurrentSys,m_CurrentSys,m_TempSys[0],halfDeltaT); + + // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES + ComputeForces(m_TempSys[0]); + + // TAKE THE FULL STEP WITH THIS NEW INFORMATION + IntegrateSysOverTime(m_CurrentSys,m_TempSys[0],m_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RK4Integrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Runga-Kutta 4 method +// This could use a generic function 4 times instead of unrolled +// but it was easier for me to debug. Fun for you to optimize. +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::RK4Integrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float halfDeltaT,sixthDeltaT; + tParticle *source,*target,*accum1,*accum2,*accum3,*accum4; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; // SOME TIME VALUES I WILL NEED + sixthDeltaT = 1.0f / 6.0f; + + // FIRST STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[1]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + accum1->f.x = halfDeltaT * source->f.x * source->oneOverM; + accum1->f.y = halfDeltaT * source->f.y * source->oneOverM; + accum1->f.z = halfDeltaT * source->f.z * source->oneOverM; + + accum1->v.x = halfDeltaT * source->v.x; + accum1->v.y = halfDeltaT * source->v.y; + accum1->v.z = halfDeltaT * source->v.z; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE OVER 1/2 TIME + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES + + // SECOND STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[2]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + accum1->f.x = halfDeltaT * target->f.x * source->oneOverM; + accum1->f.y = halfDeltaT * target->f.y * source->oneOverM; + accum1->f.z = halfDeltaT * target->f.z * source->oneOverM; + accum1->v.x = halfDeltaT * target->v.x; + accum1->v.y = halfDeltaT * target->v.y; + accum1->v.z = halfDeltaT * target->v.z; + + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES + + // THIRD STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[3]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // NOTICE I USE THE FULL DELTATIME THIS STEP + accum1->f.x = DeltaTime * target->f.x * source->oneOverM; + accum1->f.y = DeltaTime * target->f.y * source->oneOverM; + accum1->f.z = DeltaTime * target->f.z * source->oneOverM; + accum1->v.x = DeltaTime * target->v.x; + accum1->v.y = DeltaTime * target->v.y; + accum1->v.z = DeltaTime * target->v.z; + + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0]); // COMPUTE THE NEW FORCES + + // FOURTH STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[4]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // NOTICE I USE THE FULL DELTATIME THIS STEP + accum1->f.x = DeltaTime * target->f.x * source->oneOverM; + accum1->f.y = DeltaTime * target->f.y * source->oneOverM; + accum1->f.z = DeltaTime * target->f.z * source->oneOverM; + + accum1->v.x = DeltaTime * target->v.x; + accum1->v.y = DeltaTime * target->v.y; + accum1->v.z = DeltaTime * target->v.z; + + // THIS TIME I DON'T NEED TO COMPUTE THE TEMPORARY POSITIONS + source++; + target++; + accum1++; + } + + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TargetSys; + accum1 = m_TempSys[1]; + accum2 = m_TempSys[2]; + accum3 = m_TempSys[3]; + accum4 = m_TempSys[4]; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE USING RK4 FORMULA + target->v.x = source->v.x + ((accum1->f.x + ((accum2->f.x + accum3->f.x) * 2.0f) + accum4->f.x) * sixthDeltaT); + target->v.y = source->v.y + ((accum1->f.y + ((accum2->f.y + accum3->f.y) * 2.0f) + accum4->f.y) * sixthDeltaT); + target->v.z = source->v.z + ((accum1->f.z + ((accum2->f.z + accum3->f.z) * 2.0f) + accum4->f.z) * sixthDeltaT); + // DETERMINE THE NEW POSITION FOR THE PARTICLE USING RK4 FORMULA + target->pos.x = source->pos.x + ((accum1->v.x + ((accum2->v.x + accum3->v.x) * 2.0f) + accum4->v.x) * sixthDeltaT); + target->pos.y = source->pos.y + ((accum1->v.y + ((accum2->v.y + accum3->v.y) * 2.0f) + accum4->v.y) * sixthDeltaT); + target->pos.z = source->pos.z + ((accum1->v.z + ((accum2->v.z + accum3->v.z) * 2.0f) + accum4->v.z) * sixthDeltaT); + + source++; + target++; + accum1++; + accum2++; + accum3++; + accum4++; + } + +} + +int CPhysEnv::CheckForCollisions( tParticle *system ) +{ + // be optimistic! + int collisionState = NOT_COLLIDING; + float const depthEpsilon = 0.001f; + + int loop; + tParticle *curParticle; + + m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS + + curParticle = system; + for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); + loop++,curParticle++) + { + for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && + (collisionState != PENETRATING);planeIndex++) + { + tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; + + float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; + + if(axbyczd < -depthEpsilon) + { + // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(axbyczd < depthEpsilon) + { + float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); +/* if(relativeVelocity < 0.01f && relativeVelocity > -0.01f) + { + collisionState = CONTACTING; + curParticle->v.x = curParticle->v.y = curParticle->v.z = 0.0f; + curParticle->type = CONTACTING; + } + else */ + if(relativeVelocity < 0.0f) + { + collisionState = COLLIDING; + m_Contact[m_ContactCnt].type = COLLIDING; + m_Contact[m_ContactCnt].particle = loop; + memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); + m_ContactCnt++; + } + } + } + } + + return collisionState; +} + +void CPhysEnv::ResolveCollisions( tParticle *system ) +{ + tContact *contact; + tParticle *particle; // THE PARTICLE COLLIDING + float VdotN; + tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE + contact = m_Contact; + for (int loop = 0; loop < m_ContactCnt; loop++,contact++) + { + particle = &system[contact->particle]; + // CALCULATE Vn + VdotN = DotProduct(&contact->normal,&particle->v); + ScaleVector(&contact->normal, VdotN, &Vn); + // CALCULATE Vt + VectorDifference(&particle->v, &Vn, &Vt); + // SCALE Vn BY COEFFICIENT OF RESTITUTION + ScaleVector(&Vn, m_Kr, &Vn); + // SET THE VELOCITY TO BE THE NEW IMPULSE + VectorDifference(&Vt, &Vn, &particle->v); + } +} + +void CPhysEnv::Simulate(float DeltaTime, BOOL running) +{ + float CurrentTime = 0.0f; + float TargetTime = DeltaTime; + tParticle *tempSys; + int collisionState; + + while(CurrentTime < DeltaTime) + { + if (running) + { + ComputeForces(m_CurrentSys); + + // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK + // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, + // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. + // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY + if (m_CollisionRootFinding) + { + EulerIntegrate(TargetTime-CurrentTime); + } + else + { + switch (m_IntegratorType) + { + case EULER_INTEGRATOR: + EulerIntegrate(TargetTime-CurrentTime); + break; + case MIDPOINT_INTEGRATOR: + MidPointIntegrate(TargetTime-CurrentTime); + break; + case RK4_INTEGRATOR: + RK4Integrate(TargetTime-CurrentTime); + break; + } + } + } + + collisionState = CheckForCollisions(m_TargetSys); + + if(collisionState == PENETRATING) + { + // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER + m_CollisionRootFinding = TRUE; + // we simulated too far, so subdivide time and try again + TargetTime = (CurrentTime + TargetTime) / 2.0f; + + // blow up if we aren't moving forward each step, which is + // probably caused by interpenetration at the frame start + assert(fabs(TargetTime - CurrentTime) > EPSILON); + } + else + { + // either colliding or clear + if(collisionState == COLLIDING) + { + int Counter = 0; + do + { + ResolveCollisions(m_TargetSys); + Counter++; + } while((CheckForCollisions(m_TargetSys) == + COLLIDING) && (Counter < 100)); + + assert(Counter < 100); + m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT BACK TO NORMAL + } + + // we made a successful step, so swap configurations + // to "save" the data for the next step + + CurrentTime = TargetTime; + TargetTime = DeltaTime; + + // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN + tempSys = m_CurrentSys; + m_CurrentSys = m_TargetSys; + m_TargetSys = tempSys; + } + } +} diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.h index fa28b04..2362a38 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/PhysEnv.h @@ -1,136 +1,136 @@ -#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) -#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// PhysEnv.h : header file -// -#include "MathDefs.h" - -#define EPSILON 0.00001f // ERROR TERM -#define DEFAULT_DAMPING 0.002f - -enum tCollisionTypes -{ - NOT_COLLIDING, - PENETRATING, - COLLIDING, - CONTACTING -}; - -enum tIntegratorTypes -{ - EULER_INTEGRATOR, - MIDPOINT_INTEGRATOR, - RK4_INTEGRATOR -}; - - -// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH -struct tCollisionPlane -{ - tVector normal; // inward pointing - float d; // ax + by + cz + d = 0 -}; - -// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM -struct tParticle -{ - tVector pos; // Position of Particle - tVector v; // Velocity of Particle - tVector f; // Force Acting on Particle - float oneOverM; // 1 / Mass of Particle -}; - -// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM -struct tContact -{ - int particle; // Particle Index - tVector normal; // Normal of Collision plane - int type; // COLLIDING OR CONTACT -}; - -// TYPE FOR SPRINGS IN SYSTEM -struct tSpring -{ - int p1,p2; // PARTICLE INDEX FOR ENDS - float restLen; // LENGTH OF SPRING AT REST - float Ks; // SPRING CONSTANT - float Kd; // SPRING DAMPING -}; - -class CPhysEnv -{ -// Construction -public: - CPhysEnv(); - void RenderWorld(); - void SetWorldParticles(tVector *coords,int particleCnt); - void ResetWorld(); - void Simulate(float DeltaTime,BOOL running); - void ApplyUserForce(tVector *force); - void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); - void GetNearestPoint(int x, int y); - void AddSpring(); - void SetVertexMass(); - void SetWorldProperties(); - void FreeSystem(); - void LoadData(FILE *fp); - void SaveData(FILE *fp); - BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN - BOOL m_UseDamping; // SHOULD DAMPING BE ON - BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED - BOOL m_DrawSprings; // DRAW THE SPRING LINES - BOOL m_DrawVertices; // DRAW VERTICES - BOOL m_MouseForceActive; // MOUSE DRAG FORCE - BOOL m_CollisionRootFinding; // TRYING TO FIND A COLLISION - int m_IntegratorType; - -// Attributes -private: - float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; - tVector m_Gravity; // GRAVITY FORCE VECTOR - tVector m_UserForce; // USER FORCE VECTOR - float m_UserForceMag; // MAGNITUDE OF USER FORCE - float m_Kd; // DAMPING FACTOR - float m_Kr; // COEFFICIENT OF RESTITUTION - float m_Ksh; // HOOK'S SPRING CONSTANT - float m_Ksd; // SPRING DAMPING - float m_Csf, m_Ckf; // Static and Kinetic Friction - float m_MouseForceKs; // MOUSE SPRING COEFFICIENT - tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES - int m_CollisionPlaneCnt; - tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS - int m_ContactCnt; // COLLISION COUNT - tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES - tParticle *m_CurrentSys,*m_TargetSys; - tParticle *m_TempSys[5]; // SETUP FOR TEMP PARTICLES USED WHILE INTEGRATING - int m_ParticleCnt; - tSpring *m_Spring; // VALID SPRINGS IN SYSTEM - int m_SpringCnt; - int m_Pick[2]; // INDEX COUNTERS FOR SELECTING - tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR -// Operations -private: - inline void IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime); - void RK4Integrate( float DeltaTime); - void MidPointIntegrate( float DeltaTime); - void EulerIntegrate( float DeltaTime); - void ComputeForces( tParticle *system ); - int CheckForCollisions( tParticle *system ); - void ResolveCollisions( tParticle *system ); - void CompareBuffer(int size, float *buffer,float x, float y); - -// Implementation -public: - virtual ~CPhysEnv(); - -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PhysEnv.h : header file +// +#include "MathDefs.h" + +#define EPSILON 0.00001f // ERROR TERM +#define DEFAULT_DAMPING 0.002f + +enum tCollisionTypes +{ + NOT_COLLIDING, + PENETRATING, + COLLIDING, + CONTACTING +}; + +enum tIntegratorTypes +{ + EULER_INTEGRATOR, + MIDPOINT_INTEGRATOR, + RK4_INTEGRATOR +}; + + +// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH +struct tCollisionPlane +{ + tVector normal; // inward pointing + float d; // ax + by + cz + d = 0 +}; + +// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM +struct tParticle +{ + tVector pos; // Position of Particle + tVector v; // Velocity of Particle + tVector f; // Force Acting on Particle + float oneOverM; // 1 / Mass of Particle +}; + +// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM +struct tContact +{ + int particle; // Particle Index + tVector normal; // Normal of Collision plane + int type; // COLLIDING OR CONTACT +}; + +// TYPE FOR SPRINGS IN SYSTEM +struct tSpring +{ + int p1,p2; // PARTICLE INDEX FOR ENDS + float restLen; // LENGTH OF SPRING AT REST + float Ks; // SPRING CONSTANT + float Kd; // SPRING DAMPING +}; + +class CPhysEnv +{ +// Construction +public: + CPhysEnv(); + void RenderWorld(); + void SetWorldParticles(tVector *coords,int particleCnt); + void ResetWorld(); + void Simulate(float DeltaTime,BOOL running); + void ApplyUserForce(tVector *force); + void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); + void GetNearestPoint(int x, int y); + void AddSpring(); + void SetVertexMass(); + void SetWorldProperties(); + void FreeSystem(); + void LoadData(FILE *fp); + void SaveData(FILE *fp); + BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN + BOOL m_UseDamping; // SHOULD DAMPING BE ON + BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED + BOOL m_DrawSprings; // DRAW THE SPRING LINES + BOOL m_DrawVertices; // DRAW VERTICES + BOOL m_MouseForceActive; // MOUSE DRAG FORCE + BOOL m_CollisionRootFinding; // TRYING TO FIND A COLLISION + int m_IntegratorType; + +// Attributes +private: + float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; + tVector m_Gravity; // GRAVITY FORCE VECTOR + tVector m_UserForce; // USER FORCE VECTOR + float m_UserForceMag; // MAGNITUDE OF USER FORCE + float m_Kd; // DAMPING FACTOR + float m_Kr; // COEFFICIENT OF RESTITUTION + float m_Ksh; // HOOK'S SPRING CONSTANT + float m_Ksd; // SPRING DAMPING + float m_Csf, m_Ckf; // Static and Kinetic Friction + float m_MouseForceKs; // MOUSE SPRING COEFFICIENT + tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES + int m_CollisionPlaneCnt; + tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS + int m_ContactCnt; // COLLISION COUNT + tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES + tParticle *m_CurrentSys,*m_TargetSys; + tParticle *m_TempSys[5]; // SETUP FOR TEMP PARTICLES USED WHILE INTEGRATING + int m_ParticleCnt; + tSpring *m_Spring; // VALID SPRINGS IN SYSTEM + int m_SpringCnt; + int m_Pick[2]; // INDEX COUNTERS FOR SELECTING + tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR +// Operations +private: + inline void IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime); + void RK4Integrate( float DeltaTime); + void MidPointIntegrate( float DeltaTime); + void EulerIntegrate( float DeltaTime); + void ComputeForces( tParticle *system ); + int CheckForCollisions( tParticle *system ); + void ResolveCollisions( tParticle *system ); + void CompareBuffer(int size, float *buffer,float x, float y); + +// Implementation +public: + virtual ~CPhysEnv(); + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/ReadMe.txt b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/ReadMe.txt index 6c80cbd..30be0b7 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/ReadMe.txt +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/ReadMe.txt @@ -1,127 +1,127 @@ -3D Real-time Soft Body Dynamics Demonstration April 5, 1999 --------------------------------------------------------- -v. 2.0 - -Sorry it took some time to release this code. It took a -while to recover from the GDC andd get my actual job-work -caught up. I finally sat down and commented and cleaned -things up. - -This is the same demonstration as the February column with -the addition of better integration. There are two integrators -in addition to the Euler one from that issue. - -Midpoint Method (RK2) - This integrator evaluates the function at a half step then - takes a full step with those values - -Runge-Kutta 4 - This very sophisticated integrator actually evaluates the - function four times and is very stable even with very stiff - springs. - -For example the "GonaBlow" test using the Euler integrator blew up. -Using both the Midpoint and RK4 integrators, this works fine. -Try these files with the new engine. - -GonaBlow.dps Spring Stiffness = 20.0 Damping = 0.1 Midpoint & RK4 -GonaBlw2.dps Spring Stiffness = 200.0 Damping = 0.01 RK4 only - -Since the new integrators need to recompute the forces multiple -times, there are quite a few extra calculations. In fact I found -while the collisions were being resolved and the simulator was backing -up to find the exact time of collision, the sim was too slow. So -I set it up so that it uses the Euler integrator only during collision -rootfinding. This dramatically speeds up performance while not effecting -stability as far as I can see. - -This needs to be optimized like crazy if you want to use it in a -production application. One obvious point for optimizing would be -to change the way the springs work so that they use the squared-distance -as the baseline so it would avoid the SQRT function in the force -calculations. I am sure you will all find a lot of others. The -RK4 code could probably be organized a lot better I know. Drop me -a copy of any cool improvements you make. - -Jeff - -v. 1.0 Jan 1999 - -This program simulates soft body dynamics of a particle system -with particles connected with springs. - -This program is fairly complicated. In order to show off the -features I wanted to demonstrate, I needed to create quite a -number of functions and UI. I appologize for all the extra junk -but it was as clear as I could make it in the time allowed. -All the major functions for the actual dynamic simulation are in -the files: PhysEnv.h and PhysEnv.cpp. Some of the timing -and display code is in OGLView.h and OGLView.cpp. Most of -the UI is passed through MainFrm.cpp to OGLView. - -All of the simulation constants can be set through the -Simulation Properties dialog. Any changes to the spring constants -are applied to all springs in the simulation. There is currently -no way to change the settings for an individual spring. - -You can load in one of the pre-made simulations or create a -new one by loading in an OBJ. The OBJ needs to be scaled -within a +-5 unit cube world so it fits within the world boundaries. -An OBJ file loads as a point cloud. You then can connect the dots -by selecting vertices two at a time. Press "ENTER" to connect the -points with a spring. The normal length of the spring is the distance -at the time of spring creation. - -You can select one or two vertices and apply an user force to -the selected vertex/vertices. Once selected, a user force is -applied with the arrow keys for X-axis and Z-axis and HOME/END -applies the force to the Y-axis. The magnitude of the user force -is set in the sim properties dialog. - -You can also click and drag the LMB to apply a force in the local -X and Y axis. The mousespring force is set in the sim properties -dialog. The force will apply to the one or two vertices selected. - -Demos: - -"GonaBlow" -Be sure an check out the "GonaBlow" demo. It shows what happens -when the integrator suffers from numerical instability. You can -prove this by halving the MaxStepSize in the Timing Property Dialog. -We will fix that next month. - -"BoxBad" -This box is only connected along the cube edges. It is not stable in -this form. Try it out and see why. - -"BoxGood" -By adding crossbeam supports, it becomes stable. This is a good example -of how to create a stable model. - -"Diamond" -Another shape with pretty stiff springs. It is interesting to see how -it balances on an edge and then eventually falls. I suspect this is rounding -errors. In theory, it should balance exactly forever. - -This is a pretty complex demo. Any problems or questions, email me. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I compiled the code with Visual C++ 6.0. It has been tested -with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -Also, depending on how well GLlines are drawn on your system, the -sim should run too fast, too slow, or just right. I try to lock -it to the clock except to set the timesteps. If it is strange, -adjust COGLView::RunSim(). - +3D Real-time Soft Body Dynamics Demonstration April 5, 1999 +-------------------------------------------------------- +v. 2.0 + +Sorry it took some time to release this code. It took a +while to recover from the GDC andd get my actual job-work +caught up. I finally sat down and commented and cleaned +things up. + +This is the same demonstration as the February column with +the addition of better integration. There are two integrators +in addition to the Euler one from that issue. + +Midpoint Method (RK2) + This integrator evaluates the function at a half step then + takes a full step with those values + +Runge-Kutta 4 + This very sophisticated integrator actually evaluates the + function four times and is very stable even with very stiff + springs. + +For example the "GonaBlow" test using the Euler integrator blew up. +Using both the Midpoint and RK4 integrators, this works fine. +Try these files with the new engine. + +GonaBlow.dps Spring Stiffness = 20.0 Damping = 0.1 Midpoint & RK4 +GonaBlw2.dps Spring Stiffness = 200.0 Damping = 0.01 RK4 only + +Since the new integrators need to recompute the forces multiple +times, there are quite a few extra calculations. In fact I found +while the collisions were being resolved and the simulator was backing +up to find the exact time of collision, the sim was too slow. So +I set it up so that it uses the Euler integrator only during collision +rootfinding. This dramatically speeds up performance while not effecting +stability as far as I can see. + +This needs to be optimized like crazy if you want to use it in a +production application. One obvious point for optimizing would be +to change the way the springs work so that they use the squared-distance +as the baseline so it would avoid the SQRT function in the force +calculations. I am sure you will all find a lot of others. The +RK4 code could probably be organized a lot better I know. Drop me +a copy of any cool improvements you make. + +Jeff + +v. 1.0 Jan 1999 + +This program simulates soft body dynamics of a particle system +with particles connected with springs. + +This program is fairly complicated. In order to show off the +features I wanted to demonstrate, I needed to create quite a +number of functions and UI. I appologize for all the extra junk +but it was as clear as I could make it in the time allowed. +All the major functions for the actual dynamic simulation are in +the files: PhysEnv.h and PhysEnv.cpp. Some of the timing +and display code is in OGLView.h and OGLView.cpp. Most of +the UI is passed through MainFrm.cpp to OGLView. + +All of the simulation constants can be set through the +Simulation Properties dialog. Any changes to the spring constants +are applied to all springs in the simulation. There is currently +no way to change the settings for an individual spring. + +You can load in one of the pre-made simulations or create a +new one by loading in an OBJ. The OBJ needs to be scaled +within a +-5 unit cube world so it fits within the world boundaries. +An OBJ file loads as a point cloud. You then can connect the dots +by selecting vertices two at a time. Press "ENTER" to connect the +points with a spring. The normal length of the spring is the distance +at the time of spring creation. + +You can select one or two vertices and apply an user force to +the selected vertex/vertices. Once selected, a user force is +applied with the arrow keys for X-axis and Z-axis and HOME/END +applies the force to the Y-axis. The magnitude of the user force +is set in the sim properties dialog. + +You can also click and drag the LMB to apply a force in the local +X and Y axis. The mousespring force is set in the sim properties +dialog. The force will apply to the one or two vertices selected. + +Demos: + +"GonaBlow" +Be sure an check out the "GonaBlow" demo. It shows what happens +when the integrator suffers from numerical instability. You can +prove this by halving the MaxStepSize in the Timing Property Dialog. +We will fix that next month. + +"BoxBad" +This box is only connected along the cube edges. It is not stable in +this form. Try it out and see why. + +"BoxGood" +By adding crossbeam supports, it becomes stable. This is a good example +of how to create a stable model. + +"Diamond" +Another shape with pretty stiff springs. It is interesting to see how +it balances on an edge and then eventually falls. I suspect this is rounding +errors. In theory, it should balance exactly forever. + +This is a pretty complex demo. Any problems or questions, email me. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I compiled the code with Visual C++ 6.0. It has been tested +with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +Also, depending on how well GLlines are drawn on your system, the +sim should run too fast, too slow, or just right. I try to lock +it to the clock except to set the timesteps. If it is strange, +adjust COGLView::RunSim(). + diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.cpp index 5d47e9a..3fda127 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.cpp @@ -1,58 +1,58 @@ -// SimProps.cpp : implementation file -// - -#include "stdafx.h" -#include "squashy.h" -#include "SimProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - - -CSimProps::CSimProps(CWnd* pParent /*=NULL*/) - : CDialog(CSimProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSimProps) - m_CoefRest = 0.0f; - m_Damping = 0.0f; - m_GravX = 0.0f; - m_GravY = 0.0f; - m_GravZ = 0.0f; - m_SpringConst = 0.0f; - m_SpringDamp = 0.0f; - m_UserForceMag = 0.0f; - m_MouseSpring = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSimProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSimProps) - DDX_Text(pDX, IDC_COEFREST, m_CoefRest); - DDX_Text(pDX, IDC_Damping, m_Damping); - DDX_Text(pDX, IDC_GRAVX, m_GravX); - DDX_Text(pDX, IDC_GRAVY, m_GravY); - DDX_Text(pDX, IDC_GRAVZ, m_GravZ); - DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); - DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); - DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); - DDX_Text(pDX, IDC_MOUSESPRING, m_MouseSpring); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSimProps, CDialog) - //{{AFX_MSG_MAP(CSimProps) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSimProps message handlers +// SimProps.cpp : implementation file +// + +#include "stdafx.h" +#include "squashy.h" +#include "SimProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + + +CSimProps::CSimProps(CWnd* pParent /*=NULL*/) + : CDialog(CSimProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSimProps) + m_CoefRest = 0.0f; + m_Damping = 0.0f; + m_GravX = 0.0f; + m_GravY = 0.0f; + m_GravZ = 0.0f; + m_SpringConst = 0.0f; + m_SpringDamp = 0.0f; + m_UserForceMag = 0.0f; + m_MouseSpring = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSimProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSimProps) + DDX_Text(pDX, IDC_COEFREST, m_CoefRest); + DDX_Text(pDX, IDC_Damping, m_Damping); + DDX_Text(pDX, IDC_GRAVX, m_GravX); + DDX_Text(pDX, IDC_GRAVY, m_GravY); + DDX_Text(pDX, IDC_GRAVZ, m_GravZ); + DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); + DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); + DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); + DDX_Text(pDX, IDC_MOUSESPRING, m_MouseSpring); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSimProps, CDialog) + //{{AFX_MSG_MAP(CSimProps) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSimProps message handlers diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.h index de3b133..f514208 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/SimProps.h @@ -1,53 +1,53 @@ -#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) -#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// SimProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - -class CSimProps : public CDialog -{ -// Construction -public: - CSimProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSimProps) - enum { IDD = IDD_SIMPROP }; - float m_CoefRest; - float m_Damping; - float m_GravX; - float m_GravY; - float m_GravZ; - float m_SpringConst; - float m_SpringDamp; - float m_UserForceMag; - float m_MouseSpring; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSimProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSimProps) - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// SimProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + +class CSimProps : public CDialog +{ +// Construction +public: + CSimProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSimProps) + enum { IDD = IDD_SIMPROP }; + float m_CoefRest; + float m_Damping; + float m_GravX; + float m_GravY; + float m_GravZ; + float m_SpringConst; + float m_SpringDamp; + float m_UserForceMag; + float m_MouseSpring; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSimProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSimProps) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.cpp index 68cf8c4..ac13a71 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.cpp @@ -1,166 +1,166 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { -// free(child->primChannel); - child->primChannel = NULL; - } - if (child->visualCnt > 0) - { - free(child->visuals->vertexData); - if (child->visuals->faceIndex) - free(child->visuals->faceIndex); - free(child->visuals); - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - if (root->visualCnt > 0) - { - free(root->visuals->vertexData); - if (root->visuals->faceIndex) - free(root->visuals->faceIndex); - free(root->visuals); - } - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { +// free(child->primChannel); + child->primChannel = NULL; + } + if (child->visualCnt > 0) + { + free(child->visuals->vertexData); + if (child->visuals->faceIndex) + free(child->visuals->faceIndex); + free(child->visuals); + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + if (root->visualCnt > 0) + { + free(root->visuals->vertexData); + if (root->visuals->faceIndex) + free(root->visuals->faceIndex); + free(root->visuals); + } + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.h index 46b5d27..87139bd 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Skeleton.h @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -#define ushort unsigned short -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "MathDefs.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS - ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED - int vSize; // NUMBER OF FLOATS IN A VERTEX - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *faceNormal; // POINTER TO FACE NORMALS - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tVector Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - int glTex; - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -}; - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +#define ushort unsigned short +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "MathDefs.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS + ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED + int vSize; // NUMBER OF FLOATS IN A VERTEX + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *faceNormal; // POINTER TO FACE NORMALS + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tVector Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + int glTex; + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +}; + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.cpp index 0cfe8cd..561bf65 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Squashy.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Squashy.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp - -BEGIN_MESSAGE_MAP(CSquashyApp, CWinApp) - //{{AFX_MSG_MAP(CSquashyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp construction - -CSquashyApp::CSquashyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSquashyApp object - -CSquashyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp initialization - -BOOL CSquashyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSquashyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Squashy.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Squashy.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp + +BEGIN_MESSAGE_MAP(CSquashyApp, CWinApp) + //{{AFX_MSG_MAP(CSquashyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp construction + +CSquashyApp::CSquashyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSquashyApp object + +CSquashyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp initialization + +BOOL CSquashyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSquashyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp commands diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.h index b92b5f2..954a5f4 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Squashy.h : main header file for the Squashy application -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp: -// See Squashy.cpp for the implementation of this class -// - -class CSquashyApp : public CWinApp -{ -public: - CSquashyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSquashyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSquashyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Squashy.h : main header file for the Squashy application +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp: +// See Squashy.cpp for the implementation of this class +// + +class CSquashyApp : public CWinApp +{ +public: + CSquashyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSquashyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSquashyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.mak b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.mak index 62582b1..449012a 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.mak +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/Squashy.mak @@ -1,342 +1,342 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Squashy.dsp -!IF "$(CFG)" == "" -CFG=Squashy - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Squashy - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Squashy - Win32 Release" && "$(CFG)" != "Squashy - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Squashy.mak" CFG="Squashy - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Squashy - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Squashy - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Squashy - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\Squashy.obj" - -@erase "$(INTDIR)\Squashy.pch" - -@erase "$(INTDIR)\Squashy.res" - -@erase "$(INTDIR)\Squashy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PickObj.obj" - -@erase "$(INTDIR)\PickObj.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\Squashy.bsc" - -@erase "$(OUTDIR)\Squashy.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\Squashy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PickObj.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Squashy.pdb" /machine:I386 /out:"$(OUTDIR)\Squashy.exe" -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\Squashy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PickObj.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Squashy.res" - -"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\Squashy.obj" - -@erase "$(INTDIR)\Squashy.pch" - -@erase "$(INTDIR)\Squashy.res" - -@erase "$(INTDIR)\Squashy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PickObj.obj" - -@erase "$(INTDIR)\PickObj.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\Squashy.bsc" - -@erase "$(OUTDIR)\Squashy.exe" - -@erase "$(OUTDIR)\Squashy.ilk" - -@erase "$(OUTDIR)\Squashy.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\Squashy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PickObj.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Squashy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Squashy.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\Squashy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PickObj.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Squashy.res" - -"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("Squashy.dep") -!INCLUDE "Squashy.dep" -!ELSE -!MESSAGE Warning: cannot find "Squashy.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "Squashy - Win32 Release" || "$(CFG)" == "Squashy - Win32 Debug" -SOURCE=.\Bitmap.cpp - -"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Squashy.cpp - -"$(INTDIR)\Squashy.obj" "$(INTDIR)\Squashy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Squashy.rc - -"$(INTDIR)\Squashy.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\LoadOBJ.cpp - -"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\MainFrm.cpp - -"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\MathDefs.cpp - -"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\OGLView.cpp - -"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\PickObj.cpp - -"$(INTDIR)\PickObj.obj" "$(INTDIR)\PickObj.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Skeleton.cpp - -"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\StdAfx.cpp - -!IF "$(CFG)" == "Squashy - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Squashy.dsp +!IF "$(CFG)" == "" +CFG=Squashy - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Squashy - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Squashy - Win32 Release" && "$(CFG)" != "Squashy - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Squashy.mak" CFG="Squashy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Squashy - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Squashy - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Squashy - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\Squashy.obj" + -@erase "$(INTDIR)\Squashy.pch" + -@erase "$(INTDIR)\Squashy.res" + -@erase "$(INTDIR)\Squashy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PickObj.obj" + -@erase "$(INTDIR)\PickObj.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\Squashy.bsc" + -@erase "$(OUTDIR)\Squashy.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\Squashy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PickObj.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Squashy.pdb" /machine:I386 /out:"$(OUTDIR)\Squashy.exe" +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\Squashy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PickObj.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Squashy.res" + +"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\Squashy.obj" + -@erase "$(INTDIR)\Squashy.pch" + -@erase "$(INTDIR)\Squashy.res" + -@erase "$(INTDIR)\Squashy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PickObj.obj" + -@erase "$(INTDIR)\PickObj.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\Squashy.bsc" + -@erase "$(OUTDIR)\Squashy.exe" + -@erase "$(OUTDIR)\Squashy.ilk" + -@erase "$(OUTDIR)\Squashy.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\Squashy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PickObj.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Squashy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Squashy.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\Squashy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PickObj.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Squashy.res" + +"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("Squashy.dep") +!INCLUDE "Squashy.dep" +!ELSE +!MESSAGE Warning: cannot find "Squashy.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "Squashy - Win32 Release" || "$(CFG)" == "Squashy - Win32 Debug" +SOURCE=.\Bitmap.cpp + +"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Squashy.cpp + +"$(INTDIR)\Squashy.obj" "$(INTDIR)\Squashy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Squashy.rc + +"$(INTDIR)\Squashy.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\LoadOBJ.cpp + +"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\MainFrm.cpp + +"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\MathDefs.cpp + +"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\OGLView.cpp + +"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\PickObj.cpp + +"$(INTDIR)\PickObj.obj" "$(INTDIR)\PickObj.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Skeleton.cpp + +"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\StdAfx.cpp + +!IF "$(CFG)" == "Squashy - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.cpp index 6a8db00..6aae14b 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Squashy.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Squashy.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.h index ddefdab..571c76c 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.cpp index c1823de..56471a3 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.cpp @@ -1,48 +1,48 @@ -// TimeProps.cpp : implementation file -// - -#include "stdafx.h" -#include "squashy.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - - -CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) - : CDialog(CTimeProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CTimeProps) - m_FixedTimeSteps = FALSE; - m_Iterations = 0; - m_MaxTimeStep = 0.0f; - //}}AFX_DATA_INIT -} - - -void CTimeProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CTimeProps) - DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); - DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); - DDV_MinMaxInt(pDX, m_Iterations, 1, 100); - DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CTimeProps, CDialog) - //{{AFX_MSG_MAP(CTimeProps) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps message handlers +// TimeProps.cpp : implementation file +// + +#include "stdafx.h" +#include "squashy.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + + +CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) + : CDialog(CTimeProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTimeProps) + m_FixedTimeSteps = FALSE; + m_Iterations = 0; + m_MaxTimeStep = 0.0f; + //}}AFX_DATA_INIT +} + + +void CTimeProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTimeProps) + DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); + DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); + DDV_MinMaxInt(pDX, m_Iterations, 1, 100); + DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CTimeProps, CDialog) + //{{AFX_MSG_MAP(CTimeProps) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps message handlers diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.h index 07041d8..2222823 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/TimeProps.h @@ -1,48 +1,48 @@ -#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// TimeProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - -class CTimeProps : public CDialog -{ -// Construction -public: - CTimeProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CTimeProps) - enum { IDD = IDD_SIMTIMING }; - BOOL m_FixedTimeSteps; - int m_Iterations; - float m_MaxTimeStep; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CTimeProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CTimeProps) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// TimeProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + +class CTimeProps : public CDialog +{ +// Construction +public: + CTimeProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTimeProps) + enum { IDD = IDD_SIMTIMING }; + BOOL m_FixedTimeSteps; + int m_Iterations; + float m_MaxTimeStep; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTimeProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CTimeProps) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.cpp b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.cpp index 35359fa..d060351 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.cpp +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.cpp @@ -1,43 +1,43 @@ -// VertMass.cpp : implementation file -// - -#include "stdafx.h" -#include "squashy.h" -#include "VertMass.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CVertMass dialog - - -CVertMass::CVertMass(CWnd* pParent /*=NULL*/) - : CDialog(CVertMass::IDD, pParent) -{ - //{{AFX_DATA_INIT(CVertMass) - m_VertexMass = 0.0f; - //}}AFX_DATA_INIT -} - - -void CVertMass::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CVertMass) - DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CVertMass, CDialog) - //{{AFX_MSG_MAP(CVertMass) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CVertMass message handlers +// VertMass.cpp : implementation file +// + +#include "stdafx.h" +#include "squashy.h" +#include "VertMass.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CVertMass dialog + + +CVertMass::CVertMass(CWnd* pParent /*=NULL*/) + : CDialog(CVertMass::IDD, pParent) +{ + //{{AFX_DATA_INIT(CVertMass) + m_VertexMass = 0.0f; + //}}AFX_DATA_INIT +} + + +void CVertMass::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CVertMass) + DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CVertMass, CDialog) + //{{AFX_MSG_MAP(CVertMass) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CVertMass message handlers diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.h index d721109..57035f5 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/VertMass.h @@ -1,46 +1,46 @@ -#if !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// VertMass.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CVertMass dialog - -class CVertMass : public CDialog -{ -// Construction -public: - CVertMass(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CVertMass) - enum { IDD = IDD_VERTEXMASS }; - float m_VertexMass; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CVertMass) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CVertMass) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// VertMass.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CVertMass dialog + +class CVertMass : public CDialog +{ +// Construction +public: + CVertMass(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CVertMass) + enum { IDD = IDD_VERTEXMASS }; + float m_VertexMass; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CVertMass) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CVertMass) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/resource.h b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/resource.h index 3b6f482..a45fce8 100644 --- a/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/resource.h +++ b/Particle Dynamics Part 2 - Better Integration/Code/OGL/Squashy/resource.h @@ -1,80 +1,80 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Squashy.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SQUASHYTYPE 129 -#define IDD_SETROTATE 130 -#define IDB_HUP 131 -#define IDB_HDN 132 -#define IDD_DIALOG1 132 -#define IDB_HUPP 133 -#define IDD_LOADOBJ 133 -#define IDD_PICKOBJ 133 -#define IDB_HDNP 134 -#define IDD_SIMPROP 134 -#define IDB_VDN 135 -#define IDD_VERTEXMASS 135 -#define IDB_VUP 136 -#define IDD_SIMTIMING 136 -#define IDB_VUPP 137 -#define IDB_VDNP 138 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_BUTTON1 1001 -#define IDC_BROWSE1 1001 -#define IDC_ZAXIS 1002 -#define IDC_BROWSE2 1002 -#define IDC_SLIDER1 1003 -#define IDC_EDIT1 1004 -#define IDC_GRAVX 1004 -#define IDC_MAXTIMESTEP 1004 -#define IDC_EDIT2 1005 -#define IDC_OBJLIST 1005 -#define IDC_GRAVY 1005 -#define IDC_ITERATIONS 1005 -#define IDC_GRAVZ 1006 -#define IDC_COEFREST 1007 -#define IDC_SPRINGCONST 1008 -#define IDC_Damping 1009 -#define IDC_SPRINGDAMP 1010 -#define IDC_USERFORCEMAG 1011 -#define IDC_VERTEXMASS 1012 -#define IDC_MOUSESPRING 1013 -#define IDC_FIXEDTIME 1014 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_METHOD_FASTBBOX 32775 -#define ID_VIEW_SHOWBBOX 32776 -#define ID_VIEW_SHOWOBBOX 32777 -#define ID_VIEW_SHOWSPRINGS 32778 -#define ID_VIEW_SHOWGEOMETRY 32779 -#define ID_SIMULATION_RUNNING 32780 -#define ID_SIMULATION_RESET 32781 -#define ID_SIMULATION_SETSIMPROPERTIES 32782 -#define ID_SIMULATION_USEGRAVITY 32783 -#define ID_VIEW_SHOWVERTICES 32785 -#define ID_FILE_NEWSYSTEM 32786 -#define ID_SIMULATION_SETVERTEXMASS 32787 -#define ID_SIMULATION_SETTIMINGPROPERTIES 32788 -#define ID_INTEGRATOR_EULER 32789 -#define ID_INTEGRATOR_MIDPOINT 32790 -#define ID_INTEGRATOR_RUNGEKUTTA4 32791 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 137 -#define _APS_NEXT_COMMAND_VALUE 32792 -#define _APS_NEXT_CONTROL_VALUE 1015 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Squashy.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SQUASHYTYPE 129 +#define IDD_SETROTATE 130 +#define IDB_HUP 131 +#define IDB_HDN 132 +#define IDD_DIALOG1 132 +#define IDB_HUPP 133 +#define IDD_LOADOBJ 133 +#define IDD_PICKOBJ 133 +#define IDB_HDNP 134 +#define IDD_SIMPROP 134 +#define IDB_VDN 135 +#define IDD_VERTEXMASS 135 +#define IDB_VUP 136 +#define IDD_SIMTIMING 136 +#define IDB_VUPP 137 +#define IDB_VDNP 138 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_BUTTON1 1001 +#define IDC_BROWSE1 1001 +#define IDC_ZAXIS 1002 +#define IDC_BROWSE2 1002 +#define IDC_SLIDER1 1003 +#define IDC_EDIT1 1004 +#define IDC_GRAVX 1004 +#define IDC_MAXTIMESTEP 1004 +#define IDC_EDIT2 1005 +#define IDC_OBJLIST 1005 +#define IDC_GRAVY 1005 +#define IDC_ITERATIONS 1005 +#define IDC_GRAVZ 1006 +#define IDC_COEFREST 1007 +#define IDC_SPRINGCONST 1008 +#define IDC_Damping 1009 +#define IDC_SPRINGDAMP 1010 +#define IDC_USERFORCEMAG 1011 +#define IDC_VERTEXMASS 1012 +#define IDC_MOUSESPRING 1013 +#define IDC_FIXEDTIME 1014 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_METHOD_FASTBBOX 32775 +#define ID_VIEW_SHOWBBOX 32776 +#define ID_VIEW_SHOWOBBOX 32777 +#define ID_VIEW_SHOWSPRINGS 32778 +#define ID_VIEW_SHOWGEOMETRY 32779 +#define ID_SIMULATION_RUNNING 32780 +#define ID_SIMULATION_RESET 32781 +#define ID_SIMULATION_SETSIMPROPERTIES 32782 +#define ID_SIMULATION_USEGRAVITY 32783 +#define ID_VIEW_SHOWVERTICES 32785 +#define ID_FILE_NEWSYSTEM 32786 +#define ID_SIMULATION_SETVERTEXMASS 32787 +#define ID_SIMULATION_SETTIMINGPROPERTIES 32788 +#define ID_INTEGRATOR_EULER 32789 +#define ID_INTEGRATOR_MIDPOINT 32790 +#define ID_INTEGRATOR_RUNGEKUTTA4 32791 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 137 +#define _APS_NEXT_COMMAND_VALUE 32792 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Particle Dynamics/code/OGL/Squashy/LoadOBJ.cpp b/Particle Dynamics/code/OGL/Squashy/LoadOBJ.cpp index 144fb4e..29c273c 100644 --- a/Particle Dynamics/code/OGL/Squashy/LoadOBJ.cpp +++ b/Particle Dynamics/code/OGL/Squashy/LoadOBJ.cpp @@ -1,376 +1,376 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = (float)atof(words.GetAt(1)); - visual->Ka.g = (float)atof(words.GetAt(2)); - visual->Ka.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = (float)atof(words.GetAt(1)); - visual->Kd.g = (float)atof(words.GetAt(2)); - visual->Kd.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = (float)atof(words.GetAt(1)); - visual->Ks.g = (float)atof(words.GetAt(2)); - visual->Ks.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = (float)atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle anything other than -// 3-4 vertex polygons. -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loopcnt; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - loopcnt = words->GetSize(); - - // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < loopcnt; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } - face->flags = 0; - if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; - if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; - if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; - else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; - else - { - ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); - face->flags |= FACE_TYPE_TRI; - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone, flags of what to load -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; - unsigned short *indexData; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = (float)atof(words.GetAt(1)); - normal[nPos].y = (float)atof(words.GetAt(2)); - normal[nPos].z = (float)atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = (float)atof(words.GetAt(1)); - texture[tPos].v = (float)atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = (float)atof(words.GetAt(1)); - vertex[vPos].y = (float)atof(words.GetAt(2)); - vertex[vPos].z = (float)atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 5) - { - sprintf(buffer,"Face %d has more than 4 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS - // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF - // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER - if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; - else visual->vPerFace = 4; - - if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - } - visual->faceCnt = fPos; - if ((flags & LOADOBJ_REUSEVERTICES) > 0) - { - visual->reuseVertices = TRUE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); - visual->vertexCnt = vPos; - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); - if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA - { - memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); - } - else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS - { - visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT - } - } - else - { - visual->reuseVertices = FALSE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->vertexCnt = fPos * visual->vPerFace; - visual->faceIndex = NULL; - } - - data = visual->vertexData; - indexData = visual->faceIndex; - for (loop = 0; loop < fPos; loop++) - { - // ERROR CHECKING TO MAKE SURE - if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - - for (loop2 = 0; loop2 < visual->vPerFace; loop2++) - { - // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT - if ((flags & LOADOBJ_REUSEVERTICES) == 0) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - } - else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE - { - *indexData++ = face[loop].v[loop2] - 1; - } - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = (float)atof(words.GetAt(1)); + visual->Ka.g = (float)atof(words.GetAt(2)); + visual->Ka.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = (float)atof(words.GetAt(1)); + visual->Kd.g = (float)atof(words.GetAt(2)); + visual->Kd.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = (float)atof(words.GetAt(1)); + visual->Ks.g = (float)atof(words.GetAt(2)); + visual->Ks.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = (float)atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle anything other than +// 3-4 vertex polygons. +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loopcnt; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + loopcnt = words->GetSize(); + + // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < loopcnt; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } + face->flags = 0; + if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; + if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; + if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; + else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; + else + { + ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); + face->flags |= FACE_TYPE_TRI; + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone, flags of what to load +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; + unsigned short *indexData; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = (float)atof(words.GetAt(1)); + normal[nPos].y = (float)atof(words.GetAt(2)); + normal[nPos].z = (float)atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = (float)atof(words.GetAt(1)); + texture[tPos].v = (float)atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = (float)atof(words.GetAt(1)); + vertex[vPos].y = (float)atof(words.GetAt(2)); + vertex[vPos].z = (float)atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 5) + { + sprintf(buffer,"Face %d has more than 4 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS + // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF + // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER + if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; + else visual->vPerFace = 4; + + if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + } + visual->faceCnt = fPos; + if ((flags & LOADOBJ_REUSEVERTICES) > 0) + { + visual->reuseVertices = TRUE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); + visual->vertexCnt = vPos; + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); + if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA + { + memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); + } + else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS + { + visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT + } + } + else + { + visual->reuseVertices = FALSE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->vertexCnt = fPos * visual->vPerFace; + visual->faceIndex = NULL; + } + + data = visual->vertexData; + indexData = visual->faceIndex; + for (loop = 0; loop < fPos; loop++) + { + // ERROR CHECKING TO MAKE SURE + if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + + for (loop2 = 0; loop2 < visual->vPerFace; loop2++) + { + // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT + if ((flags & LOADOBJ_REUSEVERTICES) == 0) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + } + else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE + { + *indexData++ = face[loop].v[loop2] - 1; + } + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/Particle Dynamics/code/OGL/Squashy/LoadOBJ.h b/Particle Dynamics/code/OGL/Squashy/LoadOBJ.h index 2b75bb3..8184168 100644 --- a/Particle Dynamics/code/OGL/Squashy/LoadOBJ.h +++ b/Particle Dynamics/code/OGL/Squashy/LoadOBJ.h @@ -1,46 +1,46 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -enum LOAD_OBJFLAGS -{ - LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO - LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA - LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS -}; - -// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS -typedef struct -{ - long v[4],n[4],t[4]; - int flags; // FACE TYPES -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +enum LOAD_OBJFLAGS +{ + LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO + LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA + LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS +}; + +// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS +typedef struct +{ + long v[4],n[4],t[4]; + int flags; // FACE TYPES +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/MainFrm.cpp b/Particle Dynamics/code/OGL/Squashy/MainFrm.cpp index 406df58..6f9bef9 100644 --- a/Particle Dynamics/code/OGL/Squashy/MainFrm.cpp +++ b/Particle Dynamics/code/OGL/Squashy/MainFrm.cpp @@ -1,337 +1,337 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Squashy.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) - ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) - ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) - ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) - ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) - ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) - ON_WM_CLOSE() - ON_COMMAND(ID_SIMULATION_SETVERTEXMASS, OnSimulationSetvertexmass) - ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) - ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[1024]; // PLACE TO PUT THE MESSAGE - char who[80],which[80],version[80],extensions[255]; // OPENGL STUFF -/////////////////////////////////////////////////////////////////////////////// - m_OGLView.GetGLInfo(who,which,version,extensions); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who,which,version,extensions); - MessageBox(message,"Which OpenGL Renderer?",MB_OK); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom - - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case ' ': - break; - } - m_OGLView.HandleKeyUp(nChar); -// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -} - - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - - -void CMainFrame::OnFileNewsystem() -{ - m_OGLView.NewSystem(); -} - -void CMainFrame::OnFileOpen() -{ - char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnFileSave() -{ - char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnSimulationRunning() -{ - m_OGLView.HandleKeyUp('R'); // FORCE SYSTEM TO START RUNNING THROUGH KEYPRESS -} - -void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_SimRunning ); -} - -void CMainFrame::OnSimulationReset() -{ - m_OGLView.m_PhysEnv.ResetWorld(); - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnSimulationSetsimproperties() -{ - m_OGLView.OnSimulationSetsimproperties(); -} - -void CMainFrame::OnSimulationSettimingproperties() -{ - m_OGLView.OnSetTimeProperties(); -} - -void CMainFrame::OnSimulationSetvertexmass() -{ - m_OGLView.OnSimulationSetVertexMass(); -} - -void CMainFrame::OnSimulationUsegravity() -{ - m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); -} - - -void CMainFrame::OnViewShowgeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnViewShowsprings() -{ - m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); -} - -void CMainFrame::OnViewShowvertices() -{ - m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); -} - -void CMainFrame::OnClose() -{ - m_OGLView.m_SimRunning = FALSE; - - CFrameWnd::OnClose(); -} - -BOOL CMainFrame::DestroyWindow() -{ - - return CFrameWnd::DestroyWindow(); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Squashy.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) + ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) + ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) + ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) + ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) + ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) + ON_WM_CLOSE() + ON_COMMAND(ID_SIMULATION_SETVERTEXMASS, OnSimulationSetvertexmass) + ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) + ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[1024]; // PLACE TO PUT THE MESSAGE + char who[80],which[80],version[80],extensions[255]; // OPENGL STUFF +/////////////////////////////////////////////////////////////////////////////// + m_OGLView.GetGLInfo(who,which,version,extensions); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who,which,version,extensions); + MessageBox(message,"Which OpenGL Renderer?",MB_OK); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom + + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case ' ': + break; + } + m_OGLView.HandleKeyUp(nChar); +// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +} + + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + + +void CMainFrame::OnFileNewsystem() +{ + m_OGLView.NewSystem(); +} + +void CMainFrame::OnFileOpen() +{ + char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnFileSave() +{ + char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnSimulationRunning() +{ + m_OGLView.HandleKeyUp('R'); // FORCE SYSTEM TO START RUNNING THROUGH KEYPRESS +} + +void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_SimRunning ); +} + +void CMainFrame::OnSimulationReset() +{ + m_OGLView.m_PhysEnv.ResetWorld(); + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnSimulationSetsimproperties() +{ + m_OGLView.OnSimulationSetsimproperties(); +} + +void CMainFrame::OnSimulationSettimingproperties() +{ + m_OGLView.OnSetTimeProperties(); +} + +void CMainFrame::OnSimulationSetvertexmass() +{ + m_OGLView.OnSimulationSetVertexMass(); +} + +void CMainFrame::OnSimulationUsegravity() +{ + m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); +} + + +void CMainFrame::OnViewShowgeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnViewShowsprings() +{ + m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); +} + +void CMainFrame::OnViewShowvertices() +{ + m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); +} + +void CMainFrame::OnClose() +{ + m_OGLView.m_SimRunning = FALSE; + + CFrameWnd::OnClose(); +} + +BOOL CMainFrame::DestroyWindow() +{ + + return CFrameWnd::DestroyWindow(); +} diff --git a/Particle Dynamics/code/OGL/Squashy/MainFrm.h b/Particle Dynamics/code/OGL/Squashy/MainFrm.h index 14dbffc..f11048e 100644 --- a/Particle Dynamics/code/OGL/Squashy/MainFrm.h +++ b/Particle Dynamics/code/OGL/Squashy/MainFrm.h @@ -1,103 +1,103 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual BOOL DestroyWindow(); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileOpen(); - afx_msg void OnSimulationRunning(); - afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); - afx_msg void OnSimulationReset(); - afx_msg void OnSimulationSetsimproperties(); - afx_msg void OnSimulationUsegravity(); - afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); - afx_msg void OnFileSave(); - afx_msg void OnViewShowgeometry(); - afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); - afx_msg void OnViewShowsprings(); - afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); - afx_msg void OnViewShowvertices(); - afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); - afx_msg void OnClose(); - afx_msg void OnSimulationSetvertexmass(); - afx_msg void OnFileNewsystem(); - afx_msg void OnSimulationSettimingproperties(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL DestroyWindow(); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileOpen(); + afx_msg void OnSimulationRunning(); + afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); + afx_msg void OnSimulationReset(); + afx_msg void OnSimulationSetsimproperties(); + afx_msg void OnSimulationUsegravity(); + afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); + afx_msg void OnFileSave(); + afx_msg void OnViewShowgeometry(); + afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); + afx_msg void OnViewShowsprings(); + afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); + afx_msg void OnViewShowvertices(); + afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); + afx_msg void OnClose(); + afx_msg void OnSimulationSetvertexmass(); + afx_msg void OnFileNewsystem(); + afx_msg void OnSimulationSettimingproperties(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/MathDefs.cpp b/Particle Dynamics/code/OGL/Squashy/MathDefs.cpp index 849dbc4..5f58c91 100644 --- a/Particle Dynamics/code/OGL/Squashy/MathDefs.cpp +++ b/Particle Dynamics/code/OGL/Squashy/MathDefs.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: IdentityMatrix -// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void IdentityMatrix(tMatrix *mat) -{ -///// Local Variables ///////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < 16; loop++) - mat->m[loop] = 0.0f; - mat->m[0] = - mat->m[5] = - mat->m[10] = - mat->m[15] = - 1.0f; -} -//// IdentityMatrix /////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByRotMatrix -// Purpose: Multiplies a vector by a 4x4 Rotation Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z); - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z); - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z); -} -//// MultVectorByRotMatrix /////////////////////////////////////////////////// - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void ScaleVector(tVector *v, float scale, tVector *result) -{ - result->x = v->x * scale; - result->y = v->y * scale; - result->z = v->z * scale; -} - -void VectorSum(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x + v2->x; - result->y = v1->y + v2->y; - result->z = v1->z + v2->z; -} - -void VectorDifference(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: IdentityMatrix +// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void IdentityMatrix(tMatrix *mat) +{ +///// Local Variables ///////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < 16; loop++) + mat->m[loop] = 0.0f; + mat->m[0] = + mat->m[5] = + mat->m[10] = + mat->m[15] = + 1.0f; +} +//// IdentityMatrix /////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByRotMatrix +// Purpose: Multiplies a vector by a 4x4 Rotation Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z); + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z); + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z); +} +//// MultVectorByRotMatrix /////////////////////////////////////////////////// + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void ScaleVector(tVector *v, float scale, tVector *result) +{ + result->x = v->x * scale; + result->y = v->y * scale; + result->z = v->z * scale; +} + +void VectorSum(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x + v2->x; + result->y = v1->y + v2->y; + result->z = v1->z + v2->z; +} + +void VectorDifference(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/Particle Dynamics/code/OGL/Squashy/MathDefs.h b/Particle Dynamics/code/OGL/Squashy/MathDefs.h index 60a8d95..efd75ea 100644 --- a/Particle Dynamics/code/OGL/Squashy/MathDefs.h +++ b/Particle Dynamics/code/OGL/Squashy/MathDefs.h @@ -1,117 +1,117 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float nx,ny,nz; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void IdentityMatrix(tMatrix *mat); -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float nx,ny,nz; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void IdentityMatrix(tMatrix *mat); +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Particle Dynamics/code/OGL/Squashy/OGLView.cpp b/Particle Dynamics/code/OGL/Squashy/OGLView.cpp index 5c204e2..111c968 100644 --- a/Particle Dynamics/code/OGL/Squashy/OGLView.cpp +++ b/Particle Dynamics/code/OGL/Squashy/OGLView.cpp @@ -1,832 +1,832 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "Squashy.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION - -#define LERP(a,b,c) (a + ((b - a) * c)) -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_SimRunning = FALSE; - m_CurBone = NULL; - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.b_trans.z = -100.0f; - m_Skeleton.trans.z = -100.0f; - - m_FrameCnt = 0; - - m_TimeIterations = 10; - m_UseFixedTimeStep = FALSE; - m_MaxTimeStep = 0.01f; - - m_hDC = NULL; - - m_PickX = -1; - m_PickY = -1; -} - -COGLView::~COGLView() -{ - DestroySkeleton(&m_Skeleton); -} - - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual = NULL; -/////////////////////////////////////////////////////////////////////////////// - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_CLOSE() - ON_WM_LBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -float COGLView::GetTime( void ) -{ - static DWORD StartMilliseconds; - if(!StartMilliseconds) - { - // yes, the first time through will be a 0 timestep - StartMilliseconds = timeGetTime(); - } - - DWORD CurrentMilliseconds = timeGetTime(); - return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; -} - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glDisable(GL_TEXTURE_2D); - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 - GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); -// glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); -// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - glLineWidth(2.0f); - glPointSize(8.0f); - glDisable(GL_LINE_SMOOTH); - glDepthFunc(GL_LEQUAL); - glDisable(GL_CULL_FACE); - -// glShadeModel(GL_SMOOTH); -// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - -// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); -// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); -// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); -// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 -// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glDisable(GL_LIGHTING); -// glEnable(GL_LIGHT0); - -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo(char *who,char *which, char *version, char *extensions) -{ - strcpy(who,(char *)::glGetString( GL_VENDOR )); - - strcpy(which,(char *)::glGetString( GL_RENDERER )); - - strcpy(version, (char *)::glGetString( GL_VERSION )); - strcpy(extensions, (char *)::glGetString( GL_EXTENSIONS )); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: RunSim -// Purpose: Actual simulation loop -// Notes: Allows you to adjust the rate of simulation or to change it -// to fixed time steps or actual timesteps. -/////////////////////////////////////////////////////////////////////////////// -void COGLView::RunSim() -{ -/// Local Variables /////////////////////////////////////////////////////////// - float Time; - float DeltaTime; -/////////////////////////////////////////////////////////////////////////////// - - if (m_UseFixedTimeStep) - Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); - else - Time = GetTime() * m_TimeIterations; - - while(m_LastTime < Time) - { - DeltaTime = Time - m_LastTime; - if(DeltaTime > m_MaxTimeStep) - { - DeltaTime = m_MaxTimeStep; - } - - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - m_LastTime += DeltaTime; - } - m_LastTime = Time; -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ - if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) - { - glColor3f(1.0f,1.0f,1.0f); - // Declare the Array of Data - glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); - if (curBone->visuals[0].reuseVertices) - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - else - glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - } - else - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); - else - glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); - } - } -} -// drawModel - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; - if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; - if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; - - // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); - - // ROTATE THE ROOT - glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); - - if (m_PickX > -1) - m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); - -// for (loop = 0; loop < 10; loop++) - RunSim(); - - m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION - - glPopMatrix(); - glFinish(); - - if (m_hDC) - SwapBuffers(m_hDC); - -// PLAYING WITH CHECKING FRAMETIMING -/* if (m_SimRunning) - { - m_FrameCnt++; - char message[80]; - DWORD end = timeGetTime(); - float diff = (float)(m_FrameCnt * 1000)/(float)(end - m_StartTime); - - sprintf(message,"%.2f",diff); - m_ptrStatusBar->SetPaneText(0,message); - }*/ - m_PickX = -1; - m_PickY = -1; -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - m_ScreenWidth = cx; - m_ScreenHeight = cy; - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - if ((nFlags & MK_SHIFT) == 0) - { - m_PickX = point.x; - m_PickY = m_ScreenHeight - point.y; - drawScene(); - } - SetCapture( ); - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE - ReleaseCapture(); - CWnd::OnLButtonUp(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - tVector userforce; - switch (nChar) - { - case 13: - m_PhysEnv.AddSpring(); - break; - case 'G': - m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; - break; - case '1': m_curVisual = 0; - break; - case '2': m_curVisual = 1; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - break; - case 'F': - glPolygonMode(GL_FRONT,GL_FILL); - break; - case 'R': - m_SimRunning = !m_SimRunning; - if (m_SimRunning) - m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM - m_StartTime = timeGetTime(); - m_FrameCnt = 0; - break; - case 'T': - m_PhysEnv.ResetWorld(); - break; - case VK_HOME: - userforce.x = m_Skeleton.matrix.m[1]; - userforce.y = m_Skeleton.matrix.m[5]; - userforce.z = m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_END: - userforce.x = -m_Skeleton.matrix.m[1]; - userforce.y = -m_Skeleton.matrix.m[5]; - userforce.z = -m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_RIGHT: - userforce.x = m_Skeleton.matrix.m[0]; - userforce.y = m_Skeleton.matrix.m[4]; - userforce.z = m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_LEFT: - userforce.x = -m_Skeleton.matrix.m[0]; - userforce.y = -m_Skeleton.matrix.m[4]; - userforce.z = -m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_UP: - userforce.x = -m_Skeleton.matrix.m[2]; - userforce.y = -m_Skeleton.matrix.m[6]; - userforce.z = -m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_DOWN: - userforce.x = m_Skeleton.matrix.m[2]; - userforce.y = m_Skeleton.matrix.m[6]; - userforce.z = m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - } - - MSG msg; - - if (m_SimRunning) - { - while (m_SimRunning == TRUE) - { - while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - m_SimRunning = FALSE; - m_hDC = NULL; - PostQuitMessage(0); - break; - } - if (msg.message == WM_CLOSE) - { - m_SimRunning = FALSE; - } - - // Dispatch any messages as needed - if (!AfxGetApp()->PreTranslateMessage(&msg)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - // Give the Idle system some time - AfxGetApp()->OnIdle(0); - AfxGetApp()->OnIdle(1); - - } - drawScene(); - } - } - else - Invalidate(TRUE); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - tVector localX,localY; - - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CONTROL' BUTTON ROTATE - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - // ELSE ROTATE THE BONE - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS - { - // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES - localY.x = m_Skeleton.matrix.m[1]; - localY.y = m_Skeleton.matrix.m[5]; - localY.z = m_Skeleton.matrix.m[9]; - - localX.x = m_Skeleton.matrix.m[0]; - localX.y = m_Skeleton.matrix.m[4]; - localX.z = m_Skeleton.matrix.m[8]; - - m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); - m_PhysEnv.m_MouseForceActive = TRUE; - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: NewSystem -// Purpose: Clears the Simulation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::NewSystem() -{ - m_PhysEnv.FreeSystem(); - m_SimRunning = FALSE; - if (m_Skeleton.childCnt > 0) - { - if (m_Skeleton.children->visuals->vertexData) - free(m_Skeleton.children->visuals->vertexData); - if (m_Skeleton.children->visuals->faceIndex) - free(m_Skeleton.children->visuals->faceIndex); - free(m_Skeleton.children->visuals); - free(m_Skeleton.children); - m_Skeleton.childCnt = 0; - } - drawScene(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadFiles -// Purpose: Loads the OBJ files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadFile(CString file1,CString baseName,CString ext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *children; - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - ext.MakeUpper(); - if (ext == "OBJ") - { - visual = (t_Visual *)malloc(sizeof(t_Visual)); - NewSystem(); // CLEAR WHAT DATA IS THERE - // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT - if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, - LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) - { - // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SetWorldParticles((tVector *)visual->vertexData,visual->vertexCnt); - - children = (t_Bone *)malloc(sizeof(t_Bone)); - m_CurBone = &children[m_Skeleton.childCnt]; - ResetBone(m_CurBone,&m_Skeleton); - strcpy(m_CurBone->name,(LPCTSTR)baseName); - m_CurBone->visuals = visual; - m_CurBone->visualCnt = 1; - m_Skeleton.childCnt = 1; - m_Skeleton.children = children; - } - else - { - MessageBox("Must Be A Valid OBJ File","Error",MB_OK); - free(visual); - } - } - else // LOAD SIM SYSTEM - { - if (file1.GetLength()) - { - fp = fopen(file1,"rb"); - if (fp != NULL) - { - NewSystem(); // CLEAR WHAT DATA IS THERE - fread(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); - fread(m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); - visual = m_Skeleton.children->visuals; - fread(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); - fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.LoadData(fp); - } - } - fclose(fp); - } - } - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: SaveFiles -// Purpose: Saves the Particle System -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SaveFile(CString file1,CString baseName) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - if (file1.GetLength() > 0) - { - fp = fopen(file1,"wb"); - if (fp != NULL) - { - fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - fwrite(&m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - visual = m_Skeleton.children->visuals; - fwrite(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SaveData(fp); - } - } - fclose(fp); - } - } -} - -void COGLView::OnClose() -{ - - CWnd::OnClose(); -} - -void COGLView::OnSimulationSetsimproperties() -{ - m_PhysEnv.SetWorldProperties(); -} - -void COGLView::OnSimulationSetVertexMass() -{ - m_PhysEnv.SetVertexMass(); -} - -void COGLView::OnSetTimeProperties() -{ - CTimeProps dialog; - dialog.m_Iterations = m_TimeIterations; - dialog.m_FixedTimeSteps = m_UseFixedTimeStep; - dialog.m_MaxTimeStep = m_MaxTimeStep; - if (dialog.DoModal()) - { - m_TimeIterations = dialog.m_Iterations; - m_UseFixedTimeStep = dialog.m_FixedTimeSteps; - m_MaxTimeStep = dialog.m_MaxTimeStep; - } -} - +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "Squashy.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION + +#define LERP(a,b,c) (a + ((b - a) * c)) +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_SimRunning = FALSE; + m_CurBone = NULL; + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.b_trans.z = -100.0f; + m_Skeleton.trans.z = -100.0f; + + m_FrameCnt = 0; + + m_TimeIterations = 10; + m_UseFixedTimeStep = FALSE; + m_MaxTimeStep = 0.01f; + + m_hDC = NULL; + + m_PickX = -1; + m_PickY = -1; +} + +COGLView::~COGLView() +{ + DestroySkeleton(&m_Skeleton); +} + + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual = NULL; +/////////////////////////////////////////////////////////////////////////////// + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_CLOSE() + ON_WM_LBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +float COGLView::GetTime( void ) +{ + static DWORD StartMilliseconds; + if(!StartMilliseconds) + { + // yes, the first time through will be a 0 timestep + StartMilliseconds = timeGetTime(); + } + + DWORD CurrentMilliseconds = timeGetTime(); + return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; +} + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glDisable(GL_TEXTURE_2D); + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 + GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); +// glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); +// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glLineWidth(2.0f); + glPointSize(8.0f); + glDisable(GL_LINE_SMOOTH); + glDepthFunc(GL_LEQUAL); + glDisable(GL_CULL_FACE); + +// glShadeModel(GL_SMOOTH); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); +// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); +// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); +// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 +// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_LIGHTING); +// glEnable(GL_LIGHT0); + +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo(char *who,char *which, char *version, char *extensions) +{ + strcpy(who,(char *)::glGetString( GL_VENDOR )); + + strcpy(which,(char *)::glGetString( GL_RENDERER )); + + strcpy(version, (char *)::glGetString( GL_VERSION )); + strcpy(extensions, (char *)::glGetString( GL_EXTENSIONS )); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: RunSim +// Purpose: Actual simulation loop +// Notes: Allows you to adjust the rate of simulation or to change it +// to fixed time steps or actual timesteps. +/////////////////////////////////////////////////////////////////////////////// +void COGLView::RunSim() +{ +/// Local Variables /////////////////////////////////////////////////////////// + float Time; + float DeltaTime; +/////////////////////////////////////////////////////////////////////////////// + + if (m_UseFixedTimeStep) + Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); + else + Time = GetTime() * m_TimeIterations; + + while(m_LastTime < Time) + { + DeltaTime = Time - m_LastTime; + if(DeltaTime > m_MaxTimeStep) + { + DeltaTime = m_MaxTimeStep; + } + + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + m_LastTime += DeltaTime; + } + m_LastTime = Time; +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ + if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) + { + glColor3f(1.0f,1.0f,1.0f); + // Declare the Array of Data + glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); + if (curBone->visuals[0].reuseVertices) + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + else + glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + } + else + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); + else + glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); + } + } +} +// drawModel + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; + if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; + if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; + + // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); + + // ROTATE THE ROOT + glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); + + if (m_PickX > -1) + m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); + +// for (loop = 0; loop < 10; loop++) + RunSim(); + + m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION + + glPopMatrix(); + glFinish(); + + if (m_hDC) + SwapBuffers(m_hDC); + +// PLAYING WITH CHECKING FRAMETIMING +/* if (m_SimRunning) + { + m_FrameCnt++; + char message[80]; + DWORD end = timeGetTime(); + float diff = (float)(m_FrameCnt * 1000)/(float)(end - m_StartTime); + + sprintf(message,"%.2f",diff); + m_ptrStatusBar->SetPaneText(0,message); + }*/ + m_PickX = -1; + m_PickY = -1; +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + m_ScreenWidth = cx; + m_ScreenHeight = cy; + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + if ((nFlags & MK_SHIFT) == 0) + { + m_PickX = point.x; + m_PickY = m_ScreenHeight - point.y; + drawScene(); + } + SetCapture( ); + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE + ReleaseCapture(); + CWnd::OnLButtonUp(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + tVector userforce; + switch (nChar) + { + case 13: + m_PhysEnv.AddSpring(); + break; + case 'G': + m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; + break; + case '1': m_curVisual = 0; + break; + case '2': m_curVisual = 1; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + break; + case 'F': + glPolygonMode(GL_FRONT,GL_FILL); + break; + case 'R': + m_SimRunning = !m_SimRunning; + if (m_SimRunning) + m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM + m_StartTime = timeGetTime(); + m_FrameCnt = 0; + break; + case 'T': + m_PhysEnv.ResetWorld(); + break; + case VK_HOME: + userforce.x = m_Skeleton.matrix.m[1]; + userforce.y = m_Skeleton.matrix.m[5]; + userforce.z = m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_END: + userforce.x = -m_Skeleton.matrix.m[1]; + userforce.y = -m_Skeleton.matrix.m[5]; + userforce.z = -m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_RIGHT: + userforce.x = m_Skeleton.matrix.m[0]; + userforce.y = m_Skeleton.matrix.m[4]; + userforce.z = m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_LEFT: + userforce.x = -m_Skeleton.matrix.m[0]; + userforce.y = -m_Skeleton.matrix.m[4]; + userforce.z = -m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_UP: + userforce.x = -m_Skeleton.matrix.m[2]; + userforce.y = -m_Skeleton.matrix.m[6]; + userforce.z = -m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_DOWN: + userforce.x = m_Skeleton.matrix.m[2]; + userforce.y = m_Skeleton.matrix.m[6]; + userforce.z = m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + } + + MSG msg; + + if (m_SimRunning) + { + while (m_SimRunning == TRUE) + { + while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + m_SimRunning = FALSE; + m_hDC = NULL; + PostQuitMessage(0); + break; + } + if (msg.message == WM_CLOSE) + { + m_SimRunning = FALSE; + } + + // Dispatch any messages as needed + if (!AfxGetApp()->PreTranslateMessage(&msg)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + // Give the Idle system some time + AfxGetApp()->OnIdle(0); + AfxGetApp()->OnIdle(1); + + } + drawScene(); + } + } + else + Invalidate(TRUE); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + tVector localX,localY; + + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CONTROL' BUTTON ROTATE + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + // ELSE ROTATE THE BONE + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS + { + // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES + localY.x = m_Skeleton.matrix.m[1]; + localY.y = m_Skeleton.matrix.m[5]; + localY.z = m_Skeleton.matrix.m[9]; + + localX.x = m_Skeleton.matrix.m[0]; + localX.y = m_Skeleton.matrix.m[4]; + localX.z = m_Skeleton.matrix.m[8]; + + m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); + m_PhysEnv.m_MouseForceActive = TRUE; + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: NewSystem +// Purpose: Clears the Simulation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::NewSystem() +{ + m_PhysEnv.FreeSystem(); + m_SimRunning = FALSE; + if (m_Skeleton.childCnt > 0) + { + if (m_Skeleton.children->visuals->vertexData) + free(m_Skeleton.children->visuals->vertexData); + if (m_Skeleton.children->visuals->faceIndex) + free(m_Skeleton.children->visuals->faceIndex); + free(m_Skeleton.children->visuals); + free(m_Skeleton.children); + m_Skeleton.childCnt = 0; + } + drawScene(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadFiles +// Purpose: Loads the OBJ files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadFile(CString file1,CString baseName,CString ext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *children; + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + ext.MakeUpper(); + if (ext == "OBJ") + { + visual = (t_Visual *)malloc(sizeof(t_Visual)); + NewSystem(); // CLEAR WHAT DATA IS THERE + // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT + if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, + LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) + { + // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SetWorldParticles((tVector *)visual->vertexData,visual->vertexCnt); + + children = (t_Bone *)malloc(sizeof(t_Bone)); + m_CurBone = &children[m_Skeleton.childCnt]; + ResetBone(m_CurBone,&m_Skeleton); + strcpy(m_CurBone->name,(LPCTSTR)baseName); + m_CurBone->visuals = visual; + m_CurBone->visualCnt = 1; + m_Skeleton.childCnt = 1; + m_Skeleton.children = children; + } + else + { + MessageBox("Must Be A Valid OBJ File","Error",MB_OK); + free(visual); + } + } + else // LOAD SIM SYSTEM + { + if (file1.GetLength()) + { + fp = fopen(file1,"rb"); + if (fp != NULL) + { + NewSystem(); // CLEAR WHAT DATA IS THERE + fread(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); + fread(m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); + visual = m_Skeleton.children->visuals; + fread(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); + fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.LoadData(fp); + } + } + fclose(fp); + } + } + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: SaveFiles +// Purpose: Saves the Particle System +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SaveFile(CString file1,CString baseName) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + if (file1.GetLength() > 0) + { + fp = fopen(file1,"wb"); + if (fp != NULL) + { + fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + fwrite(&m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + visual = m_Skeleton.children->visuals; + fwrite(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SaveData(fp); + } + } + fclose(fp); + } + } +} + +void COGLView::OnClose() +{ + + CWnd::OnClose(); +} + +void COGLView::OnSimulationSetsimproperties() +{ + m_PhysEnv.SetWorldProperties(); +} + +void COGLView::OnSimulationSetVertexMass() +{ + m_PhysEnv.SetVertexMass(); +} + +void COGLView::OnSetTimeProperties() +{ + CTimeProps dialog; + dialog.m_Iterations = m_TimeIterations; + dialog.m_FixedTimeSteps = m_UseFixedTimeStep; + dialog.m_MaxTimeStep = m_MaxTimeStep; + if (dialog.DoModal()) + { + m_TimeIterations = dialog.m_Iterations; + m_UseFixedTimeStep = dialog.m_FixedTimeSteps; + m_MaxTimeStep = dialog.m_MaxTimeStep; + } +} + diff --git a/Particle Dynamics/code/OGL/Squashy/OGLView.h b/Particle Dynamics/code/OGL/Squashy/OGLView.h index c32f848..9948419 100644 --- a/Particle Dynamics/code/OGL/Squashy/OGLView.h +++ b/Particle Dynamics/code/OGL/Squashy/OGLView.h @@ -1,123 +1,123 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -#include "PhysEnv.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry,m_SimRunning; - int m_curVisual; - float m_MorphPos; - DWORD m_StartTime; - DWORD m_FrameCnt; - int m_TimeIterations; - BOOL m_UseFixedTimeStep; - float m_MaxTimeStep; - float m_LastTime; - - - CPhysEnv m_PhysEnv; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - void OnSimulationSetVertexMass(); - void OnSimulationSetsimproperties(); - void OnSetTimeProperties(); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(char *who,char *which, char *version, char *extensions); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - GLvoid morphModel(t_Bone *curBone); - GLvoid LoadBoneTexture(t_Bone *curBone); - void NewSystem(); - void LoadFile(CString file1,CString baseName,CString ext); - void SaveFile(CString file1,CString baseName); - void RunSim(); - float GetTime( void ); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Skeleton,*m_CurBone; - int m_PickX, m_PickY; - int m_ScreenWidth; - int m_ScreenHeight; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnClose(); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +#include "PhysEnv.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry,m_SimRunning; + int m_curVisual; + float m_MorphPos; + DWORD m_StartTime; + DWORD m_FrameCnt; + int m_TimeIterations; + BOOL m_UseFixedTimeStep; + float m_MaxTimeStep; + float m_LastTime; + + + CPhysEnv m_PhysEnv; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + void OnSimulationSetVertexMass(); + void OnSimulationSetsimproperties(); + void OnSetTimeProperties(); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(char *who,char *which, char *version, char *extensions); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + GLvoid morphModel(t_Bone *curBone); + GLvoid LoadBoneTexture(t_Bone *curBone); + void NewSystem(); + void LoadFile(CString file1,CString baseName,CString ext); + void SaveFile(CString file1,CString baseName); + void RunSim(); + float GetTime( void ); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Skeleton,*m_CurBone; + int m_PickX, m_PickY; + int m_ScreenWidth; + int m_ScreenHeight; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnClose(); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/PhysEnv.cpp b/Particle Dynamics/code/OGL/Squashy/PhysEnv.cpp index 2fe4488..5ae5d69 100644 --- a/Particle Dynamics/code/OGL/Squashy/PhysEnv.cpp +++ b/Particle Dynamics/code/OGL/Squashy/PhysEnv.cpp @@ -1,824 +1,824 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// PhysEnv.cpp : Physical World implementation file -// -// Purpose: Implementation of Particle Physics System -// -// Created: -// JL 12/1/98 -// -// Notes: A bit of this along with the organization comes from Chris Hecker's -// Physics Articles from last year. Hopefully this will get everyone -// back up to speed before we dig deeper into the world of Dynamics. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998-1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include -#include - -#include "Squashy.h" -#include "PhysEnv.h" -#include "SimProps.h" -#include "VertMass.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -///////////////////////////////////////////////////////////////////////////// -// CPhysEnv - -// INITIALIZE THE SIMULATION WORLD -CPhysEnv::CPhysEnv() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - m_ParticleSys[0] = NULL; - m_ParticleSys[1] = NULL; - m_ParticleSys[2] = NULL; // RESET BUFFER - m_ParticleCnt = 0; - m_Contact = NULL; - m_Spring = NULL; - m_SpringCnt = 0; - - m_UseGravity = TRUE; - m_DrawSprings = TRUE; - m_DrawVertices = TRUE; - m_MouseForceActive = FALSE; - - MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) - m_UserForceMag = 100.0; - m_UserForceActive = FALSE; - m_Kd = 0.04f; // DAMPING FACTOR - m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT - m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT - m_Ksd = 0.1f; // SPRING DAMPING CONSTANT - - m_MouseForceKs = 0.08f; // MOUSE SPRING CONSTANT - - // CREATE THE SIZE FOR THE SIMULATION WORLD - m_WorldSizeX = 15.0f; - m_WorldSizeY = 15.0f; - m_WorldSizeZ = 15.0f; - - m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); - m_CollisionPlaneCnt = 6; - - // MAKE THE TOP PLANE (CEILING) - MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) - m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; - - // MAKE THE BOTTOM PLANE (FLOOR) - MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) - m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; - - // MAKE THE LEFT PLANE - MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) - m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; - - // MAKE THE RIGHT PLANE - MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) - m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; - - // MAKE THE FRONT PLANE - MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) - m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; - - // MAKE THE BACK PLANE - MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) - m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; - -} - -CPhysEnv::~CPhysEnv() -{ - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - if (m_Contact) - free(m_Contact); - if (m_Spring) - free(m_Spring); - free(m_CollisionPlane); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RenderWorld -// Purpose: Draw the current system (particles, springs, userforces) -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::RenderWorld() -{ - tParticle *tempParticle; - tSpring *tempSpring; - - // FIRST DRAW THE WORLD CONTAINER - glColor3f(1.0f,1.0f,1.0f); - // do a big linestrip to get most of edges - glBegin(GL_LINE_STRIP); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glEnd(); - // fill in the stragglers - glBegin(GL_LINES); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - - // draw floor - glDisable(GL_CULL_FACE); - glBegin(GL_QUADS); - glColor3f(0.0f,0.0f,0.5f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - glEnable(GL_CULL_FACE); - - - if (m_ParticleSys) - { - if (m_Spring && m_DrawSprings) - { - glBegin(GL_LINES); - glColor3f(0.0f,0.8f,0.8f); - tempSpring = m_Spring; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); - glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); - tempSpring++; - } - if (m_MouseForceActive) // DRAW MOUSESPRING FORCE - { - if (m_Pick[0] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); - glVertex3fv((float *)&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); - glVertex3fv((float *)&m_MouseDragPos[1]); - } - } - glEnd(); - } - if (m_DrawVertices) - { - glBegin(GL_POINTS); - tempParticle = m_CurrentSys; - for (int loop = 0; loop < m_ParticleCnt; loop++) - { - if (loop == m_Pick[0]) - glColor3f(0.0f,0.8f,0.0f); - else if (loop == m_Pick[1]) - glColor3f(0.8f,0.0f,0.0f); - else - glColor3f(0.8f,0.8f,0.0f); - glVertex3fv((float *)&tempParticle->pos); - tempParticle++; - } - glEnd(); - } - } - -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetNearestPoint -// Purpose: Use OpenGL Feedback to find the closest point to a mouseclick -// Arguments: Screen coordinates of the hit -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::GetNearestPoint(int x, int y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *feedBuffer; - int hitCount; - tParticle *tempParticle; - int loop; -/////////////////////////////////////////////////////////////////////////////// - // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) - feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); - // TELL OPENGL ABOUT THE BUFFER - glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); - (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE - - tempParticle = m_CurrentSys; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS - glPassThrough((float)loop); - // SEND THE VERTEX - glBegin(GL_POINTS); - glVertex3fv((float *)&tempParticle->pos); - glEnd(); - tempParticle++; - } - hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET - CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT - free(feedBuffer); // GET RID OF THE MEMORY -} -////// GetNearestPoint //////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CompareBuffer -// Purpose: Check the feedback buffer to see if anything is hit -// Arguments: Number of hits, pointer to buffer, point to test -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLint count; - GLfloat token,point[3]; - int loop,currentVertex,result = -1; - long nearest = -1, dist; -/////////////////////////////////////////////////////////////////////////////// - count = size; - while (count) - { - token = buffer[size - count]; // CHECK THE TOKEN - count--; - if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER - { - currentVertex = (int)buffer[size - count]; // WHAT VERTEX - count--; - } - else if (token == GL_POINT_TOKEN) - { - // THERE ARE THREE ELEMENTS TO A POINT TOKEN - for (loop = 0; loop < 3; loop++) - { - point[loop] = buffer[size - count]; - count--; - } - dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); - if (result == -1 || dist < nearest) - { - nearest = dist; - result = currentVertex; - } - } - } - - if (nearest < 50.0f) - { - if (m_Pick[0] == -1) - m_Pick[0] = result; - else if (m_Pick[1] == -1) - m_Pick[1] = result; - else - { - m_Pick[0] = result; - m_Pick[1] = -1; - } - } -} -////// CompareBuffer ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetWorldParticles -// Purpose: Inform the System of the particles under control -// Arguments: List of vertices and count -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetWorldParticles(tVector *coords,int particleCnt) -{ - tParticle *tempParticle; - - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - if (m_Contact) - free(m_Contact); - // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_ParticleCnt = particleCnt; - - m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt); - m_ContactCnt = 0; - - tempParticle = m_CurrentSys; - for (int loop = 0; loop < particleCnt; loop++) - { - MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) - MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) - MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) - tempParticle->oneOverM = 1.0f; // MASS OF 1 - tempParticle++; - coords++; - } - - // COPY THE SYSTEM TO THE SECOND ONE ALSO - memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); - // COPY THE SYSTEM TO THE RESET BUFFER ALSO - memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); - - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; -} -////// SetWorldParticles ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: FreeSystem -// Purpose: Remove all particles and clear it out -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::FreeSystem() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - if (m_ParticleSys[0]) - { - m_ParticleSys[0] = NULL; - free(m_ParticleSys[0]); - } - if (m_ParticleSys[1]) - { - free(m_ParticleSys[1]); - m_ParticleSys[1] = NULL; - } - if (m_ParticleSys[2]) - { - free(m_ParticleSys[2]); - m_ParticleSys[2] = NULL; // RESET BUFFER - } - if (m_Contact) - { - free(m_Contact); - m_Contact = NULL; - } - if (m_Spring) - { - free(m_Spring); - m_Spring = NULL; - } - m_SpringCnt = 0; - m_ParticleCnt = 0; -} -////// FreeSystem ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadData -// Purpose: Load a simulation system -// Arguments: File pointer -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::LoadData(FILE *fp) -{ - fread(&m_UseGravity,sizeof(BOOL),1,fp); - fread(&m_UseDamping,sizeof(BOOL),1,fp); - fread(&m_UserForceActive,sizeof(BOOL),1,fp); - fread(&m_Gravity,sizeof(tVector),1,fp); - fread(&m_UserForce,sizeof(tVector),1,fp); - fread(&m_UserForceMag,sizeof(float),1,fp); - fread(&m_Kd,sizeof(float),1,fp); - fread(&m_Kr,sizeof(float),1,fp); - fread(&m_Ksh,sizeof(float),1,fp); - fread(&m_Ksd,sizeof(float),1,fp); - fread(&m_ParticleCnt,sizeof(int),1,fp); - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; - m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); - fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fread(&m_SpringCnt,sizeof(int),1,fp); - m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); - fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fread(m_Pick,sizeof(int),2,fp); -} -////// LoadData ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SaveData -// Purpose: Save a simulation system -// Arguments: File pointer -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SaveData(FILE *fp) -{ - fwrite(&m_UseGravity,sizeof(BOOL),1,fp); - fwrite(&m_UseDamping,sizeof(BOOL),1,fp); - fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); - fwrite(&m_Gravity,sizeof(tVector),1,fp); - fwrite(&m_UserForce,sizeof(tVector),1,fp); - fwrite(&m_UserForceMag,sizeof(float),1,fp); - fwrite(&m_Kd,sizeof(float),1,fp); - fwrite(&m_Kr,sizeof(float),1,fp); - fwrite(&m_Ksh,sizeof(float),1,fp); - fwrite(&m_Ksd,sizeof(float),1,fp); - fwrite(&m_ParticleCnt,sizeof(int),1,fp); - fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(&m_SpringCnt,sizeof(int),1,fp); - fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fwrite(m_Pick,sizeof(int),2,fp); -} -////// SaveData ////////////////////////////////////////////////////////////// - -// RESET THE SIM TO INITIAL VALUES -void CPhysEnv::ResetWorld() -{ - memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); - memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); -} - -void CPhysEnv::SetWorldProperties() -{ - CSimProps dialog; - dialog.m_CoefRest = m_Kr; - dialog.m_Damping = m_Kd; - dialog.m_GravX = m_Gravity.x; - dialog.m_GravY = m_Gravity.y; - dialog.m_GravZ = m_Gravity.z; - dialog.m_SpringConst = m_Ksh; - dialog.m_SpringDamp = m_Ksd; - dialog.m_UserForceMag = m_UserForceMag; - dialog.m_MouseSpring = m_MouseForceKs; - if (dialog.DoModal() == IDOK) - { - m_Kr = dialog.m_CoefRest; - m_Kd = dialog.m_Damping; - m_Gravity.x = dialog.m_GravX; - m_Gravity.y = dialog.m_GravY; - m_Gravity.z = dialog.m_GravZ; - m_UserForceMag = dialog.m_UserForceMag; - m_Ksh = dialog.m_SpringConst; - m_Ksd = dialog.m_SpringDamp; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - m_Spring[loop].Ks = m_Ksh; - m_Spring[loop].Kd = m_Ksd; - } - - // GET THE NEW MOUSESPRING FORCE - m_MouseForceKs = dialog.m_MouseSpring; - } -} - - -void CPhysEnv::SetVertexMass() -{ - CVertMass dialog; - dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; - if (dialog.DoModal() == IDOK) - { - m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; - } -} - -void CPhysEnv::ApplyUserForce(tVector *force) -{ - ScaleVector(force, m_UserForceMag, &m_UserForce); - m_UserForceActive = TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetMouseForce -// Purpose: Allows the user to interact with selected points by dragging -// Arguments: Delta distance from clicked point, local x and y axes -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector tempX,tempY; -/////////////////////////////////////////////////////////////////////////////// - ScaleVector(localX, (float)deltaX * 0.03f, &tempX); - ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); - if (m_Pick[0] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); - VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); - VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); - } -} -/// SetMouseForce ///////////////////////////////////////////////////////////// - -void CPhysEnv::AddSpring() -{ - tSpring *spring; - // MAKE SURE TWO PARTICLES ARE PICKED - if (m_Pick[0] > -1 && m_Pick[1] > -1) - { - spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); - if (m_Spring != NULL) - memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); - m_Spring = spring; - spring = &m_Spring[m_SpringCnt++]; - spring->Ks = m_Ksh; - spring->Kd = m_Ksd; - spring->p1 = m_Pick[0]; - spring->p2 = m_Pick[1]; - spring->restLen = - sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, - &m_CurrentSys[m_Pick[1]].pos)); - } -} - -void CPhysEnv::ComputeForces( tParticle *system ) -{ - int loop; - tParticle *curParticle,*p1, *p2; - tSpring *spring; - float dist, Hterm, Dterm; - tVector springForce,deltaV,deltaP; - - curParticle = system; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR - - if (m_UseGravity) - { - curParticle->f.x += (m_Gravity.x * curParticle->oneOverM); - curParticle->f.y += (m_Gravity.y * curParticle->oneOverM); - curParticle->f.z += (m_Gravity.z * curParticle->oneOverM); - } - - if (m_UseDamping) - { - curParticle->f.x += (-m_Kd * curParticle->v.x); - curParticle->f.y += (-m_Kd * curParticle->v.y); - curParticle->f.z += (-m_Kd * curParticle->v.z); - } - else - { - curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); - curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); - curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); - } - curParticle++; - } - - // CHECK IF THERE IS A USER FORCE BEING APPLIED - if (m_UserForceActive) - { - if (m_Pick[0] != -1) - { - VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); - } - if (m_Pick[1] != -1) - { - VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); - } - MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE - } - - // NOW DO ALL THE SPRINGS - spring = m_Spring; - for (loop = 0; loop < m_SpringCnt; loop++) - { - p1 = &system[spring->p1]; - p2 = &system[spring->p2]; - VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) - - VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector - Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 - spring++; // DO THE NEXT SPRING - } - - // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE - if (m_MouseForceActive) - { - // APPLY TO EACH PICKED PARTICLE - if (m_Pick[0] > -1) - { - p1 = &system[m_Pick[0]]; - VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - if (m_Pick[1] > -1) - { - p1 = &system[m_Pick[1]]; - VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: Integrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses Euler's method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::Integrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - tParticle *source,*target; -/////////////////////////////////////////////////////////////////////////////// - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TargetSys; // WHERE I AM GOING TO STORE THE NEW STATE - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (DeltaTime * source->f.x * source->oneOverM); - target->v.y = source->v.y + (DeltaTime * source->f.y * source->oneOverM); - target->v.z = source->v.z + (DeltaTime * source->f.z * source->oneOverM); - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (DeltaTime * source->v.x); - target->pos.y = source->pos.y + (DeltaTime * source->v.y); - target->pos.z = source->pos.z + (DeltaTime * source->v.z); - - source++; - target++; - } -} - -int CPhysEnv::CheckForCollisions( tParticle *system ) -{ - // be optimistic! - int collisionState = NOT_COLLIDING; - float const depthEpsilon = 0.001f; - - int loop; - tParticle *curParticle; - - m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS - - curParticle = system; - for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); - loop++,curParticle++) - { - for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && - (collisionState != PENETRATING);planeIndex++) - { - tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; - - float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; - - if(axbyczd < -depthEpsilon) - { - // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(axbyczd < depthEpsilon) - { - float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); - - if(relativeVelocity < 0.0f) - { - collisionState = COLLIDING; - m_Contact[m_ContactCnt].particle = loop; - memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); - m_ContactCnt++; - } - } - } - } - - return collisionState; -} - -void CPhysEnv::ResolveCollisions( tParticle *system ) -{ - tContact *contact; - tParticle *particle; // THE PARTICLE COLLIDING - float VdotN; - tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE - contact = m_Contact; - for (int loop = 0; loop < m_ContactCnt; loop++,contact++) - { - particle = &system[contact->particle]; - // CALCULATE Vn - VdotN = DotProduct(&contact->normal,&particle->v); - ScaleVector(&contact->normal, VdotN, &Vn); - // CALCULATE Vt - VectorDifference(&particle->v, &Vn, &Vt); - // SCALE Vn BY COEFFICIENT OF RESTITUTION - ScaleVector(&Vn, m_Kr, &Vn); - // SET THE VELOCITY TO BE THE NEW IMPULSE - VectorDifference(&Vt, &Vn, &particle->v); - } -} - -void CPhysEnv::Simulate(float DeltaTime, BOOL running) -{ - float CurrentTime = 0.0f; - float TargetTime = DeltaTime; - tParticle *tempSys; - int collisionState; - - while(CurrentTime < DeltaTime) - { - if (running) - { - ComputeForces(m_CurrentSys); - - Integrate(TargetTime-CurrentTime); - } - - collisionState = CheckForCollisions(m_TargetSys); - - if(collisionState == PENETRATING) - { - // we simulated too far, so subdivide time and try again - TargetTime = (CurrentTime + TargetTime) / 2.0f; - - // blow up if we aren't moving forward each step, which is - // probably caused by interpenetration at the frame start - assert(fabs(TargetTime - CurrentTime) > EPSILON); - } - else - { - // either colliding or clear - if(collisionState == COLLIDING) - { - int Counter = 0; - do - { - ResolveCollisions(m_TargetSys); - Counter++; - } while((CheckForCollisions(m_TargetSys) == - COLLIDING) && (Counter < 100)); - - assert(Counter < 100); - } - - // we made a successful step, so swap configurations - // to "save" the data for the next step - - CurrentTime = TargetTime; - TargetTime = DeltaTime; - - // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN - tempSys = m_CurrentSys; - m_CurrentSys = m_TargetSys; - m_TargetSys = tempSys; - } - } -} +/////////////////////////////////////////////////////////////////////////////// +// +// PhysEnv.cpp : Physical World implementation file +// +// Purpose: Implementation of Particle Physics System +// +// Created: +// JL 12/1/98 +// +// Notes: A bit of this along with the organization comes from Chris Hecker's +// Physics Articles from last year. Hopefully this will get everyone +// back up to speed before we dig deeper into the world of Dynamics. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998-1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include + +#include "Squashy.h" +#include "PhysEnv.h" +#include "SimProps.h" +#include "VertMass.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +///////////////////////////////////////////////////////////////////////////// +// CPhysEnv + +// INITIALIZE THE SIMULATION WORLD +CPhysEnv::CPhysEnv() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + m_ParticleSys[0] = NULL; + m_ParticleSys[1] = NULL; + m_ParticleSys[2] = NULL; // RESET BUFFER + m_ParticleCnt = 0; + m_Contact = NULL; + m_Spring = NULL; + m_SpringCnt = 0; + + m_UseGravity = TRUE; + m_DrawSprings = TRUE; + m_DrawVertices = TRUE; + m_MouseForceActive = FALSE; + + MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) + m_UserForceMag = 100.0; + m_UserForceActive = FALSE; + m_Kd = 0.04f; // DAMPING FACTOR + m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT + m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT + m_Ksd = 0.1f; // SPRING DAMPING CONSTANT + + m_MouseForceKs = 0.08f; // MOUSE SPRING CONSTANT + + // CREATE THE SIZE FOR THE SIMULATION WORLD + m_WorldSizeX = 15.0f; + m_WorldSizeY = 15.0f; + m_WorldSizeZ = 15.0f; + + m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); + m_CollisionPlaneCnt = 6; + + // MAKE THE TOP PLANE (CEILING) + MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) + m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; + + // MAKE THE BOTTOM PLANE (FLOOR) + MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) + m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; + + // MAKE THE LEFT PLANE + MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) + m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; + + // MAKE THE RIGHT PLANE + MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) + m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; + + // MAKE THE FRONT PLANE + MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) + m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; + + // MAKE THE BACK PLANE + MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) + m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; + +} + +CPhysEnv::~CPhysEnv() +{ + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + if (m_Contact) + free(m_Contact); + if (m_Spring) + free(m_Spring); + free(m_CollisionPlane); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RenderWorld +// Purpose: Draw the current system (particles, springs, userforces) +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::RenderWorld() +{ + tParticle *tempParticle; + tSpring *tempSpring; + + // FIRST DRAW THE WORLD CONTAINER + glColor3f(1.0f,1.0f,1.0f); + // do a big linestrip to get most of edges + glBegin(GL_LINE_STRIP); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glEnd(); + // fill in the stragglers + glBegin(GL_LINES); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + + // draw floor + glDisable(GL_CULL_FACE); + glBegin(GL_QUADS); + glColor3f(0.0f,0.0f,0.5f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + glEnable(GL_CULL_FACE); + + + if (m_ParticleSys) + { + if (m_Spring && m_DrawSprings) + { + glBegin(GL_LINES); + glColor3f(0.0f,0.8f,0.8f); + tempSpring = m_Spring; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); + glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); + tempSpring++; + } + if (m_MouseForceActive) // DRAW MOUSESPRING FORCE + { + if (m_Pick[0] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); + glVertex3fv((float *)&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); + glVertex3fv((float *)&m_MouseDragPos[1]); + } + } + glEnd(); + } + if (m_DrawVertices) + { + glBegin(GL_POINTS); + tempParticle = m_CurrentSys; + for (int loop = 0; loop < m_ParticleCnt; loop++) + { + if (loop == m_Pick[0]) + glColor3f(0.0f,0.8f,0.0f); + else if (loop == m_Pick[1]) + glColor3f(0.8f,0.0f,0.0f); + else + glColor3f(0.8f,0.8f,0.0f); + glVertex3fv((float *)&tempParticle->pos); + tempParticle++; + } + glEnd(); + } + } + +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetNearestPoint +// Purpose: Use OpenGL Feedback to find the closest point to a mouseclick +// Arguments: Screen coordinates of the hit +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::GetNearestPoint(int x, int y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *feedBuffer; + int hitCount; + tParticle *tempParticle; + int loop; +/////////////////////////////////////////////////////////////////////////////// + // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) + feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); + // TELL OPENGL ABOUT THE BUFFER + glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); + (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE + + tempParticle = m_CurrentSys; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS + glPassThrough((float)loop); + // SEND THE VERTEX + glBegin(GL_POINTS); + glVertex3fv((float *)&tempParticle->pos); + glEnd(); + tempParticle++; + } + hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET + CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT + free(feedBuffer); // GET RID OF THE MEMORY +} +////// GetNearestPoint //////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CompareBuffer +// Purpose: Check the feedback buffer to see if anything is hit +// Arguments: Number of hits, pointer to buffer, point to test +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLint count; + GLfloat token,point[3]; + int loop,currentVertex,result = -1; + long nearest = -1, dist; +/////////////////////////////////////////////////////////////////////////////// + count = size; + while (count) + { + token = buffer[size - count]; // CHECK THE TOKEN + count--; + if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER + { + currentVertex = (int)buffer[size - count]; // WHAT VERTEX + count--; + } + else if (token == GL_POINT_TOKEN) + { + // THERE ARE THREE ELEMENTS TO A POINT TOKEN + for (loop = 0; loop < 3; loop++) + { + point[loop] = buffer[size - count]; + count--; + } + dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); + if (result == -1 || dist < nearest) + { + nearest = dist; + result = currentVertex; + } + } + } + + if (nearest < 50.0f) + { + if (m_Pick[0] == -1) + m_Pick[0] = result; + else if (m_Pick[1] == -1) + m_Pick[1] = result; + else + { + m_Pick[0] = result; + m_Pick[1] = -1; + } + } +} +////// CompareBuffer ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetWorldParticles +// Purpose: Inform the System of the particles under control +// Arguments: List of vertices and count +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetWorldParticles(tVector *coords,int particleCnt) +{ + tParticle *tempParticle; + + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + if (m_Contact) + free(m_Contact); + // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_ParticleCnt = particleCnt; + + m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt); + m_ContactCnt = 0; + + tempParticle = m_CurrentSys; + for (int loop = 0; loop < particleCnt; loop++) + { + MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) + MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) + MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) + tempParticle->oneOverM = 1.0f; // MASS OF 1 + tempParticle++; + coords++; + } + + // COPY THE SYSTEM TO THE SECOND ONE ALSO + memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); + // COPY THE SYSTEM TO THE RESET BUFFER ALSO + memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); + + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; +} +////// SetWorldParticles ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: FreeSystem +// Purpose: Remove all particles and clear it out +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::FreeSystem() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + if (m_ParticleSys[0]) + { + m_ParticleSys[0] = NULL; + free(m_ParticleSys[0]); + } + if (m_ParticleSys[1]) + { + free(m_ParticleSys[1]); + m_ParticleSys[1] = NULL; + } + if (m_ParticleSys[2]) + { + free(m_ParticleSys[2]); + m_ParticleSys[2] = NULL; // RESET BUFFER + } + if (m_Contact) + { + free(m_Contact); + m_Contact = NULL; + } + if (m_Spring) + { + free(m_Spring); + m_Spring = NULL; + } + m_SpringCnt = 0; + m_ParticleCnt = 0; +} +////// FreeSystem ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadData +// Purpose: Load a simulation system +// Arguments: File pointer +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::LoadData(FILE *fp) +{ + fread(&m_UseGravity,sizeof(BOOL),1,fp); + fread(&m_UseDamping,sizeof(BOOL),1,fp); + fread(&m_UserForceActive,sizeof(BOOL),1,fp); + fread(&m_Gravity,sizeof(tVector),1,fp); + fread(&m_UserForce,sizeof(tVector),1,fp); + fread(&m_UserForceMag,sizeof(float),1,fp); + fread(&m_Kd,sizeof(float),1,fp); + fread(&m_Kr,sizeof(float),1,fp); + fread(&m_Ksh,sizeof(float),1,fp); + fread(&m_Ksd,sizeof(float),1,fp); + fread(&m_ParticleCnt,sizeof(int),1,fp); + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; + m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); + fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fread(&m_SpringCnt,sizeof(int),1,fp); + m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); + fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fread(m_Pick,sizeof(int),2,fp); +} +////// LoadData ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SaveData +// Purpose: Save a simulation system +// Arguments: File pointer +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SaveData(FILE *fp) +{ + fwrite(&m_UseGravity,sizeof(BOOL),1,fp); + fwrite(&m_UseDamping,sizeof(BOOL),1,fp); + fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); + fwrite(&m_Gravity,sizeof(tVector),1,fp); + fwrite(&m_UserForce,sizeof(tVector),1,fp); + fwrite(&m_UserForceMag,sizeof(float),1,fp); + fwrite(&m_Kd,sizeof(float),1,fp); + fwrite(&m_Kr,sizeof(float),1,fp); + fwrite(&m_Ksh,sizeof(float),1,fp); + fwrite(&m_Ksd,sizeof(float),1,fp); + fwrite(&m_ParticleCnt,sizeof(int),1,fp); + fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(&m_SpringCnt,sizeof(int),1,fp); + fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fwrite(m_Pick,sizeof(int),2,fp); +} +////// SaveData ////////////////////////////////////////////////////////////// + +// RESET THE SIM TO INITIAL VALUES +void CPhysEnv::ResetWorld() +{ + memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); + memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); +} + +void CPhysEnv::SetWorldProperties() +{ + CSimProps dialog; + dialog.m_CoefRest = m_Kr; + dialog.m_Damping = m_Kd; + dialog.m_GravX = m_Gravity.x; + dialog.m_GravY = m_Gravity.y; + dialog.m_GravZ = m_Gravity.z; + dialog.m_SpringConst = m_Ksh; + dialog.m_SpringDamp = m_Ksd; + dialog.m_UserForceMag = m_UserForceMag; + dialog.m_MouseSpring = m_MouseForceKs; + if (dialog.DoModal() == IDOK) + { + m_Kr = dialog.m_CoefRest; + m_Kd = dialog.m_Damping; + m_Gravity.x = dialog.m_GravX; + m_Gravity.y = dialog.m_GravY; + m_Gravity.z = dialog.m_GravZ; + m_UserForceMag = dialog.m_UserForceMag; + m_Ksh = dialog.m_SpringConst; + m_Ksd = dialog.m_SpringDamp; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + m_Spring[loop].Ks = m_Ksh; + m_Spring[loop].Kd = m_Ksd; + } + + // GET THE NEW MOUSESPRING FORCE + m_MouseForceKs = dialog.m_MouseSpring; + } +} + + +void CPhysEnv::SetVertexMass() +{ + CVertMass dialog; + dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; + if (dialog.DoModal() == IDOK) + { + m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; + } +} + +void CPhysEnv::ApplyUserForce(tVector *force) +{ + ScaleVector(force, m_UserForceMag, &m_UserForce); + m_UserForceActive = TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetMouseForce +// Purpose: Allows the user to interact with selected points by dragging +// Arguments: Delta distance from clicked point, local x and y axes +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector tempX,tempY; +/////////////////////////////////////////////////////////////////////////////// + ScaleVector(localX, (float)deltaX * 0.03f, &tempX); + ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); + if (m_Pick[0] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); + VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); + VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); + } +} +/// SetMouseForce ///////////////////////////////////////////////////////////// + +void CPhysEnv::AddSpring() +{ + tSpring *spring; + // MAKE SURE TWO PARTICLES ARE PICKED + if (m_Pick[0] > -1 && m_Pick[1] > -1) + { + spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); + if (m_Spring != NULL) + memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); + m_Spring = spring; + spring = &m_Spring[m_SpringCnt++]; + spring->Ks = m_Ksh; + spring->Kd = m_Ksd; + spring->p1 = m_Pick[0]; + spring->p2 = m_Pick[1]; + spring->restLen = + sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, + &m_CurrentSys[m_Pick[1]].pos)); + } +} + +void CPhysEnv::ComputeForces( tParticle *system ) +{ + int loop; + tParticle *curParticle,*p1, *p2; + tSpring *spring; + float dist, Hterm, Dterm; + tVector springForce,deltaV,deltaP; + + curParticle = system; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR + + if (m_UseGravity) + { + curParticle->f.x += (m_Gravity.x * curParticle->oneOverM); + curParticle->f.y += (m_Gravity.y * curParticle->oneOverM); + curParticle->f.z += (m_Gravity.z * curParticle->oneOverM); + } + + if (m_UseDamping) + { + curParticle->f.x += (-m_Kd * curParticle->v.x); + curParticle->f.y += (-m_Kd * curParticle->v.y); + curParticle->f.z += (-m_Kd * curParticle->v.z); + } + else + { + curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); + curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); + curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); + } + curParticle++; + } + + // CHECK IF THERE IS A USER FORCE BEING APPLIED + if (m_UserForceActive) + { + if (m_Pick[0] != -1) + { + VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); + } + if (m_Pick[1] != -1) + { + VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); + } + MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE + } + + // NOW DO ALL THE SPRINGS + spring = m_Spring; + for (loop = 0; loop < m_SpringCnt; loop++) + { + p1 = &system[spring->p1]; + p2 = &system[spring->p2]; + VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) + + VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector + Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 + spring++; // DO THE NEXT SPRING + } + + // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE + if (m_MouseForceActive) + { + // APPLY TO EACH PICKED PARTICLE + if (m_Pick[0] > -1) + { + p1 = &system[m_Pick[0]]; + VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + if (m_Pick[1] > -1) + { + p1 = &system[m_Pick[1]]; + VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: Integrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses Euler's method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::Integrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + tParticle *source,*target; +/////////////////////////////////////////////////////////////////////////////// + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TargetSys; // WHERE I AM GOING TO STORE THE NEW STATE + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (DeltaTime * source->f.x * source->oneOverM); + target->v.y = source->v.y + (DeltaTime * source->f.y * source->oneOverM); + target->v.z = source->v.z + (DeltaTime * source->f.z * source->oneOverM); + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (DeltaTime * source->v.x); + target->pos.y = source->pos.y + (DeltaTime * source->v.y); + target->pos.z = source->pos.z + (DeltaTime * source->v.z); + + source++; + target++; + } +} + +int CPhysEnv::CheckForCollisions( tParticle *system ) +{ + // be optimistic! + int collisionState = NOT_COLLIDING; + float const depthEpsilon = 0.001f; + + int loop; + tParticle *curParticle; + + m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS + + curParticle = system; + for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); + loop++,curParticle++) + { + for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && + (collisionState != PENETRATING);planeIndex++) + { + tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; + + float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; + + if(axbyczd < -depthEpsilon) + { + // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(axbyczd < depthEpsilon) + { + float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); + + if(relativeVelocity < 0.0f) + { + collisionState = COLLIDING; + m_Contact[m_ContactCnt].particle = loop; + memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); + m_ContactCnt++; + } + } + } + } + + return collisionState; +} + +void CPhysEnv::ResolveCollisions( tParticle *system ) +{ + tContact *contact; + tParticle *particle; // THE PARTICLE COLLIDING + float VdotN; + tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE + contact = m_Contact; + for (int loop = 0; loop < m_ContactCnt; loop++,contact++) + { + particle = &system[contact->particle]; + // CALCULATE Vn + VdotN = DotProduct(&contact->normal,&particle->v); + ScaleVector(&contact->normal, VdotN, &Vn); + // CALCULATE Vt + VectorDifference(&particle->v, &Vn, &Vt); + // SCALE Vn BY COEFFICIENT OF RESTITUTION + ScaleVector(&Vn, m_Kr, &Vn); + // SET THE VELOCITY TO BE THE NEW IMPULSE + VectorDifference(&Vt, &Vn, &particle->v); + } +} + +void CPhysEnv::Simulate(float DeltaTime, BOOL running) +{ + float CurrentTime = 0.0f; + float TargetTime = DeltaTime; + tParticle *tempSys; + int collisionState; + + while(CurrentTime < DeltaTime) + { + if (running) + { + ComputeForces(m_CurrentSys); + + Integrate(TargetTime-CurrentTime); + } + + collisionState = CheckForCollisions(m_TargetSys); + + if(collisionState == PENETRATING) + { + // we simulated too far, so subdivide time and try again + TargetTime = (CurrentTime + TargetTime) / 2.0f; + + // blow up if we aren't moving forward each step, which is + // probably caused by interpenetration at the frame start + assert(fabs(TargetTime - CurrentTime) > EPSILON); + } + else + { + // either colliding or clear + if(collisionState == COLLIDING) + { + int Counter = 0; + do + { + ResolveCollisions(m_TargetSys); + Counter++; + } while((CheckForCollisions(m_TargetSys) == + COLLIDING) && (Counter < 100)); + + assert(Counter < 100); + } + + // we made a successful step, so swap configurations + // to "save" the data for the next step + + CurrentTime = TargetTime; + TargetTime = DeltaTime; + + // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN + tempSys = m_CurrentSys; + m_CurrentSys = m_TargetSys; + m_TargetSys = tempSys; + } + } +} diff --git a/Particle Dynamics/code/OGL/Squashy/PhysEnv.h b/Particle Dynamics/code/OGL/Squashy/PhysEnv.h index 355f26a..e288190 100644 --- a/Particle Dynamics/code/OGL/Squashy/PhysEnv.h +++ b/Particle Dynamics/code/OGL/Squashy/PhysEnv.h @@ -1,119 +1,119 @@ -#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) -#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// PhysEnv.h : header file -// -#include "MathDefs.h" - -#define EPSILON 0.00001f // ERROR TERM -#define DEFAULT_DAMPING 0.002f - -enum tCollisionTypes -{ - NOT_COLLIDING, - PENETRATING, - COLLIDING -}; - -// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH -struct tCollisionPlane -{ - tVector normal; // inward pointing - float d; // ax + by + cz + d = 0 -}; - -// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM -struct tParticle -{ - tVector pos; // Position of Particle - tVector v; // Velocity of Particle - tVector f; // Force Acting on Particle - float oneOverM; // 1 / Mass of Particle -}; - -// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM -struct tContact -{ - int particle; // Particle Index - tVector normal; // Normal of Collision plane -}; - -// TYPE FOR SPRINGS IN SYSTEM -struct tSpring -{ - int p1,p2; // PARTICLE INDEX FOR ENDS - float restLen; // LENGTH OF SPRING AT REST - float Ks; // SPRING CONSTANT - float Kd; // SPRING DAMPING -}; - -class CPhysEnv -{ -// Construction -public: - CPhysEnv(); - void RenderWorld(); - void SetWorldParticles(tVector *coords,int particleCnt); - void ResetWorld(); - void Simulate(float DeltaTime,BOOL running); - void ApplyUserForce(tVector *force); - void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); - void GetNearestPoint(int x, int y); - void AddSpring(); - void SetVertexMass(); - void SetWorldProperties(); - void FreeSystem(); - void LoadData(FILE *fp); - void SaveData(FILE *fp); - BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN - BOOL m_UseDamping; // SHOULD DAMPING BE ON - BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED - BOOL m_DrawSprings; // DRAW THE SPRING LINES - BOOL m_DrawVertices; // DRAW VERTICES - BOOL m_MouseForceActive; // MOUSE DRAG FORCE - -// Attributes -private: - float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; - tVector m_Gravity; // GRAVITY FORCE VECTOR - tVector m_UserForce; // USER FORCE VECTOR - float m_UserForceMag; // MAGNITUDE OF USER FORCE - float m_Kd; // DAMPING FACTOR - float m_Kr; // COEFFICIENT OF RESTITUTION - float m_Ksh; // HOOK'S SPRING CONSTANT - float m_Ksd; // SPRING DAMPING - float m_MouseForceKs; // MOUSE SPRING COEFFICIENT - tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES - int m_CollisionPlaneCnt; - tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS - int m_ContactCnt; // COLLISION COUNT - tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES - tParticle *m_CurrentSys,*m_TargetSys; - int m_ParticleCnt; - tSpring *m_Spring; // VALID SPRINGS IN SYSTEM - int m_SpringCnt; - int m_Pick[2]; // INDEX COUNTERS FOR SELECTING - tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR -// Operations -private: - void Integrate( float DeltaTime); - void ComputeForces( tParticle *system ); - int CheckForCollisions( tParticle *system ); - void ResolveCollisions( tParticle *system ); - void CompareBuffer(int size, float *buffer,float x, float y); - -// Implementation -public: - virtual ~CPhysEnv(); - -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PhysEnv.h : header file +// +#include "MathDefs.h" + +#define EPSILON 0.00001f // ERROR TERM +#define DEFAULT_DAMPING 0.002f + +enum tCollisionTypes +{ + NOT_COLLIDING, + PENETRATING, + COLLIDING +}; + +// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH +struct tCollisionPlane +{ + tVector normal; // inward pointing + float d; // ax + by + cz + d = 0 +}; + +// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM +struct tParticle +{ + tVector pos; // Position of Particle + tVector v; // Velocity of Particle + tVector f; // Force Acting on Particle + float oneOverM; // 1 / Mass of Particle +}; + +// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM +struct tContact +{ + int particle; // Particle Index + tVector normal; // Normal of Collision plane +}; + +// TYPE FOR SPRINGS IN SYSTEM +struct tSpring +{ + int p1,p2; // PARTICLE INDEX FOR ENDS + float restLen; // LENGTH OF SPRING AT REST + float Ks; // SPRING CONSTANT + float Kd; // SPRING DAMPING +}; + +class CPhysEnv +{ +// Construction +public: + CPhysEnv(); + void RenderWorld(); + void SetWorldParticles(tVector *coords,int particleCnt); + void ResetWorld(); + void Simulate(float DeltaTime,BOOL running); + void ApplyUserForce(tVector *force); + void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); + void GetNearestPoint(int x, int y); + void AddSpring(); + void SetVertexMass(); + void SetWorldProperties(); + void FreeSystem(); + void LoadData(FILE *fp); + void SaveData(FILE *fp); + BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN + BOOL m_UseDamping; // SHOULD DAMPING BE ON + BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED + BOOL m_DrawSprings; // DRAW THE SPRING LINES + BOOL m_DrawVertices; // DRAW VERTICES + BOOL m_MouseForceActive; // MOUSE DRAG FORCE + +// Attributes +private: + float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; + tVector m_Gravity; // GRAVITY FORCE VECTOR + tVector m_UserForce; // USER FORCE VECTOR + float m_UserForceMag; // MAGNITUDE OF USER FORCE + float m_Kd; // DAMPING FACTOR + float m_Kr; // COEFFICIENT OF RESTITUTION + float m_Ksh; // HOOK'S SPRING CONSTANT + float m_Ksd; // SPRING DAMPING + float m_MouseForceKs; // MOUSE SPRING COEFFICIENT + tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES + int m_CollisionPlaneCnt; + tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS + int m_ContactCnt; // COLLISION COUNT + tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES + tParticle *m_CurrentSys,*m_TargetSys; + int m_ParticleCnt; + tSpring *m_Spring; // VALID SPRINGS IN SYSTEM + int m_SpringCnt; + int m_Pick[2]; // INDEX COUNTERS FOR SELECTING + tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR +// Operations +private: + void Integrate( float DeltaTime); + void ComputeForces( tParticle *system ); + int CheckForCollisions( tParticle *system ); + void ResolveCollisions( tParticle *system ); + void CompareBuffer(int size, float *buffer,float x, float y); + +// Implementation +public: + virtual ~CPhysEnv(); + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/ReadMe.txt b/Particle Dynamics/code/OGL/Squashy/ReadMe.txt index 637f40c..b1159cd 100644 --- a/Particle Dynamics/code/OGL/Squashy/ReadMe.txt +++ b/Particle Dynamics/code/OGL/Squashy/ReadMe.txt @@ -1,82 +1,82 @@ -3D Real-time Soft Body Dynamics Demonstration Jan 20, 1999 --------------------------------------------------------- -v. 1.0 - -This program simulates soft body dynamics of a particle system -with particles connected with springs. - -This program is fairly complicated. In order to show off the -features I wanted to demonstrate, I needed to create quite a -number of functions and UI. I appologize for all the extra junk -but it was as clear as I could make it in the time allowed. -All the major functions for the actual dynamic simulation are in -the files: PhysEnv.h and PhysEnv.cpp. Some of the timing -and display code is in OGLView.h and OGLView.cpp. Most of -the UI is passed through MainFrm.cpp to OGLView. - -All of the simulation constants can be set through the -Simulation Properties dialog. Any changes to the spring constants -are applied to all springs in the simulation. There is currently -no way to change the settings for an individual spring. - -You can load in one of the pre-made simulations or create a -new one by loading in an OBJ. The OBJ needs to be scaled -within a +-5 unit cube world so it fits within the world boundaries. -An OBJ file loads as a point cloud. You then can connect the dots -by selecting vertices two at a time. Press "ENTER" to connect the -points with a spring. The normal length of the spring is the distance -at the time of spring creation. - -You can select one or two vertices and apply an user force to -the selected vertex/vertices. Once selected, a user force is -applied with the arrow keys for X-axis and Z-axis and HOME/END -applies the force to the Y-axis. The magnitude of the user force -is set in the sim properties dialog. - -You can also click and drag the LMB to apply a force in the local -X and Y axis. The mousespring force is set in the sim properties -dialog. The force will apply to the one or two vertices selected. - -Demos: - -"GonaBlow" -Be sure an check out the "GonaBlow" demo. It shows what happens -when the integrator suffers from numerical instability. You can -prove this by halving the MaxStepSize in the Timing Property Dialog. -We will fix that next month. - -"BoxBad" -This box is only connected along the cube edges. It is not stable in -this form. Try it out and see why. - -"BoxGood" -By adding crossbeam supports, it becomes stable. This is a good example -of how to create a stable model. - -"Diamond" -Another shape with pretty stiff springs. It is interesting to see how -it balances on an edge and then eventually falls. I suspect this is rounding -errors. In theory, it should balance exactly forever. - -This is a pretty complex demo. Any problems or questions, email me. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I compiled the code with Visual C++ 6.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -Also, depending on how well GLlines are drawn on your system, the -sim should run too fast, too slow, or just right. I try to lock -it to the clock except to set the timesteps. If it is strange, -adjust COGLView::RunSim(). - +3D Real-time Soft Body Dynamics Demonstration Jan 20, 1999 +-------------------------------------------------------- +v. 1.0 + +This program simulates soft body dynamics of a particle system +with particles connected with springs. + +This program is fairly complicated. In order to show off the +features I wanted to demonstrate, I needed to create quite a +number of functions and UI. I appologize for all the extra junk +but it was as clear as I could make it in the time allowed. +All the major functions for the actual dynamic simulation are in +the files: PhysEnv.h and PhysEnv.cpp. Some of the timing +and display code is in OGLView.h and OGLView.cpp. Most of +the UI is passed through MainFrm.cpp to OGLView. + +All of the simulation constants can be set through the +Simulation Properties dialog. Any changes to the spring constants +are applied to all springs in the simulation. There is currently +no way to change the settings for an individual spring. + +You can load in one of the pre-made simulations or create a +new one by loading in an OBJ. The OBJ needs to be scaled +within a +-5 unit cube world so it fits within the world boundaries. +An OBJ file loads as a point cloud. You then can connect the dots +by selecting vertices two at a time. Press "ENTER" to connect the +points with a spring. The normal length of the spring is the distance +at the time of spring creation. + +You can select one or two vertices and apply an user force to +the selected vertex/vertices. Once selected, a user force is +applied with the arrow keys for X-axis and Z-axis and HOME/END +applies the force to the Y-axis. The magnitude of the user force +is set in the sim properties dialog. + +You can also click and drag the LMB to apply a force in the local +X and Y axis. The mousespring force is set in the sim properties +dialog. The force will apply to the one or two vertices selected. + +Demos: + +"GonaBlow" +Be sure an check out the "GonaBlow" demo. It shows what happens +when the integrator suffers from numerical instability. You can +prove this by halving the MaxStepSize in the Timing Property Dialog. +We will fix that next month. + +"BoxBad" +This box is only connected along the cube edges. It is not stable in +this form. Try it out and see why. + +"BoxGood" +By adding crossbeam supports, it becomes stable. This is a good example +of how to create a stable model. + +"Diamond" +Another shape with pretty stiff springs. It is interesting to see how +it balances on an edge and then eventually falls. I suspect this is rounding +errors. In theory, it should balance exactly forever. + +This is a pretty complex demo. Any problems or questions, email me. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I compiled the code with Visual C++ 6.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +Also, depending on how well GLlines are drawn on your system, the +sim should run too fast, too slow, or just right. I try to lock +it to the clock except to set the timesteps. If it is strange, +adjust COGLView::RunSim(). + diff --git a/Particle Dynamics/code/OGL/Squashy/SimProps.cpp b/Particle Dynamics/code/OGL/Squashy/SimProps.cpp index 5d47e9a..3fda127 100644 --- a/Particle Dynamics/code/OGL/Squashy/SimProps.cpp +++ b/Particle Dynamics/code/OGL/Squashy/SimProps.cpp @@ -1,58 +1,58 @@ -// SimProps.cpp : implementation file -// - -#include "stdafx.h" -#include "squashy.h" -#include "SimProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - - -CSimProps::CSimProps(CWnd* pParent /*=NULL*/) - : CDialog(CSimProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSimProps) - m_CoefRest = 0.0f; - m_Damping = 0.0f; - m_GravX = 0.0f; - m_GravY = 0.0f; - m_GravZ = 0.0f; - m_SpringConst = 0.0f; - m_SpringDamp = 0.0f; - m_UserForceMag = 0.0f; - m_MouseSpring = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSimProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSimProps) - DDX_Text(pDX, IDC_COEFREST, m_CoefRest); - DDX_Text(pDX, IDC_Damping, m_Damping); - DDX_Text(pDX, IDC_GRAVX, m_GravX); - DDX_Text(pDX, IDC_GRAVY, m_GravY); - DDX_Text(pDX, IDC_GRAVZ, m_GravZ); - DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); - DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); - DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); - DDX_Text(pDX, IDC_MOUSESPRING, m_MouseSpring); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSimProps, CDialog) - //{{AFX_MSG_MAP(CSimProps) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSimProps message handlers +// SimProps.cpp : implementation file +// + +#include "stdafx.h" +#include "squashy.h" +#include "SimProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + + +CSimProps::CSimProps(CWnd* pParent /*=NULL*/) + : CDialog(CSimProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSimProps) + m_CoefRest = 0.0f; + m_Damping = 0.0f; + m_GravX = 0.0f; + m_GravY = 0.0f; + m_GravZ = 0.0f; + m_SpringConst = 0.0f; + m_SpringDamp = 0.0f; + m_UserForceMag = 0.0f; + m_MouseSpring = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSimProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSimProps) + DDX_Text(pDX, IDC_COEFREST, m_CoefRest); + DDX_Text(pDX, IDC_Damping, m_Damping); + DDX_Text(pDX, IDC_GRAVX, m_GravX); + DDX_Text(pDX, IDC_GRAVY, m_GravY); + DDX_Text(pDX, IDC_GRAVZ, m_GravZ); + DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); + DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); + DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); + DDX_Text(pDX, IDC_MOUSESPRING, m_MouseSpring); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSimProps, CDialog) + //{{AFX_MSG_MAP(CSimProps) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSimProps message handlers diff --git a/Particle Dynamics/code/OGL/Squashy/SimProps.h b/Particle Dynamics/code/OGL/Squashy/SimProps.h index de3b133..f514208 100644 --- a/Particle Dynamics/code/OGL/Squashy/SimProps.h +++ b/Particle Dynamics/code/OGL/Squashy/SimProps.h @@ -1,53 +1,53 @@ -#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) -#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// SimProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - -class CSimProps : public CDialog -{ -// Construction -public: - CSimProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSimProps) - enum { IDD = IDD_SIMPROP }; - float m_CoefRest; - float m_Damping; - float m_GravX; - float m_GravY; - float m_GravZ; - float m_SpringConst; - float m_SpringDamp; - float m_UserForceMag; - float m_MouseSpring; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSimProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSimProps) - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// SimProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + +class CSimProps : public CDialog +{ +// Construction +public: + CSimProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSimProps) + enum { IDD = IDD_SIMPROP }; + float m_CoefRest; + float m_Damping; + float m_GravX; + float m_GravY; + float m_GravZ; + float m_SpringConst; + float m_SpringDamp; + float m_UserForceMag; + float m_MouseSpring; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSimProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSimProps) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/Skeleton.cpp b/Particle Dynamics/code/OGL/Squashy/Skeleton.cpp index 68cf8c4..ac13a71 100644 --- a/Particle Dynamics/code/OGL/Squashy/Skeleton.cpp +++ b/Particle Dynamics/code/OGL/Squashy/Skeleton.cpp @@ -1,166 +1,166 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { -// free(child->primChannel); - child->primChannel = NULL; - } - if (child->visualCnt > 0) - { - free(child->visuals->vertexData); - if (child->visuals->faceIndex) - free(child->visuals->faceIndex); - free(child->visuals); - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - if (root->visualCnt > 0) - { - free(root->visuals->vertexData); - if (root->visuals->faceIndex) - free(root->visuals->faceIndex); - free(root->visuals); - } - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { +// free(child->primChannel); + child->primChannel = NULL; + } + if (child->visualCnt > 0) + { + free(child->visuals->vertexData); + if (child->visuals->faceIndex) + free(child->visuals->faceIndex); + free(child->visuals); + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + if (root->visualCnt > 0) + { + free(root->visuals->vertexData); + if (root->visuals->faceIndex) + free(root->visuals->faceIndex); + free(root->visuals); + } + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Particle Dynamics/code/OGL/Squashy/Skeleton.h b/Particle Dynamics/code/OGL/Squashy/Skeleton.h index 46b5d27..87139bd 100644 --- a/Particle Dynamics/code/OGL/Squashy/Skeleton.h +++ b/Particle Dynamics/code/OGL/Squashy/Skeleton.h @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -#define ushort unsigned short -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "MathDefs.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS - ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED - int vSize; // NUMBER OF FLOATS IN A VERTEX - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *faceNormal; // POINTER TO FACE NORMALS - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tVector Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - int glTex; - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -}; - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +#define ushort unsigned short +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "MathDefs.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS + ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED + int vSize; // NUMBER OF FLOATS IN A VERTEX + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *faceNormal; // POINTER TO FACE NORMALS + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tVector Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + int glTex; + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +}; + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/Squashy.cpp b/Particle Dynamics/code/OGL/Squashy/Squashy.cpp index 0cfe8cd..561bf65 100644 --- a/Particle Dynamics/code/OGL/Squashy/Squashy.cpp +++ b/Particle Dynamics/code/OGL/Squashy/Squashy.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Squashy.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Squashy.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp - -BEGIN_MESSAGE_MAP(CSquashyApp, CWinApp) - //{{AFX_MSG_MAP(CSquashyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp construction - -CSquashyApp::CSquashyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSquashyApp object - -CSquashyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp initialization - -BOOL CSquashyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSquashyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Squashy.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Squashy.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp + +BEGIN_MESSAGE_MAP(CSquashyApp, CWinApp) + //{{AFX_MSG_MAP(CSquashyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp construction + +CSquashyApp::CSquashyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSquashyApp object + +CSquashyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp initialization + +BOOL CSquashyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSquashyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp commands diff --git a/Particle Dynamics/code/OGL/Squashy/Squashy.h b/Particle Dynamics/code/OGL/Squashy/Squashy.h index b92b5f2..954a5f4 100644 --- a/Particle Dynamics/code/OGL/Squashy/Squashy.h +++ b/Particle Dynamics/code/OGL/Squashy/Squashy.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Squashy.h : main header file for the Squashy application -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CSquashyApp: -// See Squashy.cpp for the implementation of this class -// - -class CSquashyApp : public CWinApp -{ -public: - CSquashyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSquashyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSquashyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Squashy.h : main header file for the Squashy application +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CSquashyApp: +// See Squashy.cpp for the implementation of this class +// + +class CSquashyApp : public CWinApp +{ +public: + CSquashyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSquashyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSquashyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Squashy_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/Squashy.mak b/Particle Dynamics/code/OGL/Squashy/Squashy.mak index 62582b1..449012a 100644 --- a/Particle Dynamics/code/OGL/Squashy/Squashy.mak +++ b/Particle Dynamics/code/OGL/Squashy/Squashy.mak @@ -1,342 +1,342 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Squashy.dsp -!IF "$(CFG)" == "" -CFG=Squashy - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Squashy - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Squashy - Win32 Release" && "$(CFG)" != "Squashy - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Squashy.mak" CFG="Squashy - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Squashy - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Squashy - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Squashy - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\Squashy.obj" - -@erase "$(INTDIR)\Squashy.pch" - -@erase "$(INTDIR)\Squashy.res" - -@erase "$(INTDIR)\Squashy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PickObj.obj" - -@erase "$(INTDIR)\PickObj.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\Squashy.bsc" - -@erase "$(OUTDIR)\Squashy.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\Squashy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PickObj.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Squashy.pdb" /machine:I386 /out:"$(OUTDIR)\Squashy.exe" -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\Squashy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PickObj.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Squashy.res" - -"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\Squashy.obj" - -@erase "$(INTDIR)\Squashy.pch" - -@erase "$(INTDIR)\Squashy.res" - -@erase "$(INTDIR)\Squashy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PickObj.obj" - -@erase "$(INTDIR)\PickObj.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\Squashy.bsc" - -@erase "$(OUTDIR)\Squashy.exe" - -@erase "$(OUTDIR)\Squashy.ilk" - -@erase "$(OUTDIR)\Squashy.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\Squashy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PickObj.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Squashy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Squashy.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\Squashy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PickObj.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Squashy.res" - -"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("Squashy.dep") -!INCLUDE "Squashy.dep" -!ELSE -!MESSAGE Warning: cannot find "Squashy.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "Squashy - Win32 Release" || "$(CFG)" == "Squashy - Win32 Debug" -SOURCE=.\Bitmap.cpp - -"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Squashy.cpp - -"$(INTDIR)\Squashy.obj" "$(INTDIR)\Squashy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Squashy.rc - -"$(INTDIR)\Squashy.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\LoadOBJ.cpp - -"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\MainFrm.cpp - -"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\MathDefs.cpp - -"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\OGLView.cpp - -"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\PickObj.cpp - -"$(INTDIR)\PickObj.obj" "$(INTDIR)\PickObj.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Skeleton.cpp - -"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\StdAfx.cpp - -!IF "$(CFG)" == "Squashy - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Squashy.dsp +!IF "$(CFG)" == "" +CFG=Squashy - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Squashy - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Squashy - Win32 Release" && "$(CFG)" != "Squashy - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Squashy.mak" CFG="Squashy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Squashy - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Squashy - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Squashy - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\Squashy.obj" + -@erase "$(INTDIR)\Squashy.pch" + -@erase "$(INTDIR)\Squashy.res" + -@erase "$(INTDIR)\Squashy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PickObj.obj" + -@erase "$(INTDIR)\PickObj.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\Squashy.bsc" + -@erase "$(OUTDIR)\Squashy.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\Squashy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PickObj.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Squashy.pdb" /machine:I386 /out:"$(OUTDIR)\Squashy.exe" +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\Squashy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PickObj.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Squashy.res" + +"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\Squashy.obj" + -@erase "$(INTDIR)\Squashy.pch" + -@erase "$(INTDIR)\Squashy.res" + -@erase "$(INTDIR)\Squashy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PickObj.obj" + -@erase "$(INTDIR)\PickObj.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\Squashy.bsc" + -@erase "$(OUTDIR)\Squashy.exe" + -@erase "$(OUTDIR)\Squashy.ilk" + -@erase "$(OUTDIR)\Squashy.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\Squashy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PickObj.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Squashy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Squashy.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\Squashy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PickObj.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Squashy.res" + +"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("Squashy.dep") +!INCLUDE "Squashy.dep" +!ELSE +!MESSAGE Warning: cannot find "Squashy.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "Squashy - Win32 Release" || "$(CFG)" == "Squashy - Win32 Debug" +SOURCE=.\Bitmap.cpp + +"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Squashy.cpp + +"$(INTDIR)\Squashy.obj" "$(INTDIR)\Squashy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Squashy.rc + +"$(INTDIR)\Squashy.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\LoadOBJ.cpp + +"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\MainFrm.cpp + +"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\MathDefs.cpp + +"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\OGLView.cpp + +"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\PickObj.cpp + +"$(INTDIR)\PickObj.obj" "$(INTDIR)\PickObj.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Skeleton.cpp + +"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\StdAfx.cpp + +!IF "$(CFG)" == "Squashy - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/Particle Dynamics/code/OGL/Squashy/StdAfx.cpp b/Particle Dynamics/code/OGL/Squashy/StdAfx.cpp index 6a8db00..6aae14b 100644 --- a/Particle Dynamics/code/OGL/Squashy/StdAfx.cpp +++ b/Particle Dynamics/code/OGL/Squashy/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Squashy.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Squashy.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Particle Dynamics/code/OGL/Squashy/StdAfx.h b/Particle Dynamics/code/OGL/Squashy/StdAfx.h index ddefdab..571c76c 100644 --- a/Particle Dynamics/code/OGL/Squashy/StdAfx.h +++ b/Particle Dynamics/code/OGL/Squashy/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/TimeProps.cpp b/Particle Dynamics/code/OGL/Squashy/TimeProps.cpp index c1823de..56471a3 100644 --- a/Particle Dynamics/code/OGL/Squashy/TimeProps.cpp +++ b/Particle Dynamics/code/OGL/Squashy/TimeProps.cpp @@ -1,48 +1,48 @@ -// TimeProps.cpp : implementation file -// - -#include "stdafx.h" -#include "squashy.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - - -CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) - : CDialog(CTimeProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CTimeProps) - m_FixedTimeSteps = FALSE; - m_Iterations = 0; - m_MaxTimeStep = 0.0f; - //}}AFX_DATA_INIT -} - - -void CTimeProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CTimeProps) - DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); - DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); - DDV_MinMaxInt(pDX, m_Iterations, 1, 100); - DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CTimeProps, CDialog) - //{{AFX_MSG_MAP(CTimeProps) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps message handlers +// TimeProps.cpp : implementation file +// + +#include "stdafx.h" +#include "squashy.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + + +CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) + : CDialog(CTimeProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTimeProps) + m_FixedTimeSteps = FALSE; + m_Iterations = 0; + m_MaxTimeStep = 0.0f; + //}}AFX_DATA_INIT +} + + +void CTimeProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTimeProps) + DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); + DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); + DDV_MinMaxInt(pDX, m_Iterations, 1, 100); + DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CTimeProps, CDialog) + //{{AFX_MSG_MAP(CTimeProps) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps message handlers diff --git a/Particle Dynamics/code/OGL/Squashy/TimeProps.h b/Particle Dynamics/code/OGL/Squashy/TimeProps.h index 07041d8..2222823 100644 --- a/Particle Dynamics/code/OGL/Squashy/TimeProps.h +++ b/Particle Dynamics/code/OGL/Squashy/TimeProps.h @@ -1,48 +1,48 @@ -#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// TimeProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - -class CTimeProps : public CDialog -{ -// Construction -public: - CTimeProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CTimeProps) - enum { IDD = IDD_SIMTIMING }; - BOOL m_FixedTimeSteps; - int m_Iterations; - float m_MaxTimeStep; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CTimeProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CTimeProps) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// TimeProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + +class CTimeProps : public CDialog +{ +// Construction +public: + CTimeProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTimeProps) + enum { IDD = IDD_SIMTIMING }; + BOOL m_FixedTimeSteps; + int m_Iterations; + float m_MaxTimeStep; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTimeProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CTimeProps) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/VertMass.cpp b/Particle Dynamics/code/OGL/Squashy/VertMass.cpp index 35359fa..d060351 100644 --- a/Particle Dynamics/code/OGL/Squashy/VertMass.cpp +++ b/Particle Dynamics/code/OGL/Squashy/VertMass.cpp @@ -1,43 +1,43 @@ -// VertMass.cpp : implementation file -// - -#include "stdafx.h" -#include "squashy.h" -#include "VertMass.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CVertMass dialog - - -CVertMass::CVertMass(CWnd* pParent /*=NULL*/) - : CDialog(CVertMass::IDD, pParent) -{ - //{{AFX_DATA_INIT(CVertMass) - m_VertexMass = 0.0f; - //}}AFX_DATA_INIT -} - - -void CVertMass::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CVertMass) - DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CVertMass, CDialog) - //{{AFX_MSG_MAP(CVertMass) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CVertMass message handlers +// VertMass.cpp : implementation file +// + +#include "stdafx.h" +#include "squashy.h" +#include "VertMass.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CVertMass dialog + + +CVertMass::CVertMass(CWnd* pParent /*=NULL*/) + : CDialog(CVertMass::IDD, pParent) +{ + //{{AFX_DATA_INIT(CVertMass) + m_VertexMass = 0.0f; + //}}AFX_DATA_INIT +} + + +void CVertMass::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CVertMass) + DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CVertMass, CDialog) + //{{AFX_MSG_MAP(CVertMass) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CVertMass message handlers diff --git a/Particle Dynamics/code/OGL/Squashy/VertMass.h b/Particle Dynamics/code/OGL/Squashy/VertMass.h index d721109..57035f5 100644 --- a/Particle Dynamics/code/OGL/Squashy/VertMass.h +++ b/Particle Dynamics/code/OGL/Squashy/VertMass.h @@ -1,46 +1,46 @@ -#if !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// VertMass.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CVertMass dialog - -class CVertMass : public CDialog -{ -// Construction -public: - CVertMass(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CVertMass) - enum { IDD = IDD_VERTEXMASS }; - float m_VertexMass; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CVertMass) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CVertMass) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// VertMass.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CVertMass dialog + +class CVertMass : public CDialog +{ +// Construction +public: + CVertMass(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CVertMass) + enum { IDD = IDD_VERTEXMASS }; + float m_VertexMass; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CVertMass) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CVertMass) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/Particle Dynamics/code/OGL/Squashy/resource.h b/Particle Dynamics/code/OGL/Squashy/resource.h index bb97b5d..4b45026 100644 --- a/Particle Dynamics/code/OGL/Squashy/resource.h +++ b/Particle Dynamics/code/OGL/Squashy/resource.h @@ -1,77 +1,77 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Squashy.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SQUASHYTYPE 129 -#define IDD_SETROTATE 130 -#define IDB_HUP 131 -#define IDB_HDN 132 -#define IDD_DIALOG1 132 -#define IDB_HUPP 133 -#define IDD_LOADOBJ 133 -#define IDD_PICKOBJ 133 -#define IDB_HDNP 134 -#define IDD_SIMPROP 134 -#define IDB_VDN 135 -#define IDD_VERTEXMASS 135 -#define IDB_VUP 136 -#define IDD_SIMTIMING 136 -#define IDB_VUPP 137 -#define IDB_VDNP 138 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_BUTTON1 1001 -#define IDC_BROWSE1 1001 -#define IDC_ZAXIS 1002 -#define IDC_BROWSE2 1002 -#define IDC_SLIDER1 1003 -#define IDC_EDIT1 1004 -#define IDC_GRAVX 1004 -#define IDC_MAXTIMESTEP 1004 -#define IDC_EDIT2 1005 -#define IDC_OBJLIST 1005 -#define IDC_GRAVY 1005 -#define IDC_ITERATIONS 1005 -#define IDC_GRAVZ 1006 -#define IDC_COEFREST 1007 -#define IDC_SPRINGCONST 1008 -#define IDC_Damping 1009 -#define IDC_SPRINGDAMP 1010 -#define IDC_USERFORCEMAG 1011 -#define IDC_VERTEXMASS 1012 -#define IDC_MOUSESPRING 1013 -#define IDC_FIXEDTIME 1014 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_METHOD_FASTBBOX 32775 -#define ID_VIEW_SHOWBBOX 32776 -#define ID_VIEW_SHOWOBBOX 32777 -#define ID_VIEW_SHOWSPRINGS 32778 -#define ID_VIEW_SHOWGEOMETRY 32779 -#define ID_SIMULATION_RUNNING 32780 -#define ID_SIMULATION_RESET 32781 -#define ID_SIMULATION_SETSIMPROPERTIES 32782 -#define ID_SIMULATION_USEGRAVITY 32783 -#define ID_VIEW_SHOWVERTICES 32785 -#define ID_FILE_NEWSYSTEM 32786 -#define ID_SIMULATION_SETVERTEXMASS 32787 -#define ID_SIMULATION_SETTIMINGPROPERTIES 32788 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 137 -#define _APS_NEXT_COMMAND_VALUE 32789 -#define _APS_NEXT_CONTROL_VALUE 1015 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Squashy.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SQUASHYTYPE 129 +#define IDD_SETROTATE 130 +#define IDB_HUP 131 +#define IDB_HDN 132 +#define IDD_DIALOG1 132 +#define IDB_HUPP 133 +#define IDD_LOADOBJ 133 +#define IDD_PICKOBJ 133 +#define IDB_HDNP 134 +#define IDD_SIMPROP 134 +#define IDB_VDN 135 +#define IDD_VERTEXMASS 135 +#define IDB_VUP 136 +#define IDD_SIMTIMING 136 +#define IDB_VUPP 137 +#define IDB_VDNP 138 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_BUTTON1 1001 +#define IDC_BROWSE1 1001 +#define IDC_ZAXIS 1002 +#define IDC_BROWSE2 1002 +#define IDC_SLIDER1 1003 +#define IDC_EDIT1 1004 +#define IDC_GRAVX 1004 +#define IDC_MAXTIMESTEP 1004 +#define IDC_EDIT2 1005 +#define IDC_OBJLIST 1005 +#define IDC_GRAVY 1005 +#define IDC_ITERATIONS 1005 +#define IDC_GRAVZ 1006 +#define IDC_COEFREST 1007 +#define IDC_SPRINGCONST 1008 +#define IDC_Damping 1009 +#define IDC_SPRINGDAMP 1010 +#define IDC_USERFORCEMAG 1011 +#define IDC_VERTEXMASS 1012 +#define IDC_MOUSESPRING 1013 +#define IDC_FIXEDTIME 1014 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_METHOD_FASTBBOX 32775 +#define ID_VIEW_SHOWBBOX 32776 +#define ID_VIEW_SHOWOBBOX 32777 +#define ID_VIEW_SHOWSPRINGS 32778 +#define ID_VIEW_SHOWGEOMETRY 32779 +#define ID_SIMULATION_RUNNING 32780 +#define ID_SIMULATION_RESET 32781 +#define ID_SIMULATION_SETSIMPROPERTIES 32782 +#define ID_SIMULATION_USEGRAVITY 32783 +#define ID_VIEW_SHOWVERTICES 32785 +#define ID_FILE_NEWSYSTEM 32786 +#define ID_SIMULATION_SETVERTEXMASS 32787 +#define ID_SIMULATION_SETTIMINGPROPERTIES 32788 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 137 +#define _APS_NEXT_COMMAND_VALUE 32789 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Particle Systems/Code/OGL/Spray/EditEmit.cpp b/Particle Systems/Code/OGL/Spray/EditEmit.cpp index 49497fa..4b44c2c 100644 --- a/Particle Systems/Code/OGL/Spray/EditEmit.cpp +++ b/Particle Systems/Code/OGL/Spray/EditEmit.cpp @@ -1,113 +1,113 @@ -// EditEmit.cpp : implementation file -// - -#include "stdafx.h" -#include "Spray.h" -#include "EditEmit.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CEditEmit dialog - - -CEditEmit::CEditEmit(CWnd* pParent /*=NULL*/) - : CDialog(CEditEmit::IDD, pParent) -{ - //{{AFX_DATA_INIT(CEditEmit) - m_endColorB = 0.0f; - m_endColorBVar = 0.0f; - m_endColorG = 0.0f; - m_endColorGVar = 0.0f; - m_endColorR = 0.0f; - m_endColorRVar = 0.0f; - m_emits = 0; - m_emitVar = 0; - m_forceX = 0.0f; - m_forceY = 0.0f; - m_forceZ = 0.0f; - m_life = 0; - m_lifeVar = 0; - m_pitch = 0.0f; - m_pitchVar = 0.0f; - m_startColorB = 0.0f; - m_startColorBVar = 0.0f; - m_startColorG = 0.0f; - m_startColorGVar = 0.0f; - m_startColorR = 0.0f; - m_startColorRVar = 0.0f; - m_speed = 0.0f; - m_speedVar = 0.0f; - m_yaw = 0.0f; - m_yawVar = 0.0f; - m_name = _T(""); - m_TotalParticles = 0; - //}}AFX_DATA_INIT -} - - -void CEditEmit::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CEditEmit) - DDX_Text(pDX, IDC_ECOLORB, m_endColorB); - DDV_MinMaxFloat(pDX, m_endColorB, 0.f, 1.f); - DDX_Text(pDX, IDC_ECOLORBV, m_endColorBVar); - DDV_MinMaxFloat(pDX, m_endColorBVar, 0.f, 1.f); - DDX_Text(pDX, IDC_ECOLORG, m_endColorG); - DDV_MinMaxFloat(pDX, m_endColorG, 0.f, 1.f); - DDX_Text(pDX, IDC_ECOLORGV, m_endColorGVar); - DDV_MinMaxFloat(pDX, m_endColorGVar, 0.f, 1.f); - DDX_Text(pDX, IDC_ECOLORR, m_endColorR); - DDV_MinMaxFloat(pDX, m_endColorR, 0.f, 1.f); - DDX_Text(pDX, IDC_ECOLORRV, m_endColorRVar); - DDV_MinMaxFloat(pDX, m_endColorRVar, 0.f, 1.f); - DDX_Text(pDX, IDC_EMITS, m_emits); - DDX_Text(pDX, IDC_EMITVAR, m_emitVar); - DDX_Text(pDX, IDC_FORCEX, m_forceX); - DDX_Text(pDX, IDC_FORCEY, m_forceY); - DDX_Text(pDX, IDC_FORCEZ, m_forceZ); - DDX_Text(pDX, IDC_LIFE, m_life); - DDX_Text(pDX, IDC_LIFEVAR, m_lifeVar); - DDX_Text(pDX, IDC_PITCH, m_pitch); - DDV_MinMaxFloat(pDX, m_pitch, 0.f, 360.f); - DDX_Text(pDX, IDC_PITCHVAR, m_pitchVar); - DDV_MinMaxFloat(pDX, m_pitchVar, 0.f, 360.f); - DDX_Text(pDX, IDC_SCOLORB, m_startColorB); - DDV_MinMaxFloat(pDX, m_startColorB, 0.f, 1.f); - DDX_Text(pDX, IDC_SCOLORBV, m_startColorBVar); - DDV_MinMaxFloat(pDX, m_startColorBVar, 0.f, 1.f); - DDX_Text(pDX, IDC_SCOLORG, m_startColorG); - DDV_MinMaxFloat(pDX, m_startColorG, 0.f, 1.f); - DDX_Text(pDX, IDC_SCOLORGV, m_startColorGVar); - DDV_MinMaxFloat(pDX, m_startColorGVar, 0.f, 1.f); - DDX_Text(pDX, IDC_SCOLORR, m_startColorR); - DDV_MinMaxFloat(pDX, m_startColorR, 0.f, 1.f); - DDX_Text(pDX, IDC_SCOLORRV, m_startColorRVar); - DDV_MinMaxFloat(pDX, m_startColorRVar, 0.f, 1.f); - DDX_Text(pDX, IDC_SPEED, m_speed); - DDX_Text(pDX, IDC_SPEEDVAR, m_speedVar); - DDX_Text(pDX, IDC_YAW, m_yaw); - DDV_MinMaxFloat(pDX, m_yaw, 0.f, 360.f); - DDX_Text(pDX, IDC_YAWVAR, m_yawVar); - DDV_MinMaxFloat(pDX, m_yawVar, 0.f, 360.f); - DDX_Text(pDX, IDC_NAME, m_name); - DDV_MaxChars(pDX, m_name, 80); - DDX_Text(pDX, IDC_TOTALPARTS, m_TotalParticles); - DDV_MinMaxInt(pDX, m_TotalParticles, 1, 4000); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CEditEmit, CDialog) - //{{AFX_MSG_MAP(CEditEmit) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CEditEmit message handlers +// EditEmit.cpp : implementation file +// + +#include "stdafx.h" +#include "Spray.h" +#include "EditEmit.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CEditEmit dialog + + +CEditEmit::CEditEmit(CWnd* pParent /*=NULL*/) + : CDialog(CEditEmit::IDD, pParent) +{ + //{{AFX_DATA_INIT(CEditEmit) + m_endColorB = 0.0f; + m_endColorBVar = 0.0f; + m_endColorG = 0.0f; + m_endColorGVar = 0.0f; + m_endColorR = 0.0f; + m_endColorRVar = 0.0f; + m_emits = 0; + m_emitVar = 0; + m_forceX = 0.0f; + m_forceY = 0.0f; + m_forceZ = 0.0f; + m_life = 0; + m_lifeVar = 0; + m_pitch = 0.0f; + m_pitchVar = 0.0f; + m_startColorB = 0.0f; + m_startColorBVar = 0.0f; + m_startColorG = 0.0f; + m_startColorGVar = 0.0f; + m_startColorR = 0.0f; + m_startColorRVar = 0.0f; + m_speed = 0.0f; + m_speedVar = 0.0f; + m_yaw = 0.0f; + m_yawVar = 0.0f; + m_name = _T(""); + m_TotalParticles = 0; + //}}AFX_DATA_INIT +} + + +void CEditEmit::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CEditEmit) + DDX_Text(pDX, IDC_ECOLORB, m_endColorB); + DDV_MinMaxFloat(pDX, m_endColorB, 0.f, 1.f); + DDX_Text(pDX, IDC_ECOLORBV, m_endColorBVar); + DDV_MinMaxFloat(pDX, m_endColorBVar, 0.f, 1.f); + DDX_Text(pDX, IDC_ECOLORG, m_endColorG); + DDV_MinMaxFloat(pDX, m_endColorG, 0.f, 1.f); + DDX_Text(pDX, IDC_ECOLORGV, m_endColorGVar); + DDV_MinMaxFloat(pDX, m_endColorGVar, 0.f, 1.f); + DDX_Text(pDX, IDC_ECOLORR, m_endColorR); + DDV_MinMaxFloat(pDX, m_endColorR, 0.f, 1.f); + DDX_Text(pDX, IDC_ECOLORRV, m_endColorRVar); + DDV_MinMaxFloat(pDX, m_endColorRVar, 0.f, 1.f); + DDX_Text(pDX, IDC_EMITS, m_emits); + DDX_Text(pDX, IDC_EMITVAR, m_emitVar); + DDX_Text(pDX, IDC_FORCEX, m_forceX); + DDX_Text(pDX, IDC_FORCEY, m_forceY); + DDX_Text(pDX, IDC_FORCEZ, m_forceZ); + DDX_Text(pDX, IDC_LIFE, m_life); + DDX_Text(pDX, IDC_LIFEVAR, m_lifeVar); + DDX_Text(pDX, IDC_PITCH, m_pitch); + DDV_MinMaxFloat(pDX, m_pitch, 0.f, 360.f); + DDX_Text(pDX, IDC_PITCHVAR, m_pitchVar); + DDV_MinMaxFloat(pDX, m_pitchVar, 0.f, 360.f); + DDX_Text(pDX, IDC_SCOLORB, m_startColorB); + DDV_MinMaxFloat(pDX, m_startColorB, 0.f, 1.f); + DDX_Text(pDX, IDC_SCOLORBV, m_startColorBVar); + DDV_MinMaxFloat(pDX, m_startColorBVar, 0.f, 1.f); + DDX_Text(pDX, IDC_SCOLORG, m_startColorG); + DDV_MinMaxFloat(pDX, m_startColorG, 0.f, 1.f); + DDX_Text(pDX, IDC_SCOLORGV, m_startColorGVar); + DDV_MinMaxFloat(pDX, m_startColorGVar, 0.f, 1.f); + DDX_Text(pDX, IDC_SCOLORR, m_startColorR); + DDV_MinMaxFloat(pDX, m_startColorR, 0.f, 1.f); + DDX_Text(pDX, IDC_SCOLORRV, m_startColorRVar); + DDV_MinMaxFloat(pDX, m_startColorRVar, 0.f, 1.f); + DDX_Text(pDX, IDC_SPEED, m_speed); + DDX_Text(pDX, IDC_SPEEDVAR, m_speedVar); + DDX_Text(pDX, IDC_YAW, m_yaw); + DDV_MinMaxFloat(pDX, m_yaw, 0.f, 360.f); + DDX_Text(pDX, IDC_YAWVAR, m_yawVar); + DDV_MinMaxFloat(pDX, m_yawVar, 0.f, 360.f); + DDX_Text(pDX, IDC_NAME, m_name); + DDV_MaxChars(pDX, m_name, 80); + DDX_Text(pDX, IDC_TOTALPARTS, m_TotalParticles); + DDV_MinMaxInt(pDX, m_TotalParticles, 1, 4000); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CEditEmit, CDialog) + //{{AFX_MSG_MAP(CEditEmit) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CEditEmit message handlers diff --git a/Particle Systems/Code/OGL/Spray/EditEmit.h b/Particle Systems/Code/OGL/Spray/EditEmit.h index 40edd82..bb9adff 100644 --- a/Particle Systems/Code/OGL/Spray/EditEmit.h +++ b/Particle Systems/Code/OGL/Spray/EditEmit.h @@ -1,72 +1,72 @@ -#if !defined(AFX_EDITEMIT_H__F171A980_D718_11D1_83A2_004005308EB5__INCLUDED_) -#define AFX_EDITEMIT_H__F171A980_D718_11D1_83A2_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// EditEmit.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CEditEmit dialog - -class CEditEmit : public CDialog -{ -// Construction -public: - CEditEmit(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CEditEmit) - enum { IDD = IDD_SETEMITTER }; - float m_endColorB; - float m_endColorBVar; - float m_endColorG; - float m_endColorGVar; - float m_endColorR; - float m_endColorRVar; - int m_emits; - int m_emitVar; - float m_forceX; - float m_forceY; - float m_forceZ; - int m_life; - int m_lifeVar; - float m_pitch; - float m_pitchVar; - float m_startColorB; - float m_startColorBVar; - float m_startColorG; - float m_startColorGVar; - float m_startColorR; - float m_startColorRVar; - float m_speed; - float m_speedVar; - float m_yaw; - float m_yawVar; - CString m_name; - int m_TotalParticles; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CEditEmit) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CEditEmit) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_EDITEMIT_H__F171A980_D718_11D1_83A2_004005308EB5__INCLUDED_) +#if !defined(AFX_EDITEMIT_H__F171A980_D718_11D1_83A2_004005308EB5__INCLUDED_) +#define AFX_EDITEMIT_H__F171A980_D718_11D1_83A2_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// EditEmit.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CEditEmit dialog + +class CEditEmit : public CDialog +{ +// Construction +public: + CEditEmit(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CEditEmit) + enum { IDD = IDD_SETEMITTER }; + float m_endColorB; + float m_endColorBVar; + float m_endColorG; + float m_endColorGVar; + float m_endColorR; + float m_endColorRVar; + int m_emits; + int m_emitVar; + float m_forceX; + float m_forceY; + float m_forceZ; + int m_life; + int m_lifeVar; + float m_pitch; + float m_pitchVar; + float m_startColorB; + float m_startColorBVar; + float m_startColorG; + float m_startColorGVar; + float m_startColorR; + float m_startColorRVar; + float m_speed; + float m_speedVar; + float m_yaw; + float m_yawVar; + CString m_name; + int m_TotalParticles; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CEditEmit) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CEditEmit) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_EDITEMIT_H__F171A980_D718_11D1_83A2_004005308EB5__INCLUDED_) diff --git a/Particle Systems/Code/OGL/Spray/MainFrm.cpp b/Particle Systems/Code/OGL/Spray/MainFrm.cpp index 2287c85..248875e 100644 --- a/Particle Systems/Code/OGL/Spray/MainFrm.cpp +++ b/Particle Systems/Code/OGL/Spray/MainFrm.cpp @@ -1,274 +1,274 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Particle System -// -// Created: -// JL 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "Spray.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_NEW, OnFileNew) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_SETTINGS_ANTIALIASPOINTS, OnSettingsAntialiaspoints) - ON_UPDATE_COMMAND_UI(ID_SETTINGS_ANTIALIASPOINTS, OnUpdateSettingsAntialiaspoints) - ON_COMMAND(ID_SETTINGS_EDITEMITTER, OnSettingsEditemitter) - ON_COMMAND(ID_SETTINGS_SHOWAXIS, OnSettingsShowaxis) - ON_UPDATE_COMMAND_UI(ID_SETTINGS_SHOWAXIS, OnUpdateSettingsShowaxis) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_COUNT2, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case 'Q': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -/////////////////////////////////////////////////////////////////////////////// -// Function: IdleFunc -// Purpose: Process state changes if animating -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::IdleFunc() -{ - m_OGLView.IdleFunc(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnFileNew -// Purpose: Clear the weight settings for the model -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileNew() -{ - m_OGLView.resetEmitter(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnFileOpen -// Purpose: Load the Emitter settings for the system -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileOpen() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Particle Emitter Files (*.pef)|*.PEF|All Files (*.*)|*.*||"; - char directory[80]; - CFileDialog *dialog; -/////////////////////////////////////////////////////////////////////////////// - // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY - _getcwd(directory,80); - dialog = new CFileDialog(TRUE,"PEF",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - if (!m_OGLView.GetEmitter(dialog->GetPathName())) - { - MessageBox("Unable to load Emitter File","Error",MB_OK); - } - } - // RESET THE MAIN DIRECTORY - _chdir(directory); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnFileSave -// Purpose: Save the Emitter settings for the system -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileSave() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Weight Files (*.PEF)|*.PEF|All Files (*.*)|*.*||"; - char directory[80]; - CFileDialog *dialog; -/////////////////////////////////////////////////////////////////////////////// - // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY - _getcwd(directory,80); - dialog = new CFileDialog(FALSE,"PEF",NULL,OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - if (!m_OGLView.SaveEmitter(dialog->GetPathName())) - { - MessageBox("Unable to Save Emitter File","Error",MB_OK); - } - } - // RESET THE MAIN DIRECTORY - _chdir(directory); -} - -void CMainFrame::OnSettingsAntialiaspoints() -{ - m_OGLView.m_AntiAlias = !m_OGLView.m_AntiAlias; -} - -void CMainFrame::OnUpdateSettingsAntialiaspoints(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_AntiAlias ); -} - -void CMainFrame::OnSettingsEditemitter() -{ - m_OGLView.editEmitter(&m_OGLView.m_Emitter); -} - -void CMainFrame::OnSettingsShowaxis() -{ - m_OGLView.m_DrawAxis = !m_OGLView.m_DrawAxis; -} - -void CMainFrame::OnUpdateSettingsShowaxis(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawAxis ); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Particle System +// +// Created: +// JL 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "Spray.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_NEW, OnFileNew) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_SETTINGS_ANTIALIASPOINTS, OnSettingsAntialiaspoints) + ON_UPDATE_COMMAND_UI(ID_SETTINGS_ANTIALIASPOINTS, OnUpdateSettingsAntialiaspoints) + ON_COMMAND(ID_SETTINGS_EDITEMITTER, OnSettingsEditemitter) + ON_COMMAND(ID_SETTINGS_SHOWAXIS, OnSettingsShowaxis) + ON_UPDATE_COMMAND_UI(ID_SETTINGS_SHOWAXIS, OnUpdateSettingsShowaxis) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_COUNT2, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case 'Q': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +/////////////////////////////////////////////////////////////////////////////// +// Function: IdleFunc +// Purpose: Process state changes if animating +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::IdleFunc() +{ + m_OGLView.IdleFunc(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnFileNew +// Purpose: Clear the weight settings for the model +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileNew() +{ + m_OGLView.resetEmitter(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnFileOpen +// Purpose: Load the Emitter settings for the system +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileOpen() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Particle Emitter Files (*.pef)|*.PEF|All Files (*.*)|*.*||"; + char directory[80]; + CFileDialog *dialog; +/////////////////////////////////////////////////////////////////////////////// + // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY + _getcwd(directory,80); + dialog = new CFileDialog(TRUE,"PEF",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + if (!m_OGLView.GetEmitter(dialog->GetPathName())) + { + MessageBox("Unable to load Emitter File","Error",MB_OK); + } + } + // RESET THE MAIN DIRECTORY + _chdir(directory); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnFileSave +// Purpose: Save the Emitter settings for the system +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileSave() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Weight Files (*.PEF)|*.PEF|All Files (*.*)|*.*||"; + char directory[80]; + CFileDialog *dialog; +/////////////////////////////////////////////////////////////////////////////// + // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY + _getcwd(directory,80); + dialog = new CFileDialog(FALSE,"PEF",NULL,OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + if (!m_OGLView.SaveEmitter(dialog->GetPathName())) + { + MessageBox("Unable to Save Emitter File","Error",MB_OK); + } + } + // RESET THE MAIN DIRECTORY + _chdir(directory); +} + +void CMainFrame::OnSettingsAntialiaspoints() +{ + m_OGLView.m_AntiAlias = !m_OGLView.m_AntiAlias; +} + +void CMainFrame::OnUpdateSettingsAntialiaspoints(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_AntiAlias ); +} + +void CMainFrame::OnSettingsEditemitter() +{ + m_OGLView.editEmitter(&m_OGLView.m_Emitter); +} + +void CMainFrame::OnSettingsShowaxis() +{ + m_OGLView.m_DrawAxis = !m_OGLView.m_DrawAxis; +} + +void CMainFrame::OnUpdateSettingsShowaxis(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawAxis ); +} diff --git a/Particle Systems/Code/OGL/Spray/MainFrm.h b/Particle Systems/Code/OGL/Spray/MainFrm.h index a899938..3fd2a0f 100644 --- a/Particle Systems/Code/OGL/Spray/MainFrm.h +++ b/Particle Systems/Code/OGL/Spray/MainFrm.h @@ -1,90 +1,90 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Deformation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__86F99069_D3EC_11D1_83A2_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__86F99069_D3EC_11D1_83A2_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Particle.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - -// Operations -public: - CMainFrame(); - - void IdleFunc(); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - - void InitializeEmitter(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileNew(); - afx_msg void OnFileOpen(); - afx_msg void OnFileSave(); - afx_msg void OnSettingsAntialiaspoints(); - afx_msg void OnUpdateSettingsAntialiaspoints(CCmdUI* pCmdUI); - afx_msg void OnSettingsEditemitter(); - afx_msg void OnSettingsShowaxis(); - afx_msg void OnUpdateSettingsShowaxis(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__86F99069_D3EC_11D1_83A2_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Deformation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__86F99069_D3EC_11D1_83A2_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__86F99069_D3EC_11D1_83A2_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Particle.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + +// Operations +public: + CMainFrame(); + + void IdleFunc(); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + + void InitializeEmitter(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileNew(); + afx_msg void OnFileOpen(); + afx_msg void OnFileSave(); + afx_msg void OnSettingsAntialiaspoints(); + afx_msg void OnUpdateSettingsAntialiaspoints(CCmdUI* pCmdUI); + afx_msg void OnSettingsEditemitter(); + afx_msg void OnSettingsShowaxis(); + afx_msg void OnUpdateSettingsShowaxis(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__86F99069_D3EC_11D1_83A2_004005308EB5__INCLUDED_) diff --git a/Particle Systems/Code/OGL/Spray/MathStuff.h b/Particle Systems/Code/OGL/Spray/MathStuff.h index 2621eda..2825473 100644 --- a/Particle Systems/Code/OGL/Spray/MathStuff.h +++ b/Particle Systems/Code/OGL/Spray/MathStuff.h @@ -1,72 +1,72 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathStuff.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHSTUFF_H__INCLUDED_) -#define MATHSTUFF_H__INCLUDED_ - -#define M_PI 3.14159265358979323846 -#define HALF_PI 1.57079632679489661923 - -#define DEGTORAD(d) ((d * (float)M_PI) / 180.0f); -#define RADTODEG(r) ((r * 180.0f) /(float)M_PI); - -typedef struct -{ - float x,y,z; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathStuff.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHSTUFF_H__INCLUDED_) +#define MATHSTUFF_H__INCLUDED_ + +#define M_PI 3.14159265358979323846 +#define HALF_PI 1.57079632679489661923 + +#define DEGTORAD(d) ((d * (float)M_PI) / 180.0f); +#define RADTODEG(r) ((r * 180.0f) /(float)M_PI); + +typedef struct +{ + float x,y,z; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Particle Systems/Code/OGL/Spray/Matrix.cpp b/Particle Systems/Code/OGL/Spray/Matrix.cpp index b31a902..1943627 100644 --- a/Particle Systems/Code/OGL/Spray/Matrix.cpp +++ b/Particle Systems/Code/OGL/Spray/Matrix.cpp @@ -1,45 +1,45 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Matrix.cpp : implementation file -// -// Purpose: Implementation of Matrix Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "matrix.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Matrix.cpp : implementation file +// +// Purpose: Implementation of Matrix Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "matrix.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// diff --git a/Particle Systems/Code/OGL/Spray/Matrix.h b/Particle Systems/Code/OGL/Spray/Matrix.h index 4c7536a..cb3c900 100644 --- a/Particle Systems/Code/OGL/Spray/Matrix.h +++ b/Particle Systems/Code/OGL/Spray/Matrix.h @@ -1,39 +1,39 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Matrix.h : Matrix Structure Header File -// -// Purpose: Declare Basic Matrix Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATRIX_H__INCLUDED_) -#define MATRIX_H__INCLUDED_ - -#include "Math.h" // MATH SYSTEM HEADER - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); - -#endif // !defined(MATRIX_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// Matrix.h : Matrix Structure Header File +// +// Purpose: Declare Basic Matrix Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATRIX_H__INCLUDED_) +#define MATRIX_H__INCLUDED_ + +#include "Math.h" // MATH SYSTEM HEADER + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); + +#endif // !defined(MATRIX_H__INCLUDED_) + diff --git a/Particle Systems/Code/OGL/Spray/OGLView.cpp b/Particle Systems/Code/OGL/Spray/OGLView.cpp index f15ec8b..fb1c585 100644 --- a/Particle Systems/Code/OGL/Spray/OGLView.cpp +++ b/Particle Systems/Code/OGL/Spray/OGLView.cpp @@ -1,619 +1,619 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Particle System -// -// Created: -// JL 2/18/98 -// Revisions: -// Integrated into Particle System Demo 4/14/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Spray.h" -#include "OGLView.h" -#include "particle.h" -#include "EditEmit.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -// IF YOU WANT TO TRY A QUICKER TWO BONE WEIGHTING SYSTEM UNDEF THIS -#define DEFORM_GENERAL_SOLUTION // FULL MULTI-BONE DEFORMATION -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0f // SPEED OF ROTATION -#define ANGLE_SPEED 0.01f // SPEED OF ANGLE ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/// Message Maps ////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_LBUTTONUP() - ON_WM_RBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - initParticleSystem(); - initEmitter(&m_Emitter); - m_CurrentEmitter = &m_Emitter; - m_DrawAxis = TRUE; // DRAW ORIGIN AXIS - m_DrawSystem = TRUE; // ANIMATE THE PARTICLES - m_AntiAlias = TRUE; // ANTIALIAS THE PARTICLES - - m_ViewRot.x = 0.0; - m_ViewRot.y = 0.0; - m_ViewRot.z = 0.0; -} - -COGLView::~COGLView() -{ -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - UpdateStatus(); // DRAW INITIAL STATUS BAR - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -void COGLView::UpdateStatus() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - sprintf(message,"# %d",m_Emitter.particleCount); - - m_ptrStatusBar->SetPaneText(1,message); - -} - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); -// glScalef(1.0,1.0,1.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - drawScene(FALSE); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(35.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(40.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_LINE); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); - glPointSize(2.0); // JUST 1 PIXEL DOTS FOR NOW -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -GLvoid COGLView::drawScene(BOOL drawSelectRect) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Emitter.pos.x, m_Emitter.pos.y, m_Emitter.pos.z); - - glRotatef(m_ViewRot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_ViewRot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_ViewRot.x, 1.0f, 0.0f, 0.0f); - - // DRAW THE AXIS OGL OBJECT - if (m_DrawAxis) - glCallList(OGL_AXIS_DLIST); - - renderEmitter(&m_Emitter,m_AntiAlias); - - glPopMatrix(); - - glFinish(); - - SwapBuffers(m_hDC); - - // DRAW THE STATS AT THE BOTTOM OF THE SCREEN - UpdateStatus(); -} - - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(FALSE); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); - m_ScreenWidth = cx; - m_ScreenHeight = cy; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: IdleFunc -// Purpose: Process state changes if animating -/////////////////////////////////////////////////////////////////////////////// -void COGLView::IdleFunc() -{ - if (m_DrawSystem) - { - updateEmitter(&m_Emitter); - drawScene(FALSE); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Input Functions -/////////////////////////////////////////////////////////////////////////////// - -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - if (m_CurrentEmitter != NULL) - { - m_Grab_Pitch = m_CurrentEmitter->pitch; - m_Grab_Yaw = m_CurrentEmitter->yaw; - m_Grab_Rot_X = m_ViewRot.x; - m_Grab_Rot_Y = m_ViewRot.y; - m_Grab_Rot_Z = m_ViewRot.z; - m_Grab_Trans_X = m_CurrentEmitter->pos.x; - m_Grab_Trans_Y = m_CurrentEmitter->pos.y; - m_Grab_Trans_Z = m_CurrentEmitter->pos.z; - } - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - if ((nFlags & MK_SHIFT) > 0) - { - drawScene(FALSE); - } - - CWnd::OnLButtonUp(nFlags, point); -} - -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - if (m_CurrentEmitter != NULL) - { - m_Grab_Pitch = m_CurrentEmitter->pitch; - m_Grab_Yaw = m_CurrentEmitter->yaw; - m_Grab_Rot_X = m_ViewRot.x; - m_Grab_Rot_Y = m_ViewRot.y; - m_Grab_Rot_Z = m_ViewRot.z; - m_Grab_Trans_X = m_CurrentEmitter->pos.x; - m_Grab_Trans_Y = m_CurrentEmitter->pos.y; - m_Grab_Trans_Z = m_CurrentEmitter->pos.z; - } - CWnd::OnRButtonDown(nFlags, point); -} - -void COGLView::OnRButtonUp(UINT nFlags, CPoint point) -{ - if ((nFlags & MK_SHIFT) > 0) - { - drawScene(FALSE); - } - - - CWnd::OnRButtonUp(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case ' ': // MANUALLY STEP THE SYSTEM - m_DrawSystem = FALSE; - updateEmitter(&m_Emitter); - break; - case 13: - m_DrawSystem = !m_DrawSystem; - break; - case 'D': - m_DrawAxis = !m_DrawAxis; - break; - case 'E': - editEmitter(&m_Emitter); - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - break; - case 'F': - glPolygonMode(GL_FRONT,GL_FILL); - break; - case 'A': - m_AntiAlias = !m_AntiAlias; - break; - } - drawScene(FALSE); -} - -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (m_CurrentEmitter != NULL) - { - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_CurrentEmitter->pos.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - if ((point.y - m_mousepos.y) != 0) - { - m_CurrentEmitter->pos.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(FALSE); - } - } - // ELSE ROTATE THE ROOT - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_ViewRot.y = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_CurrentEmitter->pos.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -// Double click runs editEmitter -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - editEmitter(&m_Emitter); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: editEmitter -// Purpose: editEmitter settings -// Arguments: The Emitter to update -// Notes: Allows you to tweak the emitter settings -/////////////////////////////////////////////////////////////////////////////// -void COGLView::editEmitter(tEmitter *emitter) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CEditEmit dial; -/////////////////////////////////////////////////////////////////////////////// - dial.m_TotalParticles = emitter->totalParticles; - dial.m_emits = emitter->emitsPerFrame; - dial.m_emitVar = emitter->emitVar; - dial.m_forceX = emitter->force.x; - dial.m_forceY = emitter->force.y; - dial.m_forceZ = emitter->force.z; - dial.m_life = emitter->life; - dial.m_lifeVar = emitter->lifeVar; - dial.m_startColorB = emitter->startColor.b; - dial.m_startColorBVar = emitter->startColorVar.b; - dial.m_startColorG = emitter->startColor.g; - dial.m_startColorGVar = emitter->startColorVar.g; - dial.m_startColorR = emitter->startColor.r; - dial.m_startColorRVar = emitter->startColorVar.r; - dial.m_endColorB = emitter->endColor.b; - dial.m_endColorBVar = emitter->endColorVar.b; - dial.m_endColorG = emitter->endColor.g; - dial.m_endColorGVar = emitter->endColorVar.g; - dial.m_endColorR = emitter->endColor.r; - dial.m_endColorRVar = emitter->endColorVar.r; - dial.m_speed = emitter->speed; - dial.m_speedVar = emitter->speedVar; - dial.m_yaw = RADTODEG(emitter->yaw); // DISPLAY IN DEGREES SINCE IT MAKES SENSE - dial.m_yawVar = RADTODEG(emitter->yawVar); - dial.m_pitch = RADTODEG(emitter->pitch); - dial.m_pitchVar = RADTODEG(emitter->pitchVar); - dial.m_name = emitter->name; - if (dial.DoModal()) - { - emitter->totalParticles = dial.m_TotalParticles; - emitter->emitsPerFrame = dial.m_emits; - emitter->emitVar = dial.m_emitVar; - emitter->force.x = dial.m_forceX; - emitter->force.y = dial.m_forceY; - emitter->force.z = dial.m_forceZ; - emitter->life = dial.m_life; - emitter->lifeVar = dial.m_lifeVar; - emitter->startColor.b = dial.m_startColorB; - emitter->startColorVar.b = dial.m_startColorBVar; - emitter->startColor.g = dial.m_startColorG; - emitter->startColorVar.g = dial.m_startColorGVar; - emitter->startColor.r = dial.m_startColorR; - emitter->startColorVar.r = dial.m_startColorRVar; - emitter->endColor.b = dial.m_endColorB; - emitter->endColorVar.b = dial.m_endColorBVar; - emitter->endColor.g = dial.m_endColorG; - emitter->endColorVar.g = dial.m_endColorGVar; - emitter->endColor.r = dial.m_endColorR; - emitter->endColorVar.r = dial.m_endColorRVar; - emitter->speed = dial.m_speed; - emitter->speedVar = dial.m_speedVar; - emitter->yaw = DEGTORAD(dial.m_yaw); // CONVERT TO RADIANS - emitter->yawVar = DEGTORAD(dial.m_yawVar); - emitter->pitch = DEGTORAD(dial.m_pitch); - emitter->pitchVar = DEGTORAD(dial.m_pitchVar); - strcpy(emitter->name,dial.m_name); - } -} -/// editEmitter /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: resetEmitter -// Purpose: Reset emitter to initial settings -/////////////////////////////////////////////////////////////////////////////// -void COGLView::resetEmitter() -{ - setDefaultEmitter(&m_Emitter); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetEmitter -// Purpose: Get the Emitter Settings from a file -// Arguments: Filename to get it from -// Returns: Success -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::GetEmitter(CString filename) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tParticle *particle; // NULL TERMINATED LINKED LIST - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - particle = m_Emitter.particle; // SAVE THIS SINCE IT IS THE ACTIVE LIST - fp = fopen(filename,"rb"); - if (fp != NULL) - { - fread(&m_Emitter,sizeof(tEmitter),1,fp); - // LOAD THE VIEWING ANGLE ALSO - fread(&m_ViewRot.z,sizeof(float),1,fp); - fread(&m_ViewRot.y,sizeof(float),1,fp); - fread(&m_ViewRot.x,sizeof(float),1,fp); - fclose(fp); - m_Emitter.particle = particle; // RESTORE THE ACTIVE LIST - drawScene(FALSE); - return TRUE; - } - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SaveEmitter -// Purpose: Save the Emitter settings to a file -// Arguments: Filename to put it in -// Returns: Success -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::SaveEmitter(CString filename) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"wb"); - if (fp != NULL) - { - fwrite(&m_Emitter,sizeof(tEmitter),1,fp); - // SAVE OFF THE VIEWING ANGLE ALSO - fwrite(&m_ViewRot.z,sizeof(float),1,fp); - fwrite(&m_ViewRot.y,sizeof(float),1,fp); - fwrite(&m_ViewRot.x,sizeof(float),1,fp); - fclose(fp); - return TRUE; - } - return FALSE; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Particle System +// +// Created: +// JL 2/18/98 +// Revisions: +// Integrated into Particle System Demo 4/14/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Spray.h" +#include "OGLView.h" +#include "particle.h" +#include "EditEmit.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +// IF YOU WANT TO TRY A QUICKER TWO BONE WEIGHTING SYSTEM UNDEF THIS +#define DEFORM_GENERAL_SOLUTION // FULL MULTI-BONE DEFORMATION +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0f // SPEED OF ROTATION +#define ANGLE_SPEED 0.01f // SPEED OF ANGLE ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/// Message Maps ////////////////////////////////////////////////////////////// +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_LBUTTONUP() + ON_WM_RBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + initParticleSystem(); + initEmitter(&m_Emitter); + m_CurrentEmitter = &m_Emitter; + m_DrawAxis = TRUE; // DRAW ORIGIN AXIS + m_DrawSystem = TRUE; // ANIMATE THE PARTICLES + m_AntiAlias = TRUE; // ANTIALIAS THE PARTICLES + + m_ViewRot.x = 0.0; + m_ViewRot.y = 0.0; + m_ViewRot.z = 0.0; +} + +COGLView::~COGLView() +{ +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + UpdateStatus(); // DRAW INITIAL STATUS BAR + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +void COGLView::UpdateStatus() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + sprintf(message,"# %d",m_Emitter.particleCount); + + m_ptrStatusBar->SetPaneText(1,message); + +} + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); +// glScalef(1.0,1.0,1.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + drawScene(FALSE); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(35.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(40.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_LINE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + glPointSize(2.0); // JUST 1 PIXEL DOTS FOR NOW +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +GLvoid COGLView::drawScene(BOOL drawSelectRect) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Emitter.pos.x, m_Emitter.pos.y, m_Emitter.pos.z); + + glRotatef(m_ViewRot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_ViewRot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_ViewRot.x, 1.0f, 0.0f, 0.0f); + + // DRAW THE AXIS OGL OBJECT + if (m_DrawAxis) + glCallList(OGL_AXIS_DLIST); + + renderEmitter(&m_Emitter,m_AntiAlias); + + glPopMatrix(); + + glFinish(); + + SwapBuffers(m_hDC); + + // DRAW THE STATS AT THE BOTTOM OF THE SCREEN + UpdateStatus(); +} + + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(FALSE); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); + m_ScreenWidth = cx; + m_ScreenHeight = cy; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: IdleFunc +// Purpose: Process state changes if animating +/////////////////////////////////////////////////////////////////////////////// +void COGLView::IdleFunc() +{ + if (m_DrawSystem) + { + updateEmitter(&m_Emitter); + drawScene(FALSE); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Input Functions +/////////////////////////////////////////////////////////////////////////////// + +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + if (m_CurrentEmitter != NULL) + { + m_Grab_Pitch = m_CurrentEmitter->pitch; + m_Grab_Yaw = m_CurrentEmitter->yaw; + m_Grab_Rot_X = m_ViewRot.x; + m_Grab_Rot_Y = m_ViewRot.y; + m_Grab_Rot_Z = m_ViewRot.z; + m_Grab_Trans_X = m_CurrentEmitter->pos.x; + m_Grab_Trans_Y = m_CurrentEmitter->pos.y; + m_Grab_Trans_Z = m_CurrentEmitter->pos.z; + } + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + if ((nFlags & MK_SHIFT) > 0) + { + drawScene(FALSE); + } + + CWnd::OnLButtonUp(nFlags, point); +} + +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + if (m_CurrentEmitter != NULL) + { + m_Grab_Pitch = m_CurrentEmitter->pitch; + m_Grab_Yaw = m_CurrentEmitter->yaw; + m_Grab_Rot_X = m_ViewRot.x; + m_Grab_Rot_Y = m_ViewRot.y; + m_Grab_Rot_Z = m_ViewRot.z; + m_Grab_Trans_X = m_CurrentEmitter->pos.x; + m_Grab_Trans_Y = m_CurrentEmitter->pos.y; + m_Grab_Trans_Z = m_CurrentEmitter->pos.z; + } + CWnd::OnRButtonDown(nFlags, point); +} + +void COGLView::OnRButtonUp(UINT nFlags, CPoint point) +{ + if ((nFlags & MK_SHIFT) > 0) + { + drawScene(FALSE); + } + + + CWnd::OnRButtonUp(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case ' ': // MANUALLY STEP THE SYSTEM + m_DrawSystem = FALSE; + updateEmitter(&m_Emitter); + break; + case 13: + m_DrawSystem = !m_DrawSystem; + break; + case 'D': + m_DrawAxis = !m_DrawAxis; + break; + case 'E': + editEmitter(&m_Emitter); + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + break; + case 'F': + glPolygonMode(GL_FRONT,GL_FILL); + break; + case 'A': + m_AntiAlias = !m_AntiAlias; + break; + } + drawScene(FALSE); +} + +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (m_CurrentEmitter != NULL) + { + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_CurrentEmitter->pos.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + if ((point.y - m_mousepos.y) != 0) + { + m_CurrentEmitter->pos.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(FALSE); + } + } + // ELSE ROTATE THE ROOT + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_ViewRot.y = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_CurrentEmitter->pos.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +// Double click runs editEmitter +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + editEmitter(&m_Emitter); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: editEmitter +// Purpose: editEmitter settings +// Arguments: The Emitter to update +// Notes: Allows you to tweak the emitter settings +/////////////////////////////////////////////////////////////////////////////// +void COGLView::editEmitter(tEmitter *emitter) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CEditEmit dial; +/////////////////////////////////////////////////////////////////////////////// + dial.m_TotalParticles = emitter->totalParticles; + dial.m_emits = emitter->emitsPerFrame; + dial.m_emitVar = emitter->emitVar; + dial.m_forceX = emitter->force.x; + dial.m_forceY = emitter->force.y; + dial.m_forceZ = emitter->force.z; + dial.m_life = emitter->life; + dial.m_lifeVar = emitter->lifeVar; + dial.m_startColorB = emitter->startColor.b; + dial.m_startColorBVar = emitter->startColorVar.b; + dial.m_startColorG = emitter->startColor.g; + dial.m_startColorGVar = emitter->startColorVar.g; + dial.m_startColorR = emitter->startColor.r; + dial.m_startColorRVar = emitter->startColorVar.r; + dial.m_endColorB = emitter->endColor.b; + dial.m_endColorBVar = emitter->endColorVar.b; + dial.m_endColorG = emitter->endColor.g; + dial.m_endColorGVar = emitter->endColorVar.g; + dial.m_endColorR = emitter->endColor.r; + dial.m_endColorRVar = emitter->endColorVar.r; + dial.m_speed = emitter->speed; + dial.m_speedVar = emitter->speedVar; + dial.m_yaw = RADTODEG(emitter->yaw); // DISPLAY IN DEGREES SINCE IT MAKES SENSE + dial.m_yawVar = RADTODEG(emitter->yawVar); + dial.m_pitch = RADTODEG(emitter->pitch); + dial.m_pitchVar = RADTODEG(emitter->pitchVar); + dial.m_name = emitter->name; + if (dial.DoModal()) + { + emitter->totalParticles = dial.m_TotalParticles; + emitter->emitsPerFrame = dial.m_emits; + emitter->emitVar = dial.m_emitVar; + emitter->force.x = dial.m_forceX; + emitter->force.y = dial.m_forceY; + emitter->force.z = dial.m_forceZ; + emitter->life = dial.m_life; + emitter->lifeVar = dial.m_lifeVar; + emitter->startColor.b = dial.m_startColorB; + emitter->startColorVar.b = dial.m_startColorBVar; + emitter->startColor.g = dial.m_startColorG; + emitter->startColorVar.g = dial.m_startColorGVar; + emitter->startColor.r = dial.m_startColorR; + emitter->startColorVar.r = dial.m_startColorRVar; + emitter->endColor.b = dial.m_endColorB; + emitter->endColorVar.b = dial.m_endColorBVar; + emitter->endColor.g = dial.m_endColorG; + emitter->endColorVar.g = dial.m_endColorGVar; + emitter->endColor.r = dial.m_endColorR; + emitter->endColorVar.r = dial.m_endColorRVar; + emitter->speed = dial.m_speed; + emitter->speedVar = dial.m_speedVar; + emitter->yaw = DEGTORAD(dial.m_yaw); // CONVERT TO RADIANS + emitter->yawVar = DEGTORAD(dial.m_yawVar); + emitter->pitch = DEGTORAD(dial.m_pitch); + emitter->pitchVar = DEGTORAD(dial.m_pitchVar); + strcpy(emitter->name,dial.m_name); + } +} +/// editEmitter /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: resetEmitter +// Purpose: Reset emitter to initial settings +/////////////////////////////////////////////////////////////////////////////// +void COGLView::resetEmitter() +{ + setDefaultEmitter(&m_Emitter); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetEmitter +// Purpose: Get the Emitter Settings from a file +// Arguments: Filename to get it from +// Returns: Success +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::GetEmitter(CString filename) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tParticle *particle; // NULL TERMINATED LINKED LIST + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + particle = m_Emitter.particle; // SAVE THIS SINCE IT IS THE ACTIVE LIST + fp = fopen(filename,"rb"); + if (fp != NULL) + { + fread(&m_Emitter,sizeof(tEmitter),1,fp); + // LOAD THE VIEWING ANGLE ALSO + fread(&m_ViewRot.z,sizeof(float),1,fp); + fread(&m_ViewRot.y,sizeof(float),1,fp); + fread(&m_ViewRot.x,sizeof(float),1,fp); + fclose(fp); + m_Emitter.particle = particle; // RESTORE THE ACTIVE LIST + drawScene(FALSE); + return TRUE; + } + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SaveEmitter +// Purpose: Save the Emitter settings to a file +// Arguments: Filename to put it in +// Returns: Success +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::SaveEmitter(CString filename) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"wb"); + if (fp != NULL) + { + fwrite(&m_Emitter,sizeof(tEmitter),1,fp); + // SAVE OFF THE VIEWING ANGLE ALSO + fwrite(&m_ViewRot.z,sizeof(float),1,fp); + fwrite(&m_ViewRot.y,sizeof(float),1,fp); + fwrite(&m_ViewRot.x,sizeof(float),1,fp); + fclose(fp); + return TRUE; + } + return FALSE; +} + diff --git a/Particle Systems/Code/OGL/Spray/OGLView.h b/Particle Systems/Code/OGL/Spray/OGLView.h index 628d19a..befe7a5 100644 --- a/Particle Systems/Code/OGL/Spray/OGLView.h +++ b/Particle Systems/Code/OGL/Spray/OGLView.h @@ -1,107 +1,107 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Particle System -// -// Created: -// JL 11/1/97 -// Revisions: -// Integrated into Particle System Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "particle.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Yaw,m_Grab_Pitch; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - int m_ScreenWidth, m_ScreenHeight; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(BOOL drawSelectRect); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void UpdateStatus(); - void IdleFunc(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - void resetEmitter(); - void editEmitter(tEmitter *emitter); - BOOL GetEmitter(CString filename); - BOOL SaveEmitter(CString filename); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - BOOL m_AntiAlias; - BOOL m_DrawAxis; - tEmitter m_Emitter; - -protected: - BOOL m_DrawSystem; - tVector m_ViewRot; // USED TO ALLOW VIEW TO ROTATE - tEmitter *m_CurrentEmitter; - // Generated message map functions - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnRButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Particle System +// +// Created: +// JL 11/1/97 +// Revisions: +// Integrated into Particle System Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "particle.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Yaw,m_Grab_Pitch; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + int m_ScreenWidth, m_ScreenHeight; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(BOOL drawSelectRect); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void UpdateStatus(); + void IdleFunc(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + void resetEmitter(); + void editEmitter(tEmitter *emitter); + BOOL GetEmitter(CString filename); + BOOL SaveEmitter(CString filename); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + BOOL m_AntiAlias; + BOOL m_DrawAxis; + tEmitter m_Emitter; + +protected: + BOOL m_DrawSystem; + tVector m_ViewRot; // USED TO ALLOW VIEW TO ROTATE + tEmitter *m_CurrentEmitter; + // Generated message map functions + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Particle Systems/Code/OGL/Spray/Particle.cpp b/Particle Systems/Code/OGL/Spray/Particle.cpp index 34f11e4..90d51fa 100644 --- a/Particle Systems/Code/OGL/Spray/Particle.cpp +++ b/Particle Systems/Code/OGL/Spray/Particle.cpp @@ -1,382 +1,382 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Particle.cpp : Particle System support file -// -// Purpose: Structure Support routines for Particle System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Particle Demo 4/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "Spray.h" -#include "Particle.h" -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -// -// Particle.cpp : Particle System structure implementation -// -// Purpose: Implementation code of Particle System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 4/1/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include - -/// Global Definitions //////////////////////////////////////////////////////// -const int HALF_RAND = (RAND_MAX / 2); -/////////////////////////////////////////////////////////////////////////////// - -/// Global Member Variables /////////////////////////////////////////////////// -// REALLY ARE PRIVATE MEMBER VARIABLES OF PARTICLE CLASS -tParticle *m_ParticlePool; // POOL TO PULL PARTICLES FROM -/////////////////////////////////////////////////////////////////////////////// - -float RandomNum() -{ - int rn; - rn = rand(); - return ((float)(rn - HALF_RAND) / (float)HALF_RAND); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RotationToDirection -// Purpose: Convert a Yaw and Pitch to a direction vector -/////////////////////////////////////////////////////////////////////////////// -void RotationToDirection(float pitch,float yaw,tVector *direction) -{ - direction->x = (float)(-sin(yaw) * cos(pitch)); - direction->y = (float)sin(pitch); - direction->z = (float)(cos(pitch) * cos(yaw)); -} -/// initParticleSystem //////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: initParticleSystem -// Purpose: Initialize the particle system -// Notes: This is really the CREATOR for the particle class -// Since I am doing it C, I need to call it -/////////////////////////////////////////////////////////////////////////////// -BOOL initParticleSystem() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - srand( (unsigned)time( NULL ) ); - - // SO I DON'T NEED TO DYNAMICALLY ALLOC THE PARTICLES IN THE RUNTIME - // I WANT TO PULL ALREADY CREATED PARTICLES FROM A GLOBAL POOL. - m_ParticlePool = (tParticle *)malloc(MAX_PARTICLES * sizeof(tParticle)); - // THIS IS A LINKED LIST OF PARTICLES, SO I NEED TO ESTABLISH LINKS - for (loop = 0; loop < MAX_PARTICLES - 1; loop++) - { - m_ParticlePool[loop].next = &m_ParticlePool[loop + 1]; - } - // SET THE LAST PARTICLE TO POINT TO NULL - m_ParticlePool[MAX_PARTICLES - 1].next = NULL; - - return TRUE; -} -/// initParticleSystem //////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: setDefaultEmitter -// Purpose: Set up some default settings -// Arguments: The emitter to setup -/////////////////////////////////////////////////////////////////////////////// -BOOL setDefaultEmitter(tEmitter *emitter) -{ - emitter->id = 0; // UNUSED - strcpy(emitter->name, "Emitter"); - emitter->flags = NULL; - emitter->prev = NULL; // NOT USED - emitter->next = NULL; // NOT USED - emitter->pos.x = 0.0f; // XYZ POSITION - emitter->pos.y = -0.5f; // XYZ POSITION - emitter->pos.z = -5.0f; // XYZ POSITION - - emitter->yaw = DEGTORAD(0.0f); - emitter->yawVar = DEGTORAD(360.0f); - emitter->pitch = DEGTORAD(90.0f); - emitter->pitchVar = DEGTORAD(40.0f); - emitter->speed = 0.05f; - emitter->speedVar = 0.01f; - - emitter->totalParticles = 4000; - emitter->particleCount = 0; - emitter->emitsPerFrame = 100; - emitter->emitVar = 15; - emitter->life = 60; - emitter->lifeVar = 15; - emitter->startColor.r = 0.6f; - emitter->startColor.g = 0.6f; - emitter->startColor.b = 0.8f; - emitter->startColorVar.r = 0.1f; - emitter->startColorVar.g = 0.1f; - emitter->startColorVar.b = 0.1f; - emitter->endColor.r = 0.0f; - emitter->endColor.g = 0.0f; - emitter->endColor.b = 0.8f; - emitter->endColorVar.r = 0.1f; - emitter->endColorVar.g = 0.1f; - emitter->endColorVar.b = 0.2f; - - emitter->force.x = 0.000f; - emitter->force.y = -0.001f; - emitter->force.z = 0.0f; - return TRUE; -} -/// setDefaultEmitter ///////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: initEmitter -// Purpose: Initialize an emitter in the system -// Arguments: The emitter to initialize -/////////////////////////////////////////////////////////////////////////////// -BOOL initEmitter(tEmitter *emitter) -{ - setDefaultEmitter(emitter); - emitter->particle = NULL; // NULL TERMINATED LINKED LIST - return TRUE; -} -/// initEmitter /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: addParticle -// Purpose: add a particle to an emitter -// Arguments: The emitter to add to -/////////////////////////////////////////////////////////////////////////////// -BOOL addParticle(tEmitter *emitter) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tParticle *particle; - tColor start,end; - float yaw,pitch,speed; -/////////////////////////////////////////////////////////////////////////////// - // IF THERE IS AN EMITTER AND A PARTICLE IN THE POOL - // AND I HAVEN'T EMITTED MY MAX - if (emitter != NULL && m_ParticlePool != NULL && - emitter->particleCount < emitter->totalParticles) - { - particle = m_ParticlePool; // THE CURRENT PARTICLE - m_ParticlePool = m_ParticlePool->next; // FIX THE POOL POINTERS - - if (emitter->particle != NULL) - emitter->particle->prev = particle; // SET BACK LINK - particle->next = emitter->particle; // SET ITS NEXT POINTER - particle->prev = NULL; // IT HAS NO BACK POINTER - emitter->particle = particle; // SET IT IN THE EMITTER - - particle->pos.x = 0.0f; // RELATIVE TO EMITTER BASE - particle->pos.y = 0.0f; - particle->pos.z = 0.0f; - - particle->prevPos.x = 0.0f; // USED FOR ANTI ALIAS - particle->prevPos.y = 0.0f; - particle->prevPos.z = 0.0f; - - // CALCULATE THE STARTING DIRECTION VECTOR - yaw = emitter->yaw + (emitter->yawVar * RandomNum()); - pitch = emitter->pitch + (emitter->pitchVar * RandomNum()); - - // CONVERT THE ROTATIONS TO A VECTOR - RotationToDirection(pitch,yaw,&particle->dir); - - // MULTIPLY IN THE SPEED FACTOR - speed = emitter->speed + (emitter->speedVar * RandomNum()); - particle->dir.x *= speed; - particle->dir.y *= speed; - particle->dir.z *= speed; - - // CALCULATE THE COLORS - start.r = emitter->startColor.r + (emitter->startColorVar.r * RandomNum()); - start.g = emitter->startColor.g + (emitter->startColorVar.g * RandomNum()); - start.b = emitter->startColor.b + (emitter->startColorVar.b * RandomNum()); - end.r = emitter->endColor.r + (emitter->endColorVar.r * RandomNum()); - end.g = emitter->endColor.g + (emitter->endColorVar.g * RandomNum()); - end.b = emitter->endColor.b + (emitter->endColorVar.b * RandomNum()); - - particle->color.r = start.r; - particle->color.g = start.g; - particle->color.b = start.b; - - // CALCULATE THE LIFE SPAN - particle->life = emitter->life + (int)((float)emitter->lifeVar * RandomNum()); - - // CREATE THE COLOR DELTA - particle->deltaColor.r = (end.r - start.r) / particle->life; - particle->deltaColor.g = (end.g - start.g) / particle->life; - particle->deltaColor.b = (end.b - start.b) / particle->life; - - emitter->particleCount++; // A NEW PARTICLE IS BORN - return TRUE; - } - return FALSE; -} -/// addParticle /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: updateParticle -// Purpose: updateParticle settings -// Arguments: The particle to update and the emitter it came from -/////////////////////////////////////////////////////////////////////////////// -BOOL updateParticle(tParticle *particle,tEmitter *emitter) -{ - // IF THIS IS AN VALID PARTICLE - if (particle != NULL && particle->life > 0) - { - // SAVE ITS OLD POS FOR ANTI ALIASING - particle->prevPos.x = particle->pos.x; - particle->prevPos.y = particle->pos.y; - particle->prevPos.z = particle->pos.z; - - // CALCULATE THE NEW - particle->pos.x += particle->dir.x; - particle->pos.y += particle->dir.y; - particle->pos.z += particle->dir.z; - - // APPLY GLOBAL FORCE TO DIRECTION - particle->dir.x += emitter->force.x; - particle->dir.y += emitter->force.y; - particle->dir.z += emitter->force.z; - - // SAVE THE OLD COLOR - particle->prevColor.r = particle->color.r; - particle->prevColor.g = particle->color.g; - particle->prevColor.b = particle->color.b; - - // GET THE NEW COLOR - particle->color.r += particle->deltaColor.r; - particle->color.g += particle->deltaColor.g; - particle->color.b += particle->deltaColor.b; - - particle->life--; // IT IS A CYCLE OLDER - return TRUE; - } - else if (particle != NULL && particle->life == 0) - { - // FREE THIS SUCKER UP BACK TO THE MAIN POOL - if (particle->prev != NULL) - particle->prev->next = particle->next; - else - emitter->particle = particle->next; - // FIX UP THE NEXT'S PREV POINTER IF THERE IS A NEXT - if (particle->next != NULL) - particle->next->prev = particle->prev; - particle->next = m_ParticlePool; - m_ParticlePool = particle; // NEW POOL POINTER - emitter->particleCount--; // ADD ONE TO POOL - } - return FALSE; -} -/// updateParticle /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: updateEmitter -// Purpose: updateEmitter setting -// Arguments: The Emitter to update -// Notes: This is called once per frame to update the emitter -/////////////////////////////////////////////////////////////////////////////// -BOOL updateEmitter(tEmitter *emitter) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,emits; - tParticle *particle, *next; -/////////////////////////////////////////////////////////////////////////////// - // IF THERE IS AN EMITTER - if (emitter != NULL) - { - if (emitter->particle != NULL) - { - // GO THROUGH THE PARTICLES AND UPDATE THEM - particle = emitter->particle; - while (particle) - { - next = particle->next; // SAVE THIS BECAUSE IT MAY CHANGE UNDER ME - updateParticle(particle,emitter); - particle = next; - } - } - - // EMIT PARTICLES FOR THIS FRAME - emits = emitter->emitsPerFrame + (int)((float)emitter->emitVar * RandomNum()); - for (loop = 0; loop < emits; loop++) - addParticle(emitter); - - return TRUE; - } - return FALSE; -} -/// updateEmitter /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: renderEmitter -// Purpose: render particle system -// Arguments: The Emitter to render -// Notes: This is called once per frame to render the emitter -/////////////////////////////////////////////////////////////////////////////// -BOOL renderEmitter(tEmitter *emitter, BOOL antiAlias) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tParticle *particle; -/////////////////////////////////////////////////////////////////////////////// - // IF THERE IS AN EMITTER - if (emitter != NULL) - { - if (emitter->particle != NULL) - { - particle = emitter->particle; - // DON'T ANTIALIAS FIRST FRAME - if (antiAlias) - glBegin(GL_LINES); - else - glBegin(GL_POINTS); - while (particle) - { - if (antiAlias) - { - glColor3f(particle->prevColor.r, particle->prevColor.g, particle->prevColor.b); - glVertex3f(particle->prevPos.x,particle->prevPos.y,particle->prevPos.z); - } - glColor3f(particle->color.r, particle->color.g, particle->color.b); - glVertex3f(particle->pos.x,particle->pos.y,particle->pos.z); - particle = particle->next; - } - glEnd(); - } - - return TRUE; - } - return FALSE; -} -/// renderEmitter /////////////////////////////////////////////////////////////// - +/////////////////////////////////////////////////////////////////////////////// +// +// Particle.cpp : Particle System support file +// +// Purpose: Structure Support routines for Particle System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Particle Demo 4/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "Spray.h" +#include "Particle.h" +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// +// Particle.cpp : Particle System structure implementation +// +// Purpose: Implementation code of Particle System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 4/1/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include + +/// Global Definitions //////////////////////////////////////////////////////// +const int HALF_RAND = (RAND_MAX / 2); +/////////////////////////////////////////////////////////////////////////////// + +/// Global Member Variables /////////////////////////////////////////////////// +// REALLY ARE PRIVATE MEMBER VARIABLES OF PARTICLE CLASS +tParticle *m_ParticlePool; // POOL TO PULL PARTICLES FROM +/////////////////////////////////////////////////////////////////////////////// + +float RandomNum() +{ + int rn; + rn = rand(); + return ((float)(rn - HALF_RAND) / (float)HALF_RAND); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RotationToDirection +// Purpose: Convert a Yaw and Pitch to a direction vector +/////////////////////////////////////////////////////////////////////////////// +void RotationToDirection(float pitch,float yaw,tVector *direction) +{ + direction->x = (float)(-sin(yaw) * cos(pitch)); + direction->y = (float)sin(pitch); + direction->z = (float)(cos(pitch) * cos(yaw)); +} +/// initParticleSystem //////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: initParticleSystem +// Purpose: Initialize the particle system +// Notes: This is really the CREATOR for the particle class +// Since I am doing it C, I need to call it +/////////////////////////////////////////////////////////////////////////////// +BOOL initParticleSystem() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + srand( (unsigned)time( NULL ) ); + + // SO I DON'T NEED TO DYNAMICALLY ALLOC THE PARTICLES IN THE RUNTIME + // I WANT TO PULL ALREADY CREATED PARTICLES FROM A GLOBAL POOL. + m_ParticlePool = (tParticle *)malloc(MAX_PARTICLES * sizeof(tParticle)); + // THIS IS A LINKED LIST OF PARTICLES, SO I NEED TO ESTABLISH LINKS + for (loop = 0; loop < MAX_PARTICLES - 1; loop++) + { + m_ParticlePool[loop].next = &m_ParticlePool[loop + 1]; + } + // SET THE LAST PARTICLE TO POINT TO NULL + m_ParticlePool[MAX_PARTICLES - 1].next = NULL; + + return TRUE; +} +/// initParticleSystem //////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: setDefaultEmitter +// Purpose: Set up some default settings +// Arguments: The emitter to setup +/////////////////////////////////////////////////////////////////////////////// +BOOL setDefaultEmitter(tEmitter *emitter) +{ + emitter->id = 0; // UNUSED + strcpy(emitter->name, "Emitter"); + emitter->flags = NULL; + emitter->prev = NULL; // NOT USED + emitter->next = NULL; // NOT USED + emitter->pos.x = 0.0f; // XYZ POSITION + emitter->pos.y = -0.5f; // XYZ POSITION + emitter->pos.z = -5.0f; // XYZ POSITION + + emitter->yaw = DEGTORAD(0.0f); + emitter->yawVar = DEGTORAD(360.0f); + emitter->pitch = DEGTORAD(90.0f); + emitter->pitchVar = DEGTORAD(40.0f); + emitter->speed = 0.05f; + emitter->speedVar = 0.01f; + + emitter->totalParticles = 4000; + emitter->particleCount = 0; + emitter->emitsPerFrame = 100; + emitter->emitVar = 15; + emitter->life = 60; + emitter->lifeVar = 15; + emitter->startColor.r = 0.6f; + emitter->startColor.g = 0.6f; + emitter->startColor.b = 0.8f; + emitter->startColorVar.r = 0.1f; + emitter->startColorVar.g = 0.1f; + emitter->startColorVar.b = 0.1f; + emitter->endColor.r = 0.0f; + emitter->endColor.g = 0.0f; + emitter->endColor.b = 0.8f; + emitter->endColorVar.r = 0.1f; + emitter->endColorVar.g = 0.1f; + emitter->endColorVar.b = 0.2f; + + emitter->force.x = 0.000f; + emitter->force.y = -0.001f; + emitter->force.z = 0.0f; + return TRUE; +} +/// setDefaultEmitter ///////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: initEmitter +// Purpose: Initialize an emitter in the system +// Arguments: The emitter to initialize +/////////////////////////////////////////////////////////////////////////////// +BOOL initEmitter(tEmitter *emitter) +{ + setDefaultEmitter(emitter); + emitter->particle = NULL; // NULL TERMINATED LINKED LIST + return TRUE; +} +/// initEmitter /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: addParticle +// Purpose: add a particle to an emitter +// Arguments: The emitter to add to +/////////////////////////////////////////////////////////////////////////////// +BOOL addParticle(tEmitter *emitter) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tParticle *particle; + tColor start,end; + float yaw,pitch,speed; +/////////////////////////////////////////////////////////////////////////////// + // IF THERE IS AN EMITTER AND A PARTICLE IN THE POOL + // AND I HAVEN'T EMITTED MY MAX + if (emitter != NULL && m_ParticlePool != NULL && + emitter->particleCount < emitter->totalParticles) + { + particle = m_ParticlePool; // THE CURRENT PARTICLE + m_ParticlePool = m_ParticlePool->next; // FIX THE POOL POINTERS + + if (emitter->particle != NULL) + emitter->particle->prev = particle; // SET BACK LINK + particle->next = emitter->particle; // SET ITS NEXT POINTER + particle->prev = NULL; // IT HAS NO BACK POINTER + emitter->particle = particle; // SET IT IN THE EMITTER + + particle->pos.x = 0.0f; // RELATIVE TO EMITTER BASE + particle->pos.y = 0.0f; + particle->pos.z = 0.0f; + + particle->prevPos.x = 0.0f; // USED FOR ANTI ALIAS + particle->prevPos.y = 0.0f; + particle->prevPos.z = 0.0f; + + // CALCULATE THE STARTING DIRECTION VECTOR + yaw = emitter->yaw + (emitter->yawVar * RandomNum()); + pitch = emitter->pitch + (emitter->pitchVar * RandomNum()); + + // CONVERT THE ROTATIONS TO A VECTOR + RotationToDirection(pitch,yaw,&particle->dir); + + // MULTIPLY IN THE SPEED FACTOR + speed = emitter->speed + (emitter->speedVar * RandomNum()); + particle->dir.x *= speed; + particle->dir.y *= speed; + particle->dir.z *= speed; + + // CALCULATE THE COLORS + start.r = emitter->startColor.r + (emitter->startColorVar.r * RandomNum()); + start.g = emitter->startColor.g + (emitter->startColorVar.g * RandomNum()); + start.b = emitter->startColor.b + (emitter->startColorVar.b * RandomNum()); + end.r = emitter->endColor.r + (emitter->endColorVar.r * RandomNum()); + end.g = emitter->endColor.g + (emitter->endColorVar.g * RandomNum()); + end.b = emitter->endColor.b + (emitter->endColorVar.b * RandomNum()); + + particle->color.r = start.r; + particle->color.g = start.g; + particle->color.b = start.b; + + // CALCULATE THE LIFE SPAN + particle->life = emitter->life + (int)((float)emitter->lifeVar * RandomNum()); + + // CREATE THE COLOR DELTA + particle->deltaColor.r = (end.r - start.r) / particle->life; + particle->deltaColor.g = (end.g - start.g) / particle->life; + particle->deltaColor.b = (end.b - start.b) / particle->life; + + emitter->particleCount++; // A NEW PARTICLE IS BORN + return TRUE; + } + return FALSE; +} +/// addParticle /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: updateParticle +// Purpose: updateParticle settings +// Arguments: The particle to update and the emitter it came from +/////////////////////////////////////////////////////////////////////////////// +BOOL updateParticle(tParticle *particle,tEmitter *emitter) +{ + // IF THIS IS AN VALID PARTICLE + if (particle != NULL && particle->life > 0) + { + // SAVE ITS OLD POS FOR ANTI ALIASING + particle->prevPos.x = particle->pos.x; + particle->prevPos.y = particle->pos.y; + particle->prevPos.z = particle->pos.z; + + // CALCULATE THE NEW + particle->pos.x += particle->dir.x; + particle->pos.y += particle->dir.y; + particle->pos.z += particle->dir.z; + + // APPLY GLOBAL FORCE TO DIRECTION + particle->dir.x += emitter->force.x; + particle->dir.y += emitter->force.y; + particle->dir.z += emitter->force.z; + + // SAVE THE OLD COLOR + particle->prevColor.r = particle->color.r; + particle->prevColor.g = particle->color.g; + particle->prevColor.b = particle->color.b; + + // GET THE NEW COLOR + particle->color.r += particle->deltaColor.r; + particle->color.g += particle->deltaColor.g; + particle->color.b += particle->deltaColor.b; + + particle->life--; // IT IS A CYCLE OLDER + return TRUE; + } + else if (particle != NULL && particle->life == 0) + { + // FREE THIS SUCKER UP BACK TO THE MAIN POOL + if (particle->prev != NULL) + particle->prev->next = particle->next; + else + emitter->particle = particle->next; + // FIX UP THE NEXT'S PREV POINTER IF THERE IS A NEXT + if (particle->next != NULL) + particle->next->prev = particle->prev; + particle->next = m_ParticlePool; + m_ParticlePool = particle; // NEW POOL POINTER + emitter->particleCount--; // ADD ONE TO POOL + } + return FALSE; +} +/// updateParticle /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: updateEmitter +// Purpose: updateEmitter setting +// Arguments: The Emitter to update +// Notes: This is called once per frame to update the emitter +/////////////////////////////////////////////////////////////////////////////// +BOOL updateEmitter(tEmitter *emitter) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,emits; + tParticle *particle, *next; +/////////////////////////////////////////////////////////////////////////////// + // IF THERE IS AN EMITTER + if (emitter != NULL) + { + if (emitter->particle != NULL) + { + // GO THROUGH THE PARTICLES AND UPDATE THEM + particle = emitter->particle; + while (particle) + { + next = particle->next; // SAVE THIS BECAUSE IT MAY CHANGE UNDER ME + updateParticle(particle,emitter); + particle = next; + } + } + + // EMIT PARTICLES FOR THIS FRAME + emits = emitter->emitsPerFrame + (int)((float)emitter->emitVar * RandomNum()); + for (loop = 0; loop < emits; loop++) + addParticle(emitter); + + return TRUE; + } + return FALSE; +} +/// updateEmitter /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: renderEmitter +// Purpose: render particle system +// Arguments: The Emitter to render +// Notes: This is called once per frame to render the emitter +/////////////////////////////////////////////////////////////////////////////// +BOOL renderEmitter(tEmitter *emitter, BOOL antiAlias) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tParticle *particle; +/////////////////////////////////////////////////////////////////////////////// + // IF THERE IS AN EMITTER + if (emitter != NULL) + { + if (emitter->particle != NULL) + { + particle = emitter->particle; + // DON'T ANTIALIAS FIRST FRAME + if (antiAlias) + glBegin(GL_LINES); + else + glBegin(GL_POINTS); + while (particle) + { + if (antiAlias) + { + glColor3f(particle->prevColor.r, particle->prevColor.g, particle->prevColor.b); + glVertex3f(particle->prevPos.x,particle->prevPos.y,particle->prevPos.z); + } + glColor3f(particle->color.r, particle->color.g, particle->color.b); + glVertex3f(particle->pos.x,particle->pos.y,particle->pos.z); + particle = particle->next; + } + glEnd(); + } + + return TRUE; + } + return FALSE; +} +/// renderEmitter /////////////////////////////////////////////////////////////// + diff --git a/Particle Systems/Code/OGL/Spray/Particle.h b/Particle Systems/Code/OGL/Spray/Particle.h index 5d7ff87..fb23eaf 100644 --- a/Particle Systems/Code/OGL/Spray/Particle.h +++ b/Particle Systems/Code/OGL/Spray/Particle.h @@ -1,87 +1,87 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Particle.h : Particle System structure definition file -// -// Purpose: Structure Definition of Particle System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 4/1/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(PARTICLE_H__INCLUDED_) -#define PARTICLE_H__INCLUDED_ - -/// Particle Definitions ////////////////////////////////////////////////////// -#define MAX_PARTICLES 4000 // MAXIMUM NUMBER OF PARTICLES -/////////////////////////////////////////////////////////////////////////////// - -#include "MathStuff.h" // GET THE TYPE FOR MATH STRUCTURES - -/// Structure Definitions /////////////////////////////////////////////////////// - -// TODO: Could add Alpha component here to allow for blending -struct tColor -{ - float r,g,b; -}; - -struct tParticle -{ - tParticle *prev,*next; // LINK - tVector pos; // CURRENT POSITION - tVector prevPos; // PREVIOUS POSITION - tVector dir; // CURRENT DIRECTION WITH SPEED - int life; // HOW LONG IT WILL LAST - tColor color; // CURRENT COLOR OF PARTICLE - tColor prevColor; // LAST COLOR OF PARTICLE - tColor deltaColor; // CHANGE OF COLOR -}; - -struct tEmitter -{ - long id; // EMITTER ID - char name[80]; // EMITTER NAME - long flags; // EMITTER FLAGS - // LINK INFO - tEmitter *prev; // POINTER TO PARENT BONE - tEmitter *next; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector pos; // XYZ POSITION - float yaw, yawVar; // YAW AND VARIATION - float pitch, pitchVar; // PITCH AND VARIATION - float speed,speedVar; - // Particle - tParticle *particle; // NULL TERMINATED LINKED LIST - int totalParticles; // TOTAL EMITTED AT ANY TIME - int particleCount; // TOTAL EMITTED RIGHT NOW - int emitsPerFrame, emitVar; // EMITS PER FRAME AND VARIATION - int life, lifeVar; // LIFE COUNT AND VARIATION - tColor startColor, startColorVar; // CURRENT COLOR OF PARTICLE - tColor endColor, endColorVar; // CURRENT COLOR OF PARTICLE - // Physics - tVector force; -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// -BOOL initParticleSystem(); -BOOL setDefaultEmitter(tEmitter *emitter); -BOOL initEmitter(tEmitter *emitter); -BOOL updateEmitter(tEmitter *emitter); // DRAW THE SYSTEM FOR A FRAME -BOOL renderEmitter(tEmitter *emitter, BOOL antiAlias); -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(PARTICLE_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Particle.h : Particle System structure definition file +// +// Purpose: Structure Definition of Particle System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 4/1/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(PARTICLE_H__INCLUDED_) +#define PARTICLE_H__INCLUDED_ + +/// Particle Definitions ////////////////////////////////////////////////////// +#define MAX_PARTICLES 4000 // MAXIMUM NUMBER OF PARTICLES +/////////////////////////////////////////////////////////////////////////////// + +#include "MathStuff.h" // GET THE TYPE FOR MATH STRUCTURES + +/// Structure Definitions /////////////////////////////////////////////////////// + +// TODO: Could add Alpha component here to allow for blending +struct tColor +{ + float r,g,b; +}; + +struct tParticle +{ + tParticle *prev,*next; // LINK + tVector pos; // CURRENT POSITION + tVector prevPos; // PREVIOUS POSITION + tVector dir; // CURRENT DIRECTION WITH SPEED + int life; // HOW LONG IT WILL LAST + tColor color; // CURRENT COLOR OF PARTICLE + tColor prevColor; // LAST COLOR OF PARTICLE + tColor deltaColor; // CHANGE OF COLOR +}; + +struct tEmitter +{ + long id; // EMITTER ID + char name[80]; // EMITTER NAME + long flags; // EMITTER FLAGS + // LINK INFO + tEmitter *prev; // POINTER TO PARENT BONE + tEmitter *next; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector pos; // XYZ POSITION + float yaw, yawVar; // YAW AND VARIATION + float pitch, pitchVar; // PITCH AND VARIATION + float speed,speedVar; + // Particle + tParticle *particle; // NULL TERMINATED LINKED LIST + int totalParticles; // TOTAL EMITTED AT ANY TIME + int particleCount; // TOTAL EMITTED RIGHT NOW + int emitsPerFrame, emitVar; // EMITS PER FRAME AND VARIATION + int life, lifeVar; // LIFE COUNT AND VARIATION + tColor startColor, startColorVar; // CURRENT COLOR OF PARTICLE + tColor endColor, endColorVar; // CURRENT COLOR OF PARTICLE + // Physics + tVector force; +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// +BOOL initParticleSystem(); +BOOL setDefaultEmitter(tEmitter *emitter); +BOOL initEmitter(tEmitter *emitter); +BOOL updateEmitter(tEmitter *emitter); // DRAW THE SYSTEM FOR A FRAME +BOOL renderEmitter(tEmitter *emitter, BOOL antiAlias); +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(PARTICLE_H__INCLUDED_) diff --git a/Particle Systems/Code/OGL/Spray/ReadMe.txt b/Particle Systems/Code/OGL/Spray/ReadMe.txt index b468be0..db5e34d 100644 --- a/Particle Systems/Code/OGL/Spray/ReadMe.txt +++ b/Particle Systems/Code/OGL/Spray/ReadMe.txt @@ -1,12 +1,12 @@ -Things for you to do to extend the model: - -Add alpha component to all the color settings to allow -for blending of particles. - -Allow size variation of particles using glPointSize() - -Use SGI_POINT extentions if available for perspective sizing. - -Render each particle as a billboarded textured polygon. - - +Things for you to do to extend the model: + +Add alpha component to all the color settings to allow +for blending of particles. + +Allow size variation of particles using glPointSize() + +Use SGI_POINT extentions if available for perspective sizing. + +Render each particle as a billboarded textured polygon. + + diff --git a/Particle Systems/Code/OGL/Spray/Spray.cpp b/Particle Systems/Code/OGL/Spray/Spray.cpp index c6a6ae0..e6f5922 100644 --- a/Particle Systems/Code/OGL/Spray/Spray.cpp +++ b/Particle Systems/Code/OGL/Spray/Spray.cpp @@ -1,159 +1,159 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Spray.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Spray.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSprayApp - -BEGIN_MESSAGE_MAP(CSprayApp, CWinApp) - //{{AFX_MSG_MAP(CSprayApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands - ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) - ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSprayApp construction - -CSprayApp::CSprayApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSprayApp object - -CSprayApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSprayApp initialization - -BOOL CSprayApp::InitInstance() -{ - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSprayApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSprayApp commands - -BOOL CSprayApp::OnIdle(LONG lCount) -{ - // Force the main window to redraw itself - if (IsWindow(m_pMainWnd->GetSafeHwnd())) - ((CMainFrame *)m_pMainWnd)->IdleFunc(); - - // Want more OnIdle calls - return TRUE; -} +/////////////////////////////////////////////////////////////////////////////// +// +// Spray.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Spray.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSprayApp + +BEGIN_MESSAGE_MAP(CSprayApp, CWinApp) + //{{AFX_MSG_MAP(CSprayApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSprayApp construction + +CSprayApp::CSprayApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSprayApp object + +CSprayApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSprayApp initialization + +BOOL CSprayApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSprayApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSprayApp commands + +BOOL CSprayApp::OnIdle(LONG lCount) +{ + // Force the main window to redraw itself + if (IsWindow(m_pMainWnd->GetSafeHwnd())) + ((CMainFrame *)m_pMainWnd)->IdleFunc(); + + // Want more OnIdle calls + return TRUE; +} diff --git a/Particle Systems/Code/OGL/Spray/Spray.h b/Particle Systems/Code/OGL/Spray/Spray.h index 4ffc1f4..f661907 100644 --- a/Particle Systems/Code/OGL/Spray/Spray.h +++ b/Particle Systems/Code/OGL/Spray/Spray.h @@ -1,66 +1,66 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Spray.h : main header file for the SkinApp Demo -// -// Purpose: header of Main Application of Quaternion Animation System -// -// Created: -// JL 2/18/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SPRAY_H__86F99065_D3EC_11D1_83A2_004005308EB5__INCLUDED_) -#define AFX_SPRAY_H__86F99065_D3EC_11D1_83A2_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CSprayApp: -// See Spray.cpp for the implementation of this class -// - -class CSprayApp : public CWinApp -{ -public: - CSprayApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSprayApp) - public: - virtual BOOL InitInstance(); - virtual BOOL OnIdle(LONG lCount); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSprayApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SPRAY_H__86F99065_D3EC_11D1_83A2_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Spray.h : main header file for the SkinApp Demo +// +// Purpose: header of Main Application of Quaternion Animation System +// +// Created: +// JL 2/18/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SPRAY_H__86F99065_D3EC_11D1_83A2_004005308EB5__INCLUDED_) +#define AFX_SPRAY_H__86F99065_D3EC_11D1_83A2_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CSprayApp: +// See Spray.cpp for the implementation of this class +// + +class CSprayApp : public CWinApp +{ +public: + CSprayApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSprayApp) + public: + virtual BOOL InitInstance(); + virtual BOOL OnIdle(LONG lCount); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSprayApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SPRAY_H__86F99065_D3EC_11D1_83A2_004005308EB5__INCLUDED_) diff --git a/Particle Systems/Code/OGL/Spray/StdAfx.cpp b/Particle Systems/Code/OGL/Spray/StdAfx.cpp index 338a79a..e6e1102 100644 --- a/Particle Systems/Code/OGL/Spray/StdAfx.cpp +++ b/Particle Systems/Code/OGL/Spray/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Spray.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Spray.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Particle Systems/Code/OGL/Spray/StdAfx.h b/Particle Systems/Code/OGL/Spray/StdAfx.h index c631ada..26520eb 100644 --- a/Particle Systems/Code/OGL/Spray/StdAfx.h +++ b/Particle Systems/Code/OGL/Spray/StdAfx.h @@ -1,25 +1,25 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__86F99067_D3EC_11D1_83A2_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__86F99067_D3EC_11D1_83A2_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__86F99067_D3EC_11D1_83A2_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__86F99067_D3EC_11D1_83A2_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__86F99067_D3EC_11D1_83A2_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__86F99067_D3EC_11D1_83A2_004005308EB5__INCLUDED_) diff --git a/Particle Systems/Code/OGL/Spray/resource.h b/Particle Systems/Code/OGL/Spray/resource.h index bde316f..02ba5c3 100644 --- a/Particle Systems/Code/OGL/Spray/resource.h +++ b/Particle Systems/Code/OGL/Spray/resource.h @@ -1,59 +1,59 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Spray.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SPRAYTYPE 129 -#define IDD_SETROTATE 130 -#define IDD_SETEMITTER 131 -#define IDC_XAXIS 1000 -#define IDC_YAW 1000 -#define IDC_YAXIS 1001 -#define IDC_YAWVAR 1001 -#define IDC_ZAXIS 1002 -#define IDC_PITCH 1002 -#define IDC_PITCHVAR 1003 -#define IDC_SPEED 1004 -#define IDC_SPEEDVAR 1005 -#define IDC_LIFE 1006 -#define IDC_LIFEVAR 1007 -#define IDC_EMITS 1008 -#define IDC_EMITVAR 1009 -#define IDC_TOTALPARTS 1010 -#define IDC_FORCEZ 1011 -#define IDC_FORCEY 1012 -#define IDC_FORCEX 1013 -#define IDC_SCOLORB 1014 -#define IDC_SCOLORG 1017 -#define IDC_SCOLORR 1018 -#define IDC_SCOLORBV 1020 -#define IDC_SCOLORGV 1021 -#define IDC_SCOLORRV 1022 -#define IDC_ECOLORB 1023 -#define IDC_ECOLORG 1024 -#define IDC_ECOLORR 1025 -#define IDC_ECOLORBV 1026 -#define IDC_ECOLORGV 1027 -#define IDC_ECOLORRV 1028 -#define IDC_NAME 1029 -#define ID_HELP_WHICHOPENGL 32771 -#define ID_SETTINGS_EDITEMITTER 32772 -#define ID_SETTINGS_ANTIALIASPOINTS 32773 -#define ID_SETTINGS_SHOWAXIS 32774 -#define ID_INDICATOR_STATUS 59142 -#define ID_INDICATOR_COUNT 59142 -#define ID_INDICATOR_ROT 59143 -#define ID_INDICATOR_COUNT2 59143 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 132 -#define _APS_NEXT_COMMAND_VALUE 32775 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Spray.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SPRAYTYPE 129 +#define IDD_SETROTATE 130 +#define IDD_SETEMITTER 131 +#define IDC_XAXIS 1000 +#define IDC_YAW 1000 +#define IDC_YAXIS 1001 +#define IDC_YAWVAR 1001 +#define IDC_ZAXIS 1002 +#define IDC_PITCH 1002 +#define IDC_PITCHVAR 1003 +#define IDC_SPEED 1004 +#define IDC_SPEEDVAR 1005 +#define IDC_LIFE 1006 +#define IDC_LIFEVAR 1007 +#define IDC_EMITS 1008 +#define IDC_EMITVAR 1009 +#define IDC_TOTALPARTS 1010 +#define IDC_FORCEZ 1011 +#define IDC_FORCEY 1012 +#define IDC_FORCEX 1013 +#define IDC_SCOLORB 1014 +#define IDC_SCOLORG 1017 +#define IDC_SCOLORR 1018 +#define IDC_SCOLORBV 1020 +#define IDC_SCOLORGV 1021 +#define IDC_SCOLORRV 1022 +#define IDC_ECOLORB 1023 +#define IDC_ECOLORG 1024 +#define IDC_ECOLORR 1025 +#define IDC_ECOLORBV 1026 +#define IDC_ECOLORGV 1027 +#define IDC_ECOLORRV 1028 +#define IDC_NAME 1029 +#define ID_HELP_WHICHOPENGL 32771 +#define ID_SETTINGS_EDITEMITTER 32772 +#define ID_SETTINGS_ANTIALIASPOINTS 32773 +#define ID_SETTINGS_SHOWAXIS 32774 +#define ID_INDICATOR_STATUS 59142 +#define ID_INDICATOR_COUNT 59142 +#define ID_INDICATOR_ROT 59143 +#define ID_INDICATOR_COUNT2 59143 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 132 +#define _APS_NEXT_COMMAND_VALUE 32775 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Pool Table Physics/Code/OGL/Pool/EXTERNS.h b/Pool Table Physics/Code/OGL/Pool/EXTERNS.h index 37a35d7..f3e4655 100644 --- a/Pool Table Physics/Code/OGL/Pool/EXTERNS.h +++ b/Pool Table Physics/Code/OGL/Pool/EXTERNS.h @@ -1,110 +1,110 @@ -// Externs.h -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -#include "MathDefs.h" - -// This sets up the table position in the world -// TODO: Should load with the model....? -#define TABLE_POSITION 3.45f // Height of the virtual table off ground -#define LEFT_BUMPER 4.88f // Left X coordinate of Table Bumper -#define RIGHT_BUMPER 4.88f // Right X coordinate of Table Bumper -#define TOP_BUMPER 2.3f // Top Z coordinate of Table Bumper - Ooops model error -#define BOTTOM_BUMPER 2.45f // Bottom Z coordinate of Table Bumper - -// Physical Dimension of the Ball -#define BALL_DIAMETER 0.1875f // Diameter of Billiard Ball in feet 2.25 in - -#define EPSILON 0.00001f // ERROR TERM -#define DEFAULT_DAMPING 0.002f -#define CUE_STICK_FORCE 5.0f // For Mouse interaction - -enum tCollisionTypes -{ - NOT_COLLIDING, - PENETRATING, - COLLIDING_WITH_WALL, - COLLIDING_WITH_BALL -}; - -enum tIntegratorTypes -{ - EULER_INTEGRATOR, - MIDPOINT_INTEGRATOR, - RK4_INTEGRATOR -}; - -// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM -typedef struct s_Contact -{ - int ball,ball2; // Ball Index Ball2 is only used in Ball 2 ball collisions - tVector3 normal; // Normal of Collision plane - int type; // COLLIDING OR CONTACT - float Kr; // Coefficient of restitution -} t_Contact; - -// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH -typedef struct s_CollisionPlane -{ - tVector3 normal; // inward pointing - float d; // ax + by + cz + d = 0 -} t_CollisionPlane; - -typedef struct s_Camera -{ - tVector3 rot; // CURRENT ROTATION FACTORS - tVector3 trans; // CURRENT TRANSLATION FACTORS - float fov; // FIELD OF VIEW -} t_Camera; - -// Structure to Hold the Cue Stick -typedef struct s_Cue -{ - float draw,old_draw; // How much is the stick pulled back - float yaw; // Direction - tVector3 pos; - float drawtime; -} t_CueStick; - -// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM -typedef struct s_Ball -{ - tVector3 pos; // Position of Particle - tVector3 v; // Velocity of Particle - tVector3 f; // Force Acting on Particle - tVector3 angMom; // Angular Momentum - tVector3 torque; // Torque - float oneOverM; // 1 / Mass of Particle - tQuaternion orientation; - int flags; // So I can track things -} t_Ball; - -#define POLY_SELECTED 1 -#define POLY_TEXTURED 2 - -// Camera for View System -extern t_Camera g_POV; - -// Objects for the Game -extern t_CueStick g_CueStick; -extern t_Ball *g_CurrentSys; -extern int g_CueHitBall; // Set when a Cue hits the ball -extern tVector3 g_CueForce; -extern int g_BallInPlay; -extern int g_UseFriction; // Global to Select Friction - -// External handles to all the windows, palettes, etc. -extern HWND hViewWnd; -extern HWND hMainWnd; -extern HPALETTE hPalette; -extern HDC g_hDC; - -// Other shared variables -extern double PI; - -///////////////////////// -// Functions declared in other source files -BOOL InitGame(void); // Defined in GameSim.c -void InitRender(void); // Defined in RenderWorld.c -void RenderWorld(void); // Defined in RenderWorld.c -void Simulate(float DeltaTime, BOOL running); // In GameSim.c -float GetTime( void ); +// Externs.h +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +#include "MathDefs.h" + +// This sets up the table position in the world +// TODO: Should load with the model....? +#define TABLE_POSITION 3.45f // Height of the virtual table off ground +#define LEFT_BUMPER 4.88f // Left X coordinate of Table Bumper +#define RIGHT_BUMPER 4.88f // Right X coordinate of Table Bumper +#define TOP_BUMPER 2.3f // Top Z coordinate of Table Bumper - Ooops model error +#define BOTTOM_BUMPER 2.45f // Bottom Z coordinate of Table Bumper + +// Physical Dimension of the Ball +#define BALL_DIAMETER 0.1875f // Diameter of Billiard Ball in feet 2.25 in + +#define EPSILON 0.00001f // ERROR TERM +#define DEFAULT_DAMPING 0.002f +#define CUE_STICK_FORCE 5.0f // For Mouse interaction + +enum tCollisionTypes +{ + NOT_COLLIDING, + PENETRATING, + COLLIDING_WITH_WALL, + COLLIDING_WITH_BALL +}; + +enum tIntegratorTypes +{ + EULER_INTEGRATOR, + MIDPOINT_INTEGRATOR, + RK4_INTEGRATOR +}; + +// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM +typedef struct s_Contact +{ + int ball,ball2; // Ball Index Ball2 is only used in Ball 2 ball collisions + tVector3 normal; // Normal of Collision plane + int type; // COLLIDING OR CONTACT + float Kr; // Coefficient of restitution +} t_Contact; + +// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH +typedef struct s_CollisionPlane +{ + tVector3 normal; // inward pointing + float d; // ax + by + cz + d = 0 +} t_CollisionPlane; + +typedef struct s_Camera +{ + tVector3 rot; // CURRENT ROTATION FACTORS + tVector3 trans; // CURRENT TRANSLATION FACTORS + float fov; // FIELD OF VIEW +} t_Camera; + +// Structure to Hold the Cue Stick +typedef struct s_Cue +{ + float draw,old_draw; // How much is the stick pulled back + float yaw; // Direction + tVector3 pos; + float drawtime; +} t_CueStick; + +// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM +typedef struct s_Ball +{ + tVector3 pos; // Position of Particle + tVector3 v; // Velocity of Particle + tVector3 f; // Force Acting on Particle + tVector3 angMom; // Angular Momentum + tVector3 torque; // Torque + float oneOverM; // 1 / Mass of Particle + tQuaternion orientation; + int flags; // So I can track things +} t_Ball; + +#define POLY_SELECTED 1 +#define POLY_TEXTURED 2 + +// Camera for View System +extern t_Camera g_POV; + +// Objects for the Game +extern t_CueStick g_CueStick; +extern t_Ball *g_CurrentSys; +extern int g_CueHitBall; // Set when a Cue hits the ball +extern tVector3 g_CueForce; +extern int g_BallInPlay; +extern int g_UseFriction; // Global to Select Friction + +// External handles to all the windows, palettes, etc. +extern HWND hViewWnd; +extern HWND hMainWnd; +extern HPALETTE hPalette; +extern HDC g_hDC; + +// Other shared variables +extern double PI; + +///////////////////////// +// Functions declared in other source files +BOOL InitGame(void); // Defined in GameSim.c +void InitRender(void); // Defined in RenderWorld.c +void RenderWorld(void); // Defined in RenderWorld.c +void Simulate(float DeltaTime, BOOL running); // In GameSim.c +float GetTime( void ); diff --git a/Pool Table Physics/Code/OGL/Pool/GameSim.cpp b/Pool Table Physics/Code/OGL/Pool/GameSim.cpp index fb528fe..315a89b 100644 --- a/Pool Table Physics/Code/OGL/Pool/GameSim.cpp +++ b/Pool Table Physics/Code/OGL/Pool/GameSim.cpp @@ -1,517 +1,517 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Game Simulation Implementation File GameSim.c -// -// Purpose: Implementation of Billiards Physics -// This is the meat of the physical simulation for the pool table -// Created: -// JL 9/5/99 Created for the new sample app -// -// Modified: -// -// Notes: Some base of this code is from the OpenGL Superbible. Great Book -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998-1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include // Normal Windows stuff -#include -#include -#include -#include -#include "externs.h" // Data shared between files - -#define BALL_COUNT 2 -#define SYSTEM_COUNT 3 -#define MAX_CONTACTS 10 - -void SetupBalls(); - -t_CueStick g_CueStick; -t_Ball g_Ball[2]; // Put two Balls in the world - -float g_Kd; -float g_Kr_Bumper; // Ball to Bumper Coefficient of Restitution -float g_Kr_Ball; // Ball to Ball Coefficient of Restitution -float g_Ksh; -float g_Ksd; -float g_Csf; -float g_Ckf; -int g_IntegratorType; -int g_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION -int g_UseDamping = TRUE; // Use a Damping force -int g_UseFriction = TRUE; // Use Friction -int g_CueHitBall = FALSE; // Set when a Cue hits the ball -int g_BallInPlay = FALSE; // Ball has been hit -tVector3 g_CueForce; -tVector3 g_Gravity; - -t_Contact g_Contact[MAX_CONTACTS]; // LIST OF POSSIBLE COLLISIONS -int g_ContactCnt; // COLLISION COUNT -t_CollisionPlane g_CollisionPlane[4]; // LIST OF COLLISION PLANES -int g_CollisionPlaneCnt; -t_Ball g_GameSys[SYSTEM_COUNT][BALL_COUNT]; // LIST OF PHYSICAL PARTICLES -t_Ball *g_CurrentSys,*g_TargetSys; - - -/////////////////////////////////////////////////////////////////////////////// -// Initialize the world and the objects in it. -BOOL InitGame(void) -{ - g_CueStick.draw = g_CueStick.old_draw = 0.2f; - g_CueStick.yaw = 0.0f; - g_CueStick.pos.x = -4.0f; - g_CueStick.pos.y = TABLE_POSITION; - g_CueStick.pos.z = 0.0f; - - - g_Kd = 0.02f; // DAMPING FACTOR - g_Kr_Bumper = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT - g_Kr_Ball = 0.2f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT - g_Ksh = 5.0f; // HOOK'S SPRING CONSTANT - g_Ksd = 0.1f; // SPRING DAMPING CONSTANT - - g_Csf = 0.2f; // Default Static Friction - g_Ckf = 0.1f; // Default Kinetic Friction - - g_Gravity = tVector3(0.0f, -32.0f, 0.0f); - - // Pick an Integrator. Either seem to work fine for this app - // Euler is faster so.... -// g_IntegratorType = MIDPOINT_INTEGRATOR; - g_IntegratorType = EULER_INTEGRATOR; - - g_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION - - g_ContactCnt = 0; - - SetupBalls(); - - g_CurrentSys = g_GameSys[0]; - g_TargetSys = g_GameSys[1]; - - g_CollisionPlaneCnt = 4; - - // Left Bumper - g_CollisionPlane[0].normal = tVector3(1.0f, 0.0f, 0.0f); - g_CollisionPlane[0].d = LEFT_BUMPER; - - // Right Bumper - g_CollisionPlane[1].normal = tVector3(-1.0f, 0.0f, 0.0f); - g_CollisionPlane[1].d = RIGHT_BUMPER; - - // Top Bumper - g_CollisionPlane[2].normal = tVector3( 0.0f, 0.0f, -1.0f); - g_CollisionPlane[2].d = TOP_BUMPER; - - // Right Bumper - g_CollisionPlane[3].normal = tVector3( 0.0f, 0.0f, 1.0f); - g_CollisionPlane[3].d = BOTTOM_BUMPER; - - return TRUE; -} - - -void SetupBalls() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop, loop2; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < SYSTEM_COUNT; loop++) - { - for (loop2 = 0; loop2 < BALL_COUNT; loop2++) - { - switch (loop2) - { - // Ball 1 is the Cueball - case 0: - g_GameSys[loop][loop2].pos = tVector3( -4.0f, TABLE_POSITION, 0.0f); - break; - case 1: - g_GameSys[loop][loop2].pos = tVector3( 4.0f, TABLE_POSITION, 0.0f); - break; - } - g_GameSys[loop][loop2].v = tVector3( 0.0f, 0.0f, 0.0f); - g_GameSys[loop][loop2].f = tVector3( 0.0f, 0.0f, 0.0f); - g_GameSys[loop][loop2].oneOverM = 1.0f / 0.34f; - g_GameSys[loop][loop2].angMom = tVector3( 0.0f, 0.0f, 0.0f); - g_GameSys[loop][loop2].torque = tVector3( 0.0f, 0.0f, 0.0f); - - // Clear the Quaternion - g_GameSys[loop][loop2].orientation = tQuaternion(); - - g_GameSys[loop][loop2].flags = 0; - g_GameSys[loop][loop2].flags = 0; - } - } -} - - -// Velocity Threshold that decides between Static and Kinetic Friction -#define STATIC_THRESHOLD 0.03f - -void ComputeForces( t_Ball *system) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Ball *curBall; - tVector3 contactN; - float FdotN,VdotN,Vmag; - tVector3 Vn,Vt; // CONTACT RESOLUTION IMPULSE -/////////////////////////////////////////////////////////////////////////////// - - curBall = system; - for (loop = 0; loop < BALL_COUNT; loop++) - { - curBall->f = tVector3( 0.0f,0.0f,0.0f); // Clear Force Vector - curBall->torque = tVector3( 0.0f, 0.0f, 0.0f); // Clear Torque Vector - - // TODO: Since I am only really doing 2D, I am not applying gravity here - - if (g_UseDamping) - { - curBall->f += (curBall->v * -g_Kd); - } - else - { - curBall->f += (curBall->v * -DEFAULT_DAMPING); - } - - - // Handle Friction forces for Balls in Contact with the Table - // In my simple Pool table, the ball is always in contact - // Only friction with the table top is handled - if (g_UseFriction) - { - // Calculate Fn - FdotN = g_Gravity.y / curBall->oneOverM; // Gravity - // Calculate Vt Velocity Tangent to Normal Plane - contactN = tVector3( 0.0f, 1.0f, 0.0f); - VdotN = contactN.Dot(&curBall->v); - Vn = contactN * VdotN; - Vt = curBall->v - Vn; - Vmag = Vt.Length2(); - // Check if Velocity is faster then threshold - if (Vmag > STATIC_THRESHOLD) // Use Kinetic Friction model - { - Vt.NormalizeVector(); - Vt *= (FdotN * g_Ckf); - curBall->f += Vt; - } - else // Use Static Friction Model - { - Vmag = Vmag / STATIC_THRESHOLD; - Vt.NormalizeVector(); - Vt *= (FdotN * g_Csf * Vmag); - curBall->f += Vt; - - // Once the Cue Ball Stops reset the stick - if (loop == 0) - { - g_BallInPlay = FALSE; - } - } - } - - curBall++; - } - - // CHECK IF THERE IS A USER FORCE BEING APPLIED - if (g_CueHitBall) - { - system[0].f += g_CueForce; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: IntegrateSysOverTime -// Purpose: Does the Integration for all the points in a system -// Arguments: Initial Position, Source and Target Particle Systems and Time -// Notes: Computes a single integration step -/////////////////////////////////////////////////////////////////////////////// -void IntegrateSysOverTime(t_Ball *initial,t_Ball *source, t_Ball *target, float deltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float deltaTimeMass; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < BALL_COUNT; loop++) - { - deltaTimeMass = deltaTime * initial->oneOverM; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v = initial->v + (source->f * deltaTimeMass); - - target->oneOverM = initial->oneOverM; - - // SET THE NEW POSITION - target->pos = initial->pos + (source->v * deltaTime); - - initial++; - source++; - target++; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses Euler's method -/////////////////////////////////////////////////////////////////////////////// -void EulerIntegrate( float DeltaTime) -{ - // JUST TAKE A SINGLE STEP - IntegrateSysOverTime(g_CurrentSys,g_CurrentSys, g_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: MidPointIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Midpoint method -/////////////////////////////////////////////////////////////////////////////// -void MidPointIntegrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float halfDeltaT; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; - - // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION - IntegrateSysOverTime(g_CurrentSys,g_CurrentSys,&g_GameSys[2][0],halfDeltaT); - - // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES - ComputeForces(&g_GameSys[2][0]); - - // TAKE THE FULL STEP WITH THIS NEW INFORMATION - IntegrateSysOverTime(g_CurrentSys,&g_GameSys[2][0],g_TargetSys,DeltaTime); -} - -int CheckForCollisions( t_Ball *system ) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int collisionState = NOT_COLLIDING; - float const depthEpsilon = 0.001f; - float const ballDepthEpsilon = 0.0001f; - int loop,loop2,planeIndex; - t_Ball *curBall,*ball2; - t_CollisionPlane *plane; - float axbyczd,dist,relativeVelocity; - tVector3 distVect; -/////////////////////////////////////////////////////////////////////////////// - - g_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS - - curBall = system; - for (loop = 0; (loop < BALL_COUNT) && (collisionState != PENETRATING); - loop++,curBall++) - { - for(planeIndex = 0;(planeIndex < g_CollisionPlaneCnt) && - (collisionState != PENETRATING);planeIndex++) - { - plane = &g_CollisionPlane[planeIndex]; - - axbyczd = curBall->pos.Dot(&plane->normal) + plane->d; - - if(axbyczd < -depthEpsilon) - { - // ONCE ANY BALL PENETRATES A BUMPER, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(axbyczd < depthEpsilon) - { - relativeVelocity = plane->normal.Dot(&curBall->v); - if(relativeVelocity < 0.0f) - { - // TODO: Add a Collision with bumper sound here - collisionState = COLLIDING_WITH_WALL; - g_Contact[g_ContactCnt].type = COLLIDING_WITH_WALL; - g_Contact[g_ContactCnt].ball = loop; - g_Contact[g_ContactCnt].Kr = g_Kr_Bumper; // Ball to bumper Kr - memcpy(&g_Contact[g_ContactCnt].normal,&plane->normal,sizeof(tVector3)); - g_ContactCnt++; - } - } - } - - // Now check ball to ball collisions. - ball2 = system; - for (loop2 = 0; (loop2 < BALL_COUNT) && (collisionState != PENETRATING); - loop2++,ball2++) - { - if (loop2 == loop) continue; // don't test against self - if (curBall->flags) continue; // Skip already handled balls - - distVect = curBall->pos - ball2->pos; - - dist = distVect.Length2(); - // SINCE IT IS TESTING THE SQUARED DISTANCE, SQUARE THE RADIUS ALSO - dist = dist - (BALL_DIAMETER * BALL_DIAMETER); // Width of a ball - - if(dist < -ballDepthEpsilon) - { - // ONCE ANY BALL PENETRATES, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(dist < ballDepthEpsilon) - { - // NORMALIZE THE VECTOR - distVect.NormalizeVector(); - - relativeVelocity = distVect.Dot(curBall->v); - - if(relativeVelocity < 0.0f) - { - collisionState = COLLIDING_WITH_BALL; - g_Contact[g_ContactCnt].type = COLLIDING_WITH_BALL; - g_Contact[g_ContactCnt].ball = loop; - g_Contact[g_ContactCnt].ball2 = loop2; - g_Contact[g_ContactCnt].Kr = g_Kr_Ball; // Ball to Ball Kr - memcpy(&g_Contact[g_ContactCnt].normal,&distVect,sizeof(tVector3)); - ball2->flags = 1; - g_ContactCnt++; - } - } - } - - } - - return collisionState; -} - -void ResolveCollisions( t_Ball *system ) -{ - t_Contact *contact; - t_Ball *ball,*ball2; // THE PARTICLE COLLIDING - float VdotN; - tVector3 Vn,Vt,Vn1; // CONTACT RESOLUTION IMPULSE - int loop; - - contact = g_Contact; - for (loop = 0; loop < g_ContactCnt; loop++,contact++) - { - ball = &system[contact->ball]; - // CALCULATE Vn - VdotN = contact->normal.Dot(&ball->v); - Vn = contact->normal * VdotN; - // CALCULATE Vt - Vt = ball->v - Vn; - - // Check if it was a collision with a wall or ball - if (contact->type == COLLIDING_WITH_WALL) - { - // SCALE Vn BY COEFFICIENT OF RESTITUTION - Vn *= contact->Kr; - // SET THE VELOCITY TO BE THE NEW IMPULSE - ball->v = Vt - Vn; - } - else // Ball to ball collision - { - // Scale Vn By coefficient of restitution for ball 1 - Vn1 = Vn * contact->Kr; - // Set the velocity to be the new impulse - ball->v = Vt - Vn1; - - ball2 = &system[contact->ball2]; - // Scale Vn By 1 - coefficient of restitution for ball 2 - Vn1 = Vn * (1.0f - contact->Kr); - // Add it to the balls direction - ball2->v += Vn1; - - ball->flags = 0; - ball2->flags = 0; - } - - // TODO: Bumper Collision induced Spin - } -} - -void Simulate(float DeltaTime, BOOL running) -{ - float CurrentTime = 0.0f; - float TargetTime = DeltaTime; - t_Ball *tempSys; - int collisionState; - - while(CurrentTime < DeltaTime) - { - if (running) - { - ComputeForces(g_CurrentSys); - - // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK - // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, - // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. - // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY - if (g_CollisionRootFinding) - { - EulerIntegrate(TargetTime-CurrentTime); - } - else - { - switch (g_IntegratorType) - { - case EULER_INTEGRATOR: - EulerIntegrate(TargetTime-CurrentTime); - break; - case MIDPOINT_INTEGRATOR: - MidPointIntegrate(TargetTime-CurrentTime); - break; - } - } - } - - collisionState = CheckForCollisions(g_TargetSys); - - if(collisionState == PENETRATING) - { - // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER - g_CollisionRootFinding = TRUE; - // we simulated too far, so subdivide time and try again - TargetTime = (CurrentTime + TargetTime) / 2.0f; - - // blow up if we aren't moving forward each step, which is - // probably caused by interpenetration at the frame start - assert(fabs(TargetTime - CurrentTime) > EPSILON); - } - else - { - // either colliding or clear - if(collisionState == COLLIDING_WITH_WALL || - collisionState == COLLIDING_WITH_BALL) - { - int Counter = 0; - do - { - ResolveCollisions(g_TargetSys); - Counter++; - } while((CheckForCollisions(g_TargetSys) >= - COLLIDING_WITH_WALL) && (Counter < 500)); - - assert(Counter < 500); - g_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT BACK TO NORMAL - } - - // we made a successful step, so swap configurations - // to "save" the data for the next step - - CurrentTime = TargetTime; - TargetTime = DeltaTime; - - g_CueForce = tVector3( 0.0f,0.0f,0.0f); // Clear Cue Force - - // SWAP MY TWO SYSTEM BUFFERS SO I CAN DO IT AGAIN - tempSys = g_CurrentSys; - g_CurrentSys = g_TargetSys; - g_TargetSys = tempSys; - } - } -} +/////////////////////////////////////////////////////////////////////////////// +// +// Game Simulation Implementation File GameSim.c +// +// Purpose: Implementation of Billiards Physics +// This is the meat of the physical simulation for the pool table +// Created: +// JL 9/5/99 Created for the new sample app +// +// Modified: +// +// Notes: Some base of this code is from the OpenGL Superbible. Great Book +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998-1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include // Normal Windows stuff +#include +#include +#include +#include +#include "externs.h" // Data shared between files + +#define BALL_COUNT 2 +#define SYSTEM_COUNT 3 +#define MAX_CONTACTS 10 + +void SetupBalls(); + +t_CueStick g_CueStick; +t_Ball g_Ball[2]; // Put two Balls in the world + +float g_Kd; +float g_Kr_Bumper; // Ball to Bumper Coefficient of Restitution +float g_Kr_Ball; // Ball to Ball Coefficient of Restitution +float g_Ksh; +float g_Ksd; +float g_Csf; +float g_Ckf; +int g_IntegratorType; +int g_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION +int g_UseDamping = TRUE; // Use a Damping force +int g_UseFriction = TRUE; // Use Friction +int g_CueHitBall = FALSE; // Set when a Cue hits the ball +int g_BallInPlay = FALSE; // Ball has been hit +tVector3 g_CueForce; +tVector3 g_Gravity; + +t_Contact g_Contact[MAX_CONTACTS]; // LIST OF POSSIBLE COLLISIONS +int g_ContactCnt; // COLLISION COUNT +t_CollisionPlane g_CollisionPlane[4]; // LIST OF COLLISION PLANES +int g_CollisionPlaneCnt; +t_Ball g_GameSys[SYSTEM_COUNT][BALL_COUNT]; // LIST OF PHYSICAL PARTICLES +t_Ball *g_CurrentSys,*g_TargetSys; + + +/////////////////////////////////////////////////////////////////////////////// +// Initialize the world and the objects in it. +BOOL InitGame(void) +{ + g_CueStick.draw = g_CueStick.old_draw = 0.2f; + g_CueStick.yaw = 0.0f; + g_CueStick.pos.x = -4.0f; + g_CueStick.pos.y = TABLE_POSITION; + g_CueStick.pos.z = 0.0f; + + + g_Kd = 0.02f; // DAMPING FACTOR + g_Kr_Bumper = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT + g_Kr_Ball = 0.2f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT + g_Ksh = 5.0f; // HOOK'S SPRING CONSTANT + g_Ksd = 0.1f; // SPRING DAMPING CONSTANT + + g_Csf = 0.2f; // Default Static Friction + g_Ckf = 0.1f; // Default Kinetic Friction + + g_Gravity = tVector3(0.0f, -32.0f, 0.0f); + + // Pick an Integrator. Either seem to work fine for this app + // Euler is faster so.... +// g_IntegratorType = MIDPOINT_INTEGRATOR; + g_IntegratorType = EULER_INTEGRATOR; + + g_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION + + g_ContactCnt = 0; + + SetupBalls(); + + g_CurrentSys = g_GameSys[0]; + g_TargetSys = g_GameSys[1]; + + g_CollisionPlaneCnt = 4; + + // Left Bumper + g_CollisionPlane[0].normal = tVector3(1.0f, 0.0f, 0.0f); + g_CollisionPlane[0].d = LEFT_BUMPER; + + // Right Bumper + g_CollisionPlane[1].normal = tVector3(-1.0f, 0.0f, 0.0f); + g_CollisionPlane[1].d = RIGHT_BUMPER; + + // Top Bumper + g_CollisionPlane[2].normal = tVector3( 0.0f, 0.0f, -1.0f); + g_CollisionPlane[2].d = TOP_BUMPER; + + // Right Bumper + g_CollisionPlane[3].normal = tVector3( 0.0f, 0.0f, 1.0f); + g_CollisionPlane[3].d = BOTTOM_BUMPER; + + return TRUE; +} + + +void SetupBalls() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop, loop2; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < SYSTEM_COUNT; loop++) + { + for (loop2 = 0; loop2 < BALL_COUNT; loop2++) + { + switch (loop2) + { + // Ball 1 is the Cueball + case 0: + g_GameSys[loop][loop2].pos = tVector3( -4.0f, TABLE_POSITION, 0.0f); + break; + case 1: + g_GameSys[loop][loop2].pos = tVector3( 4.0f, TABLE_POSITION, 0.0f); + break; + } + g_GameSys[loop][loop2].v = tVector3( 0.0f, 0.0f, 0.0f); + g_GameSys[loop][loop2].f = tVector3( 0.0f, 0.0f, 0.0f); + g_GameSys[loop][loop2].oneOverM = 1.0f / 0.34f; + g_GameSys[loop][loop2].angMom = tVector3( 0.0f, 0.0f, 0.0f); + g_GameSys[loop][loop2].torque = tVector3( 0.0f, 0.0f, 0.0f); + + // Clear the Quaternion + g_GameSys[loop][loop2].orientation = tQuaternion(); + + g_GameSys[loop][loop2].flags = 0; + g_GameSys[loop][loop2].flags = 0; + } + } +} + + +// Velocity Threshold that decides between Static and Kinetic Friction +#define STATIC_THRESHOLD 0.03f + +void ComputeForces( t_Ball *system) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Ball *curBall; + tVector3 contactN; + float FdotN,VdotN,Vmag; + tVector3 Vn,Vt; // CONTACT RESOLUTION IMPULSE +/////////////////////////////////////////////////////////////////////////////// + + curBall = system; + for (loop = 0; loop < BALL_COUNT; loop++) + { + curBall->f = tVector3( 0.0f,0.0f,0.0f); // Clear Force Vector + curBall->torque = tVector3( 0.0f, 0.0f, 0.0f); // Clear Torque Vector + + // TODO: Since I am only really doing 2D, I am not applying gravity here + + if (g_UseDamping) + { + curBall->f += (curBall->v * -g_Kd); + } + else + { + curBall->f += (curBall->v * -DEFAULT_DAMPING); + } + + + // Handle Friction forces for Balls in Contact with the Table + // In my simple Pool table, the ball is always in contact + // Only friction with the table top is handled + if (g_UseFriction) + { + // Calculate Fn + FdotN = g_Gravity.y / curBall->oneOverM; // Gravity + // Calculate Vt Velocity Tangent to Normal Plane + contactN = tVector3( 0.0f, 1.0f, 0.0f); + VdotN = contactN.Dot(&curBall->v); + Vn = contactN * VdotN; + Vt = curBall->v - Vn; + Vmag = Vt.Length2(); + // Check if Velocity is faster then threshold + if (Vmag > STATIC_THRESHOLD) // Use Kinetic Friction model + { + Vt.NormalizeVector(); + Vt *= (FdotN * g_Ckf); + curBall->f += Vt; + } + else // Use Static Friction Model + { + Vmag = Vmag / STATIC_THRESHOLD; + Vt.NormalizeVector(); + Vt *= (FdotN * g_Csf * Vmag); + curBall->f += Vt; + + // Once the Cue Ball Stops reset the stick + if (loop == 0) + { + g_BallInPlay = FALSE; + } + } + } + + curBall++; + } + + // CHECK IF THERE IS A USER FORCE BEING APPLIED + if (g_CueHitBall) + { + system[0].f += g_CueForce; + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: IntegrateSysOverTime +// Purpose: Does the Integration for all the points in a system +// Arguments: Initial Position, Source and Target Particle Systems and Time +// Notes: Computes a single integration step +/////////////////////////////////////////////////////////////////////////////// +void IntegrateSysOverTime(t_Ball *initial,t_Ball *source, t_Ball *target, float deltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float deltaTimeMass; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < BALL_COUNT; loop++) + { + deltaTimeMass = deltaTime * initial->oneOverM; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v = initial->v + (source->f * deltaTimeMass); + + target->oneOverM = initial->oneOverM; + + // SET THE NEW POSITION + target->pos = initial->pos + (source->v * deltaTime); + + initial++; + source++; + target++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses Euler's method +/////////////////////////////////////////////////////////////////////////////// +void EulerIntegrate( float DeltaTime) +{ + // JUST TAKE A SINGLE STEP + IntegrateSysOverTime(g_CurrentSys,g_CurrentSys, g_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: MidPointIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Midpoint method +/////////////////////////////////////////////////////////////////////////////// +void MidPointIntegrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float halfDeltaT; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; + + // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION + IntegrateSysOverTime(g_CurrentSys,g_CurrentSys,&g_GameSys[2][0],halfDeltaT); + + // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES + ComputeForces(&g_GameSys[2][0]); + + // TAKE THE FULL STEP WITH THIS NEW INFORMATION + IntegrateSysOverTime(g_CurrentSys,&g_GameSys[2][0],g_TargetSys,DeltaTime); +} + +int CheckForCollisions( t_Ball *system ) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int collisionState = NOT_COLLIDING; + float const depthEpsilon = 0.001f; + float const ballDepthEpsilon = 0.0001f; + int loop,loop2,planeIndex; + t_Ball *curBall,*ball2; + t_CollisionPlane *plane; + float axbyczd,dist,relativeVelocity; + tVector3 distVect; +/////////////////////////////////////////////////////////////////////////////// + + g_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS + + curBall = system; + for (loop = 0; (loop < BALL_COUNT) && (collisionState != PENETRATING); + loop++,curBall++) + { + for(planeIndex = 0;(planeIndex < g_CollisionPlaneCnt) && + (collisionState != PENETRATING);planeIndex++) + { + plane = &g_CollisionPlane[planeIndex]; + + axbyczd = curBall->pos.Dot(&plane->normal) + plane->d; + + if(axbyczd < -depthEpsilon) + { + // ONCE ANY BALL PENETRATES A BUMPER, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(axbyczd < depthEpsilon) + { + relativeVelocity = plane->normal.Dot(&curBall->v); + if(relativeVelocity < 0.0f) + { + // TODO: Add a Collision with bumper sound here + collisionState = COLLIDING_WITH_WALL; + g_Contact[g_ContactCnt].type = COLLIDING_WITH_WALL; + g_Contact[g_ContactCnt].ball = loop; + g_Contact[g_ContactCnt].Kr = g_Kr_Bumper; // Ball to bumper Kr + memcpy(&g_Contact[g_ContactCnt].normal,&plane->normal,sizeof(tVector3)); + g_ContactCnt++; + } + } + } + + // Now check ball to ball collisions. + ball2 = system; + for (loop2 = 0; (loop2 < BALL_COUNT) && (collisionState != PENETRATING); + loop2++,ball2++) + { + if (loop2 == loop) continue; // don't test against self + if (curBall->flags) continue; // Skip already handled balls + + distVect = curBall->pos - ball2->pos; + + dist = distVect.Length2(); + // SINCE IT IS TESTING THE SQUARED DISTANCE, SQUARE THE RADIUS ALSO + dist = dist - (BALL_DIAMETER * BALL_DIAMETER); // Width of a ball + + if(dist < -ballDepthEpsilon) + { + // ONCE ANY BALL PENETRATES, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(dist < ballDepthEpsilon) + { + // NORMALIZE THE VECTOR + distVect.NormalizeVector(); + + relativeVelocity = distVect.Dot(curBall->v); + + if(relativeVelocity < 0.0f) + { + collisionState = COLLIDING_WITH_BALL; + g_Contact[g_ContactCnt].type = COLLIDING_WITH_BALL; + g_Contact[g_ContactCnt].ball = loop; + g_Contact[g_ContactCnt].ball2 = loop2; + g_Contact[g_ContactCnt].Kr = g_Kr_Ball; // Ball to Ball Kr + memcpy(&g_Contact[g_ContactCnt].normal,&distVect,sizeof(tVector3)); + ball2->flags = 1; + g_ContactCnt++; + } + } + } + + } + + return collisionState; +} + +void ResolveCollisions( t_Ball *system ) +{ + t_Contact *contact; + t_Ball *ball,*ball2; // THE PARTICLE COLLIDING + float VdotN; + tVector3 Vn,Vt,Vn1; // CONTACT RESOLUTION IMPULSE + int loop; + + contact = g_Contact; + for (loop = 0; loop < g_ContactCnt; loop++,contact++) + { + ball = &system[contact->ball]; + // CALCULATE Vn + VdotN = contact->normal.Dot(&ball->v); + Vn = contact->normal * VdotN; + // CALCULATE Vt + Vt = ball->v - Vn; + + // Check if it was a collision with a wall or ball + if (contact->type == COLLIDING_WITH_WALL) + { + // SCALE Vn BY COEFFICIENT OF RESTITUTION + Vn *= contact->Kr; + // SET THE VELOCITY TO BE THE NEW IMPULSE + ball->v = Vt - Vn; + } + else // Ball to ball collision + { + // Scale Vn By coefficient of restitution for ball 1 + Vn1 = Vn * contact->Kr; + // Set the velocity to be the new impulse + ball->v = Vt - Vn1; + + ball2 = &system[contact->ball2]; + // Scale Vn By 1 - coefficient of restitution for ball 2 + Vn1 = Vn * (1.0f - contact->Kr); + // Add it to the balls direction + ball2->v += Vn1; + + ball->flags = 0; + ball2->flags = 0; + } + + // TODO: Bumper Collision induced Spin + } +} + +void Simulate(float DeltaTime, BOOL running) +{ + float CurrentTime = 0.0f; + float TargetTime = DeltaTime; + t_Ball *tempSys; + int collisionState; + + while(CurrentTime < DeltaTime) + { + if (running) + { + ComputeForces(g_CurrentSys); + + // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK + // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, + // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. + // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY + if (g_CollisionRootFinding) + { + EulerIntegrate(TargetTime-CurrentTime); + } + else + { + switch (g_IntegratorType) + { + case EULER_INTEGRATOR: + EulerIntegrate(TargetTime-CurrentTime); + break; + case MIDPOINT_INTEGRATOR: + MidPointIntegrate(TargetTime-CurrentTime); + break; + } + } + } + + collisionState = CheckForCollisions(g_TargetSys); + + if(collisionState == PENETRATING) + { + // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER + g_CollisionRootFinding = TRUE; + // we simulated too far, so subdivide time and try again + TargetTime = (CurrentTime + TargetTime) / 2.0f; + + // blow up if we aren't moving forward each step, which is + // probably caused by interpenetration at the frame start + assert(fabs(TargetTime - CurrentTime) > EPSILON); + } + else + { + // either colliding or clear + if(collisionState == COLLIDING_WITH_WALL || + collisionState == COLLIDING_WITH_BALL) + { + int Counter = 0; + do + { + ResolveCollisions(g_TargetSys); + Counter++; + } while((CheckForCollisions(g_TargetSys) >= + COLLIDING_WITH_WALL) && (Counter < 500)); + + assert(Counter < 500); + g_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT BACK TO NORMAL + } + + // we made a successful step, so swap configurations + // to "save" the data for the next step + + CurrentTime = TargetTime; + TargetTime = DeltaTime; + + g_CueForce = tVector3( 0.0f,0.0f,0.0f); // Clear Cue Force + + // SWAP MY TWO SYSTEM BUFFERS SO I CAN DO IT AGAIN + tempSys = g_CurrentSys; + g_CurrentSys = g_TargetSys; + g_TargetSys = tempSys; + } + } +} diff --git a/Pool Table Physics/Code/OGL/Pool/LoadTGA.cpp b/Pool Table Physics/Code/OGL/Pool/LoadTGA.cpp index a0786bc..99e9c93 100644 --- a/Pool Table Physics/Code/OGL/Pool/LoadTGA.cpp +++ b/Pool Table Physics/Code/OGL/Pool/LoadTGA.cpp @@ -1,93 +1,93 @@ -///////////////////////////////////////////////////////////////////////////////////// -// Routines to load the texture map -///////////////////////////////////////////////////////////////////////////////////// -#include // Normal Windows stuff -#include -#include "loadtga.h" - - -/////////////////////////////////////////////////////////////////////////////// -// This stuff forward is the TGA Loading Routines -// -/////////////////////////////////////////////////////////////////////////////// - -//----------------------------------------------------------------------- -// Name: LoadTGAFile() -// Desc: Given a filename of a TGA file, it loads the image in BITMAP form -//----------------------------------------------------------------------- -unsigned char *LoadTGAFile( char * strFilename, tTGAHeader_s *header) -{ -/// Local Variables /////////////////////////////////////////////////////////// - short BitsPerPixel; - unsigned char *buffer; - int bitsize; /* Total size of bitmap */ - unsigned char *newbits; /* New RGB bits */ - unsigned char *from, *to; /* RGB looping vars */ - int i, j, /* Looping vars */ - width; /* Aligned width of bitmap */ - FILE* file; - long dwWidth, dwHeight; -/////////////////////////////////////////////////////////////////////////////// - - // Open the file and read the header - file = fopen( strFilename, "rb"); - if( NULL == file ) - return NULL; - - if ( fread( header, sizeof( tTGAHeader_s ), 1, file ) != 1 ) - { - fclose( file ); - return NULL; - } - - // Parse the TGA header - dwWidth = (long)header->d_width; - dwHeight = (long)header->d_height; - BitsPerPixel = (short)header->d_pixel_size; // 16, 24, or 32 - - // Create a bitmap to load the data into - - bitsize = dwWidth * dwHeight * (BitsPerPixel/8); - if ((newbits = (unsigned char *)calloc(bitsize, 1)) == NULL) - { - fclose( file ); - return NULL; - } - buffer = (unsigned char *)malloc(dwWidth*dwHeight*(BitsPerPixel / 8)); - if ( fread( buffer, dwWidth*dwHeight*(BitsPerPixel / 8), 1, file ) != 1 ) - { - fclose( file ); - free(buffer); - free(newbits); - return NULL; - } - - width = (BitsPerPixel / 8) * dwWidth; - - for (i = 0; i < dwHeight; i ++) - for (j = 0, from = ((unsigned char *)buffer) + i * width, - to = newbits + i * width; - j < dwWidth; - j ++, from += (BitsPerPixel / 8), to += (BitsPerPixel / 8)) - { - if (BitsPerPixel == 24) - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - } - else - { - to[0] = from[2]; - to[1] = from[1]; - to[2] = from[0]; - to[3] = from[3]; - } - }; - free(buffer); - fclose( file ); - - return newbits; -} - - +///////////////////////////////////////////////////////////////////////////////////// +// Routines to load the texture map +///////////////////////////////////////////////////////////////////////////////////// +#include // Normal Windows stuff +#include +#include "loadtga.h" + + +/////////////////////////////////////////////////////////////////////////////// +// This stuff forward is the TGA Loading Routines +// +/////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------- +// Name: LoadTGAFile() +// Desc: Given a filename of a TGA file, it loads the image in BITMAP form +//----------------------------------------------------------------------- +unsigned char *LoadTGAFile( char * strFilename, tTGAHeader_s *header) +{ +/// Local Variables /////////////////////////////////////////////////////////// + short BitsPerPixel; + unsigned char *buffer; + int bitsize; /* Total size of bitmap */ + unsigned char *newbits; /* New RGB bits */ + unsigned char *from, *to; /* RGB looping vars */ + int i, j, /* Looping vars */ + width; /* Aligned width of bitmap */ + FILE* file; + long dwWidth, dwHeight; +/////////////////////////////////////////////////////////////////////////////// + + // Open the file and read the header + file = fopen( strFilename, "rb"); + if( NULL == file ) + return NULL; + + if ( fread( header, sizeof( tTGAHeader_s ), 1, file ) != 1 ) + { + fclose( file ); + return NULL; + } + + // Parse the TGA header + dwWidth = (long)header->d_width; + dwHeight = (long)header->d_height; + BitsPerPixel = (short)header->d_pixel_size; // 16, 24, or 32 + + // Create a bitmap to load the data into + + bitsize = dwWidth * dwHeight * (BitsPerPixel/8); + if ((newbits = (unsigned char *)calloc(bitsize, 1)) == NULL) + { + fclose( file ); + return NULL; + } + buffer = (unsigned char *)malloc(dwWidth*dwHeight*(BitsPerPixel / 8)); + if ( fread( buffer, dwWidth*dwHeight*(BitsPerPixel / 8), 1, file ) != 1 ) + { + fclose( file ); + free(buffer); + free(newbits); + return NULL; + } + + width = (BitsPerPixel / 8) * dwWidth; + + for (i = 0; i < dwHeight; i ++) + for (j = 0, from = ((unsigned char *)buffer) + i * width, + to = newbits + i * width; + j < dwWidth; + j ++, from += (BitsPerPixel / 8), to += (BitsPerPixel / 8)) + { + if (BitsPerPixel == 24) + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + } + else + { + to[0] = from[2]; + to[1] = from[1]; + to[2] = from[0]; + to[3] = from[3]; + } + }; + free(buffer); + fclose( file ); + + return newbits; +} + + diff --git a/Pool Table Physics/Code/OGL/Pool/LoadTGA.h b/Pool Table Physics/Code/OGL/Pool/LoadTGA.h index 0999923..c36068c 100644 --- a/Pool Table Physics/Code/OGL/Pool/LoadTGA.h +++ b/Pool Table Physics/Code/OGL/Pool/LoadTGA.h @@ -1,27 +1,27 @@ -typedef struct -{ - unsigned char d_iif_size; // IIF size (after header), usually 0 - unsigned char d_cmap_type; // ignored - unsigned char d_image_type; // should be 2 - unsigned char pad[5]; - - unsigned short d_x_origin; - unsigned short d_y_origin; - unsigned short d_width; - unsigned short d_height; - - unsigned char d_pixel_size; // 16, 24, or 32 - unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) -} tTGAHeader_s; - -#define RGB16(r,g,b) ( ((r>>3) << 10) + ((g>>3) << 5) + (b >> 3) ) -#define RGB24(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) -#define GET16R(v) (v >> 10) -#define GET16G(v) ((v >> 5) & 0x1f) -#define GET16B(v) (v & 0x1f) - -unsigned char *LoadTGAFile( char* strFilename,tTGAHeader_s *header); - +typedef struct +{ + unsigned char d_iif_size; // IIF size (after header), usually 0 + unsigned char d_cmap_type; // ignored + unsigned char d_image_type; // should be 2 + unsigned char pad[5]; + + unsigned short d_x_origin; + unsigned short d_y_origin; + unsigned short d_width; + unsigned short d_height; + + unsigned char d_pixel_size; // 16, 24, or 32 + unsigned char d_image_descriptor; // Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) +} tTGAHeader_s; + +#define RGB16(r,g,b) ( ((r>>3) << 10) + ((g>>3) << 5) + (b >> 3) ) +#define RGB24(r,g,b) ( ((r) << 16) + ((g) << 8) + (b) ) +#define GET16R(v) (v >> 10) +#define GET16G(v) ((v >> 5) & 0x1f) +#define GET16B(v) (v & 0x1f) + +unsigned char *LoadTGAFile( char* strFilename,tTGAHeader_s *header); + diff --git a/Pool Table Physics/Code/OGL/Pool/MathDefs.cpp b/Pool Table Physics/Code/OGL/Pool/MathDefs.cpp index 7aee1f0..b77162c 100644 --- a/Pool Table Physics/Code/OGL/Pool/MathDefs.cpp +++ b/Pool Table Physics/Code/OGL/Pool/MathDefs.cpp @@ -1,589 +1,589 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.c : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: IdentityMatrix -// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void IdentityMatrix(tMatrix *mat) -{ -///// Local Variables ///////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < 16; loop++) - mat->m[loop] = 0.0f; - mat->m[0] = - mat->m[5] = - mat->m[10] = - mat->m[15] = - 1.0f; -} -//// IdentityMatrix /////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -// tVector Class -////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: equals operator -// Purpose: Sets the current vector to equal list of floats -// Arguments: float * -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator=( float *arg ) -{ - x = arg[0]; - y = arg[1]; - z = arg[2]; - w = arg[3]; - - return *this; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: addition operator -// Purpose: Subtracts a tVector from the current vector -// Arguments: tVector -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator+=( tVector &v ) -{ - x += v.x; - y += v.y; - z += v.z; - w += v.w; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: subtraction operator -// Purpose: Subtracts a tVector from the current vector -// Arguments: tVector -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator-=( tVector &v ) -{ - x -= v.x; - y -= v.y; - z -= v.z; - w -= v.w; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: multiplication operator -// Purpose: Multiply a tVector by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator*( float arg ) -{ - tVector v; - - v.x = x * arg; - v.y = y * arg; - v.z = z * arg; - v.w = w * arg; - - return v; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: division operator -// Purpose: Divides a tVector by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator/( float arg ) -{ - tVector v; - - v.x = x / arg; - v.y = y / arg; - v.z = z / arg; - v.w = w / arg; - - return v; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: multiplication operator -// Purpose: Multiply a tVector by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator*=( float arg ) -{ - tVector v; - - x *= arg; - y *= arg; - z *= arg; - w *= arg; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: division operator -// Purpose: Divides a tVector by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector tVector::operator/=( float arg ) -{ - tVector v; - - x /= arg; - y /= arg; - z /= arg; - w /= arg; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SquaredLength -// Purpose: Returns the squared length of the vector -// Arguments: none -/////////////////////////////////////////////////////////////////////////////// -float tVector::Length2() -{ - return((x * x) + (y * y) + (z * z) + (w * w)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Length -// Purpose: Returns the length of the vector -// Arguments: none -/////////////////////////////////////////////////////////////////////////////// -float tVector::Length() -{ - return((float)sqrt(Length2())); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeVector -// Purpose: Normalizes the class vector -// Arguments: none -/////////////////////////////////////////////////////////////////////////////// -void tVector::NormalizeVector() -{ - float len = Length(); - if (len != 0.0) - { - x /= len; - y /= len; - z /= len; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Lerp -// Purpose: Interpolates between vector and another by a factor -// Arguments: Vector to lerp to and factor -/////////////////////////////////////////////////////////////////////////////// -void tVector::Lerp(tVector *v1, float factor) -{ - x = x * (1.0f - factor) + v1->x * factor; - y = y * (1.0f - factor) + v1->y * factor; - z = z * (1.0f - factor) + v1->z * factor; - w = w * (1.0f - factor) + v1->w * factor; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossProduct -// Purpose: Sets the vector to equal the cross product of two vectors -// Arguments: tVector * -/////////////////////////////////////////////////////////////////////////////// -void tVector::CrossProduct(tVector &v1, tVector &v2) -{ - x = (v1.y * v2.z) - (v1.z * v2.y); - y = (v1.z * v2.x) - (v1.x * v2.z); - z = (v1.x * v2.y) - (v1.y * v2.x); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Dot -// Purpose: Return the dot product of two vectors -// Arguments: tVector * -/////////////////////////////////////////////////////////////////////////////// -float tVector::Dot(tVector *v) -{ - return ((x * v->x) + (y * v->y) + (z * v->z) + (w * v->w)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Dot -// Purpose: Return the dot product of two vectors -// Arguments: tVector * -/////////////////////////////////////////////////////////////////////////////// -float tVector::Dot(tVector &v) -{ - return ((x * v.x) + (y * v.y) + (z * v.z) + (w * v.w)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Dot -// Purpose: Return the dot product of two vectors -// Arguments: vector elements -/////////////////////////////////////////////////////////////////////////////// -float tVector::Dot(float vx, float vy, float vz, float vw) -{ - return ((x * vx) + (y * vy) + (z * vz) + (w * vw)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void tVector::MultVectorByMatrix(float *mat) -{ - tVector result; - result.x = (mat[0] * x) + - (mat[4] * y) + - (mat[8] * z) + - (mat[12] * w); - result.y = (mat[1] * x) + - (mat[5] * y) + - (mat[9] * z) + - (mat[13] * w); - result.z = (mat[2] * x) + - (mat[6] * y) + - (mat[10] * z) + - (mat[14] * w); - result.w = (mat[3] * x) + - (mat[7] * y) + - (mat[11] * z) + - (mat[15] * w); - - x = result.x; - y = result.y; - z = result.z; - w = result.w; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByRotMatrix -// Purpose: Multiplies a vector by a rotation only 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void tVector::MultVectorByRotMatrix(float *mat) -{ - tVector result; - result.x = (mat[0] * x) + - (mat[4] * y) + - (mat[8] * z); - result.y = (mat[1] * x) + - (mat[5] * y) + - (mat[9] * z); - result.z = (mat[2] * x) + - (mat[6] * y) + - (mat[10] * z); - - x = result.x; - y = result.y; - z = result.z; -} -//// MultVectorByRotMatrix ////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -// End of tVector Class -////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -// tVector3 Class -////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: equals operator -// Purpose: Sets the current vector to equal list of floats -// Arguments: float * -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator=( float *arg ) -{ - x = arg[0]; - y = arg[1]; - z = arg[2]; - - return *this; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: addition operator -// Purpose: Subtracts a tVector3 from the current vector -// Arguments: tVector3 -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator+=( tVector3 &v ) -{ - x += v.x; - y += v.y; - z += v.z; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: subtraction operator -// Purpose: Subtracts a tVector3 from the current vector -// Arguments: tVector3 -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator-=( tVector3 &v ) -{ - x -= v.x; - y -= v.y; - z -= v.z; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: multiplication operator -// Purpose: Multiply a tVector3 by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator*( float arg ) -{ - tVector3 v; - - v.x = x * arg; - v.y = y * arg; - v.z = z * arg; - - return v; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: division operator -// Purpose: Divides a tVector3 by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator/( float arg ) -{ - tVector3 v; - - v.x = x / arg; - v.y = y / arg; - v.z = z / arg; - - return v; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: multiplication operator -// Purpose: Multiply a tVector3 by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator*=( float arg ) -{ - tVector3 v; - - x *= arg; - y *= arg; - z *= arg; - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: division operator -// Purpose: Divides a tVector3 by float -// Arguments: float -/////////////////////////////////////////////////////////////////////////////// -tVector3 tVector3::operator/=( float arg ) -{ - tVector3 v; - - x /= arg; - y /= arg; - z /= arg; - - return *this; -} -/////////////////////////////////////////////////////////////////////////////// -// Function: Length2 -// Purpose: Returns the squared length of the vector -// Arguments: none -/////////////////////////////////////////////////////////////////////////////// -float tVector3::Length2() -{ - return((x * x) + (y * y) + (z * z)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Length -// Purpose: Returns the length of the vector -// Arguments: none -/////////////////////////////////////////////////////////////////////////////// -float tVector3::Length() -{ - return((float)sqrt(Length2())); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeVector -// Purpose: Normalizes the class vector -// Arguments: none -/////////////////////////////////////////////////////////////////////////////// -void tVector3::NormalizeVector() -{ - float len = Length(); - if (len != 0.0) - { - x /= len; - y /= len; - z /= len; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Lerp -// Purpose: Interpolates between vector and another by a factor -// Arguments: Vector to lerp to and factor -/////////////////////////////////////////////////////////////////////////////// -void tVector3::Lerp(tVector3 *v1, float factor) -{ - x = x * (1.0f - factor) + v1->x * factor; - y = y * (1.0f - factor) + v1->y * factor; - z = z * (1.0f - factor) + v1->z * factor; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossProduct -// Purpose: Sets the vector to equal the cross product of two vectors -// Arguments: tVector3 * -/////////////////////////////////////////////////////////////////////////////// -void tVector3::CrossProduct(tVector3 &v1, tVector3 &v2) -{ - x = (v1.y * v2.z) - (v1.z * v2.y); - y = (v1.z * v2.x) - (v1.x * v2.z); - z = (v1.x * v2.y) - (v1.y * v2.x); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Dot -// Purpose: Return the dot product of two vectors -// Arguments: tVector3 * -/////////////////////////////////////////////////////////////////////////////// -float tVector3::Dot(tVector3 *v) -{ - return ((x * v->x) + (y * v->y) + (z * v->z)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Dot -// Purpose: Return the dot product of two vectors -// Arguments: tVector3 * -/////////////////////////////////////////////////////////////////////////////// -float tVector3::Dot(tVector3 &v) -{ - return ((x * v.x) + (y * v.y) + (z * v.z)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: Dot -// Purpose: Return the dot product of two vectors -// Arguments: vector elements -/////////////////////////////////////////////////////////////////////////////// -float tVector3::Dot(float vx, float vy, float vz) -{ - return ((x * vx) + (y * vy) + (z * vz)); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void tVector3::MultVectorByMatrix(float *mat) -{ - tVector3 result; - result.x = (mat[0] * x) + - (mat[4] * y) + - (mat[8] * z) + - mat[12]; - result.y = (mat[1] * x) + - (mat[5] * y) + - (mat[9] * z) + - mat[13]; - result.z = (mat[2] * x) + - (mat[6] * y) + - (mat[10] * z) + - mat[14]; - - x = result.x; - y = result.y; - z = result.z; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByRotMatrix -// Purpose: Multiplies a vector by a rotation only 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void tVector3::MultVectorByRotMatrix(float *mat) -{ - tVector3 result; - result.x = (mat[0] * x) + - (mat[4] * y) + - (mat[8] * z); - result.y = (mat[1] * x) + - (mat[5] * y) + - (mat[9] * z); - result.z = (mat[2] * x) + - (mat[6] * y) + - (mat[10] * z); - - x = result.x; - y = result.y; - z = result.z; -} -//// MultVectorByRotMatrix ////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////// -// End of tVector3 Class -////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossProduct -// Purpose: Sets the vector to equal the cross product of two vectors -// Arguments: tVector * -/////////////////////////////////////////////////////////////////////////////// -tVector3 CrossProduct(tVector3 &v1, tVector3 &v2) -{ - tVector3 vRet; - vRet.x = (v1.y * v2.z) - (v1.z * v2.y); - vRet.y = (v1.z * v2.x) - (v1.x * v2.z); - vRet.z = (v1.x * v2.y) - (v1.y * v2.x); - return vRet; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.c : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: IdentityMatrix +// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void IdentityMatrix(tMatrix *mat) +{ +///// Local Variables ///////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < 16; loop++) + mat->m[loop] = 0.0f; + mat->m[0] = + mat->m[5] = + mat->m[10] = + mat->m[15] = + 1.0f; +} +//// IdentityMatrix /////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// tVector Class +////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: equals operator +// Purpose: Sets the current vector to equal list of floats +// Arguments: float * +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator=( float *arg ) +{ + x = arg[0]; + y = arg[1]; + z = arg[2]; + w = arg[3]; + + return *this; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: addition operator +// Purpose: Subtracts a tVector from the current vector +// Arguments: tVector +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator+=( tVector &v ) +{ + x += v.x; + y += v.y; + z += v.z; + w += v.w; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: subtraction operator +// Purpose: Subtracts a tVector from the current vector +// Arguments: tVector +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator-=( tVector &v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: multiplication operator +// Purpose: Multiply a tVector by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator*( float arg ) +{ + tVector v; + + v.x = x * arg; + v.y = y * arg; + v.z = z * arg; + v.w = w * arg; + + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: division operator +// Purpose: Divides a tVector by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator/( float arg ) +{ + tVector v; + + v.x = x / arg; + v.y = y / arg; + v.z = z / arg; + v.w = w / arg; + + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: multiplication operator +// Purpose: Multiply a tVector by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator*=( float arg ) +{ + tVector v; + + x *= arg; + y *= arg; + z *= arg; + w *= arg; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: division operator +// Purpose: Divides a tVector by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector tVector::operator/=( float arg ) +{ + tVector v; + + x /= arg; + y /= arg; + z /= arg; + w /= arg; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SquaredLength +// Purpose: Returns the squared length of the vector +// Arguments: none +/////////////////////////////////////////////////////////////////////////////// +float tVector::Length2() +{ + return((x * x) + (y * y) + (z * z) + (w * w)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Length +// Purpose: Returns the length of the vector +// Arguments: none +/////////////////////////////////////////////////////////////////////////////// +float tVector::Length() +{ + return((float)sqrt(Length2())); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeVector +// Purpose: Normalizes the class vector +// Arguments: none +/////////////////////////////////////////////////////////////////////////////// +void tVector::NormalizeVector() +{ + float len = Length(); + if (len != 0.0) + { + x /= len; + y /= len; + z /= len; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Lerp +// Purpose: Interpolates between vector and another by a factor +// Arguments: Vector to lerp to and factor +/////////////////////////////////////////////////////////////////////////////// +void tVector::Lerp(tVector *v1, float factor) +{ + x = x * (1.0f - factor) + v1->x * factor; + y = y * (1.0f - factor) + v1->y * factor; + z = z * (1.0f - factor) + v1->z * factor; + w = w * (1.0f - factor) + v1->w * factor; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossProduct +// Purpose: Sets the vector to equal the cross product of two vectors +// Arguments: tVector * +/////////////////////////////////////////////////////////////////////////////// +void tVector::CrossProduct(tVector &v1, tVector &v2) +{ + x = (v1.y * v2.z) - (v1.z * v2.y); + y = (v1.z * v2.x) - (v1.x * v2.z); + z = (v1.x * v2.y) - (v1.y * v2.x); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Dot +// Purpose: Return the dot product of two vectors +// Arguments: tVector * +/////////////////////////////////////////////////////////////////////////////// +float tVector::Dot(tVector *v) +{ + return ((x * v->x) + (y * v->y) + (z * v->z) + (w * v->w)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Dot +// Purpose: Return the dot product of two vectors +// Arguments: tVector * +/////////////////////////////////////////////////////////////////////////////// +float tVector::Dot(tVector &v) +{ + return ((x * v.x) + (y * v.y) + (z * v.z) + (w * v.w)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Dot +// Purpose: Return the dot product of two vectors +// Arguments: vector elements +/////////////////////////////////////////////////////////////////////////////// +float tVector::Dot(float vx, float vy, float vz, float vw) +{ + return ((x * vx) + (y * vy) + (z * vz) + (w * vw)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void tVector::MultVectorByMatrix(float *mat) +{ + tVector result; + result.x = (mat[0] * x) + + (mat[4] * y) + + (mat[8] * z) + + (mat[12] * w); + result.y = (mat[1] * x) + + (mat[5] * y) + + (mat[9] * z) + + (mat[13] * w); + result.z = (mat[2] * x) + + (mat[6] * y) + + (mat[10] * z) + + (mat[14] * w); + result.w = (mat[3] * x) + + (mat[7] * y) + + (mat[11] * z) + + (mat[15] * w); + + x = result.x; + y = result.y; + z = result.z; + w = result.w; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByRotMatrix +// Purpose: Multiplies a vector by a rotation only 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void tVector::MultVectorByRotMatrix(float *mat) +{ + tVector result; + result.x = (mat[0] * x) + + (mat[4] * y) + + (mat[8] * z); + result.y = (mat[1] * x) + + (mat[5] * y) + + (mat[9] * z); + result.z = (mat[2] * x) + + (mat[6] * y) + + (mat[10] * z); + + x = result.x; + y = result.y; + z = result.z; +} +//// MultVectorByRotMatrix ////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// End of tVector Class +////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// tVector3 Class +////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: equals operator +// Purpose: Sets the current vector to equal list of floats +// Arguments: float * +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator=( float *arg ) +{ + x = arg[0]; + y = arg[1]; + z = arg[2]; + + return *this; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: addition operator +// Purpose: Subtracts a tVector3 from the current vector +// Arguments: tVector3 +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator+=( tVector3 &v ) +{ + x += v.x; + y += v.y; + z += v.z; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: subtraction operator +// Purpose: Subtracts a tVector3 from the current vector +// Arguments: tVector3 +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator-=( tVector3 &v ) +{ + x -= v.x; + y -= v.y; + z -= v.z; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: multiplication operator +// Purpose: Multiply a tVector3 by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator*( float arg ) +{ + tVector3 v; + + v.x = x * arg; + v.y = y * arg; + v.z = z * arg; + + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: division operator +// Purpose: Divides a tVector3 by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator/( float arg ) +{ + tVector3 v; + + v.x = x / arg; + v.y = y / arg; + v.z = z / arg; + + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: multiplication operator +// Purpose: Multiply a tVector3 by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator*=( float arg ) +{ + tVector3 v; + + x *= arg; + y *= arg; + z *= arg; + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: division operator +// Purpose: Divides a tVector3 by float +// Arguments: float +/////////////////////////////////////////////////////////////////////////////// +tVector3 tVector3::operator/=( float arg ) +{ + tVector3 v; + + x /= arg; + y /= arg; + z /= arg; + + return *this; +} +/////////////////////////////////////////////////////////////////////////////// +// Function: Length2 +// Purpose: Returns the squared length of the vector +// Arguments: none +/////////////////////////////////////////////////////////////////////////////// +float tVector3::Length2() +{ + return((x * x) + (y * y) + (z * z)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Length +// Purpose: Returns the length of the vector +// Arguments: none +/////////////////////////////////////////////////////////////////////////////// +float tVector3::Length() +{ + return((float)sqrt(Length2())); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeVector +// Purpose: Normalizes the class vector +// Arguments: none +/////////////////////////////////////////////////////////////////////////////// +void tVector3::NormalizeVector() +{ + float len = Length(); + if (len != 0.0) + { + x /= len; + y /= len; + z /= len; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Lerp +// Purpose: Interpolates between vector and another by a factor +// Arguments: Vector to lerp to and factor +/////////////////////////////////////////////////////////////////////////////// +void tVector3::Lerp(tVector3 *v1, float factor) +{ + x = x * (1.0f - factor) + v1->x * factor; + y = y * (1.0f - factor) + v1->y * factor; + z = z * (1.0f - factor) + v1->z * factor; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossProduct +// Purpose: Sets the vector to equal the cross product of two vectors +// Arguments: tVector3 * +/////////////////////////////////////////////////////////////////////////////// +void tVector3::CrossProduct(tVector3 &v1, tVector3 &v2) +{ + x = (v1.y * v2.z) - (v1.z * v2.y); + y = (v1.z * v2.x) - (v1.x * v2.z); + z = (v1.x * v2.y) - (v1.y * v2.x); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Dot +// Purpose: Return the dot product of two vectors +// Arguments: tVector3 * +/////////////////////////////////////////////////////////////////////////////// +float tVector3::Dot(tVector3 *v) +{ + return ((x * v->x) + (y * v->y) + (z * v->z)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Dot +// Purpose: Return the dot product of two vectors +// Arguments: tVector3 * +/////////////////////////////////////////////////////////////////////////////// +float tVector3::Dot(tVector3 &v) +{ + return ((x * v.x) + (y * v.y) + (z * v.z)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: Dot +// Purpose: Return the dot product of two vectors +// Arguments: vector elements +/////////////////////////////////////////////////////////////////////////////// +float tVector3::Dot(float vx, float vy, float vz) +{ + return ((x * vx) + (y * vy) + (z * vz)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void tVector3::MultVectorByMatrix(float *mat) +{ + tVector3 result; + result.x = (mat[0] * x) + + (mat[4] * y) + + (mat[8] * z) + + mat[12]; + result.y = (mat[1] * x) + + (mat[5] * y) + + (mat[9] * z) + + mat[13]; + result.z = (mat[2] * x) + + (mat[6] * y) + + (mat[10] * z) + + mat[14]; + + x = result.x; + y = result.y; + z = result.z; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByRotMatrix +// Purpose: Multiplies a vector by a rotation only 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void tVector3::MultVectorByRotMatrix(float *mat) +{ + tVector3 result; + result.x = (mat[0] * x) + + (mat[4] * y) + + (mat[8] * z); + result.y = (mat[1] * x) + + (mat[5] * y) + + (mat[9] * z); + result.z = (mat[2] * x) + + (mat[6] * y) + + (mat[10] * z); + + x = result.x; + y = result.y; + z = result.z; +} +//// MultVectorByRotMatrix ////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// End of tVector3 Class +////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossProduct +// Purpose: Sets the vector to equal the cross product of two vectors +// Arguments: tVector * +/////////////////////////////////////////////////////////////////////////////// +tVector3 CrossProduct(tVector3 &v1, tVector3 &v2) +{ + tVector3 vRet; + vRet.x = (v1.y * v2.z) - (v1.z * v2.y); + vRet.y = (v1.z * v2.x) - (v1.x * v2.z); + vRet.z = (v1.x * v2.y) - (v1.y * v2.x); + return vRet; +} diff --git a/Pool Table Physics/Code/OGL/Pool/MathDefs.h b/Pool Table Physics/Code/OGL/Pool/MathDefs.h index 5d60083..78eba93 100644 --- a/Pool Table Physics/Code/OGL/Pool/MathDefs.h +++ b/Pool Table Physics/Code/OGL/Pool/MathDefs.h @@ -1,179 +1,179 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.1415926 -#define HALF_PI 1.5707963 -#define PI_TIMES_TWO 6.2831852 -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -#define MAX(a,b) ((a > b) ? a : b) -#define MIN(a,b) ((a < b) ? a : b) -/////////////////////////////////////////////////////////////////////////////// -typedef unsigned char uchar; - -typedef int BOOL; -typedef unsigned int uint; -typedef unsigned short ushort; -typedef unsigned char byte; - -typedef struct -{ - float u,v; -} t2DCoord; - -struct tVector -{ - float x,y,z,w; -public: - tVector() { x = y = z = 0.0f; w = 1.0f; } - tVector(tVector &_v) { x = _v.x; y = _v.y; z = _v.z; w = _v.w; } - tVector(float _x, float _y, float _z, float _w = 1.0f) { x = _x; y = _y; z = _z; w = _w; } - ~tVector() {} - -public: - - void Zero() { x = 0.0f; y = 0.0f; z = 0.0f; w = 0.0f; } - void CrossProduct(tVector &v1, tVector &v2); - float Length2(); - float Length(); - void NormalizeVector(); - void Lerp(tVector *v,float factor); - float Dot(tVector *v); - float Dot(tVector &v); - float Dot(float vx, float vy, float vz, float vw); - void MultVectorByMatrix(float *mat); - void MultVectorByRotMatrix(float *mat); - tVector operator+( tVector &arg ) { tVector ret(x + arg.x, y + arg.y, z + arg.z, w + arg.w); return ret; } - tVector operator-( tVector &arg ) { tVector ret(x - arg.x, y - arg.y, z - arg.z, w - arg.w); return ret; } - tVector operator=( tVector &arg ) { x = arg.x; y = arg.y; z = arg.z; w = arg.w; return *this; } - tVector operator*( tVector &arg ) { tVector ret(x * arg.x, y * arg.y, z * arg.z, w * arg.w); return ret; } - tVector operator=( float *arg ); - tVector operator+=( tVector &arg ); - tVector operator-=( tVector &arg ); - tVector operator*( float arg ); - tVector operator/( float arg ); - tVector operator*=( float arg ); - tVector operator/=( float arg ); -}; - -inline float DotProd(tVector &v1, tVector &v2) { tVector v = v1 * v2; return v.x + v.y + v.z + v.w; } -inline float Length2(tVector &v) { return DotProd(v, v); } -inline float Length(tVector &v) { return sqrtf(DotProd(v, v)); } -inline float rLength(tVector &v) { return 1.0f / Length(v); } -inline tVector Normalize(tVector &v) { return (Length2(v) > 0.0f) ? v * rLength(v) : v; } - -struct tVector3 -{ - float x,y,z; -public: - tVector3() { x = y = z = 0; } - tVector3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } - tVector3(tVector3&_v) { x = _v.x; y = _v.y; z = _v.z; } - ~tVector3() {} - -public: - void Zero() { x = 0.0f; y = 0.0f; z = 0.0f; } - void CrossProduct(tVector3 &v1, tVector3 &v2); - float Length2(); - float Length(); - void NormalizeVector(); - void Lerp(tVector3 *v,float factor); - float Dot(tVector3 *v); - float Dot(tVector3 &v); - float Dot(float vx, float vy, float vz); - void MultVectorByMatrix(float *mat); - void MultVectorByRotMatrix(float *mat); - tVector3 operator+( tVector3 &arg ) { tVector3 ret(x + arg.x, y + arg.y, z + arg.z); return ret; } - tVector3 operator-( tVector3 &arg ) { tVector3 ret(x - arg.x, y - arg.y, z - arg.z); return ret; } - tVector3 operator-( tVector &arg ) { tVector3 ret(x - arg.x, y - arg.y, z - arg.z); return ret; } - tVector3 operator=( tVector3 &arg ) { x = arg.x; y = arg.y; z = arg.z; return *this; } - tVector3 operator=( tVector &arg ) { x = arg.x; y = arg.y; z = arg.z; return *this; } - tVector3 operator*( tVector3 &arg ) { tVector3 ret(x * arg.x, y * arg.y, z * arg.z); return ret; } - tVector3 operator=( float *arg ); - tVector3 operator+=( tVector3 &arg ); - tVector3 operator-=( tVector3 &arg ); - tVector3 operator*( float arg ); - tVector3 operator/( float arg ); - tVector3 operator*=( float arg ); - tVector3 operator/=( float arg ); - tVector3 operator-() { return *this * -1.0f;} -}; - -/// Quaternion Definitions //////////////////////////////////////////////////// -struct tQuaternion : public tVector -{ - tQuaternion() : tVector() { } -}; -/////////////////////////////////////////////////////////////////////////////// - -tVector3 CrossProduct(tVector3 &v1, tVector3 &v2); -inline float DotProd(tVector3 &v1, tVector3 &v2) { tVector3 v = v1 * v2; return v.x + v.y + v.z; } -inline float Length2(tVector3 &v) { return DotProd(v, v); } -inline float Length(tVector3 &v) { return sqrtf(DotProd(v, v)); } -inline float rLength(tVector3 &v) { return 1.0f / Length(v); } -inline tVector3 Normalize(tVector3 &v) { return (Length2(v) > 0.0f) ? v * rLength(v) : v; } - -typedef struct -{ - float r; - float g; - float b; - float a; -} tColor; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void IdentityMatrix(tMatrix *mat); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.1415926 +#define HALF_PI 1.5707963 +#define PI_TIMES_TWO 6.2831852 +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +#define MAX(a,b) ((a > b) ? a : b) +#define MIN(a,b) ((a < b) ? a : b) +/////////////////////////////////////////////////////////////////////////////// +typedef unsigned char uchar; + +typedef int BOOL; +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned char byte; + +typedef struct +{ + float u,v; +} t2DCoord; + +struct tVector +{ + float x,y,z,w; +public: + tVector() { x = y = z = 0.0f; w = 1.0f; } + tVector(tVector &_v) { x = _v.x; y = _v.y; z = _v.z; w = _v.w; } + tVector(float _x, float _y, float _z, float _w = 1.0f) { x = _x; y = _y; z = _z; w = _w; } + ~tVector() {} + +public: + + void Zero() { x = 0.0f; y = 0.0f; z = 0.0f; w = 0.0f; } + void CrossProduct(tVector &v1, tVector &v2); + float Length2(); + float Length(); + void NormalizeVector(); + void Lerp(tVector *v,float factor); + float Dot(tVector *v); + float Dot(tVector &v); + float Dot(float vx, float vy, float vz, float vw); + void MultVectorByMatrix(float *mat); + void MultVectorByRotMatrix(float *mat); + tVector operator+( tVector &arg ) { tVector ret(x + arg.x, y + arg.y, z + arg.z, w + arg.w); return ret; } + tVector operator-( tVector &arg ) { tVector ret(x - arg.x, y - arg.y, z - arg.z, w - arg.w); return ret; } + tVector operator=( tVector &arg ) { x = arg.x; y = arg.y; z = arg.z; w = arg.w; return *this; } + tVector operator*( tVector &arg ) { tVector ret(x * arg.x, y * arg.y, z * arg.z, w * arg.w); return ret; } + tVector operator=( float *arg ); + tVector operator+=( tVector &arg ); + tVector operator-=( tVector &arg ); + tVector operator*( float arg ); + tVector operator/( float arg ); + tVector operator*=( float arg ); + tVector operator/=( float arg ); +}; + +inline float DotProd(tVector &v1, tVector &v2) { tVector v = v1 * v2; return v.x + v.y + v.z + v.w; } +inline float Length2(tVector &v) { return DotProd(v, v); } +inline float Length(tVector &v) { return sqrtf(DotProd(v, v)); } +inline float rLength(tVector &v) { return 1.0f / Length(v); } +inline tVector Normalize(tVector &v) { return (Length2(v) > 0.0f) ? v * rLength(v) : v; } + +struct tVector3 +{ + float x,y,z; +public: + tVector3() { x = y = z = 0; } + tVector3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } + tVector3(tVector3&_v) { x = _v.x; y = _v.y; z = _v.z; } + ~tVector3() {} + +public: + void Zero() { x = 0.0f; y = 0.0f; z = 0.0f; } + void CrossProduct(tVector3 &v1, tVector3 &v2); + float Length2(); + float Length(); + void NormalizeVector(); + void Lerp(tVector3 *v,float factor); + float Dot(tVector3 *v); + float Dot(tVector3 &v); + float Dot(float vx, float vy, float vz); + void MultVectorByMatrix(float *mat); + void MultVectorByRotMatrix(float *mat); + tVector3 operator+( tVector3 &arg ) { tVector3 ret(x + arg.x, y + arg.y, z + arg.z); return ret; } + tVector3 operator-( tVector3 &arg ) { tVector3 ret(x - arg.x, y - arg.y, z - arg.z); return ret; } + tVector3 operator-( tVector &arg ) { tVector3 ret(x - arg.x, y - arg.y, z - arg.z); return ret; } + tVector3 operator=( tVector3 &arg ) { x = arg.x; y = arg.y; z = arg.z; return *this; } + tVector3 operator=( tVector &arg ) { x = arg.x; y = arg.y; z = arg.z; return *this; } + tVector3 operator*( tVector3 &arg ) { tVector3 ret(x * arg.x, y * arg.y, z * arg.z); return ret; } + tVector3 operator=( float *arg ); + tVector3 operator+=( tVector3 &arg ); + tVector3 operator-=( tVector3 &arg ); + tVector3 operator*( float arg ); + tVector3 operator/( float arg ); + tVector3 operator*=( float arg ); + tVector3 operator/=( float arg ); + tVector3 operator-() { return *this * -1.0f;} +}; + +/// Quaternion Definitions //////////////////////////////////////////////////// +struct tQuaternion : public tVector +{ + tQuaternion() : tVector() { } +}; +/////////////////////////////////////////////////////////////////////////////// + +tVector3 CrossProduct(tVector3 &v1, tVector3 &v2); +inline float DotProd(tVector3 &v1, tVector3 &v2) { tVector3 v = v1 * v2; return v.x + v.y + v.z; } +inline float Length2(tVector3 &v) { return DotProd(v, v); } +inline float Length(tVector3 &v) { return sqrtf(DotProd(v, v)); } +inline float rLength(tVector3 &v) { return 1.0f / Length(v); } +inline tVector3 Normalize(tVector3 &v) { return (Length2(v) > 0.0f) ? v * rLength(v) : v; } + +typedef struct +{ + float r; + float g; + float b; + float a; +} tColor; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void IdentityMatrix(tMatrix *mat); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Pool Table Physics/Code/OGL/Pool/Pool.cpp b/Pool Table Physics/Code/OGL/Pool/Pool.cpp index e3bd5a2..b0d10df 100644 --- a/Pool Table Physics/Code/OGL/Pool/Pool.cpp +++ b/Pool Table Physics/Code/OGL/Pool/Pool.cpp @@ -1,456 +1,456 @@ -///////////////////////////////////////////////////////////////////////////////////// -// Pool.c -// This is the application shell for the Pool simulator -// -// The code base was pulled from the OpenGL Super Bible. -// Great book that I highly recommend -// -// Created: -// JL 9/5/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -// Include files -#include // Window defines -#include // Include for sqrt() -#include // OpenGL -#include // GLU library -#include "resource.h" // About box and other resource identifiers. -#include "externs.h" -#include -#include - - -/////////////////////////////////////////////////////////////////////////// -// Declaration of shared handles, etc. These are declared as externs in the -// header file externs.h -HWND g_hViewWnd = NULL; -HWND g_hMainWnd = NULL; - -HPALETTE hPalette = NULL; - -// Class Names for all the window classes in this application -static LPCTSTR lpszMainWndClass = "MainClass"; -static LPCTSTR lpszViewWndClass = "ViewClass"; - - -// Application name and instance storeage -static LPCTSTR lpszAppName = "GL Pool"; -static HINSTANCE hInstance; - - -// Declaration for Window procedures -// Defined in this file (Pool.c) -LRESULT CALLBACK WndProcMain(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -// Declaration for Window procedure -// See ViewWnd.c -LRESULT CALLBACK WndProcView(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - - -// Dialog procedure for about box -BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam); -BOOL BuildClasses(void); - -float g_LastTime = 0; -int g_SimRunning = TRUE; -long g_TimeIterations = 10; -int g_UseFixedTimeStep = FALSE; -float g_MaxTimeStep = 0.01f; - -///////////////////////////////////////////////////////////////////////////////////// -// Global Variables -///////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Create the window classes. Returns FALSE if any errors occur -BOOL BuildClasses(void) -{ - WNDCLASS wc; // Windows class structure - - // Register window style for the main window - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC) WndProcMain; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - - // No need for background brush for this window - wc.hbrBackground = NULL; - - wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); - wc.lpszClassName = lpszMainWndClass; - - // Register the window class - if(RegisterClass(&wc) == 0) - return FALSE; - - - // Register window style for the main view window - // This is a window OpenGL will render in - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) WndProcView; - - // May want to change the cursor - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - - // No need for background brush for this window - // Delete me later - wc.hbrBackground = NULL; - wc.lpszClassName = lpszViewWndClass; - - // Register the window class - if(RegisterClass(&wc) == 0) - return FALSE; - - return TRUE; -} - -float GetTime( void ) -{ - static long StartMilliseconds; - long CurrentMilliseconds; - if(!StartMilliseconds) - { - // yes, the first time through will be a 0 timestep - StartMilliseconds = timeGetTime(); - } - - CurrentMilliseconds = timeGetTime(); - return (float)(CurrentMilliseconds - StartMilliseconds) / 1000.0f; -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: RunSim -// Purpose: Actual simulation loop -// Notes: Allows you to adjust the rate of simulation or to change it -// to fixed time steps or actual timesteps. -/////////////////////////////////////////////////////////////////////////////// -void RunSim() -{ -/// Local Variables /////////////////////////////////////////////////////////// - float Time; - float DeltaTime; -/////////////////////////////////////////////////////////////////////////////// - - if (g_UseFixedTimeStep) - Time = g_LastTime + (g_MaxTimeStep * g_TimeIterations); - else - Time = GetTime(); - - if (g_SimRunning) - { - while(g_LastTime < Time) - { - DeltaTime = Time - g_LastTime; - if(DeltaTime > g_MaxTimeStep) - { - DeltaTime = g_MaxTimeStep; - } - - Simulate(DeltaTime,g_SimRunning); - g_LastTime += DeltaTime; - } - g_LastTime = Time; - } - else - { - DeltaTime = 0; - Simulate(DeltaTime,g_SimRunning); - } - RenderWorld(); -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Entry point of all Windows programs -int APIENTRY WinMain( HINSTANCE hInst, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - MSG msg; // Windows message structure - - // Variable is scoped to this file - hInstance = hInst; - - - // Create the window classes for the main window and the - // children - if(!BuildClasses()) - return FALSE; - - // Initializes the world geography - if(!InitGame()) - return FALSE; - - // Create the main application window - g_hMainWnd = CreateWindow( - lpszMainWndClass, - lpszAppName, - WS_OVERLAPPEDWINDOW, - 0, 0, // Size and dimensions of window - 640, 480, - NULL, - NULL, - hInstance, - NULL); - - // Display the window - ShowWindow(g_hMainWnd,SW_SHOW); - UpdateWindow(g_hMainWnd); - - // Process application messages until the application closes - for (;;) - { - if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) - { - if (msg.message == WM_QUIT) - break; - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - RunSim(); - } - } - - return msg.wParam; -} - - - -/////////////////////////////////////////////////////////////////////////////// -// Window procedure, handles all top messages for this program -LRESULT CALLBACK WndProcMain(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - switch (message) - { - // Window creation, setup here - case WM_CREATE: - { - HANDLE hMenu = GetMenu(hWnd); - - // Set initial menu check state - CheckMenuItem((HMENU)hMenu,ID_USE_FRICTION,MF_BYCOMMAND | MF_CHECKED); - - - // Create the child windows - // View Window - g_hViewWnd = CreateWindow( - lpszViewWndClass, - NULL, - WS_DLGFRAME | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS| WS_VISIBLE, - 0, 0, - 10, 10, - hWnd, - NULL, - hInstance, - NULL); - - g_LastTime = GetTime(); - } - break; - - // Window is being destroyed, cleanup - case WM_DESTROY: - - // Tell the application to terminate after the window - // is gone. - PostQuitMessage(0); - break; - - // Window is resized. - // This is really only going to be called once. Why resize here - // instead of just creating the windows where we want them? Because - // changes to the GUI may change the size of borders, etc. This - // code should continue to work regardless of any changes to the - // GUI. - case WM_SIZE: - { - RECT clientRect; - int width,height; - - GetClientRect(g_hMainWnd,&clientRect); - - // Position the viewing window - width = clientRect.right - clientRect.left; - height = (clientRect.bottom*2)/5; - MoveWindow(g_hViewWnd,0,0, - width,clientRect.bottom-clientRect.top,TRUE); - - } - break; - - // Windows is telling the application that it may modify - // the system palette. This message in essance asks the - // application for a new palette. - case WM_QUERYNEWPALETTE: - // Pass the message to the OpenGL Windows, none of the other - // Windows use anything outside the standard set of colors - PostMessage(g_hViewWnd,message,wParam,lParam); - break; - - - // This window may set the palette, even though it is not the - // currently active window. - case WM_PALETTECHANGED: - // Pass the message to the OpenGL Windows, none of the other - // Windows use anything outside the standard 16 colors - PostMessage(g_hViewWnd,message,wParam,lParam); - break; - - // Catch and handle the arrow keys for movement - case WM_KEYDOWN: - { - switch(wParam) - { - case VK_UP: // Up arrow, move forward - { - - if (g_POV.rot.x > 0.0f) g_POV.rot.x -= 1.0; - // Invalidate the view window (compass doesn't change) - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - } - - case VK_DOWN: // Down arrow, move backward - { - - if (g_POV.rot.x < 90.0f) g_POV.rot.x += 1.0; - // Invalidate the view window (compass doesn't change) - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - } - - case VK_LEFT: // Left arrow, turn left - { - g_POV.rot.y += 1.0; - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - } - - case VK_RIGHT: // Right Arrow, turn right - { - g_POV.rot.y -= 1.0; - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - } - case VK_PRIOR: // PGUP Zoom Out - { - - if (g_POV.trans.z > 1.0f) g_POV.trans.z -= 1.0; - // Invalidate the view window (compass doesn't change) - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - } - case VK_NEXT: // PGDN Zoom In - { - - if (g_POV.trans.z < 9.0f) g_POV.trans.z += 1.0; - // Invalidate the view window (compass doesn't change) - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - } - } - } - break; - - // A menu command - case WM_COMMAND: - { - HANDLE hMenu = GetMenu(hWnd); - - switch(LOWORD(wParam)) - { - // Exit the program - case ID_FILE_EXIT: - DestroyWindow(hWnd); - break; - - // Display the about box - case ID_HELP_ABOUT: - DialogBox (hInstance, - MAKEINTRESOURCE(IDD_DIALOG_ABOUT), - hWnd, - AboutDlgProc); - break; - - // Turn On/Off Friction - case ID_USE_FRICTION: - g_UseFriction = !g_UseFriction; - if (g_UseFriction) - { - CheckMenuItem((HMENU)hMenu,ID_USE_FRICTION,MF_BYCOMMAND | MF_CHECKED); - } - else - CheckMenuItem((HMENU)hMenu,ID_USE_FRICTION,MF_BYCOMMAND | MF_UNCHECKED); - - InvalidateRect(g_hViewWnd,NULL,FALSE); - break; - - } - } - break; - - - default: // Passes it on if unproccessed - return (DefWindowProc(hWnd, message, wParam, lParam)); - - } - - return (0L); -} - - - -/////////////////////////////////////////////////////////////////////////// -// Dialog procedure -BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) -{ - switch (message) - { - // Process command messages - case WM_COMMAND: - { - // Validate and Make the changes - if(LOWORD(wParam) == IDOK) - EndDialog(hDlg,TRUE); - } - break; - - // Closed from sysbox - case WM_CLOSE: - EndDialog(hDlg,TRUE); - break; - } - return FALSE; -} - - - - - - - - +///////////////////////////////////////////////////////////////////////////////////// +// Pool.c +// This is the application shell for the Pool simulator +// +// The code base was pulled from the OpenGL Super Bible. +// Great book that I highly recommend +// +// Created: +// JL 9/5/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +// Include files +#include // Window defines +#include // Include for sqrt() +#include // OpenGL +#include // GLU library +#include "resource.h" // About box and other resource identifiers. +#include "externs.h" +#include +#include + + +/////////////////////////////////////////////////////////////////////////// +// Declaration of shared handles, etc. These are declared as externs in the +// header file externs.h +HWND g_hViewWnd = NULL; +HWND g_hMainWnd = NULL; + +HPALETTE hPalette = NULL; + +// Class Names for all the window classes in this application +static LPCTSTR lpszMainWndClass = "MainClass"; +static LPCTSTR lpszViewWndClass = "ViewClass"; + + +// Application name and instance storeage +static LPCTSTR lpszAppName = "GL Pool"; +static HINSTANCE hInstance; + + +// Declaration for Window procedures +// Defined in this file (Pool.c) +LRESULT CALLBACK WndProcMain(HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam); + +// Declaration for Window procedure +// See ViewWnd.c +LRESULT CALLBACK WndProcView(HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam); + + +// Dialog procedure for about box +BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam); +BOOL BuildClasses(void); + +float g_LastTime = 0; +int g_SimRunning = TRUE; +long g_TimeIterations = 10; +int g_UseFixedTimeStep = FALSE; +float g_MaxTimeStep = 0.01f; + +///////////////////////////////////////////////////////////////////////////////////// +// Global Variables +///////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Create the window classes. Returns FALSE if any errors occur +BOOL BuildClasses(void) +{ + WNDCLASS wc; // Windows class structure + + // Register window style for the main window + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC) WndProcMain; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + + // No need for background brush for this window + wc.hbrBackground = NULL; + + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); + wc.lpszClassName = lpszMainWndClass; + + // Register the window class + if(RegisterClass(&wc) == 0) + return FALSE; + + + // Register window style for the main view window + // This is a window OpenGL will render in + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC) WndProcView; + + // May want to change the cursor + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + + // No need for background brush for this window + // Delete me later + wc.hbrBackground = NULL; + wc.lpszClassName = lpszViewWndClass; + + // Register the window class + if(RegisterClass(&wc) == 0) + return FALSE; + + return TRUE; +} + +float GetTime( void ) +{ + static long StartMilliseconds; + long CurrentMilliseconds; + if(!StartMilliseconds) + { + // yes, the first time through will be a 0 timestep + StartMilliseconds = timeGetTime(); + } + + CurrentMilliseconds = timeGetTime(); + return (float)(CurrentMilliseconds - StartMilliseconds) / 1000.0f; +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: RunSim +// Purpose: Actual simulation loop +// Notes: Allows you to adjust the rate of simulation or to change it +// to fixed time steps or actual timesteps. +/////////////////////////////////////////////////////////////////////////////// +void RunSim() +{ +/// Local Variables /////////////////////////////////////////////////////////// + float Time; + float DeltaTime; +/////////////////////////////////////////////////////////////////////////////// + + if (g_UseFixedTimeStep) + Time = g_LastTime + (g_MaxTimeStep * g_TimeIterations); + else + Time = GetTime(); + + if (g_SimRunning) + { + while(g_LastTime < Time) + { + DeltaTime = Time - g_LastTime; + if(DeltaTime > g_MaxTimeStep) + { + DeltaTime = g_MaxTimeStep; + } + + Simulate(DeltaTime,g_SimRunning); + g_LastTime += DeltaTime; + } + g_LastTime = Time; + } + else + { + DeltaTime = 0; + Simulate(DeltaTime,g_SimRunning); + } + RenderWorld(); +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Entry point of all Windows programs +int APIENTRY WinMain( HINSTANCE hInst, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + MSG msg; // Windows message structure + + // Variable is scoped to this file + hInstance = hInst; + + + // Create the window classes for the main window and the + // children + if(!BuildClasses()) + return FALSE; + + // Initializes the world geography + if(!InitGame()) + return FALSE; + + // Create the main application window + g_hMainWnd = CreateWindow( + lpszMainWndClass, + lpszAppName, + WS_OVERLAPPEDWINDOW, + 0, 0, // Size and dimensions of window + 640, 480, + NULL, + NULL, + hInstance, + NULL); + + // Display the window + ShowWindow(g_hMainWnd,SW_SHOW); + UpdateWindow(g_hMainWnd); + + // Process application messages until the application closes + for (;;) + { + if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) + break; + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + { + RunSim(); + } + } + + return msg.wParam; +} + + + +/////////////////////////////////////////////////////////////////////////////// +// Window procedure, handles all top messages for this program +LRESULT CALLBACK WndProcMain(HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + switch (message) + { + // Window creation, setup here + case WM_CREATE: + { + HANDLE hMenu = GetMenu(hWnd); + + // Set initial menu check state + CheckMenuItem((HMENU)hMenu,ID_USE_FRICTION,MF_BYCOMMAND | MF_CHECKED); + + + // Create the child windows + // View Window + g_hViewWnd = CreateWindow( + lpszViewWndClass, + NULL, + WS_DLGFRAME | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS| WS_VISIBLE, + 0, 0, + 10, 10, + hWnd, + NULL, + hInstance, + NULL); + + g_LastTime = GetTime(); + } + break; + + // Window is being destroyed, cleanup + case WM_DESTROY: + + // Tell the application to terminate after the window + // is gone. + PostQuitMessage(0); + break; + + // Window is resized. + // This is really only going to be called once. Why resize here + // instead of just creating the windows where we want them? Because + // changes to the GUI may change the size of borders, etc. This + // code should continue to work regardless of any changes to the + // GUI. + case WM_SIZE: + { + RECT clientRect; + int width,height; + + GetClientRect(g_hMainWnd,&clientRect); + + // Position the viewing window + width = clientRect.right - clientRect.left; + height = (clientRect.bottom*2)/5; + MoveWindow(g_hViewWnd,0,0, + width,clientRect.bottom-clientRect.top,TRUE); + + } + break; + + // Windows is telling the application that it may modify + // the system palette. This message in essance asks the + // application for a new palette. + case WM_QUERYNEWPALETTE: + // Pass the message to the OpenGL Windows, none of the other + // Windows use anything outside the standard set of colors + PostMessage(g_hViewWnd,message,wParam,lParam); + break; + + + // This window may set the palette, even though it is not the + // currently active window. + case WM_PALETTECHANGED: + // Pass the message to the OpenGL Windows, none of the other + // Windows use anything outside the standard 16 colors + PostMessage(g_hViewWnd,message,wParam,lParam); + break; + + // Catch and handle the arrow keys for movement + case WM_KEYDOWN: + { + switch(wParam) + { + case VK_UP: // Up arrow, move forward + { + + if (g_POV.rot.x > 0.0f) g_POV.rot.x -= 1.0; + // Invalidate the view window (compass doesn't change) + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + } + + case VK_DOWN: // Down arrow, move backward + { + + if (g_POV.rot.x < 90.0f) g_POV.rot.x += 1.0; + // Invalidate the view window (compass doesn't change) + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + } + + case VK_LEFT: // Left arrow, turn left + { + g_POV.rot.y += 1.0; + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + } + + case VK_RIGHT: // Right Arrow, turn right + { + g_POV.rot.y -= 1.0; + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + } + case VK_PRIOR: // PGUP Zoom Out + { + + if (g_POV.trans.z > 1.0f) g_POV.trans.z -= 1.0; + // Invalidate the view window (compass doesn't change) + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + } + case VK_NEXT: // PGDN Zoom In + { + + if (g_POV.trans.z < 9.0f) g_POV.trans.z += 1.0; + // Invalidate the view window (compass doesn't change) + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + } + } + } + break; + + // A menu command + case WM_COMMAND: + { + HANDLE hMenu = GetMenu(hWnd); + + switch(LOWORD(wParam)) + { + // Exit the program + case ID_FILE_EXIT: + DestroyWindow(hWnd); + break; + + // Display the about box + case ID_HELP_ABOUT: + DialogBox (hInstance, + MAKEINTRESOURCE(IDD_DIALOG_ABOUT), + hWnd, + AboutDlgProc); + break; + + // Turn On/Off Friction + case ID_USE_FRICTION: + g_UseFriction = !g_UseFriction; + if (g_UseFriction) + { + CheckMenuItem((HMENU)hMenu,ID_USE_FRICTION,MF_BYCOMMAND | MF_CHECKED); + } + else + CheckMenuItem((HMENU)hMenu,ID_USE_FRICTION,MF_BYCOMMAND | MF_UNCHECKED); + + InvalidateRect(g_hViewWnd,NULL,FALSE); + break; + + } + } + break; + + + default: // Passes it on if unproccessed + return (DefWindowProc(hWnd, message, wParam, lParam)); + + } + + return (0L); +} + + + +/////////////////////////////////////////////////////////////////////////// +// Dialog procedure +BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) +{ + switch (message) + { + // Process command messages + case WM_COMMAND: + { + // Validate and Make the changes + if(LOWORD(wParam) == IDOK) + EndDialog(hDlg,TRUE); + } + break; + + // Closed from sysbox + case WM_CLOSE: + EndDialog(hDlg,TRUE); + break; + } + return FALSE; +} + + + + + + + + diff --git a/Pool Table Physics/Code/OGL/Pool/RENDERWORLD.cpp b/Pool Table Physics/Code/OGL/Pool/RENDERWORLD.cpp index 35f3d31..eca235b 100644 --- a/Pool Table Physics/Code/OGL/Pool/RENDERWORLD.cpp +++ b/Pool Table Physics/Code/OGL/Pool/RENDERWORLD.cpp @@ -1,414 +1,414 @@ -///////////////////////////////////////////////////////////////////////////////////// -// RenderWorld.c -// This file actually renders the world complete with balls and cuestick -// -// The code base was pulled from the OpenGL Super Bible. -// Great book that I highly recommend -// -// Created: -// JL 9/5/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include // Normal Windows stuff -#include -#include -#include // Core OpenGL functions -#include // OpenGL Utility functions -#include -#include "externs.h" // Data shared between files -#include "loadtga.h" // Routines to load the texture files -#include "Models.h" // Actual Geometry for balls and cue - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define OGL_WBALL_DLIST 2 // OPENGL LIST FOR WHITE BALL -#define OGL_YBALL_DLIST 3 // OPENGL LIST FOR YELLOW BALL -#define OGL_CUE_DLIST 4 // OPENGL LIST FOR CUE STICK - -#define ART_PATH "art/" -#define MAX_TEXTURES 255 - -typedef struct s_TexPool -{ - char map[255]; - GLuint glTex; - byte *data; - int type; -}t_TexPool; - -// A Polygon can be Quad or Triangle -typedef struct { - t2DCoord t1[4],t2[4]; - uint TexNdx1; - uint TexNdx2; - unsigned short index[4]; - long type; - long color[4]; // RGB VERTEX COLOR -} tPrimPoly; - -// A Scene consisting for Triangles and Quads -typedef struct -{ - long vertexCnt; - tVector3 *vertex; - long triCnt,quadCnt; - tPrimPoly *tri,*quad; - char map[255]; -} t_Visual; - -t_Camera g_POV; // Camera for View -int g_TextureCnt; // Number of Textures loaded -t_TexPool g_TexPool[MAX_TEXTURES]; // Place to store texture info -t_Visual g_Scene; // Actual Scene - -void LoadTextures(); -void LoadSceneFile(char *filename); -void RenderScene(); - -//////////////////////////////////////////////////////////////////////////////// -// Initialize the Render System -//////////////////////////////////////////////////////////////////////////////// -void InitRender(void) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - - // Initialize position of the Point of View - g_POV.trans.x = 0.0f; - g_POV.trans.y = 0.0f; - g_POV.trans.z = 8.0f; - g_POV.rot.x = 20.0f; - g_POV.rot.y = 90.0f; - g_POV.rot.z = 0.0f; - - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glNewList(OGL_WBALL_DLIST,GL_COMPILE); - // Declare the Array of Data - glInterleavedArrays(WBALLFORMAT,0,(GLvoid *)&WBALLMODEL); - - // This doesn't work on my TNT 2 - // glDrawArrays(GL_TRIANGLES,0,WBALLPOLYCNT * 3); - - // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER - glBegin(GL_TRIANGLES); - for (loop = 0; loop < WBALLPOLYCNT * 3; loop++) - { - glArrayElement(loop); - } - glEnd(); - glEndList(); - - glNewList(OGL_YBALL_DLIST,GL_COMPILE); - // Declare the Array of Data - glInterleavedArrays(YBALLFORMAT,0,(GLvoid *)&YBALLMODEL); - - // This doesn't work on my TNT 2 - // glDrawArrays(GL_TRIANGLES,0,YBALLPOLYCNT * 3); - - // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER - glBegin(GL_TRIANGLES); - for (loop = 0; loop < YBALLPOLYCNT * 3; loop++) - { - glArrayElement(loop); - } - glEnd(); - glEndList(); - - glNewList(OGL_CUE_DLIST,GL_COMPILE); - // Declare the Array of Data - glInterleavedArrays(CUEFORMAT,0,(GLvoid *)&CUEMODEL); - - // This doesn't work on my TNT 2 - // glDrawArrays(GL_TRIANGLES,0,YBALLPOLYCNT * 3); - - // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER - glBegin(GL_TRIANGLES); - for (loop = 0; loop < CUEPOLYCNT * 3; loop++) - { - glArrayElement(loop); - } - glEnd(); - glEndList(); - - LoadTextures(); - - LoadSceneFile("Pool.ros"); // Load the Scene Data -} - -#define NUM_TEXTURES 8 - -static char TextureFiles[NUM_TEXTURES][80] = { - "DogPoker.tga", - "Wood.tga", - "NewCastle.tga", - "Guinness.tga", - "Felt.tga", - "Stucco.tga", - "Harp.tga", - "Carpet.tga" -}; - -///////////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadTextures -// Purpose: Load all the TGA files in a directory and store them in a texture pool -///////////////////////////////////////////////////////////////////////////////////// -void LoadTextures() -{ - GLubyte *rgb; /* Bitmap RGB pixels */ - char texName[80]; - tTGAHeader_s tgaHeader; - HANDLE specHandle; - WIN32_FIND_DATA fileData; - int rv; - - // LOAD THE LIST OF FILE NAMES - g_TextureCnt = 0; - sprintf(texName,"%s*.tga",ART_PATH); - int i; - for (i = 0; i < 8; i++) - { - sprintf(g_TexPool[g_TextureCnt].map,"%s%s",ART_PATH,TextureFiles[i]); - // GENERATE THE OPENGL TEXTURE ID - glGenTextures(1,&g_TexPool[g_TextureCnt].glTex); - - rgb = LoadTGAFile( g_TexPool[g_TextureCnt].map,&tgaHeader); - if (rgb == NULL) - { - MessageBox(NULL,"Unable to Open File...",g_TexPool[g_TextureCnt].map,MB_OK); - g_TexPool[g_TextureCnt].glTex = 0; - return; - } - - glBindTexture(GL_TEXTURE_2D, g_TexPool[g_TextureCnt].glTex); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - - /* - * Define the 2D texture image. - */ - - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); /* Force 4-byte alignment */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - - if (tgaHeader.d_pixel_size == 32) - { - glTexImage2D(GL_TEXTURE_2D, 0, 4, tgaHeader.d_width, tgaHeader.d_height, 0, - GL_RGBA , GL_UNSIGNED_BYTE, rgb); - rv = gluBuild2DMipmaps( GL_TEXTURE_2D, 4, tgaHeader.d_width, tgaHeader.d_height, - GL_RGBA, GL_UNSIGNED_BYTE, rgb ); - } - else - { - glTexImage2D(GL_TEXTURE_2D, 0, 3, tgaHeader.d_width, tgaHeader.d_height, 0, - GL_RGB, GL_UNSIGNED_BYTE, rgb); - rv = gluBuild2DMipmaps( GL_TEXTURE_2D, 3, tgaHeader.d_width, tgaHeader.d_height, GL_RGB, - GL_UNSIGNED_BYTE, rgb ); - } - /* - *Free the bitmap and RGB images, then return 0 (no errors). - */ - - free(rgb); - - g_TextureCnt++; - } -} - -void LoadSceneFile(char *filename) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; - char tempstr[80]; - t_Visual *visual; -/////////////////////////////////////////////////////////////////////////////// - - fp = fopen(filename,"rb"); - if (fp != NULL) - { - fread(tempstr,1,4,fp); // FDAT - if (strncmp(tempstr,"ROSC",4)!= 0) - { - MessageBox(NULL,"Not a Valid Data File","Load File", MB_OK|MB_ICONEXCLAMATION); - return; - } - - visual = &g_Scene; - - fread(&visual->vertexCnt,sizeof(long),1,fp); - - visual->vertex = (tVector3 *)malloc(sizeof(tVector3) * visual->vertexCnt); - fread(visual->vertex,sizeof(tVector3),visual->vertexCnt,fp); - - fread(&visual->triCnt,sizeof(long),1,fp); - - visual->tri = (tPrimPoly *)malloc(sizeof(tPrimPoly) * (visual->triCnt)); - fread(visual->tri,sizeof(tPrimPoly),visual->triCnt,fp); - - fread(&visual->quadCnt,sizeof(long),1,fp); - - visual->quad = (tPrimPoly *)malloc(sizeof(tPrimPoly) * (visual->quadCnt)); - fread(visual->quad,sizeof(tPrimPoly),visual->quadCnt,fp); - - fclose(fp); - } -} - -// TODO: If I add more billiard balls, this will need some work. Assumes two. -void RenderCueAndBalls() -{ - // Draw the White Ball - glPushMatrix(); - glTranslatef(g_CurrentSys[0].pos.x,g_CurrentSys[0].pos.y,g_CurrentSys[0].pos.z); - glCallList(OGL_WBALL_DLIST); - glPopMatrix(); - - // Draw the White Ball - glPushMatrix(); - glTranslatef(g_CurrentSys[1].pos.x,g_CurrentSys[1].pos.y,g_CurrentSys[1].pos.z); - glCallList(OGL_YBALL_DLIST); - glPopMatrix(); - - // Draw the Cue Stick - glPushMatrix(); - glTranslatef(g_CueStick.pos.x,g_CueStick.pos.y,g_CueStick.pos.z); - glRotatef(g_CueStick.yaw, 0.0f, 1.0f, 0.0f); - glRotatef(-5.0f, 1.0f, 0.0f, 0.0f); // Tilt it back a little for looks - glTranslatef(0,0,g_CueStick.draw); - glCallList(OGL_CUE_DLIST); - glPopMatrix(); -} - -void RenderScene() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2; - t_Visual *visual; // IN THIS CASE THE DATA IS COLOR VERTICES - tPrimPoly *poly; -////////////////////////////////////////////////////////////////////////////// - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE - - visual = &g_Scene; - for (loop2 = 0; loop2 < g_TextureCnt; loop2++) - { - poly = visual->quad; - glBindTexture(GL_TEXTURE_2D, g_TexPool[loop2].glTex); - - for (loop = 0; loop < visual->quadCnt; loop++) - { - if ((poly->type & POLY_TEXTURED) > 0 && poly->TexNdx1 == (uint)loop2) - { - glBegin(GL_QUADS); - glTexCoord2fv((float *)&poly->t1[0]); - glColor3ubv((unsigned char *)&poly->color[0]); - glVertex3fv((float *)&visual->vertex[poly->index[0]]); - glTexCoord2fv((float *)&poly->t1[1]); - glColor3ubv((unsigned char *)&poly->color[1]); - glVertex3fv((float *)&visual->vertex[poly->index[1]]); - glTexCoord2fv((float *)&poly->t1[2]); - glColor3ubv((unsigned char *)&poly->color[2]); - glVertex3fv((float *)&visual->vertex[poly->index[2]]); - glTexCoord2fv((float *)&poly->t1[3]); - glColor3ubv((unsigned char *)&poly->color[3]); - glVertex3fv((float *)&visual->vertex[poly->index[3]]); - glEnd(); - } - poly++; - } - - poly = visual->tri; - for (loop = 0; loop < visual->triCnt; loop++) - { - if ((poly->type & POLY_TEXTURED) > 0 && poly->TexNdx1 == (uint)loop2) - { - glBegin(GL_TRIANGLES); - glTexCoord2fv((float *)&poly->t1[0]); - glColor3ubv((unsigned char *)&poly->color[0]); - glVertex3fv((float *)&visual->vertex[poly->index[0]]); - glTexCoord2fv((float *)&poly->t1[1]); - glColor3ubv((unsigned char *)&poly->color[1]); - glVertex3fv((float *)&visual->vertex[poly->index[1]]); - glTexCoord2fv((float *)&poly->t1[2]); - glColor3ubv((unsigned char *)&poly->color[2]); - glVertex3fv((float *)&visual->vertex[poly->index[2]]); - glEnd(); - } - poly++; - } - } - glDisable(GL_TEXTURE_2D); -} - -//////////////////////////////////////////////////////////////////////////////// -// Render the entire scene -//////////////////////////////////////////////////////////////////////////////// -void RenderWorld(void) -{ - // Clear the window with current clearing color - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - - g_CueStick.yaw = -g_POV.rot.y; // Set the Cue To be centered on my view - - // Set root skeleton's orientation and position - glTranslatef(-g_POV.trans.x, -g_POV.trans.y, -g_POV.trans.z); - - glRotatef(g_POV.rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(g_POV.rot.x, 1.0f, 0.0f, 0.0f); - glRotatef(g_POV.rot.y, 0.0f, 1.0f, 0.0f); - - glTranslatef(-g_CueStick.pos.x, -g_CueStick.pos.y, -g_CueStick.pos.z); -// glTranslatef(0,-TABLE_POSITION,0); - - RenderScene(); // Draw the actual Scene - - RenderCueAndBalls(); - - glPopMatrix(); - - SwapBuffers(g_hDC); -} - +///////////////////////////////////////////////////////////////////////////////////// +// RenderWorld.c +// This file actually renders the world complete with balls and cuestick +// +// The code base was pulled from the OpenGL Super Bible. +// Great book that I highly recommend +// +// Created: +// JL 9/5/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include // Normal Windows stuff +#include +#include +#include // Core OpenGL functions +#include // OpenGL Utility functions +#include +#include "externs.h" // Data shared between files +#include "loadtga.h" // Routines to load the texture files +#include "Models.h" // Actual Geometry for balls and cue + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define OGL_WBALL_DLIST 2 // OPENGL LIST FOR WHITE BALL +#define OGL_YBALL_DLIST 3 // OPENGL LIST FOR YELLOW BALL +#define OGL_CUE_DLIST 4 // OPENGL LIST FOR CUE STICK + +#define ART_PATH "art/" +#define MAX_TEXTURES 255 + +typedef struct s_TexPool +{ + char map[255]; + GLuint glTex; + byte *data; + int type; +}t_TexPool; + +// A Polygon can be Quad or Triangle +typedef struct { + t2DCoord t1[4],t2[4]; + uint TexNdx1; + uint TexNdx2; + unsigned short index[4]; + long type; + long color[4]; // RGB VERTEX COLOR +} tPrimPoly; + +// A Scene consisting for Triangles and Quads +typedef struct +{ + long vertexCnt; + tVector3 *vertex; + long triCnt,quadCnt; + tPrimPoly *tri,*quad; + char map[255]; +} t_Visual; + +t_Camera g_POV; // Camera for View +int g_TextureCnt; // Number of Textures loaded +t_TexPool g_TexPool[MAX_TEXTURES]; // Place to store texture info +t_Visual g_Scene; // Actual Scene + +void LoadTextures(); +void LoadSceneFile(char *filename); +void RenderScene(); + +//////////////////////////////////////////////////////////////////////////////// +// Initialize the Render System +//////////////////////////////////////////////////////////////////////////////// +void InitRender(void) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + + // Initialize position of the Point of View + g_POV.trans.x = 0.0f; + g_POV.trans.y = 0.0f; + g_POV.trans.z = 8.0f; + g_POV.rot.x = 20.0f; + g_POV.rot.y = 90.0f; + g_POV.rot.z = 0.0f; + + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glNewList(OGL_WBALL_DLIST,GL_COMPILE); + // Declare the Array of Data + glInterleavedArrays(WBALLFORMAT,0,(GLvoid *)&WBALLMODEL); + + // This doesn't work on my TNT 2 + // glDrawArrays(GL_TRIANGLES,0,WBALLPOLYCNT * 3); + + // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER + glBegin(GL_TRIANGLES); + for (loop = 0; loop < WBALLPOLYCNT * 3; loop++) + { + glArrayElement(loop); + } + glEnd(); + glEndList(); + + glNewList(OGL_YBALL_DLIST,GL_COMPILE); + // Declare the Array of Data + glInterleavedArrays(YBALLFORMAT,0,(GLvoid *)&YBALLMODEL); + + // This doesn't work on my TNT 2 + // glDrawArrays(GL_TRIANGLES,0,YBALLPOLYCNT * 3); + + // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER + glBegin(GL_TRIANGLES); + for (loop = 0; loop < YBALLPOLYCNT * 3; loop++) + { + glArrayElement(loop); + } + glEnd(); + glEndList(); + + glNewList(OGL_CUE_DLIST,GL_COMPILE); + // Declare the Array of Data + glInterleavedArrays(CUEFORMAT,0,(GLvoid *)&CUEMODEL); + + // This doesn't work on my TNT 2 + // glDrawArrays(GL_TRIANGLES,0,YBALLPOLYCNT * 3); + + // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER + glBegin(GL_TRIANGLES); + for (loop = 0; loop < CUEPOLYCNT * 3; loop++) + { + glArrayElement(loop); + } + glEnd(); + glEndList(); + + LoadTextures(); + + LoadSceneFile("Pool.ros"); // Load the Scene Data +} + +#define NUM_TEXTURES 8 + +static char TextureFiles[NUM_TEXTURES][80] = { + "DogPoker.tga", + "Wood.tga", + "NewCastle.tga", + "Guinness.tga", + "Felt.tga", + "Stucco.tga", + "Harp.tga", + "Carpet.tga" +}; + +///////////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadTextures +// Purpose: Load all the TGA files in a directory and store them in a texture pool +///////////////////////////////////////////////////////////////////////////////////// +void LoadTextures() +{ + GLubyte *rgb; /* Bitmap RGB pixels */ + char texName[80]; + tTGAHeader_s tgaHeader; + HANDLE specHandle; + WIN32_FIND_DATA fileData; + int rv; + + // LOAD THE LIST OF FILE NAMES + g_TextureCnt = 0; + sprintf(texName,"%s*.tga",ART_PATH); + int i; + for (i = 0; i < 8; i++) + { + sprintf(g_TexPool[g_TextureCnt].map,"%s%s",ART_PATH,TextureFiles[i]); + // GENERATE THE OPENGL TEXTURE ID + glGenTextures(1,&g_TexPool[g_TextureCnt].glTex); + + rgb = LoadTGAFile( g_TexPool[g_TextureCnt].map,&tgaHeader); + if (rgb == NULL) + { + MessageBox(NULL,"Unable to Open File...",g_TexPool[g_TextureCnt].map,MB_OK); + g_TexPool[g_TextureCnt].glTex = 0; + return; + } + + glBindTexture(GL_TEXTURE_2D, g_TexPool[g_TextureCnt].glTex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + /* + * Define the 2D texture image. + */ + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); /* Force 4-byte alignment */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + + if (tgaHeader.d_pixel_size == 32) + { + glTexImage2D(GL_TEXTURE_2D, 0, 4, tgaHeader.d_width, tgaHeader.d_height, 0, + GL_RGBA , GL_UNSIGNED_BYTE, rgb); + rv = gluBuild2DMipmaps( GL_TEXTURE_2D, 4, tgaHeader.d_width, tgaHeader.d_height, + GL_RGBA, GL_UNSIGNED_BYTE, rgb ); + } + else + { + glTexImage2D(GL_TEXTURE_2D, 0, 3, tgaHeader.d_width, tgaHeader.d_height, 0, + GL_RGB, GL_UNSIGNED_BYTE, rgb); + rv = gluBuild2DMipmaps( GL_TEXTURE_2D, 3, tgaHeader.d_width, tgaHeader.d_height, GL_RGB, + GL_UNSIGNED_BYTE, rgb ); + } + /* + *Free the bitmap and RGB images, then return 0 (no errors). + */ + + free(rgb); + + g_TextureCnt++; + } +} + +void LoadSceneFile(char *filename) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; + char tempstr[80]; + t_Visual *visual; +/////////////////////////////////////////////////////////////////////////////// + + fp = fopen(filename,"rb"); + if (fp != NULL) + { + fread(tempstr,1,4,fp); // FDAT + if (strncmp(tempstr,"ROSC",4)!= 0) + { + MessageBox(NULL,"Not a Valid Data File","Load File", MB_OK|MB_ICONEXCLAMATION); + return; + } + + visual = &g_Scene; + + fread(&visual->vertexCnt,sizeof(long),1,fp); + + visual->vertex = (tVector3 *)malloc(sizeof(tVector3) * visual->vertexCnt); + fread(visual->vertex,sizeof(tVector3),visual->vertexCnt,fp); + + fread(&visual->triCnt,sizeof(long),1,fp); + + visual->tri = (tPrimPoly *)malloc(sizeof(tPrimPoly) * (visual->triCnt)); + fread(visual->tri,sizeof(tPrimPoly),visual->triCnt,fp); + + fread(&visual->quadCnt,sizeof(long),1,fp); + + visual->quad = (tPrimPoly *)malloc(sizeof(tPrimPoly) * (visual->quadCnt)); + fread(visual->quad,sizeof(tPrimPoly),visual->quadCnt,fp); + + fclose(fp); + } +} + +// TODO: If I add more billiard balls, this will need some work. Assumes two. +void RenderCueAndBalls() +{ + // Draw the White Ball + glPushMatrix(); + glTranslatef(g_CurrentSys[0].pos.x,g_CurrentSys[0].pos.y,g_CurrentSys[0].pos.z); + glCallList(OGL_WBALL_DLIST); + glPopMatrix(); + + // Draw the White Ball + glPushMatrix(); + glTranslatef(g_CurrentSys[1].pos.x,g_CurrentSys[1].pos.y,g_CurrentSys[1].pos.z); + glCallList(OGL_YBALL_DLIST); + glPopMatrix(); + + // Draw the Cue Stick + glPushMatrix(); + glTranslatef(g_CueStick.pos.x,g_CueStick.pos.y,g_CueStick.pos.z); + glRotatef(g_CueStick.yaw, 0.0f, 1.0f, 0.0f); + glRotatef(-5.0f, 1.0f, 0.0f, 0.0f); // Tilt it back a little for looks + glTranslatef(0,0,g_CueStick.draw); + glCallList(OGL_CUE_DLIST); + glPopMatrix(); +} + +void RenderScene() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2; + t_Visual *visual; // IN THIS CASE THE DATA IS COLOR VERTICES + tPrimPoly *poly; +////////////////////////////////////////////////////////////////////////////// + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE + + visual = &g_Scene; + for (loop2 = 0; loop2 < g_TextureCnt; loop2++) + { + poly = visual->quad; + glBindTexture(GL_TEXTURE_2D, g_TexPool[loop2].glTex); + + for (loop = 0; loop < visual->quadCnt; loop++) + { + if ((poly->type & POLY_TEXTURED) > 0 && poly->TexNdx1 == (uint)loop2) + { + glBegin(GL_QUADS); + glTexCoord2fv((float *)&poly->t1[0]); + glColor3ubv((unsigned char *)&poly->color[0]); + glVertex3fv((float *)&visual->vertex[poly->index[0]]); + glTexCoord2fv((float *)&poly->t1[1]); + glColor3ubv((unsigned char *)&poly->color[1]); + glVertex3fv((float *)&visual->vertex[poly->index[1]]); + glTexCoord2fv((float *)&poly->t1[2]); + glColor3ubv((unsigned char *)&poly->color[2]); + glVertex3fv((float *)&visual->vertex[poly->index[2]]); + glTexCoord2fv((float *)&poly->t1[3]); + glColor3ubv((unsigned char *)&poly->color[3]); + glVertex3fv((float *)&visual->vertex[poly->index[3]]); + glEnd(); + } + poly++; + } + + poly = visual->tri; + for (loop = 0; loop < visual->triCnt; loop++) + { + if ((poly->type & POLY_TEXTURED) > 0 && poly->TexNdx1 == (uint)loop2) + { + glBegin(GL_TRIANGLES); + glTexCoord2fv((float *)&poly->t1[0]); + glColor3ubv((unsigned char *)&poly->color[0]); + glVertex3fv((float *)&visual->vertex[poly->index[0]]); + glTexCoord2fv((float *)&poly->t1[1]); + glColor3ubv((unsigned char *)&poly->color[1]); + glVertex3fv((float *)&visual->vertex[poly->index[1]]); + glTexCoord2fv((float *)&poly->t1[2]); + glColor3ubv((unsigned char *)&poly->color[2]); + glVertex3fv((float *)&visual->vertex[poly->index[2]]); + glEnd(); + } + poly++; + } + } + glDisable(GL_TEXTURE_2D); +} + +//////////////////////////////////////////////////////////////////////////////// +// Render the entire scene +//////////////////////////////////////////////////////////////////////////////// +void RenderWorld(void) +{ + // Clear the window with current clearing color + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + g_CueStick.yaw = -g_POV.rot.y; // Set the Cue To be centered on my view + + // Set root skeleton's orientation and position + glTranslatef(-g_POV.trans.x, -g_POV.trans.y, -g_POV.trans.z); + + glRotatef(g_POV.rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(g_POV.rot.x, 1.0f, 0.0f, 0.0f); + glRotatef(g_POV.rot.y, 0.0f, 1.0f, 0.0f); + + glTranslatef(-g_CueStick.pos.x, -g_CueStick.pos.y, -g_CueStick.pos.z); +// glTranslatef(0,-TABLE_POSITION,0); + + RenderScene(); // Draw the actual Scene + + RenderCueAndBalls(); + + glPopMatrix(); + + SwapBuffers(g_hDC); +} + diff --git a/Pool Table Physics/Code/OGL/Pool/Readme.txt b/Pool Table Physics/Code/OGL/Pool/Readme.txt index d2559b0..240fc75 100644 --- a/Pool Table Physics/Code/OGL/Pool/Readme.txt +++ b/Pool Table Physics/Code/OGL/Pool/Readme.txt @@ -1,77 +1,77 @@ -3D Billiard Physicls Sept 1999 --------------------------------------------------------- -v. 1.0 - -I know this is very late and to top that off it is a work in progress. -Too much real work got in the way of my demos and I got way behind. -The goal was to create a more game like application instead of the -standard tool type MFC interface project. So, I stripped everything out -of the article test app and put a new face on it. - -The program uses a dynamic simulation to handle billiard ball collisions -and friction. One aspect missing right now is the rotational physics. -I decided I wanted to change the matrix method used in the article to -a quaternion model which will be better for future stuff. I haven't yet -had time to integrate all that code in. I will post the update as soon -as all that is in but since people have been asking for what I have... - -I wanted to make the geometry format generic but it was too big a pain. -So it is my own custom. You would have to provide your own models if -you want to change it. At least you can change the textures. - -The balls and cue stick are in the Model.h file as ascii data. The -world is in a proprietary format. No biggy and not real efficient -but it works. Handles both tris and quads in two seperate data lists. - -Thanks to my sister, Christine Lander, for creating the meshes to give -the app some pizzazz. - -I plan on continuing to update this more once I get all caught up. I -was thinking I may release a full billiards game with source to the -community for Christmas. At least that gives me a goal. - -Hope you enjoy. It seems like a pretty cool start to something. -Email me any problems or suggestions. - -Jeff - -How it works. - - Click and drag the Left Mouse Button to line up the cue. - - Click and drag the Right Mouse Button to pull back the stick and drag - forward to shoot. - - -Problems for you to explore: - - Make this into a game.... You know with pockets and score and sound... - - Add some more balls. - - Tackle integrating the rotational effects. It is 90% there already. - - Bumper Collision induced Spin - - Ball to Ball spin transfer - - Add the 3D component to the physics so you can do jumps. - - No solution for tunneling. If you hit things too hard ball-ball collisions may miss. - - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I compiled the code with Visual C++ 6.0. It has been tested -with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL -Drivers, Riva 128, TNT, TNT2, AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX Voodoo series. -3DFX OpenGL that does not support OpenGL in a window will not work -with this application. - +3D Billiard Physicls Sept 1999 +-------------------------------------------------------- +v. 1.0 + +I know this is very late and to top that off it is a work in progress. +Too much real work got in the way of my demos and I got way behind. +The goal was to create a more game like application instead of the +standard tool type MFC interface project. So, I stripped everything out +of the article test app and put a new face on it. + +The program uses a dynamic simulation to handle billiard ball collisions +and friction. One aspect missing right now is the rotational physics. +I decided I wanted to change the matrix method used in the article to +a quaternion model which will be better for future stuff. I haven't yet +had time to integrate all that code in. I will post the update as soon +as all that is in but since people have been asking for what I have... + +I wanted to make the geometry format generic but it was too big a pain. +So it is my own custom. You would have to provide your own models if +you want to change it. At least you can change the textures. + +The balls and cue stick are in the Model.h file as ascii data. The +world is in a proprietary format. No biggy and not real efficient +but it works. Handles both tris and quads in two seperate data lists. + +Thanks to my sister, Christine Lander, for creating the meshes to give +the app some pizzazz. + +I plan on continuing to update this more once I get all caught up. I +was thinking I may release a full billiards game with source to the +community for Christmas. At least that gives me a goal. + +Hope you enjoy. It seems like a pretty cool start to something. +Email me any problems or suggestions. + +Jeff + +How it works. + + Click and drag the Left Mouse Button to line up the cue. + + Click and drag the Right Mouse Button to pull back the stick and drag + forward to shoot. + + +Problems for you to explore: + + Make this into a game.... You know with pockets and score and sound... + + Add some more balls. + + Tackle integrating the rotational effects. It is 90% there already. + + Bumper Collision induced Spin + + Ball to Ball spin transfer + + Add the 3D component to the physics so you can do jumps. + + No solution for tunneling. If you hit things too hard ball-ball collisions may miss. + + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I compiled the code with Visual C++ 6.0. It has been tested +with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL +Drivers, Riva 128, TNT, TNT2, AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX Voodoo series. +3DFX OpenGL that does not support OpenGL in a window will not work +with this application. + diff --git a/Pool Table Physics/Code/OGL/Pool/VIEWWND.cpp b/Pool Table Physics/Code/OGL/Pool/VIEWWND.cpp index 613d05f..50c8b9c 100644 --- a/Pool Table Physics/Code/OGL/Pool/VIEWWND.cpp +++ b/Pool Table Physics/Code/OGL/Pool/VIEWWND.cpp @@ -1,332 +1,332 @@ -// ViewWnd.c -// This file contains the window procedure and code related to the -// view window. This window does the OpenGL rendering of the terrain. - -#include // Normal Windows stuff -#include -#include // Core OpenGL functions -#include // OpenGL Utility functions -#include -#include "externs.h" // Data shared between files - -///////////////////////////////////////////////////////////////////////////////////// -// Global Variables -///////////////////////////////////////////////////////////////////////////////////// - -int g_MouseHitX, g_MouseHitY; // Needed for Mouse Interaction -int g_Dragging = FALSE; -float g_LastYaw, g_LastPitch; -int g_DrawingStick = FALSE; -float g_LastDraw; -HDC g_hDC; // Keep the Device Context - -/////////////////////////////////////////////////////////////////////////////// -// Setup the main view windows Rendering Context -void SetupViewRC(void) -{ - // Black background - glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); - - // Only draw the outside of CW wound objects - glCullFace(GL_BACK); // Cull the back - glFrontFace(GL_CCW); // Counter Clock wise wound is front - glEnable(GL_CULL_FACE); // Enable the culling - - // Do depth testing - glEnable(GL_DEPTH_TEST); - - glDisable(GL_TEXTURE_2D); - - // No lighting - glDisable(GL_LIGHTING); - glDisable(GL_LIGHT0); - - // Enable color tracking -// glEnable(GL_COLOR_MATERIAL); - - // Set Material properties to follow glColor values -// glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); - - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LESS); //GL_LEQUAL - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -} - -// Select the pixel format for a given device context. This function is identical -// to the above, but also supplies a depth buffer -void SetDCDepthPixelFormat(HDC hDC) -{ - int nPixelFormat; - - static PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure - 1, // Version of this structure - PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap) - PFD_SUPPORT_OPENGL | // Support OpenGL calls in window - PFD_DOUBLEBUFFER, // Double buffered - PFD_TYPE_RGBA, // RGBA Color mode - 24, // Want 24bit color - 0,0,0,0,0,0, // Not used to select mode - 0,0, // Not used to select mode - 0,0,0,0,0, // Not used to select mode - // Try to get away with smaller depth buffer to take advantage - // of low end PC accelerator cards - 32, // Size of depth buffer - 0, // Not used to select mode - 0, // Not used to select mode - PFD_MAIN_PLANE, // Draw in main plane - 0, // Not used to select mode - 0,0,0 }; // Not used to select mode - - // Choose a pixel format that best matches that described in pfd - nPixelFormat = ChoosePixelFormat(hDC, &pfd); - - // Set the pixel format for the device context - SetPixelFormat(hDC, nPixelFormat, &pfd); -} - -//////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////// -// Window procedure, handles all messages for this window -LRESULT CALLBACK WndProcView(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ -//// Local Variables //////////////////////////////////////////////////////////////// - int tx,ty; - static HDC hDC; // Keep the Device Context - static HGLRC hRC; // Keep the Rendering Context - float magnitude; -///////////////////////////////////////////////////////////////////////////////////// - - switch (message) - { - // Window creation, setup here - case WM_CREATE: - // Save the device context - hDC = GetDC(hWnd); - - // Set the pixel format - SetDCDepthPixelFormat(hDC); - - // Create the rendering context and make it current - hRC = wglCreateContext(hDC); - wglMakeCurrent(hDC, hRC); - - g_hDC = hDC; - // Do some setup here - SetupViewRC(); - - InitRender(); // Call RenderWorld Routine - - break; - - // Window is being destroyed, cleanup - case WM_DESTROY: - // Cleanup... - // Deselect the current rendering context and delete it - wglMakeCurrent(hDC,NULL); - wglDeleteContext(hRC); - - // Destroy the palette if it was created - if(hPalette != NULL) - DeleteObject(hPalette); - - // Release the device context - ReleaseDC(hWnd,hDC); - break; - - // Window is resized. Setup the viewing transformation - case WM_SIZE: - { - int nWidth,nHeight; - double dAspect; - - nWidth = LOWORD(lParam); // width of client area - nHeight = HIWORD(lParam); // height of client area - - if(nHeight == 0) // Don't allow divide by zero - nHeight = 1; - - dAspect = (double)nWidth/(double)nHeight; - - // Make this rendering context current - wglMakeCurrent(hDC, hRC); - - // Set the viewport to be the entire window - glViewport(0, 0, nWidth, nHeight); - - // Setup Perspective - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // Establish viewing volume - gluPerspective(60.0, dAspect,0.2f, 2000); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - } - break; - - case WM_PAINT: - { - float fRadius = 50.0f; - - RenderWorld(); - - // Validate the newly painted client area - ValidateRect(hWnd,NULL); - } - break; - - - // Windows is telling the application that it may modify - // the system palette. This message in essance asks the - // application for a new palette. - case WM_QUERYNEWPALETTE: - // If the palette was created. - if(hPalette) - { - int nRet; - - // Selects the palette into the current device context - SelectPalette(hDC, hPalette, FALSE); - - // Map entries from the currently selected palette to - // the system palette. The return value is the number - // of palette entries modified. - nRet = RealizePalette(hDC); - - // Repaint, forces remap of palette in current window - InvalidateRect(hWnd,NULL,FALSE); - - return nRet; - } - break; - - - // This window may set the palette, even though it is not the - // currently active window. - case WM_PALETTECHANGED: - // Don't do anything if the palette does not exist, or if - // this is the window that changed the palette. - if((hPalette != NULL) && ((HWND)wParam != hWnd)) - { - // Select the palette into the device context - SelectPalette(hDC,hPalette,FALSE); - - // Map entries to system palette - RealizePalette(hDC); - - // Remap the current colors to the newly realized palette - UpdateColors(hDC); - return 0; - } - break; - - // Handle Left Mouse Button Press - case WM_LBUTTONDOWN: - g_Dragging = TRUE; - g_LastYaw = g_POV.rot.y; // Save the old Yaw - g_LastPitch = g_POV.rot.x; // Save the old Pitch - g_MouseHitX = LOWORD(lParam); // horizontal position of cursor - g_MouseHitY = HIWORD(lParam); // vertical position of cursor - - // Reset Cue Position - g_CueStick.pos.x = g_CurrentSys->pos.x; - g_CueStick.pos.z = g_CurrentSys->pos.z; - SetCapture(hWnd); - break; - - case WM_MOUSEMOVE: - tx = LOWORD(lParam); // horizontal position of cursor - ty = HIWORD(lParam); // vertical position of cursor - if (g_Dragging) - { - if (tx != g_MouseHitX) - { - g_POV.rot.y = g_LastYaw + (float)(tx - g_MouseHitX); - InvalidateRect(hWnd,NULL,FALSE); - } - if (ty != g_MouseHitY) - { - g_POV.rot.x = g_LastPitch + (float)(ty - g_MouseHitY); - if (g_POV.rot.x < 0.0f) g_POV.rot.x = 0.0f; - if (g_POV.rot.x > 90.0f) g_POV.rot.x = 90.0f; - InvalidateRect(hWnd,NULL,FALSE); - } - - } - // Check the Motion of the Cue Stick via right mouse - if (g_DrawingStick && !g_BallInPlay) - { - if (ty != g_MouseHitY) - { - g_CueStick.draw = g_LastDraw + ((float)(ty - g_MouseHitY) * 0.1f); - // Pulling back on the cue stick - if (g_LastDraw < g_CueStick.draw) - { - g_CueStick.old_draw = g_CueStick.draw; - g_CueStick.drawtime = GetTime(); - } - // If the stick is at the ball, it is a hit - else if (g_CueStick.draw < 0.0f) - { - // TODO: Add a Cue Stick hits ball sound here - g_CueHitBall = TRUE; // Set when a Cue hits the ball - magnitude = -CUE_STICK_FORCE * ((g_CueStick.old_draw - g_CueStick.draw) / (GetTime() - g_CueStick.drawtime)); - g_CueForce.x = magnitude * sin(DEGTORAD(g_CueStick.yaw)); - g_CueForce.z = magnitude * cos(DEGTORAD(g_CueStick.yaw)); - g_CueStick.draw = 0.2f; - g_BallInPlay = TRUE; - g_DrawingStick = FALSE; - } - InvalidateRect(hWnd,NULL,FALSE); - } - - } - break; - - // Handle Left Mouse Button Release - case WM_LBUTTONUP: - g_Dragging = FALSE; - ReleaseCapture(); - break; - - // Handle Right Mouse Button Press - case WM_RBUTTONDOWN: - g_DrawingStick = TRUE; - g_LastDraw = g_CueStick.draw; // Save the old Yaw - g_CueStick.old_draw = g_CueStick.draw; // Save the old Yaw - g_MouseHitX = LOWORD(lParam); // horizontal position of cursor - g_MouseHitY = HIWORD(lParam); // vertical position of cursor - // Reset Cue Position - g_CueStick.pos.x = g_CurrentSys->pos.x; - g_CueStick.pos.z = g_CurrentSys->pos.z; - SetCapture(hWnd); - break; - - // Handle Right Mouse Button Release - case WM_RBUTTONUP: - g_DrawingStick = FALSE; - ReleaseCapture(); - break; - - default: // Passes it on if unproccessed - return (DefWindowProc(hWnd, message, wParam, lParam)); - - } - - return (0L); -} - - - +// ViewWnd.c +// This file contains the window procedure and code related to the +// view window. This window does the OpenGL rendering of the terrain. + +#include // Normal Windows stuff +#include +#include // Core OpenGL functions +#include // OpenGL Utility functions +#include +#include "externs.h" // Data shared between files + +///////////////////////////////////////////////////////////////////////////////////// +// Global Variables +///////////////////////////////////////////////////////////////////////////////////// + +int g_MouseHitX, g_MouseHitY; // Needed for Mouse Interaction +int g_Dragging = FALSE; +float g_LastYaw, g_LastPitch; +int g_DrawingStick = FALSE; +float g_LastDraw; +HDC g_hDC; // Keep the Device Context + +/////////////////////////////////////////////////////////////////////////////// +// Setup the main view windows Rendering Context +void SetupViewRC(void) +{ + // Black background + glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); + + // Only draw the outside of CW wound objects + glCullFace(GL_BACK); // Cull the back + glFrontFace(GL_CCW); // Counter Clock wise wound is front + glEnable(GL_CULL_FACE); // Enable the culling + + // Do depth testing + glEnable(GL_DEPTH_TEST); + + glDisable(GL_TEXTURE_2D); + + // No lighting + glDisable(GL_LIGHTING); + glDisable(GL_LIGHT0); + + // Enable color tracking +// glEnable(GL_COLOR_MATERIAL); + + // Set Material properties to follow glColor values +// glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LESS); //GL_LEQUAL + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +} + +// Select the pixel format for a given device context. This function is identical +// to the above, but also supplies a depth buffer +void SetDCDepthPixelFormat(HDC hDC) +{ + int nPixelFormat; + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure + 1, // Version of this structure + PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap) + PFD_SUPPORT_OPENGL | // Support OpenGL calls in window + PFD_DOUBLEBUFFER, // Double buffered + PFD_TYPE_RGBA, // RGBA Color mode + 24, // Want 24bit color + 0,0,0,0,0,0, // Not used to select mode + 0,0, // Not used to select mode + 0,0,0,0,0, // Not used to select mode + // Try to get away with smaller depth buffer to take advantage + // of low end PC accelerator cards + 32, // Size of depth buffer + 0, // Not used to select mode + 0, // Not used to select mode + PFD_MAIN_PLANE, // Draw in main plane + 0, // Not used to select mode + 0,0,0 }; // Not used to select mode + + // Choose a pixel format that best matches that described in pfd + nPixelFormat = ChoosePixelFormat(hDC, &pfd); + + // Set the pixel format for the device context + SetPixelFormat(hDC, nPixelFormat, &pfd); +} + +//////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +// Window procedure, handles all messages for this window +LRESULT CALLBACK WndProcView(HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ +//// Local Variables //////////////////////////////////////////////////////////////// + int tx,ty; + static HDC hDC; // Keep the Device Context + static HGLRC hRC; // Keep the Rendering Context + float magnitude; +///////////////////////////////////////////////////////////////////////////////////// + + switch (message) + { + // Window creation, setup here + case WM_CREATE: + // Save the device context + hDC = GetDC(hWnd); + + // Set the pixel format + SetDCDepthPixelFormat(hDC); + + // Create the rendering context and make it current + hRC = wglCreateContext(hDC); + wglMakeCurrent(hDC, hRC); + + g_hDC = hDC; + // Do some setup here + SetupViewRC(); + + InitRender(); // Call RenderWorld Routine + + break; + + // Window is being destroyed, cleanup + case WM_DESTROY: + // Cleanup... + // Deselect the current rendering context and delete it + wglMakeCurrent(hDC,NULL); + wglDeleteContext(hRC); + + // Destroy the palette if it was created + if(hPalette != NULL) + DeleteObject(hPalette); + + // Release the device context + ReleaseDC(hWnd,hDC); + break; + + // Window is resized. Setup the viewing transformation + case WM_SIZE: + { + int nWidth,nHeight; + double dAspect; + + nWidth = LOWORD(lParam); // width of client area + nHeight = HIWORD(lParam); // height of client area + + if(nHeight == 0) // Don't allow divide by zero + nHeight = 1; + + dAspect = (double)nWidth/(double)nHeight; + + // Make this rendering context current + wglMakeCurrent(hDC, hRC); + + // Set the viewport to be the entire window + glViewport(0, 0, nWidth, nHeight); + + // Setup Perspective + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // Establish viewing volume + gluPerspective(60.0, dAspect,0.2f, 2000); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + } + break; + + case WM_PAINT: + { + float fRadius = 50.0f; + + RenderWorld(); + + // Validate the newly painted client area + ValidateRect(hWnd,NULL); + } + break; + + + // Windows is telling the application that it may modify + // the system palette. This message in essance asks the + // application for a new palette. + case WM_QUERYNEWPALETTE: + // If the palette was created. + if(hPalette) + { + int nRet; + + // Selects the palette into the current device context + SelectPalette(hDC, hPalette, FALSE); + + // Map entries from the currently selected palette to + // the system palette. The return value is the number + // of palette entries modified. + nRet = RealizePalette(hDC); + + // Repaint, forces remap of palette in current window + InvalidateRect(hWnd,NULL,FALSE); + + return nRet; + } + break; + + + // This window may set the palette, even though it is not the + // currently active window. + case WM_PALETTECHANGED: + // Don't do anything if the palette does not exist, or if + // this is the window that changed the palette. + if((hPalette != NULL) && ((HWND)wParam != hWnd)) + { + // Select the palette into the device context + SelectPalette(hDC,hPalette,FALSE); + + // Map entries to system palette + RealizePalette(hDC); + + // Remap the current colors to the newly realized palette + UpdateColors(hDC); + return 0; + } + break; + + // Handle Left Mouse Button Press + case WM_LBUTTONDOWN: + g_Dragging = TRUE; + g_LastYaw = g_POV.rot.y; // Save the old Yaw + g_LastPitch = g_POV.rot.x; // Save the old Pitch + g_MouseHitX = LOWORD(lParam); // horizontal position of cursor + g_MouseHitY = HIWORD(lParam); // vertical position of cursor + + // Reset Cue Position + g_CueStick.pos.x = g_CurrentSys->pos.x; + g_CueStick.pos.z = g_CurrentSys->pos.z; + SetCapture(hWnd); + break; + + case WM_MOUSEMOVE: + tx = LOWORD(lParam); // horizontal position of cursor + ty = HIWORD(lParam); // vertical position of cursor + if (g_Dragging) + { + if (tx != g_MouseHitX) + { + g_POV.rot.y = g_LastYaw + (float)(tx - g_MouseHitX); + InvalidateRect(hWnd,NULL,FALSE); + } + if (ty != g_MouseHitY) + { + g_POV.rot.x = g_LastPitch + (float)(ty - g_MouseHitY); + if (g_POV.rot.x < 0.0f) g_POV.rot.x = 0.0f; + if (g_POV.rot.x > 90.0f) g_POV.rot.x = 90.0f; + InvalidateRect(hWnd,NULL,FALSE); + } + + } + // Check the Motion of the Cue Stick via right mouse + if (g_DrawingStick && !g_BallInPlay) + { + if (ty != g_MouseHitY) + { + g_CueStick.draw = g_LastDraw + ((float)(ty - g_MouseHitY) * 0.1f); + // Pulling back on the cue stick + if (g_LastDraw < g_CueStick.draw) + { + g_CueStick.old_draw = g_CueStick.draw; + g_CueStick.drawtime = GetTime(); + } + // If the stick is at the ball, it is a hit + else if (g_CueStick.draw < 0.0f) + { + // TODO: Add a Cue Stick hits ball sound here + g_CueHitBall = TRUE; // Set when a Cue hits the ball + magnitude = -CUE_STICK_FORCE * ((g_CueStick.old_draw - g_CueStick.draw) / (GetTime() - g_CueStick.drawtime)); + g_CueForce.x = magnitude * sin(DEGTORAD(g_CueStick.yaw)); + g_CueForce.z = magnitude * cos(DEGTORAD(g_CueStick.yaw)); + g_CueStick.draw = 0.2f; + g_BallInPlay = TRUE; + g_DrawingStick = FALSE; + } + InvalidateRect(hWnd,NULL,FALSE); + } + + } + break; + + // Handle Left Mouse Button Release + case WM_LBUTTONUP: + g_Dragging = FALSE; + ReleaseCapture(); + break; + + // Handle Right Mouse Button Press + case WM_RBUTTONDOWN: + g_DrawingStick = TRUE; + g_LastDraw = g_CueStick.draw; // Save the old Yaw + g_CueStick.old_draw = g_CueStick.draw; // Save the old Yaw + g_MouseHitX = LOWORD(lParam); // horizontal position of cursor + g_MouseHitY = HIWORD(lParam); // vertical position of cursor + // Reset Cue Position + g_CueStick.pos.x = g_CurrentSys->pos.x; + g_CueStick.pos.z = g_CurrentSys->pos.z; + SetCapture(hWnd); + break; + + // Handle Right Mouse Button Release + case WM_RBUTTONUP: + g_DrawingStick = FALSE; + ReleaseCapture(); + break; + + default: // Passes it on if unproccessed + return (DefWindowProc(hWnd, message, wParam, lParam)); + + } + + return (0L); +} + + + diff --git a/Pool Table Physics/Code/OGL/Pool/models.h b/Pool Table Physics/Code/OGL/Pool/models.h index 5b2960f..5910941 100644 --- a/Pool Table Physics/Code/OGL/Pool/models.h +++ b/Pool Table Physics/Code/OGL/Pool/models.h @@ -1,836 +1,836 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Geometry for the Cue Stick and Two Balls -// Vertex Colored Triangle Lists -// -/////////////////////////////////////////////////////////////////////////////// -#define WBALLFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define WBALLPOLYCNT 112 -float WBALLMODEL[] = { - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, -0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, -0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.1039f, -0.0431f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, 0.1039f, -0.0431f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, -0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.1039f, -0.0431f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, -0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, -0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.1039f, 0.0431f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, 0.1039f, 0.0431f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, -0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.1039f, 0.0431f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, -0.1039f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, -0.1039f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, -0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, -0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, -0.1039f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, -0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, -0.1039f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, -0.1039f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, -0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, -0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, -0.1039f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, -0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, -0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, -0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, -0.1039f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, -0.1039f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, -0.0735f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, -0.1039f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, -0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, -0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, -0.1039f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, -0.1039f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, -0.0735f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, -0.1039f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, -0.1039f, -0.0431f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, - 0.6980f, 0.6980f, 0.6980f, -0.1039f, -0.0431f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, -0.0735f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, -0.0735f, - 0.0000f, 0.0000f, 0.7216f, -0.1039f, -0.0431f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, -0.0735f, - 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, - 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, -0.1039f, 0.0431f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, - 0.0000f, 0.0000f, 0.7216f, -0.1039f, 0.0431f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, -0.0735f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, -0.0735f, - 0.6980f, 0.6980f, 0.6980f, -0.1039f, 0.0431f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, -0.0735f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, 0.0735f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, 0.0735f, - 0.6980f, 0.6980f, 0.6980f, -0.1039f, -0.0431f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, -0.1039f, -0.0431f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, 0.0735f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, - 0.0000f, 0.0000f, 0.7216f, -0.1039f, -0.0431f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, - 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, 0.0735f, - 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, 0.0735f, - 0.0000f, 0.0000f, 0.7216f, -0.1039f, 0.0431f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, -0.1039f, 0.0431f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, 0.0735f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, - 0.6980f, 0.6980f, 0.6980f, -0.1039f, 0.0431f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, - 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, 0.1039f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, 0.1039f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, 0.0735f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, 0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, 0.1039f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, 0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, 0.1039f, - 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, 0.1039f, - 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, 0.0735f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, 0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, 0.1039f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, - 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, 0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, - 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, 0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, 0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, 0.1039f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, 0.1039f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, 0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, 0.1039f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, 0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, 0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, 0.1039f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, 0.1039f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, 0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, 0.1039f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, 0.1039f, -0.0431f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, - 0.6980f, 0.6980f, 0.6980f, 0.1039f, -0.0431f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, 0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, 0.0735f, - 0.0000f, 0.0000f, 0.7216f, 0.1039f, -0.0431f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, 0.0735f, - 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, - 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, 0.1039f, 0.0431f, 0.0000f, - 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, - 0.0000f, 0.0000f, 0.7216f, 0.1039f, 0.0431f, 0.0000f, - 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, 0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, 0.0735f, - 0.6980f, 0.6980f, 0.6980f, 0.1039f, 0.0431f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, - 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, 0.0735f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, - 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, - 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, -}; - -#define YBALLFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define YBALLPOLYCNT 112 -float YBALLMODEL[] = { - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, -0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, -0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.1039f, -0.0431f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, 0.1039f, -0.0431f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, -0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.1039f, -0.0431f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, -0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, -0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.1039f, 0.0431f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, 0.1039f, 0.0431f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, -0.0735f, - 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.1039f, 0.0431f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, -0.1039f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, -0.1039f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, -0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, -0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, -0.1039f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, -0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, -0.1039f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, -0.1039f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, -0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, -0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, -0.1039f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, -0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, -0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, -0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, -0.1039f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, -0.1039f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, -0.0735f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, -0.1039f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, -0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, -0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, -0.1039f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, -0.1039f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, -0.0735f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, -0.1039f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, -0.1039f, -0.0431f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, - 0.7765f, 0.7843f, 0.0000f, -0.1039f, -0.0431f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, -0.0735f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, -0.0735f, - 0.5490f, 0.0510f, 0.0392f, -0.1039f, -0.0431f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, -0.0735f, - 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, - 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, -0.1039f, 0.0431f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, - 0.5490f, 0.0510f, 0.0392f, -0.1039f, 0.0431f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, -0.0735f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, -0.0735f, - 0.7765f, 0.7843f, 0.0000f, -0.1039f, 0.0431f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, -0.0735f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, 0.0735f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, 0.0735f, - 0.7765f, 0.7843f, 0.0000f, -0.1039f, -0.0431f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, -0.1039f, -0.0431f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, 0.0735f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, - 0.5490f, 0.0510f, 0.0392f, -0.1039f, -0.0431f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, - 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, 0.0735f, - 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, 0.0735f, - 0.5490f, 0.0510f, 0.0392f, -0.1039f, 0.0431f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, -0.1039f, 0.0431f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, 0.0735f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, - 0.7765f, 0.7843f, 0.0000f, -0.1039f, 0.0431f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, 0.1039f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, 0.1039f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, 0.0735f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, 0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, 0.1039f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, 0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, 0.1039f, - 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, 0.1039f, - 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, 0.0735f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, 0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, 0.1039f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, - 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, 0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, 0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, 0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, 0.1039f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, 0.1039f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, 0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, 0.1039f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, 0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, 0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, 0.1039f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, 0.1039f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, 0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, 0.1039f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, - 1.0000f, 1.0000f, 0.0000f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0304f, -0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, 0.1039f, -0.0431f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, - 0.7765f, 0.7843f, 0.0000f, 0.1039f, -0.0431f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, 0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, 0.0735f, - 0.5490f, 0.0510f, 0.0392f, 0.1039f, -0.0431f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, 0.0735f, - 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, - 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, 0.1039f, 0.0431f, 0.0000f, - 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, - 0.5490f, 0.0510f, 0.0392f, 0.1039f, 0.0431f, 0.0000f, - 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, 0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, 0.0735f, - 0.7765f, 0.7843f, 0.0000f, 0.1039f, 0.0431f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, - 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, 0.0735f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, 0.0304f, - 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, - 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, -}; - -#define CUEFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define CUEPOLYCNT 48 -float CUEMODEL[] = { - 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0563f, -0.0563f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0563f, -0.0563f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, 0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, 0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, 0.0563f, -0.0563f, 2.5000f, - 0.8980f, 0.6824f, 0.4745f, 0.0247f, -0.0247f, 0.0187f, - 0.9059f, 0.7137f, 0.5255f, 0.0796f, 0.0000f, 2.5000f, - 0.8980f, 0.6824f, 0.4745f, 0.0247f, -0.0247f, 0.0187f, - 0.9059f, 0.7137f, 0.5255f, 0.0350f, -0.0000f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0350f, -0.0000f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0247f, -0.0247f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0000f, -0.0796f, 2.5000f, - 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0000f, -0.0796f, 2.5000f, - 0.3608f, 0.2549f, 0.0000f, 0.0563f, -0.0563f, 2.5000f, - 0.8980f, 0.6824f, 0.4745f, 0.0563f, -0.0563f, 2.5000f, - 0.8706f, 0.6039f, 0.3451f, -0.0000f, -0.0796f, 2.5000f, - 0.8392f, 0.5098f, 0.1882f, 0.0000f, -0.0350f, 0.0187f, - 0.8980f, 0.6824f, 0.4745f, 0.0563f, -0.0563f, 2.5000f, - 0.8392f, 0.5098f, 0.1882f, 0.0000f, -0.0350f, 0.0187f, - 0.8980f, 0.6824f, 0.4745f, 0.0247f, -0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0247f, -0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0000f, -0.0350f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0563f, -0.0563f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0563f, -0.0563f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, -0.0000f, -0.0796f, 2.5000f, - 0.8706f, 0.6039f, 0.3451f, -0.0000f, -0.0796f, 2.5000f, - 0.8980f, 0.6824f, 0.4745f, -0.0563f, -0.0563f, 2.5000f, - 0.8980f, 0.6824f, 0.4745f, -0.0247f, -0.0247f, 0.0187f, - 0.8706f, 0.6039f, 0.3451f, -0.0000f, -0.0796f, 2.5000f, - 0.8980f, 0.6824f, 0.4745f, -0.0247f, -0.0247f, 0.0187f, - 0.8392f, 0.5098f, 0.1882f, 0.0000f, -0.0350f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0000f, -0.0350f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, -0.0247f, -0.0247f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0796f, 0.0000f, 2.5000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0796f, 0.0000f, 2.5000f, - 0.3608f, 0.2549f, 0.0000f, -0.0563f, -0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0563f, -0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0350f, -0.0000f, 0.0187f, - 0.9059f, 0.7137f, 0.5255f, -0.0563f, -0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0350f, -0.0000f, 0.0187f, - 0.8980f, 0.6824f, 0.4745f, -0.0247f, -0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, -0.0247f, -0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, -0.0350f, -0.0000f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0563f, 0.0563f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0563f, 0.0563f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, -0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0563f, 0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0247f, 0.0247f, 0.0187f, - 0.9059f, 0.7137f, 0.5255f, -0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, -0.0247f, 0.0247f, 0.0187f, - 0.9059f, 0.7137f, 0.5255f, -0.0350f, -0.0000f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, -0.0350f, -0.0000f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, -0.0247f, 0.0247f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.0796f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.0796f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, -0.0563f, 0.0563f, 2.5000f, - 0.9059f, 0.7098f, 0.5216f, -0.0563f, 0.0563f, 2.5000f, - 0.8706f, 0.6039f, 0.3451f, 0.0000f, 0.0796f, 2.5000f, - 0.8667f, 0.5961f, 0.3333f, 0.0000f, 0.0350f, 0.0187f, - 0.9059f, 0.7098f, 0.5216f, -0.0563f, 0.0563f, 2.5000f, - 0.8667f, 0.5961f, 0.3333f, 0.0000f, 0.0350f, 0.0187f, - 0.8902f, 0.6706f, 0.4588f, -0.0247f, 0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, -0.0247f, 0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0000f, 0.0350f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0563f, 0.0563f, 2.5000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0563f, 0.0563f, 2.5000f, - 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.0796f, 2.5000f, - 0.8706f, 0.6039f, 0.3451f, 0.0000f, 0.0796f, 2.5000f, - 0.9059f, 0.7098f, 0.5216f, 0.0563f, 0.0563f, 2.5000f, - 0.8902f, 0.6706f, 0.4588f, 0.0247f, 0.0247f, 0.0187f, - 0.8706f, 0.6039f, 0.3451f, 0.0000f, 0.0796f, 2.5000f, - 0.8902f, 0.6706f, 0.4588f, 0.0247f, 0.0247f, 0.0187f, - 0.8667f, 0.5961f, 0.3333f, 0.0000f, 0.0350f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0000f, 0.0350f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0247f, 0.0247f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, - 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0796f, 0.0000f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, - 0.4863f, 0.3451f, 0.0000f, 0.0796f, 0.0000f, 2.5000f, - 0.4863f, 0.3451f, 0.0000f, 0.0563f, 0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, 0.0563f, 0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, 0.0796f, 0.0000f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, 0.0350f, -0.0000f, 0.0187f, - 0.9059f, 0.7137f, 0.5255f, 0.0563f, 0.0563f, 2.5000f, - 0.9059f, 0.7137f, 0.5255f, 0.0350f, -0.0000f, 0.0187f, - 0.8902f, 0.6706f, 0.4588f, 0.0247f, 0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0247f, 0.0247f, 0.0187f, - 0.3373f, 0.6588f, 0.6588f, 0.0350f, -0.0000f, 0.0187f, - 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, -}; +/////////////////////////////////////////////////////////////////////////////// +// +// Geometry for the Cue Stick and Two Balls +// Vertex Colored Triangle Lists +// +/////////////////////////////////////////////////////////////////////////////// +#define WBALLFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define WBALLPOLYCNT 112 +float WBALLMODEL[] = { + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, -0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, -0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.1039f, -0.0431f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, 0.1039f, -0.0431f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, -0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.1039f, -0.0431f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, -0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, -0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.1039f, 0.0431f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, 0.1039f, 0.0431f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, -0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.1039f, 0.0431f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, -0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, -0.1039f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, -0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, -0.1039f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, -0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, -0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, -0.1039f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, -0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, -0.1039f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, -0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, -0.1039f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, -0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, -0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, -0.1039f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, -0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, -0.0431f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, -0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, -0.0795f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, -0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, -0.1039f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, -0.1039f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, -0.0735f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, -0.1039f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, -0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, -0.1125f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, -0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, -0.1039f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, -0.1039f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, -0.0735f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, -0.1039f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, -0.0304f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, -0.1039f, -0.0431f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, -0.0562f, + 0.6980f, 0.6980f, 0.6980f, -0.1039f, -0.0431f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, -0.0735f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, -0.0735f, + 0.0000f, 0.0000f, 0.7216f, -0.1039f, -0.0431f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, -0.0735f, + 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, + 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, -0.1039f, 0.0431f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, -0.0795f, + 0.0000f, 0.0000f, 0.7216f, -0.1039f, 0.0431f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, -0.0735f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, -0.0735f, + 0.6980f, 0.6980f, 0.6980f, -0.1039f, 0.0431f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, -0.0735f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, -0.1039f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, 0.0735f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, -0.0795f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, 0.0735f, + 0.6980f, 0.6980f, 0.6980f, -0.1039f, -0.0431f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, -0.1039f, -0.0431f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, 0.0735f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, + 0.0000f, 0.0000f, 0.7216f, -0.1039f, -0.0431f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, + 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, 0.0735f, + 0.3765f, 0.3765f, 1.0000f, -0.1125f, 0.0000f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, 0.0735f, + 0.0000f, 0.0000f, 0.7216f, -0.1039f, 0.0431f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, -0.1039f, 0.0431f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, 0.0735f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, + 0.6980f, 0.6980f, 0.6980f, -0.1039f, 0.0431f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, + 0.8196f, 0.8196f, 0.8196f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, -0.1039f, 0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, 0.1039f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, -0.0795f, 0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, 0.1039f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, -0.0431f, 0.0735f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, 0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, 0.1039f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, -0.0431f, 0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, 0.1039f, + 0.3765f, 0.3765f, 1.0000f, -0.0795f, 0.0000f, 0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, 0.1039f, + 0.0000f, 0.0000f, 0.7216f, -0.0735f, 0.0431f, 0.0735f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, 0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, 0.1039f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, + 0.6980f, 0.6980f, 0.6980f, -0.0735f, 0.0431f, 0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, + 0.8196f, 0.8196f, 0.8196f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1039f, 0.0431f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, 0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, -0.0795f, 0.0795f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, 0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, -0.0431f, 0.1039f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, 0.1039f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, 0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, -0.0431f, 0.1039f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, 0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.0000f, 0.0000f, 0.1125f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, 0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.0000f, 0.0431f, 0.1039f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, 0.1039f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, 0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.0000f, 0.0431f, 0.1039f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, -0.1039f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, -0.1039f, 0.0304f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, -0.0795f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, 0.1039f, -0.0431f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, -0.0795f, 0.0562f, + 0.6980f, 0.6980f, 0.6980f, 0.1039f, -0.0431f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, -0.0431f, 0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, 0.0735f, + 0.0000f, 0.0000f, 0.7216f, 0.1039f, -0.0431f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, -0.0431f, 0.0735f, + 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, + 0.3765f, 0.3765f, 1.0000f, 0.1125f, 0.0000f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, 0.1039f, 0.0431f, 0.0000f, + 0.3765f, 0.3765f, 1.0000f, 0.0795f, 0.0000f, 0.0795f, + 0.0000f, 0.0000f, 0.7216f, 0.1039f, 0.0431f, 0.0000f, + 0.0000f, 0.0000f, 0.7216f, 0.0735f, 0.0431f, 0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, 0.0735f, + 0.6980f, 0.6980f, 0.6980f, 0.1039f, 0.0431f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, + 0.6980f, 0.6980f, 0.6980f, 0.0735f, 0.0431f, 0.0735f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, + 0.8196f, 0.8196f, 0.8196f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, + 0.8196f, 0.8196f, 0.8196f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 1.0000f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.1125f, 0.0000f, +}; + +#define YBALLFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define YBALLPOLYCNT 112 +float YBALLMODEL[] = { + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, -0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, -0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.1039f, -0.0431f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, 0.1039f, -0.0431f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, -0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.1039f, -0.0431f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, -0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, -0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.1039f, 0.0431f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, 0.1039f, 0.0431f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, -0.0735f, + 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.1039f, 0.0431f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, -0.1039f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, -0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, -0.1039f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, -0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, -0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, -0.1039f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, -0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, -0.1039f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, -0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, -0.1039f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, -0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, -0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, -0.1039f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, -0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, -0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, -0.0795f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, -0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, -0.1039f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, -0.1039f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, -0.0735f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, -0.1039f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, -0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, -0.1125f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, -0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, -0.1039f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, -0.1039f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, -0.0735f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, -0.1039f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, -0.0795f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, -0.0431f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, -0.1039f, -0.0431f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, -0.0562f, + 0.7765f, 0.7843f, 0.0000f, -0.1039f, -0.0431f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, -0.0735f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, -0.0735f, + 0.5490f, 0.0510f, 0.0392f, -0.1039f, -0.0431f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, -0.0735f, + 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, + 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, -0.1039f, 0.0431f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, -0.0795f, + 0.5490f, 0.0510f, 0.0392f, -0.1039f, 0.0431f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, -0.0735f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, -0.0735f, + 0.7765f, 0.7843f, 0.0000f, -0.1039f, 0.0431f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, -0.0735f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, -0.0562f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, -0.0304f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, 0.0735f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, -0.0795f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, 0.0735f, + 0.7765f, 0.7843f, 0.0000f, -0.1039f, -0.0431f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, -0.1039f, -0.0431f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, 0.0735f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, + 0.5490f, 0.0510f, 0.0392f, -0.1039f, -0.0431f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, + 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, 0.0735f, + 0.9216f, 0.0745f, 0.0627f, -0.1125f, 0.0000f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, 0.0735f, + 0.5490f, 0.0510f, 0.0392f, -0.1039f, 0.0431f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, -0.1039f, 0.0431f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, 0.0735f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, + 0.7765f, 0.7843f, 0.0000f, -0.1039f, 0.0431f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.0000f, -0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, 0.1039f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, -0.0795f, 0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, 0.1039f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, -0.0431f, 0.0735f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, 0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, 0.1039f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, -0.0431f, 0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, 0.1039f, + 0.9216f, 0.0745f, 0.0627f, -0.0795f, 0.0000f, 0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, 0.1039f, + 0.5490f, 0.0510f, 0.0392f, -0.0735f, 0.0431f, 0.0735f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, 0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, 0.1039f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, + 0.7765f, 0.7843f, 0.0000f, -0.0735f, 0.0431f, 0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.0000f, -0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, -0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, 0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, -0.0795f, 0.0795f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, 0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, -0.0431f, 0.1039f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, 0.1039f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, 0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, -0.0431f, 0.1039f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, 0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.0000f, 0.0000f, 0.1125f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, 0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.0000f, 0.0431f, 0.1039f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, 0.1039f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, 0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.0000f, 0.0431f, 0.1039f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0795f, 0.0795f, + 1.0000f, 1.0000f, 0.0000f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1039f, 0.0431f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, -0.1125f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, -0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0304f, -0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, -0.0795f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, 0.1039f, -0.0431f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, -0.0795f, 0.0562f, + 0.7765f, 0.7843f, 0.0000f, 0.1039f, -0.0431f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, -0.0431f, 0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, 0.0735f, + 0.5490f, 0.0510f, 0.0392f, 0.1039f, -0.0431f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, -0.0431f, 0.0735f, + 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, + 0.9216f, 0.0745f, 0.0627f, 0.1125f, 0.0000f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, 0.1039f, 0.0431f, 0.0000f, + 0.9216f, 0.0745f, 0.0627f, 0.0795f, 0.0000f, 0.0795f, + 0.5490f, 0.0510f, 0.0392f, 0.1039f, 0.0431f, 0.0000f, + 0.5490f, 0.0510f, 0.0392f, 0.0735f, 0.0431f, 0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, 0.0735f, + 0.7765f, 0.7843f, 0.0000f, 0.1039f, 0.0431f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, + 0.7765f, 0.7843f, 0.0000f, 0.0735f, 0.0431f, 0.0735f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.0000f, 0.0795f, 0.0795f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.0000f, 0.0562f, 0.0795f, 0.0562f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0304f, 0.1039f, 0.0304f, + 1.0000f, 1.0000f, 0.3765f, 0.0431f, 0.1039f, 0.0000f, + 1.0000f, 1.0000f, 0.3765f, 0.0000f, 0.1125f, 0.0000f, +}; + +#define CUEFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define CUEPOLYCNT 48 +float CUEMODEL[] = { + 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0563f, -0.0563f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0563f, -0.0563f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, 0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, 0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, 0.0563f, -0.0563f, 2.5000f, + 0.8980f, 0.6824f, 0.4745f, 0.0247f, -0.0247f, 0.0187f, + 0.9059f, 0.7137f, 0.5255f, 0.0796f, 0.0000f, 2.5000f, + 0.8980f, 0.6824f, 0.4745f, 0.0247f, -0.0247f, 0.0187f, + 0.9059f, 0.7137f, 0.5255f, 0.0350f, -0.0000f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0350f, -0.0000f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0247f, -0.0247f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0000f, -0.0796f, 2.5000f, + 0.3608f, 0.2549f, 0.0000f, 0.0795f, -0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0000f, -0.0796f, 2.5000f, + 0.3608f, 0.2549f, 0.0000f, 0.0563f, -0.0563f, 2.5000f, + 0.8980f, 0.6824f, 0.4745f, 0.0563f, -0.0563f, 2.5000f, + 0.8706f, 0.6039f, 0.3451f, -0.0000f, -0.0796f, 2.5000f, + 0.8392f, 0.5098f, 0.1882f, 0.0000f, -0.0350f, 0.0187f, + 0.8980f, 0.6824f, 0.4745f, 0.0563f, -0.0563f, 2.5000f, + 0.8392f, 0.5098f, 0.1882f, 0.0000f, -0.0350f, 0.0187f, + 0.8980f, 0.6824f, 0.4745f, 0.0247f, -0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0247f, -0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0000f, -0.0350f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0563f, -0.0563f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, 0.0000f, -0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0563f, -0.0563f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, -0.0000f, -0.0796f, 2.5000f, + 0.8706f, 0.6039f, 0.3451f, -0.0000f, -0.0796f, 2.5000f, + 0.8980f, 0.6824f, 0.4745f, -0.0563f, -0.0563f, 2.5000f, + 0.8980f, 0.6824f, 0.4745f, -0.0247f, -0.0247f, 0.0187f, + 0.8706f, 0.6039f, 0.3451f, -0.0000f, -0.0796f, 2.5000f, + 0.8980f, 0.6824f, 0.4745f, -0.0247f, -0.0247f, 0.0187f, + 0.8392f, 0.5098f, 0.1882f, 0.0000f, -0.0350f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0000f, -0.0350f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, -0.0247f, -0.0247f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0796f, 0.0000f, 2.5000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, -0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0796f, 0.0000f, 2.5000f, + 0.3608f, 0.2549f, 0.0000f, -0.0563f, -0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0563f, -0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0350f, -0.0000f, 0.0187f, + 0.9059f, 0.7137f, 0.5255f, -0.0563f, -0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0350f, -0.0000f, 0.0187f, + 0.8980f, 0.6824f, 0.4745f, -0.0247f, -0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, -0.0247f, -0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, -0.0350f, -0.0000f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0563f, 0.0563f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, -0.1125f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0563f, 0.0563f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, -0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0563f, 0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0247f, 0.0247f, 0.0187f, + 0.9059f, 0.7137f, 0.5255f, -0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, -0.0247f, 0.0247f, 0.0187f, + 0.9059f, 0.7137f, 0.5255f, -0.0350f, -0.0000f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, -0.0350f, -0.0000f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, -0.0247f, 0.0247f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.0796f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, -0.0795f, 0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.0796f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, -0.0563f, 0.0563f, 2.5000f, + 0.9059f, 0.7098f, 0.5216f, -0.0563f, 0.0563f, 2.5000f, + 0.8706f, 0.6039f, 0.3451f, 0.0000f, 0.0796f, 2.5000f, + 0.8667f, 0.5961f, 0.3333f, 0.0000f, 0.0350f, 0.0187f, + 0.9059f, 0.7098f, 0.5216f, -0.0563f, 0.0563f, 2.5000f, + 0.8667f, 0.5961f, 0.3333f, 0.0000f, 0.0350f, 0.0187f, + 0.8902f, 0.6706f, 0.4588f, -0.0247f, 0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, -0.0247f, 0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0000f, 0.0350f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0563f, 0.0563f, 2.5000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.1125f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0563f, 0.0563f, 2.5000f, + 0.3608f, 0.2549f, 0.0000f, 0.0000f, 0.0796f, 2.5000f, + 0.8706f, 0.6039f, 0.3451f, 0.0000f, 0.0796f, 2.5000f, + 0.9059f, 0.7098f, 0.5216f, 0.0563f, 0.0563f, 2.5000f, + 0.8902f, 0.6706f, 0.4588f, 0.0247f, 0.0247f, 0.0187f, + 0.8706f, 0.6039f, 0.3451f, 0.0000f, 0.0796f, 2.5000f, + 0.8902f, 0.6706f, 0.4588f, 0.0247f, 0.0247f, 0.0187f, + 0.8667f, 0.5961f, 0.3333f, 0.0000f, 0.0350f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0000f, 0.0350f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0247f, 0.0247f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, + 0.3608f, 0.2549f, 0.0000f, -0.0000f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.1125f, 0.0000f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0796f, 0.0000f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, 0.0795f, 0.0795f, 5.0000f, + 0.4863f, 0.3451f, 0.0000f, 0.0796f, 0.0000f, 2.5000f, + 0.4863f, 0.3451f, 0.0000f, 0.0563f, 0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, 0.0563f, 0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, 0.0796f, 0.0000f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, 0.0350f, -0.0000f, 0.0187f, + 0.9059f, 0.7137f, 0.5255f, 0.0563f, 0.0563f, 2.5000f, + 0.9059f, 0.7137f, 0.5255f, 0.0350f, -0.0000f, 0.0187f, + 0.8902f, 0.6706f, 0.4588f, 0.0247f, 0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0247f, 0.0247f, 0.0187f, + 0.3373f, 0.6588f, 0.6588f, 0.0350f, -0.0000f, 0.0187f, + 0.2314f, 0.4471f, 0.4510f, 0.0000f, -0.0000f, -0.0000f, +}; diff --git a/Pool Table Physics/Code/OGL/Pool/resource.h b/Pool Table Physics/Code/OGL/Pool/resource.h index 269bfba..2668717 100644 --- a/Pool Table Physics/Code/OGL/Pool/resource.h +++ b/Pool Table Physics/Code/OGL/Pool/resource.h @@ -1,34 +1,34 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by RESOURCE.RC -// -#define IDR_MENU 101 -#define IDD_DIALOG_ABOUT 102 -#define IDR_TOOLBAR1 104 -#define IDC_OPENGL_VENDOR 1000 -#define IDC_OPENGL_RENDERER 1001 -#define IDC_OPENGL_VERSION 1002 -#define IDC_OPENGL_EXTENSIONS 1003 -#define IDC_GLU_VERSION 1005 -#define IDC_GLU_EXTENSIONS 1006 -#define IDC_ERROR1 1007 -#define IDC_ERROR2 1008 -#define IDC_ERROR3 1009 -#define IDC_ERROR4 1010 -#define IDC_ERROR5 1011 -#define IDC_ERROR6 1012 -#define ID_FILE_EXIT 40001 -#define ID_HELP_ABOUT 40002 -#define ID_BUTTON40003 40003 -#define ID_USE_FRICTION 40004 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 109 -#define _APS_NEXT_COMMAND_VALUE 40011 -#define _APS_NEXT_CONTROL_VALUE 1013 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by RESOURCE.RC +// +#define IDR_MENU 101 +#define IDD_DIALOG_ABOUT 102 +#define IDR_TOOLBAR1 104 +#define IDC_OPENGL_VENDOR 1000 +#define IDC_OPENGL_RENDERER 1001 +#define IDC_OPENGL_VERSION 1002 +#define IDC_OPENGL_EXTENSIONS 1003 +#define IDC_GLU_VERSION 1005 +#define IDC_GLU_EXTENSIONS 1006 +#define IDC_ERROR1 1007 +#define IDC_ERROR2 1008 +#define IDC_ERROR3 1009 +#define IDC_ERROR4 1010 +#define IDC_ERROR5 1011 +#define IDC_ERROR6 1012 +#define ID_FILE_EXIT 40001 +#define ID_HELP_ABOUT 40002 +#define ID_BUTTON40003 40003 +#define ID_USE_FRICTION 40004 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 109 +#define _APS_NEXT_COMMAND_VALUE 40011 +#define _APS_NEXT_CONTROL_VALUE 1013 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.cpp index 9b6c47d..7640417 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.cpp @@ -1,381 +1,381 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Deformation System -// -// Created: -// JL 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "SkinApp.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_VIEW_OUTLINE, OnViewOutline) - ON_UPDATE_COMMAND_UI(ID_VIEW_OUTLINE, OnUpdateViewOutline) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_VIEW_BONESYSTEM, OnViewBonesystem) - ON_UPDATE_COMMAND_UI(ID_VIEW_BONESYSTEM, OnUpdateViewBonesystem) - ON_COMMAND(ID_CONTROL_LOWERARM, OnControlLowerarm) - ON_UPDATE_COMMAND_UI(ID_CONTROL_LOWERARM, OnUpdateControlLowerarm) - ON_COMMAND(ID_CONTROL_UPPERARM, OnControlUpperarm) - ON_UPDATE_COMMAND_UI(ID_CONTROL_UPPERARM, OnUpdateControlUpperarm) - ON_COMMAND(ID_MODIFYWEIGHTS, OnModifyweights) - ON_COMMAND(ID_FILE_NEW, OnFileNew) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_STATUS, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_ROT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_ROTB, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - - InitializeSkeleton(); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Skeleton); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; // PLACE TO PUT THE MESSAGE - char who[80],which[80],version[80]; // OPENGL STUFF -/////////////////////////////////////////////////////////////////////////////// - m_OGLView.GetGLInfo(who,which,version); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s",who,which,version); - MessageBox(message,"Which OpenGL Renderer?",MB_OK); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case 'Q': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnControlLowerarm() -{ - m_OGLView.m_SelectedBone = &m_Skeleton.children[1]; - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnUpdateControlLowerarm(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(m_OGLView.m_SelectedBone == &m_Skeleton.children[1]); -} - -void CMainFrame::OnControlUpperarm() -{ - m_OGLView.m_SelectedBone = &m_Skeleton.children[0]; - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnUpdateControlUpperarm(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(m_OGLView.m_SelectedBone == &m_Skeleton.children[0]); -} - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(FALSE); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -// TOGGLE THE STATUS OF THE VIEW BONESYSTEM FLAG -void CMainFrame::OnViewBonesystem() -{ - m_OGLView.m_DrawBoneSystem = !m_OGLView.m_DrawBoneSystem; - m_OGLView.drawScene(FALSE); -} - -// SET THE CHECKED STATUS OF THE VIEW BONESYSTEM MENU BASED ON STATUS -void CMainFrame::OnUpdateViewBonesystem(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawBoneSystem ); -} - -void CMainFrame::OnViewOutline() -{ - m_OGLView.m_DrawOutline = !m_OGLView.m_DrawOutline; - if (m_OGLView.m_DrawOutline) - glPolygonMode(GL_FRONT,GL_LINE); - else - glPolygonMode(GL_FRONT,GL_FILL); - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnUpdateViewOutline(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawOutline ); -} - - -void CMainFrame::OnModifyweights() -{ - m_OGLView.ModifyWeights(); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *tempBones; -/////////////////////////////////////////////////////////////////////////////// - - // INITIALIZE SOME OF THE SKELETON VARIABLES - // I AM HARD CODING THE ARM BONE SYSTEM FOR NOW - // SO I DON'T NEED TO DEAL WITH FILE LOADING - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.p_trans.x = 2.0f; - m_Skeleton.p_trans.y = 5.0f; - m_Skeleton.p_trans.z = -20.0f; - m_Skeleton.trans.x = 2.0f; - m_Skeleton.trans.y = 5.0f; - m_Skeleton.trans.z = -20.0f; - - // ALLOC ROOM FOR BONES - tempBones = (t_Bone *)malloc(3 * sizeof(t_Bone)); - - m_Skeleton.childCnt = 1; - m_Skeleton.children = tempBones; - - ResetBone(&tempBones[0], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - ResetBone(&tempBones[1], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - ResetBone(&tempBones[2], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - - // THIS IS THE BONE FOR THE UPPER ARM - strcpy(tempBones[0].name,"UpperArm"); - tempBones[0].id = 100; // GIVE IT A UNIQUE ID - tempBones[0].childCnt = 1; - tempBones[0].children = &tempBones[1]; - tempBones[0].trans.x = 0.0; - tempBones[0].trans.y = 0.0; - tempBones[0].rot.x = 0.0; - tempBones[0].rot.y = -90.0; - tempBones[0].rot.z = 0.0; - - // THIS IS THE BONE FOR THE LOWER ARM - strcpy(tempBones[1].name,"LowerArm"); - tempBones[1].id = 101; // GIVE IT A UNIQUE ID - tempBones[1].trans.y = -4.0; - tempBones[1].childCnt = 1; - tempBones[1].children = &tempBones[2]; - - // THIS IS THE BONE FOR THE UPPER ARM - strcpy(tempBones[2].name,"Hand"); - tempBones[2].id = 102; // GIVE IT A UNIQUE ID - tempBones[2].trans.y = -5.0; - tempBones[2].childCnt = 0; - -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnFileNew -// Purpose: Clear the weight settings for the model -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileNew() -{ - m_OGLView.ResetWeights(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnFileOpen -// Purpose: Load the weight settings for the model -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileOpen() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Weight Files (*.WGT)|*.WGT|All Files (*.*)|*.*||"; - char directory[80]; - CFileDialog *dialog; -/////////////////////////////////////////////////////////////////////////////// - // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY - _getcwd(directory,80); - dialog = new CFileDialog(TRUE,"WGT",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - if (!m_OGLView.GetWeights(dialog->GetPathName())) - { - MessageBox("Unable to load Weight File","Error",MB_OK); - } - } - // RESET THE MAIN DIRECTORY - _chdir(directory); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnFileSave -// Purpose: Save the weight settings for the model -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileSave() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Weight Files (*.WGT)|*.WGT|All Files (*.*)|*.*||"; - char directory[80]; - CFileDialog *dialog; -/////////////////////////////////////////////////////////////////////////////// - // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY - _getcwd(directory,80); - dialog = new CFileDialog(FALSE,"WGT",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); - if (dialog->DoModal() == IDOK) - { - if (!m_OGLView.SaveWeights(dialog->GetPathName())) - { - MessageBox("Unable to Save Weight File","Error",MB_OK); - } - } - // RESET THE MAIN DIRECTORY - _chdir(directory); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Deformation System +// +// Created: +// JL 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "SkinApp.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_VIEW_OUTLINE, OnViewOutline) + ON_UPDATE_COMMAND_UI(ID_VIEW_OUTLINE, OnUpdateViewOutline) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_VIEW_BONESYSTEM, OnViewBonesystem) + ON_UPDATE_COMMAND_UI(ID_VIEW_BONESYSTEM, OnUpdateViewBonesystem) + ON_COMMAND(ID_CONTROL_LOWERARM, OnControlLowerarm) + ON_UPDATE_COMMAND_UI(ID_CONTROL_LOWERARM, OnUpdateControlLowerarm) + ON_COMMAND(ID_CONTROL_UPPERARM, OnControlUpperarm) + ON_UPDATE_COMMAND_UI(ID_CONTROL_UPPERARM, OnUpdateControlUpperarm) + ON_COMMAND(ID_MODIFYWEIGHTS, OnModifyweights) + ON_COMMAND(ID_FILE_NEW, OnFileNew) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_STATUS, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_ROT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_ROTB, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + + InitializeSkeleton(); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Skeleton); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; // PLACE TO PUT THE MESSAGE + char who[80],which[80],version[80]; // OPENGL STUFF +/////////////////////////////////////////////////////////////////////////////// + m_OGLView.GetGLInfo(who,which,version); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s",who,which,version); + MessageBox(message,"Which OpenGL Renderer?",MB_OK); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case 'Q': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnControlLowerarm() +{ + m_OGLView.m_SelectedBone = &m_Skeleton.children[1]; + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnUpdateControlLowerarm(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_OGLView.m_SelectedBone == &m_Skeleton.children[1]); +} + +void CMainFrame::OnControlUpperarm() +{ + m_OGLView.m_SelectedBone = &m_Skeleton.children[0]; + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnUpdateControlUpperarm(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_OGLView.m_SelectedBone == &m_Skeleton.children[0]); +} + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(FALSE); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +// TOGGLE THE STATUS OF THE VIEW BONESYSTEM FLAG +void CMainFrame::OnViewBonesystem() +{ + m_OGLView.m_DrawBoneSystem = !m_OGLView.m_DrawBoneSystem; + m_OGLView.drawScene(FALSE); +} + +// SET THE CHECKED STATUS OF THE VIEW BONESYSTEM MENU BASED ON STATUS +void CMainFrame::OnUpdateViewBonesystem(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawBoneSystem ); +} + +void CMainFrame::OnViewOutline() +{ + m_OGLView.m_DrawOutline = !m_OGLView.m_DrawOutline; + if (m_OGLView.m_DrawOutline) + glPolygonMode(GL_FRONT,GL_LINE); + else + glPolygonMode(GL_FRONT,GL_FILL); + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnUpdateViewOutline(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawOutline ); +} + + +void CMainFrame::OnModifyweights() +{ + m_OGLView.ModifyWeights(); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *tempBones; +/////////////////////////////////////////////////////////////////////////////// + + // INITIALIZE SOME OF THE SKELETON VARIABLES + // I AM HARD CODING THE ARM BONE SYSTEM FOR NOW + // SO I DON'T NEED TO DEAL WITH FILE LOADING + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.p_trans.x = 2.0f; + m_Skeleton.p_trans.y = 5.0f; + m_Skeleton.p_trans.z = -20.0f; + m_Skeleton.trans.x = 2.0f; + m_Skeleton.trans.y = 5.0f; + m_Skeleton.trans.z = -20.0f; + + // ALLOC ROOM FOR BONES + tempBones = (t_Bone *)malloc(3 * sizeof(t_Bone)); + + m_Skeleton.childCnt = 1; + m_Skeleton.children = tempBones; + + ResetBone(&tempBones[0], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + ResetBone(&tempBones[1], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + ResetBone(&tempBones[2], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + + // THIS IS THE BONE FOR THE UPPER ARM + strcpy(tempBones[0].name,"UpperArm"); + tempBones[0].id = 100; // GIVE IT A UNIQUE ID + tempBones[0].childCnt = 1; + tempBones[0].children = &tempBones[1]; + tempBones[0].trans.x = 0.0; + tempBones[0].trans.y = 0.0; + tempBones[0].rot.x = 0.0; + tempBones[0].rot.y = -90.0; + tempBones[0].rot.z = 0.0; + + // THIS IS THE BONE FOR THE LOWER ARM + strcpy(tempBones[1].name,"LowerArm"); + tempBones[1].id = 101; // GIVE IT A UNIQUE ID + tempBones[1].trans.y = -4.0; + tempBones[1].childCnt = 1; + tempBones[1].children = &tempBones[2]; + + // THIS IS THE BONE FOR THE UPPER ARM + strcpy(tempBones[2].name,"Hand"); + tempBones[2].id = 102; // GIVE IT A UNIQUE ID + tempBones[2].trans.y = -5.0; + tempBones[2].childCnt = 0; + +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnFileNew +// Purpose: Clear the weight settings for the model +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileNew() +{ + m_OGLView.ResetWeights(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnFileOpen +// Purpose: Load the weight settings for the model +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileOpen() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Weight Files (*.WGT)|*.WGT|All Files (*.*)|*.*||"; + char directory[80]; + CFileDialog *dialog; +/////////////////////////////////////////////////////////////////////////////// + // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY + _getcwd(directory,80); + dialog = new CFileDialog(TRUE,"WGT",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + if (!m_OGLView.GetWeights(dialog->GetPathName())) + { + MessageBox("Unable to load Weight File","Error",MB_OK); + } + } + // RESET THE MAIN DIRECTORY + _chdir(directory); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnFileSave +// Purpose: Save the weight settings for the model +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileSave() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Weight Files (*.WGT)|*.WGT|All Files (*.*)|*.*||"; + char directory[80]; + CFileDialog *dialog; +/////////////////////////////////////////////////////////////////////////////// + // HAD TO ADD DIRECTORY STUFF SINCE DIALOG CHANGES DIRECTORY + _getcwd(directory,80); + dialog = new CFileDialog(FALSE,"WGT",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter); + if (dialog->DoModal() == IDOK) + { + if (!m_OGLView.SaveWeights(dialog->GetPathName())) + { + MessageBox("Unable to Save Weight File","Error",MB_OK); + } + } + // RESET THE MAIN DIRECTORY + _chdir(directory); +} diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.h index 169f763..f4c3166 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/MainFrm.h @@ -1,96 +1,96 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Deformation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnViewOutline(); - afx_msg void OnUpdateViewOutline(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnViewBonesystem(); - afx_msg void OnUpdateViewBonesystem(CCmdUI* pCmdUI); - afx_msg void OnControlLowerarm(); - afx_msg void OnUpdateControlLowerarm(CCmdUI* pCmdUI); - afx_msg void OnControlUpperarm(); - afx_msg void OnUpdateControlUpperarm(CCmdUI* pCmdUI); - afx_msg void OnModifyweights(); - afx_msg void OnFileNew(); - afx_msg void OnFileOpen(); - afx_msg void OnFileSave(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Deformation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnViewOutline(); + afx_msg void OnUpdateViewOutline(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnViewBonesystem(); + afx_msg void OnUpdateViewBonesystem(CCmdUI* pCmdUI); + afx_msg void OnControlLowerarm(); + afx_msg void OnUpdateControlLowerarm(CCmdUI* pCmdUI); + afx_msg void OnControlUpperarm(); + afx_msg void OnUpdateControlUpperarm(CCmdUI* pCmdUI); + afx_msg void OnModifyweights(); + afx_msg void OnFileNew(); + afx_msg void OnFileOpen(); + afx_msg void OnFileSave(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Math.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Math.h index 0f7c9d3..2a20696 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Math.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Math.h @@ -1,66 +1,66 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Math.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATH_H__INCLUDED_) -#define MATH_H__INCLUDED_ - -typedef struct -{ - float x,y,z; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// Math.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATH_H__INCLUDED_) +#define MATH_H__INCLUDED_ + +typedef struct +{ + float x,y,z; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.cpp index b31a902..1943627 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.cpp @@ -1,45 +1,45 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Matrix.cpp : implementation file -// -// Purpose: Implementation of Matrix Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "matrix.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Matrix.cpp : implementation file +// +// Purpose: Implementation of Matrix Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "matrix.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.h index 4c7536a..cb3c900 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Matrix.h @@ -1,39 +1,39 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Matrix.h : Matrix Structure Header File -// -// Purpose: Declare Basic Matrix Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATRIX_H__INCLUDED_) -#define MATRIX_H__INCLUDED_ - -#include "Math.h" // MATH SYSTEM HEADER - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); - -#endif // !defined(MATRIX_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// Matrix.h : Matrix Structure Header File +// +// Purpose: Declare Basic Matrix Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATRIX_H__INCLUDED_) +#define MATRIX_H__INCLUDED_ + +#include "Math.h" // MATH SYSTEM HEADER + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); + +#endif // !defined(MATRIX_H__INCLUDED_) + diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.cpp index 0b7e23d..43ac64f 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.cpp @@ -1,1066 +1,1066 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Deformation System -// -// Created: -// JL 2/18/98 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "SkinApp.h" -#include "OGLView.h" -#include "SetRot.h" -#include "Matrix.h" -#include "Weight.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -// IF YOU WANT TO TRY A QUICKER TWO BONE WEIGHTING SYSTEM UNDEF THIS -#define DEFORM_GENERAL_SOLUTION // FULL MULTI-BONE DEFORMATION -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/// Message Maps ////////////////////////////////////////////////////////////// -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_LBUTTONUP() - ON_WM_RBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_DrawBoneSystem = TRUE; - m_DrawOutline = TRUE; - m_Defmode_TwoBone = TRUE; - m_Skeleton = NULL; - m_SelectedBone = NULL; - m_AnimBlend = 0.0; - LoadObjectFile("Mesh.dgf",&m_Mesh); - - // SET UP THE SELECTION ARRAY FOR PICKING VERTICES - m_SelectFlags = (int *)malloc( sizeof(int) * m_Mesh.desc->pointCnt); - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - m_SelectFlags[loop] = 0; - } -} - -COGLView::~COGLView() -{ - free(m_SelectFlags); - // FREE THE BASE MESH STORAGE - free(m_DeformedMesh); - free(m_Skeleton->children[0].CV_weight); - free(m_Skeleton->children[1].CV_weight); -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - m_Skeleton = skeleton; - - // SET UP THE WEIGHTS FOR THE BONES - // UPPER ARM - m_Skeleton->children[0].CV_weight = (float *)malloc(m_Mesh.desc->pointCnt * sizeof(float)); - // LOWER ARM - m_Skeleton->children[1].CV_weight = (float *)malloc(m_Mesh.desc->pointCnt * sizeof(float)); - // HAND - JUST FOR COMPLETENESS THE INTERFACE DOESN'T SUPPORT - // DEFORMATION OF THE HAND. WEIGHTING DIALOG IS A PAIN IN THE - // BUTT. HOWEVER, IF YOU SET UP THE WEIGHTS IT WOULD WORK - m_Skeleton->children[2].CV_weight = (float *)malloc(m_Mesh.desc->pointCnt * sizeof(float)); - - // SET INITIAL WEIGHT VALUES - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - m_Skeleton->children[0].CV_weight[loop] = 1.0f; - m_Skeleton->children[1].CV_weight[loop] = 0.0f; - // HAND WEIGHTING IS ALWAYS ZERO - m_Skeleton->children[2].CV_weight[loop] = 0.0f; - } - - // PLACE TO STORE BASE MESH POINTS - m_DeformedMesh = (tColoredVertex *)malloc(sizeof(tColoredVertex) * m_Mesh.desc->pointCnt); - memcpy(m_DeformedMesh, m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data,sizeof(tColoredVertex) * m_Mesh.desc->pointCnt); - - // GET A DEFAULT WEIGHT SYSTEM - GetWeights(CString("arm.wgt")); - - UpdateStatus(); // DRAW INITIAL STATUS BAR - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -void COGLView::UpdateStatus() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - - if (m_SelectedBone != NULL) - m_ptrStatusBar->SetPaneText(1,m_SelectedBone->name); - else - m_ptrStatusBar->SetPaneText(1,"*No Bone Selected*"); - - - sprintf(message,"UArm (%.1f,%.1f,%.1f)", - m_Skeleton->children[0].rot.x, - m_Skeleton->children[0].rot.y, - m_Skeleton->children[0].rot.z); - m_ptrStatusBar->SetPaneText(2,message); - - sprintf(message,"LArm (%.1f,%.1f,%.1f)", - m_Skeleton->children[1].rot.x, - m_Skeleton->children[1].rot.y, - m_Skeleton->children[1].rot.z); - m_ptrStatusBar->SetPaneText(3,message); -} - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: CreateBoneDLists -// Purpose: Creates the Drawlists for the Bones in a Skeleton -// Arguments: Pointer to a bone hierarchy -/////////////////////////////////////////////////////////////////////////////// -void COGLView::CreateBoneDLists(t_Bone *bone) -{ - // ONLY MAKE A BONE IF THERE IS A CHILD - if (bone->childCnt > 0) - { - // CREATE THE DISPLAY LIST FOR A BONE - glNewList(bone->id,GL_COMPILE); - glBegin(GL_LINE_STRIP); - glVertex3f( 0.0f, 0.4f, 0.0f); // 0 - glVertex3f(-0.4f, 0.0f,-0.4f); // 1 - glVertex3f( 0.4f, 0.0f,-0.4f); // 2 - glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base - glVertex3f(-0.4f, 0.0f,-0.4f); // 1 - glVertex3f(-0.4f, 0.0f, 0.4f); // 4 - glVertex3f( 0.0f, 0.4f, 0.0f); // 0 - glVertex3f( 0.4f, 0.0f,-0.4f); // 2 - glVertex3f( 0.4f, 0.0f, 0.4f); // 3 - glVertex3f( 0.0f, 0.4f, 0.0f); // 0 - glVertex3f(-0.4f, 0.0f, 0.4f); // 4 - glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base - glVertex3f( 0.4f, 0.0f, 0.4f); // 3 - glVertex3f(-0.4f, 0.0f, 0.4f); // 4 - glEnd(); - glEndList(); - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (bone->childCnt > 0) - CreateBoneDLists(bone->children); - } -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - if (m_Skeleton != NULL) - { - CreateBoneDLists(m_Skeleton->children); - } - drawScene(FALSE); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(35.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(40.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_LINE); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); - glPointSize(4.0); // NICE BEEFY POINTS FOR THE VERTEX SELECTION -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo(char *who,char *which, char *version) -{ - strcpy(who,(char *)::glGetString( GL_VENDOR )); - - strcpy(which,(char *)::glGetString( GL_RENDERER )); - - strcpy(version, (char *)::glGetString( GL_VERSION )); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawModel -// Purpose: Draw the final deformed mesh to the screen -// Arguments: Base bone for mesh, deformed mesh data to draw -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *baseBone, tColoredVertex *deformedMesh) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - - if (deformedMesh != NULL) - { - // THIS MODEL HAS VERTEX COLORS - glInterleavedArrays(GL_C3F_V3F,0,(GLvoid *)deformedMesh); - glDrawArrays(GL_TRIANGLES,0,baseBone->desc->pointCnt); - - // NOW DRAW THE VERTEX MARKERS IF THEY ARE SELECTED - glColor3f(1.0f, 0.0f, 0.0f); // Selected Vertices are Red - glBegin(GL_POINTS); - for (loop = 0; loop < baseBone->desc->pointCnt; loop++) - { - // IF A POINT IS SELECTED DRAW IT - if (m_SelectFlags[loop]) - { - glVertex3f(deformedMesh[loop].x,deformedMesh[loop].y,deformedMesh[loop].z); - } - } - glEnd(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: DeformBone -// Purpose: Deforms a model by the skeleton -// Arguments: Pointer to base bone and original and deformed data -// Notes: This is the general solution version of the deformation. -// It recurses through the skeletal hierarchy and adds the -// influence of each bone. This should work with as many -// bones as you have in the system. I have tried it on a -// model with a 25 bones system and it worked great. -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DeformBone(t_Bone *rootBone, tColoredVertex *meshdata, tColoredVertex *defdata) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,boneloop; - float weight; - tVector pre,post; - t_Bone *curBone; -/////////////////////////////////////////////////////////////////////////////// - // START ON THIS BONES CHILDREN - curBone = rootBone->children; - // GO THROUGH THEM ALL - for (boneloop = 0; boneloop < rootBone->childCnt; boneloop++) - { - // FOR EVERY VERTEX IN MY DEFORMABLE MESH - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - // GET THE WEIGHT - weight = curBone->CV_weight[loop]; - if (weight > 0.0) // ONLY CARE IF IT IS > 0 - { - // OFFSET THE ROTATIONAL CENTER ABOUT THAT BONES CENTER - pre.x = meshdata[loop].x - rootBone->children[boneloop].trans.x; - pre.y = meshdata[loop].y - rootBone->children[boneloop].trans.y; - pre.z = meshdata[loop].z - rootBone->children[boneloop].trans.z; - // PUT IT THROUGH THE ROTATION - MultVectorByMatrix(&rootBone->children[boneloop].matrix, &pre, &post); - // ADD IN THE WEIGHTED DELTA OF THIS POSITION - defdata[loop].x += ((post.x - meshdata[loop].x) * weight); - defdata[loop].y += ((post.y - meshdata[loop].y) * weight); - defdata[loop].z += ((post.z - meshdata[loop].z) * weight); - } - } - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - DeformBone(curBone, meshdata, defdata); - - curBone++; - } -} -///// DeformBone //////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DeformModel -// Purpose: Deforms a model by the skeleton -// Arguments: Pointer to base bone -// Notes: This is a special version for testing. It assumes that -// I only have two bones weighted between them instead of -// a general solution. Since it is not recursive and handles -// multiple bones, it is faster. It simply calculates the -// two possible positions and interpolates between them. -// For some characters this may be better as it is faster. -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DeformModel(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - tVector pre,post1,post2; - tColoredVertex *meshdata; // IN THIS CASE THE DATA IS COLOR VERTICES - tColoredVertex *defdata; // IN THIS CASE THE DATA IS COLOR VERTICES -/////////////////////////////////////////////////////////////////////////////// - // GET A POINTER TO THE ACTUAL VERTEX DATA - meshdata = (tColoredVertex *)m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data; - defdata = m_DeformedMesh; - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - pre.x = meshdata[loop].x - rootBone->children[0].trans.x; - pre.y = meshdata[loop].y - rootBone->children[0].trans.y; - pre.z = meshdata[loop].z - rootBone->children[0].trans.z; - MultVectorByMatrix(&rootBone->children[0].matrix, &pre, &post1); - pre.x = meshdata[loop].x - rootBone->children[1].trans.x; - pre.y = meshdata[loop].y - rootBone->children[1].trans.y; - pre.z = meshdata[loop].z - rootBone->children[1].trans.z; - MultVectorByMatrix(&rootBone->children[1].matrix, &pre, &post2); - defdata[loop].x = post1.x + ((post2.x - post1.x) * rootBone->children[1].CV_weight[loop]); - defdata[loop].y = post1.y + ((post2.y - post1.y) * rootBone->children[1].CV_weight[loop]); - defdata[loop].z = post1.z + ((post2.z - post1.z) * rootBone->children[1].CV_weight[loop]); - } -} -//// DeformModel ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawSkeleton -// Purpose: Actually draws the Skeleton it is recursive -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawSkeleton(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - // Set base orientation and position - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - - // THE SCALE IS LOCAL SO I PUSH AND POP - glPushMatrix(); - glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); - - // DO I WISH TO DISPLAY ANYTHING - if (m_DrawBoneSystem) - { - // DRAW THE AXIS OGL OBJECT - glCallList(OGL_AXIS_DLIST); - // DRAW THE ACTUAL BONE STRUCTURE - // ONLY MAKE A BONE IF THERE IS A CHILD - if (curBone->childCnt > 0) - { - if (curBone == m_SelectedBone) - glColor3f(1.0f, 1.0f, 0.0f); // Selected bone is bright Yellow - else - glColor3f(0.4f, 0.4f, 0.0f); // Selected bone is dull Yellow - // DRAW THE BONE STRUCTURE - glCallList(curBone->id); - } - } - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,curBone->matrix.m); - - glPopMatrix(); // THIS POP IS JUST FOR THE SCALE - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - drawSkeleton(curBone); - - glPopMatrix(); // THIS POPS THE WHOLE MATRIX - - curBone++; - } -} -//// drawSkeleton ///////////////////////////////////////////////////////////// - -GLvoid COGLView::drawScene(BOOL drawSelectRect) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float m[16]; -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; - if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; - if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); - - glRotatef(m_Skeleton->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton->rot.x, 1.0f, 0.0f, 0.0f); - - drawSkeleton(m_Skeleton); - - glPopMatrix(); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m); - - if (m_DrawGeometry) - { -// THIS IS TO ALLOW TESTING ON A SIMPLE TWO BONE CASE -#ifdef DEFORM_GENERAL_SOLUTION - // THE FULL REAL DEFORMATION HANDLES AS MANY BONES AS YOU WANT - // COPY THE ORIGINAL MESH INTO THE DEFORMABLE DATA - memcpy(m_DeformedMesh, m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data,sizeof(tColoredVertex) * m_Mesh.desc->pointCnt); - DeformBone(m_Skeleton, - (tColoredVertex *)m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data, - m_DeformedMesh); -#else - // TEST DEFORMATION FOR WEIGHTING BETWEEN TWO BONES ONLY - DeformModel(m_Skeleton); -#endif - drawModel(&m_Mesh,m_DeformedMesh); - } - - // IF I AM DRAGGING A SELECTION BOX, DRAW IT - if (drawSelectRect) - { - glMatrixMode(GL_PROJECTION); // I WANT TO PLAY WITH THE PROJECTION - glPushMatrix(); // SAVE THE OLD ONE - glLoadIdentity(); // LOAD A NEW ONE - gluOrtho2D(0,m_ScreenWidth,0,m_ScreenHeight); // USE WINDOW SETTINGS - glColor3f(1.0f, 1.0f, 1.0f); // DRAW A WHITE BOX - glBegin(GL_LINE_STRIP); - glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); - glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.top); - glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.bottom); - glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.bottom); - glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); - glEnd(); - glPopMatrix(); // RESTORE THE OLD PROJECTION - glMatrixMode(GL_MODELVIEW); // BACK TO MODEL MODE - } - - glFinish(); - - SwapBuffers(m_hDC); - - // DRAW THE STATS AT THE BOTTOM OF THE SCREEN - UpdateStatus(); -} - - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(FALSE); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); - m_ScreenWidth = cx; - m_ScreenHeight = cy; -} - -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - if (m_SelectedBone != NULL) - { - m_Grab_Rot_X = m_SelectedBone->rot.x; - m_Grab_Rot_Y = m_SelectedBone->rot.y; - m_Grab_Rot_Z = m_SelectedBone->rot.z; - m_Grab_Trans_X = m_Skeleton->trans.x; - m_Grab_Trans_Y = m_Skeleton->trans.y; - m_Grab_Trans_Z = m_Skeleton->trans.z; - } - m_SelectRect.left = point.x; - m_SelectRect.top = m_ScreenHeight - point.y; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - // IF I AM HOLDING THE 'SHIFT' BUTTON PICK VERTICES - if ((nFlags & MK_SHIFT) > 0) - { - SelectVertices(TRUE); - drawScene(FALSE); - } - - CWnd::OnLButtonUp(nFlags, point); -} - -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - if (m_SelectedBone != NULL) - { - m_Grab_Rot_X = m_SelectedBone->rot.x; - m_Grab_Rot_Y = m_SelectedBone->rot.y; - m_Grab_Rot_Z = m_SelectedBone->rot.z; - m_Grab_Trans_X = m_Skeleton->trans.x; - m_Grab_Trans_Y = m_Skeleton->trans.y; - m_Grab_Trans_Z = m_Skeleton->trans.z; - } - m_SelectRect.left = point.x; - m_SelectRect.top = m_ScreenHeight - point.y; - CWnd::OnRButtonDown(nFlags, point); -} - -void COGLView::OnRButtonUp(UINT nFlags, CPoint point) -{ - // IF I AM HOLDING THE 'SHIFT' BUTTON PICK VERTICES - if ((nFlags & MK_SHIFT) > 0) - { - SelectVertices(FALSE); - drawScene(FALSE); - } - - - CWnd::OnRButtonUp(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case 'D': - m_Defmode_TwoBone = !m_Defmode_TwoBone; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); - m_DrawOutline = FALSE; - break; - case 'F': - glPolygonMode(GL_FRONT,GL_FILL); - m_DrawOutline = TRUE; - break; - case '1': - m_SelectedBone = &m_Skeleton->children[0]; - break; - case '2': - m_SelectedBone = &m_Skeleton->children[1]; - break; - case '3': - m_SelectedBone = &m_Skeleton->children[2]; - break; - case ' ': // CLEAR THE SELECTION FLAGS - for (int loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - m_SelectFlags[loop] = 0; - } - break; - } - drawScene(FALSE); -} - -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - m_SelectRect.right = point.x; - m_SelectRect.bottom = m_ScreenHeight - point.y; - if (m_SelectedBone != NULL) - { - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton->trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(FALSE); - } - } - // ELSE ROTATE THE ROOT - else if ((nFlags & MK_SHIFT) == 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - if ((point.y - m_mousepos.y) != 0) - { - m_SelectedBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(FALSE); - } - // SET THE NEW START KEYFRAME POSITION - m_SelectedBone->p_rot.x = m_SelectedBone->rot.x; - m_SelectedBone->p_rot.y = m_SelectedBone->rot.y; - m_SelectedBone->p_rot.z = m_SelectedBone->rot.z; - m_AnimBlend = 0.0; - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - } - else if ((nFlags & MK_SHIFT) == 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - // SET THE NEW START KEYFRAME POSITION - m_SelectedBone->p_rot.x = m_SelectedBone->rot.x; - m_SelectedBone->p_rot.y = m_SelectedBone->rot.y; - m_SelectedBone->p_rot.z = m_SelectedBone->rot.z; - m_AnimBlend = 0.0; - } - } - } - // IF I AM HOLDING THE 'SHIFT' BUTTON DRAW MY SELECTION BOX - if ((nFlags & MK_SHIFT) > 0 && - (((nFlags & MK_LBUTTON) > 0) || ((nFlags & MK_RBUTTON) == MK_RBUTTON))) - { - drawScene(TRUE); - } - CWnd::OnMouseMove(nFlags, point); -} - -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CSetRot dialog; -/////////////////////////////////////////////////////////////////////////////// - if (m_SelectedBone != NULL) - { - dialog.m_XAxis = m_SelectedBone->rot.x; - dialog.m_YAxis = m_SelectedBone->rot.y; - dialog.m_ZAxis = m_SelectedBone->rot.z; - if (dialog.DoModal()) - { - m_SelectedBone->rot.x = dialog.m_XAxis; - m_SelectedBone->rot.y = dialog.m_YAxis; - m_SelectedBone->rot.z = dialog.m_ZAxis; - } - drawScene(FALSE); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadObjectFile -// Purpose: Load a 3D Model in my format -// Arguments: Name of file and place to put it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadObjectFile(char *filename,t_Bone *bonePtr) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; - tObjDesc *desc; /* Pointer to Desc */ - tObjFrame *frame; /* Pointer to Desc */ - short loop2; - char tempstr[80]; -/////////////////////////////////////////////////////////////////////////////// - - ResetBone(bonePtr, m_Skeleton); // SETUP INITIAL BONE SETTINGS - - bonePtr->trans.x = 0; - bonePtr->trans.y = 0; - bonePtr->trans.z = 0; - bonePtr->rot.x = 0.0; - bonePtr->rot.y = 0.0; - bonePtr->rot.z = 0.0; - - - fp = fopen(filename,"rb"); - if (fp != NULL) - { - fread(tempstr,1,4,fp); // FDAT - if (strncmp(tempstr,"DARW",4)!= 0) - { - MessageBox("Not a Valid DGF File","Load File", MB_OK|MB_ICONEXCLAMATION); - return; - } - fread(tempstr,1,4,fp); // FDAT - - fread(bonePtr,sizeof(t_Bone),1,fp); - fread(tempstr,1,4,fp); // FDAT - bonePtr->desc = (tObjDesc *)malloc(sizeof(tObjDesc)); - desc = bonePtr->desc; - fread(desc,sizeof(tObjDesc),1,fp); - for (loop2 = 0; loop2 < desc->frameCnt; loop2++) - { - fread(tempstr,1,4,fp); // FDAT - desc->frame[loop2] = (tObjFrame *)malloc(sizeof(tObjFrame)); - frame = desc->frame[loop2]; - fread(frame,sizeof(tObjFrame),1,fp); - frame->data = (float *)malloc(sizeof(float) * desc->dataSize * desc->pointCnt); - fread(frame->data,sizeof(float),desc->dataSize * desc->pointCnt,fp); - } - bonePtr->cur_desc = 0; - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SelectVertices -// Purpose: Use Feedback to get all the vertices in the view -// Arguments: Should I select or de-select? -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SelectVertices(BOOL select) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat *feedBuffer; - GLint hitCount; - tColoredVertex *meshdata; // IN THIS CASE THE DATA IS COLOR VERTICES - int loop; -/////////////////////////////////////////////////////////////////////////////// - // GET A TEMP POINTER TO THE ACTUAL VERTEX DATA - meshdata = m_DeformedMesh; - // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) - feedBuffer = (GLfloat *)malloc(sizeof(GLfloat) * m_Mesh.desc->pointCnt * 6); - // TELL OPENGL ABOUT THE BUFFER - glFeedbackBuffer(m_Mesh.desc->pointCnt * 6,GL_3D,feedBuffer); - (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE - - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS - glPassThrough((float)loop); - // SEND THE VERTEX - glBegin(GL_POINTS); - glVertex3f(meshdata[loop].x,meshdata[loop].y,meshdata[loop].z); - glEnd(); - } - hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET - CompareBuffer(hitCount,feedBuffer, select); // CHECK THEM AGAINST MY SELECTION - free(feedBuffer); // GET RID OF THE MEMORY -} -////// SelectVertices ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CompareBuffer -// Purpose: Check the feedback buffer to see if anything is tagged -// Arguments: Number of hits, pointer to buffer, Should I select or de-select -/////////////////////////////////////////////////////////////////////////////// -void COGLView::CompareBuffer(GLint size, GLfloat *buffer,BOOL select) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLint count; - GLfloat token,point[3]; - int loop,currentVertex; -/////////////////////////////////////////////////////////////////////////////// - count = size; - while (count) - { - token = buffer[size - count]; // CHECK THE TOKEN - count--; - if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER - { - currentVertex = (int)buffer[size - count]; // WHAT VERTEX - count--; - } - else if (token == GL_POINT_TOKEN) - { - // THERE ARE THREE ELEMENTS TO A POINT TOKEN - for (loop = 0; loop < 3; loop++) - { - point[loop] = buffer[size - count]; - count--; - } - // CHECK IF THE POINT WAS IN MY SELECTION RECTANGLE - // FLOATS 0 AND 1 ARE SCREEN X AND Y - // NOTE: OPENGL SETS THE BOTTOM Y=0 - if (point[0] >= m_SelectRect.left && - point[0] <= m_SelectRect.right && - point[1] <= m_SelectRect.top && - point[1] >= m_SelectRect.bottom) - // SET THIS VERTEX TO THE CURRENT SELECTION VALUE - m_SelectFlags[currentVertex] = select; - } - } -} -////// CompareBuffer ////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: ModifyWeights -// Purpose: Edit the bone weights via a dialog -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -void COGLView::ModifyWeights() -{ -/// Local Variables /////////////////////////////////////////////////////////// - CWeight dialog; - int value,loop; -/////////////////////////////////////////////////////////////////////////////// - if (dialog.DoModal()) - { - value = dialog.m_pos; - // SET NEW WEIGHT VALUES - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - if (m_SelectFlags[loop]) - { - m_Skeleton->children[0].CV_weight[loop] = 1.0f - ((float)value / 256.0f); - m_Skeleton->children[1].CV_weight[loop] = (float)value / 256.0f; - } - } - drawScene(FALSE); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: ResetWeights -// Purpose: Reset the bone weights -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -void COGLView::ResetWeights() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - // RESET ALL THE WEIGHTS TO THE DEFAULT - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - m_Skeleton->children[0].CV_weight[loop] = 1.0f; - m_Skeleton->children[1].CV_weight[loop] = 0.0f; - } - // RESET THE ROTATIONS FOR THE TWO ARM BONES - m_Skeleton->children[0].rot.x = 0.0; - m_Skeleton->children[0].rot.y = 0.0; - m_Skeleton->children[0].rot.z = 0.0; - m_Skeleton->children[1].rot.x = 0.0; - m_Skeleton->children[1].rot.y = 0.0; - m_Skeleton->children[1].rot.z = 0.0; - drawScene(FALSE); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetWeights -// Purpose: Get the bone weights from a file -// Arguments: Filename to get it from -// Returns: Success -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::GetWeights(CString filename) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"rb"); - if (fp != NULL) - { - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - fread(&m_Skeleton->children[0].CV_weight[loop],sizeof(float),1,fp); - fread(&m_Skeleton->children[1].CV_weight[loop],sizeof(float),1,fp); - } - fclose(fp); - drawScene(FALSE); - return TRUE; - } - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SaveWeights -// Purpose: Save the bone weights to a file -// Arguments: Filename to put it in -// Returns: Success -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::SaveWeights(CString filename) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"wb"); - if (fp != NULL) - { - for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) - { - fwrite(&m_Skeleton->children[0].CV_weight[loop],sizeof(float),1,fp); - fwrite(&m_Skeleton->children[1].CV_weight[loop],sizeof(float),1,fp); - } - fclose(fp); - return TRUE; - } - return FALSE; -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Deformation System +// +// Created: +// JL 2/18/98 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "SkinApp.h" +#include "OGLView.h" +#include "SetRot.h" +#include "Matrix.h" +#include "Weight.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +// IF YOU WANT TO TRY A QUICKER TWO BONE WEIGHTING SYSTEM UNDEF THIS +#define DEFORM_GENERAL_SOLUTION // FULL MULTI-BONE DEFORMATION +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/// Message Maps ////////////////////////////////////////////////////////////// +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_LBUTTONUP() + ON_WM_RBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_DrawBoneSystem = TRUE; + m_DrawOutline = TRUE; + m_Defmode_TwoBone = TRUE; + m_Skeleton = NULL; + m_SelectedBone = NULL; + m_AnimBlend = 0.0; + LoadObjectFile("Mesh.dgf",&m_Mesh); + + // SET UP THE SELECTION ARRAY FOR PICKING VERTICES + m_SelectFlags = (int *)malloc( sizeof(int) * m_Mesh.desc->pointCnt); + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + m_SelectFlags[loop] = 0; + } +} + +COGLView::~COGLView() +{ + free(m_SelectFlags); + // FREE THE BASE MESH STORAGE + free(m_DeformedMesh); + free(m_Skeleton->children[0].CV_weight); + free(m_Skeleton->children[1].CV_weight); +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + m_Skeleton = skeleton; + + // SET UP THE WEIGHTS FOR THE BONES + // UPPER ARM + m_Skeleton->children[0].CV_weight = (float *)malloc(m_Mesh.desc->pointCnt * sizeof(float)); + // LOWER ARM + m_Skeleton->children[1].CV_weight = (float *)malloc(m_Mesh.desc->pointCnt * sizeof(float)); + // HAND - JUST FOR COMPLETENESS THE INTERFACE DOESN'T SUPPORT + // DEFORMATION OF THE HAND. WEIGHTING DIALOG IS A PAIN IN THE + // BUTT. HOWEVER, IF YOU SET UP THE WEIGHTS IT WOULD WORK + m_Skeleton->children[2].CV_weight = (float *)malloc(m_Mesh.desc->pointCnt * sizeof(float)); + + // SET INITIAL WEIGHT VALUES + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + m_Skeleton->children[0].CV_weight[loop] = 1.0f; + m_Skeleton->children[1].CV_weight[loop] = 0.0f; + // HAND WEIGHTING IS ALWAYS ZERO + m_Skeleton->children[2].CV_weight[loop] = 0.0f; + } + + // PLACE TO STORE BASE MESH POINTS + m_DeformedMesh = (tColoredVertex *)malloc(sizeof(tColoredVertex) * m_Mesh.desc->pointCnt); + memcpy(m_DeformedMesh, m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data,sizeof(tColoredVertex) * m_Mesh.desc->pointCnt); + + // GET A DEFAULT WEIGHT SYSTEM + GetWeights(CString("arm.wgt")); + + UpdateStatus(); // DRAW INITIAL STATUS BAR + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +void COGLView::UpdateStatus() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + + if (m_SelectedBone != NULL) + m_ptrStatusBar->SetPaneText(1,m_SelectedBone->name); + else + m_ptrStatusBar->SetPaneText(1,"*No Bone Selected*"); + + + sprintf(message,"UArm (%.1f,%.1f,%.1f)", + m_Skeleton->children[0].rot.x, + m_Skeleton->children[0].rot.y, + m_Skeleton->children[0].rot.z); + m_ptrStatusBar->SetPaneText(2,message); + + sprintf(message,"LArm (%.1f,%.1f,%.1f)", + m_Skeleton->children[1].rot.x, + m_Skeleton->children[1].rot.y, + m_Skeleton->children[1].rot.z); + m_ptrStatusBar->SetPaneText(3,message); +} + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: CreateBoneDLists +// Purpose: Creates the Drawlists for the Bones in a Skeleton +// Arguments: Pointer to a bone hierarchy +/////////////////////////////////////////////////////////////////////////////// +void COGLView::CreateBoneDLists(t_Bone *bone) +{ + // ONLY MAKE A BONE IF THERE IS A CHILD + if (bone->childCnt > 0) + { + // CREATE THE DISPLAY LIST FOR A BONE + glNewList(bone->id,GL_COMPILE); + glBegin(GL_LINE_STRIP); + glVertex3f( 0.0f, 0.4f, 0.0f); // 0 + glVertex3f(-0.4f, 0.0f,-0.4f); // 1 + glVertex3f( 0.4f, 0.0f,-0.4f); // 2 + glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base + glVertex3f(-0.4f, 0.0f,-0.4f); // 1 + glVertex3f(-0.4f, 0.0f, 0.4f); // 4 + glVertex3f( 0.0f, 0.4f, 0.0f); // 0 + glVertex3f( 0.4f, 0.0f,-0.4f); // 2 + glVertex3f( 0.4f, 0.0f, 0.4f); // 3 + glVertex3f( 0.0f, 0.4f, 0.0f); // 0 + glVertex3f(-0.4f, 0.0f, 0.4f); // 4 + glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base + glVertex3f( 0.4f, 0.0f, 0.4f); // 3 + glVertex3f(-0.4f, 0.0f, 0.4f); // 4 + glEnd(); + glEndList(); + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (bone->childCnt > 0) + CreateBoneDLists(bone->children); + } +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + if (m_Skeleton != NULL) + { + CreateBoneDLists(m_Skeleton->children); + } + drawScene(FALSE); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(35.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(40.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_LINE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + glPointSize(4.0); // NICE BEEFY POINTS FOR THE VERTEX SELECTION +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo(char *who,char *which, char *version) +{ + strcpy(who,(char *)::glGetString( GL_VENDOR )); + + strcpy(which,(char *)::glGetString( GL_RENDERER )); + + strcpy(version, (char *)::glGetString( GL_VERSION )); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawModel +// Purpose: Draw the final deformed mesh to the screen +// Arguments: Base bone for mesh, deformed mesh data to draw +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *baseBone, tColoredVertex *deformedMesh) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + + if (deformedMesh != NULL) + { + // THIS MODEL HAS VERTEX COLORS + glInterleavedArrays(GL_C3F_V3F,0,(GLvoid *)deformedMesh); + glDrawArrays(GL_TRIANGLES,0,baseBone->desc->pointCnt); + + // NOW DRAW THE VERTEX MARKERS IF THEY ARE SELECTED + glColor3f(1.0f, 0.0f, 0.0f); // Selected Vertices are Red + glBegin(GL_POINTS); + for (loop = 0; loop < baseBone->desc->pointCnt; loop++) + { + // IF A POINT IS SELECTED DRAW IT + if (m_SelectFlags[loop]) + { + glVertex3f(deformedMesh[loop].x,deformedMesh[loop].y,deformedMesh[loop].z); + } + } + glEnd(); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: DeformBone +// Purpose: Deforms a model by the skeleton +// Arguments: Pointer to base bone and original and deformed data +// Notes: This is the general solution version of the deformation. +// It recurses through the skeletal hierarchy and adds the +// influence of each bone. This should work with as many +// bones as you have in the system. I have tried it on a +// model with a 25 bones system and it worked great. +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DeformBone(t_Bone *rootBone, tColoredVertex *meshdata, tColoredVertex *defdata) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,boneloop; + float weight; + tVector pre,post; + t_Bone *curBone; +/////////////////////////////////////////////////////////////////////////////// + // START ON THIS BONES CHILDREN + curBone = rootBone->children; + // GO THROUGH THEM ALL + for (boneloop = 0; boneloop < rootBone->childCnt; boneloop++) + { + // FOR EVERY VERTEX IN MY DEFORMABLE MESH + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + // GET THE WEIGHT + weight = curBone->CV_weight[loop]; + if (weight > 0.0) // ONLY CARE IF IT IS > 0 + { + // OFFSET THE ROTATIONAL CENTER ABOUT THAT BONES CENTER + pre.x = meshdata[loop].x - rootBone->children[boneloop].trans.x; + pre.y = meshdata[loop].y - rootBone->children[boneloop].trans.y; + pre.z = meshdata[loop].z - rootBone->children[boneloop].trans.z; + // PUT IT THROUGH THE ROTATION + MultVectorByMatrix(&rootBone->children[boneloop].matrix, &pre, &post); + // ADD IN THE WEIGHTED DELTA OF THIS POSITION + defdata[loop].x += ((post.x - meshdata[loop].x) * weight); + defdata[loop].y += ((post.y - meshdata[loop].y) * weight); + defdata[loop].z += ((post.z - meshdata[loop].z) * weight); + } + } + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + DeformBone(curBone, meshdata, defdata); + + curBone++; + } +} +///// DeformBone //////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DeformModel +// Purpose: Deforms a model by the skeleton +// Arguments: Pointer to base bone +// Notes: This is a special version for testing. It assumes that +// I only have two bones weighted between them instead of +// a general solution. Since it is not recursive and handles +// multiple bones, it is faster. It simply calculates the +// two possible positions and interpolates between them. +// For some characters this may be better as it is faster. +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DeformModel(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + tVector pre,post1,post2; + tColoredVertex *meshdata; // IN THIS CASE THE DATA IS COLOR VERTICES + tColoredVertex *defdata; // IN THIS CASE THE DATA IS COLOR VERTICES +/////////////////////////////////////////////////////////////////////////////// + // GET A POINTER TO THE ACTUAL VERTEX DATA + meshdata = (tColoredVertex *)m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data; + defdata = m_DeformedMesh; + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + pre.x = meshdata[loop].x - rootBone->children[0].trans.x; + pre.y = meshdata[loop].y - rootBone->children[0].trans.y; + pre.z = meshdata[loop].z - rootBone->children[0].trans.z; + MultVectorByMatrix(&rootBone->children[0].matrix, &pre, &post1); + pre.x = meshdata[loop].x - rootBone->children[1].trans.x; + pre.y = meshdata[loop].y - rootBone->children[1].trans.y; + pre.z = meshdata[loop].z - rootBone->children[1].trans.z; + MultVectorByMatrix(&rootBone->children[1].matrix, &pre, &post2); + defdata[loop].x = post1.x + ((post2.x - post1.x) * rootBone->children[1].CV_weight[loop]); + defdata[loop].y = post1.y + ((post2.y - post1.y) * rootBone->children[1].CV_weight[loop]); + defdata[loop].z = post1.z + ((post2.z - post1.z) * rootBone->children[1].CV_weight[loop]); + } +} +//// DeformModel ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawSkeleton +// Purpose: Actually draws the Skeleton it is recursive +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawSkeleton(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + // Set base orientation and position + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + + // THE SCALE IS LOCAL SO I PUSH AND POP + glPushMatrix(); + glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); + + // DO I WISH TO DISPLAY ANYTHING + if (m_DrawBoneSystem) + { + // DRAW THE AXIS OGL OBJECT + glCallList(OGL_AXIS_DLIST); + // DRAW THE ACTUAL BONE STRUCTURE + // ONLY MAKE A BONE IF THERE IS A CHILD + if (curBone->childCnt > 0) + { + if (curBone == m_SelectedBone) + glColor3f(1.0f, 1.0f, 0.0f); // Selected bone is bright Yellow + else + glColor3f(0.4f, 0.4f, 0.0f); // Selected bone is dull Yellow + // DRAW THE BONE STRUCTURE + glCallList(curBone->id); + } + } + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,curBone->matrix.m); + + glPopMatrix(); // THIS POP IS JUST FOR THE SCALE + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + drawSkeleton(curBone); + + glPopMatrix(); // THIS POPS THE WHOLE MATRIX + + curBone++; + } +} +//// drawSkeleton ///////////////////////////////////////////////////////////// + +GLvoid COGLView::drawScene(BOOL drawSelectRect) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float m[16]; +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; + if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; + if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); + + glRotatef(m_Skeleton->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton->rot.x, 1.0f, 0.0f, 0.0f); + + drawSkeleton(m_Skeleton); + + glPopMatrix(); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m); + + if (m_DrawGeometry) + { +// THIS IS TO ALLOW TESTING ON A SIMPLE TWO BONE CASE +#ifdef DEFORM_GENERAL_SOLUTION + // THE FULL REAL DEFORMATION HANDLES AS MANY BONES AS YOU WANT + // COPY THE ORIGINAL MESH INTO THE DEFORMABLE DATA + memcpy(m_DeformedMesh, m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data,sizeof(tColoredVertex) * m_Mesh.desc->pointCnt); + DeformBone(m_Skeleton, + (tColoredVertex *)m_Mesh.desc->frame[m_Mesh.desc->cur_frame]->data, + m_DeformedMesh); +#else + // TEST DEFORMATION FOR WEIGHTING BETWEEN TWO BONES ONLY + DeformModel(m_Skeleton); +#endif + drawModel(&m_Mesh,m_DeformedMesh); + } + + // IF I AM DRAGGING A SELECTION BOX, DRAW IT + if (drawSelectRect) + { + glMatrixMode(GL_PROJECTION); // I WANT TO PLAY WITH THE PROJECTION + glPushMatrix(); // SAVE THE OLD ONE + glLoadIdentity(); // LOAD A NEW ONE + gluOrtho2D(0,m_ScreenWidth,0,m_ScreenHeight); // USE WINDOW SETTINGS + glColor3f(1.0f, 1.0f, 1.0f); // DRAW A WHITE BOX + glBegin(GL_LINE_STRIP); + glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); + glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.top); + glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.bottom); + glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.bottom); + glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); + glEnd(); + glPopMatrix(); // RESTORE THE OLD PROJECTION + glMatrixMode(GL_MODELVIEW); // BACK TO MODEL MODE + } + + glFinish(); + + SwapBuffers(m_hDC); + + // DRAW THE STATS AT THE BOTTOM OF THE SCREEN + UpdateStatus(); +} + + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(FALSE); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); + m_ScreenWidth = cx; + m_ScreenHeight = cy; +} + +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + if (m_SelectedBone != NULL) + { + m_Grab_Rot_X = m_SelectedBone->rot.x; + m_Grab_Rot_Y = m_SelectedBone->rot.y; + m_Grab_Rot_Z = m_SelectedBone->rot.z; + m_Grab_Trans_X = m_Skeleton->trans.x; + m_Grab_Trans_Y = m_Skeleton->trans.y; + m_Grab_Trans_Z = m_Skeleton->trans.z; + } + m_SelectRect.left = point.x; + m_SelectRect.top = m_ScreenHeight - point.y; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + // IF I AM HOLDING THE 'SHIFT' BUTTON PICK VERTICES + if ((nFlags & MK_SHIFT) > 0) + { + SelectVertices(TRUE); + drawScene(FALSE); + } + + CWnd::OnLButtonUp(nFlags, point); +} + +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + if (m_SelectedBone != NULL) + { + m_Grab_Rot_X = m_SelectedBone->rot.x; + m_Grab_Rot_Y = m_SelectedBone->rot.y; + m_Grab_Rot_Z = m_SelectedBone->rot.z; + m_Grab_Trans_X = m_Skeleton->trans.x; + m_Grab_Trans_Y = m_Skeleton->trans.y; + m_Grab_Trans_Z = m_Skeleton->trans.z; + } + m_SelectRect.left = point.x; + m_SelectRect.top = m_ScreenHeight - point.y; + CWnd::OnRButtonDown(nFlags, point); +} + +void COGLView::OnRButtonUp(UINT nFlags, CPoint point) +{ + // IF I AM HOLDING THE 'SHIFT' BUTTON PICK VERTICES + if ((nFlags & MK_SHIFT) > 0) + { + SelectVertices(FALSE); + drawScene(FALSE); + } + + + CWnd::OnRButtonUp(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case 'D': + m_Defmode_TwoBone = !m_Defmode_TwoBone; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); + m_DrawOutline = FALSE; + break; + case 'F': + glPolygonMode(GL_FRONT,GL_FILL); + m_DrawOutline = TRUE; + break; + case '1': + m_SelectedBone = &m_Skeleton->children[0]; + break; + case '2': + m_SelectedBone = &m_Skeleton->children[1]; + break; + case '3': + m_SelectedBone = &m_Skeleton->children[2]; + break; + case ' ': // CLEAR THE SELECTION FLAGS + for (int loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + m_SelectFlags[loop] = 0; + } + break; + } + drawScene(FALSE); +} + +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + m_SelectRect.right = point.x; + m_SelectRect.bottom = m_ScreenHeight - point.y; + if (m_SelectedBone != NULL) + { + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton->trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(FALSE); + } + } + // ELSE ROTATE THE ROOT + else if ((nFlags & MK_SHIFT) == 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + if ((point.y - m_mousepos.y) != 0) + { + m_SelectedBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(FALSE); + } + // SET THE NEW START KEYFRAME POSITION + m_SelectedBone->p_rot.x = m_SelectedBone->rot.x; + m_SelectedBone->p_rot.y = m_SelectedBone->rot.y; + m_SelectedBone->p_rot.z = m_SelectedBone->rot.z; + m_AnimBlend = 0.0; + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + } + else if ((nFlags & MK_SHIFT) == 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + // SET THE NEW START KEYFRAME POSITION + m_SelectedBone->p_rot.x = m_SelectedBone->rot.x; + m_SelectedBone->p_rot.y = m_SelectedBone->rot.y; + m_SelectedBone->p_rot.z = m_SelectedBone->rot.z; + m_AnimBlend = 0.0; + } + } + } + // IF I AM HOLDING THE 'SHIFT' BUTTON DRAW MY SELECTION BOX + if ((nFlags & MK_SHIFT) > 0 && + (((nFlags & MK_LBUTTON) > 0) || ((nFlags & MK_RBUTTON) == MK_RBUTTON))) + { + drawScene(TRUE); + } + CWnd::OnMouseMove(nFlags, point); +} + +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CSetRot dialog; +/////////////////////////////////////////////////////////////////////////////// + if (m_SelectedBone != NULL) + { + dialog.m_XAxis = m_SelectedBone->rot.x; + dialog.m_YAxis = m_SelectedBone->rot.y; + dialog.m_ZAxis = m_SelectedBone->rot.z; + if (dialog.DoModal()) + { + m_SelectedBone->rot.x = dialog.m_XAxis; + m_SelectedBone->rot.y = dialog.m_YAxis; + m_SelectedBone->rot.z = dialog.m_ZAxis; + } + drawScene(FALSE); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadObjectFile +// Purpose: Load a 3D Model in my format +// Arguments: Name of file and place to put it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadObjectFile(char *filename,t_Bone *bonePtr) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; + tObjDesc *desc; /* Pointer to Desc */ + tObjFrame *frame; /* Pointer to Desc */ + short loop2; + char tempstr[80]; +/////////////////////////////////////////////////////////////////////////////// + + ResetBone(bonePtr, m_Skeleton); // SETUP INITIAL BONE SETTINGS + + bonePtr->trans.x = 0; + bonePtr->trans.y = 0; + bonePtr->trans.z = 0; + bonePtr->rot.x = 0.0; + bonePtr->rot.y = 0.0; + bonePtr->rot.z = 0.0; + + + fp = fopen(filename,"rb"); + if (fp != NULL) + { + fread(tempstr,1,4,fp); // FDAT + if (strncmp(tempstr,"DARW",4)!= 0) + { + MessageBox("Not a Valid DGF File","Load File", MB_OK|MB_ICONEXCLAMATION); + return; + } + fread(tempstr,1,4,fp); // FDAT + + fread(bonePtr,sizeof(t_Bone),1,fp); + fread(tempstr,1,4,fp); // FDAT + bonePtr->desc = (tObjDesc *)malloc(sizeof(tObjDesc)); + desc = bonePtr->desc; + fread(desc,sizeof(tObjDesc),1,fp); + for (loop2 = 0; loop2 < desc->frameCnt; loop2++) + { + fread(tempstr,1,4,fp); // FDAT + desc->frame[loop2] = (tObjFrame *)malloc(sizeof(tObjFrame)); + frame = desc->frame[loop2]; + fread(frame,sizeof(tObjFrame),1,fp); + frame->data = (float *)malloc(sizeof(float) * desc->dataSize * desc->pointCnt); + fread(frame->data,sizeof(float),desc->dataSize * desc->pointCnt,fp); + } + bonePtr->cur_desc = 0; + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SelectVertices +// Purpose: Use Feedback to get all the vertices in the view +// Arguments: Should I select or de-select? +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SelectVertices(BOOL select) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat *feedBuffer; + GLint hitCount; + tColoredVertex *meshdata; // IN THIS CASE THE DATA IS COLOR VERTICES + int loop; +/////////////////////////////////////////////////////////////////////////////// + // GET A TEMP POINTER TO THE ACTUAL VERTEX DATA + meshdata = m_DeformedMesh; + // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) + feedBuffer = (GLfloat *)malloc(sizeof(GLfloat) * m_Mesh.desc->pointCnt * 6); + // TELL OPENGL ABOUT THE BUFFER + glFeedbackBuffer(m_Mesh.desc->pointCnt * 6,GL_3D,feedBuffer); + (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE + + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS + glPassThrough((float)loop); + // SEND THE VERTEX + glBegin(GL_POINTS); + glVertex3f(meshdata[loop].x,meshdata[loop].y,meshdata[loop].z); + glEnd(); + } + hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET + CompareBuffer(hitCount,feedBuffer, select); // CHECK THEM AGAINST MY SELECTION + free(feedBuffer); // GET RID OF THE MEMORY +} +////// SelectVertices ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CompareBuffer +// Purpose: Check the feedback buffer to see if anything is tagged +// Arguments: Number of hits, pointer to buffer, Should I select or de-select +/////////////////////////////////////////////////////////////////////////////// +void COGLView::CompareBuffer(GLint size, GLfloat *buffer,BOOL select) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLint count; + GLfloat token,point[3]; + int loop,currentVertex; +/////////////////////////////////////////////////////////////////////////////// + count = size; + while (count) + { + token = buffer[size - count]; // CHECK THE TOKEN + count--; + if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER + { + currentVertex = (int)buffer[size - count]; // WHAT VERTEX + count--; + } + else if (token == GL_POINT_TOKEN) + { + // THERE ARE THREE ELEMENTS TO A POINT TOKEN + for (loop = 0; loop < 3; loop++) + { + point[loop] = buffer[size - count]; + count--; + } + // CHECK IF THE POINT WAS IN MY SELECTION RECTANGLE + // FLOATS 0 AND 1 ARE SCREEN X AND Y + // NOTE: OPENGL SETS THE BOTTOM Y=0 + if (point[0] >= m_SelectRect.left && + point[0] <= m_SelectRect.right && + point[1] <= m_SelectRect.top && + point[1] >= m_SelectRect.bottom) + // SET THIS VERTEX TO THE CURRENT SELECTION VALUE + m_SelectFlags[currentVertex] = select; + } + } +} +////// CompareBuffer ////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: ModifyWeights +// Purpose: Edit the bone weights via a dialog +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +void COGLView::ModifyWeights() +{ +/// Local Variables /////////////////////////////////////////////////////////// + CWeight dialog; + int value,loop; +/////////////////////////////////////////////////////////////////////////////// + if (dialog.DoModal()) + { + value = dialog.m_pos; + // SET NEW WEIGHT VALUES + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + if (m_SelectFlags[loop]) + { + m_Skeleton->children[0].CV_weight[loop] = 1.0f - ((float)value / 256.0f); + m_Skeleton->children[1].CV_weight[loop] = (float)value / 256.0f; + } + } + drawScene(FALSE); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: ResetWeights +// Purpose: Reset the bone weights +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +void COGLView::ResetWeights() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + // RESET ALL THE WEIGHTS TO THE DEFAULT + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + m_Skeleton->children[0].CV_weight[loop] = 1.0f; + m_Skeleton->children[1].CV_weight[loop] = 0.0f; + } + // RESET THE ROTATIONS FOR THE TWO ARM BONES + m_Skeleton->children[0].rot.x = 0.0; + m_Skeleton->children[0].rot.y = 0.0; + m_Skeleton->children[0].rot.z = 0.0; + m_Skeleton->children[1].rot.x = 0.0; + m_Skeleton->children[1].rot.y = 0.0; + m_Skeleton->children[1].rot.z = 0.0; + drawScene(FALSE); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetWeights +// Purpose: Get the bone weights from a file +// Arguments: Filename to get it from +// Returns: Success +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::GetWeights(CString filename) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"rb"); + if (fp != NULL) + { + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + fread(&m_Skeleton->children[0].CV_weight[loop],sizeof(float),1,fp); + fread(&m_Skeleton->children[1].CV_weight[loop],sizeof(float),1,fp); + } + fclose(fp); + drawScene(FALSE); + return TRUE; + } + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SaveWeights +// Purpose: Save the bone weights to a file +// Arguments: Filename to put it in +// Returns: Success +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::SaveWeights(CString filename) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"wb"); + if (fp != NULL) + { + for (loop = 0; loop < m_Mesh.desc->pointCnt; loop++) + { + fwrite(&m_Skeleton->children[0].CV_weight[loop],sizeof(float),1,fp); + fwrite(&m_Skeleton->children[1].CV_weight[loop],sizeof(float),1,fp); + } + fclose(fp); + return TRUE; + } + return FALSE; +} diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.h index 46778be..866e388 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/OGLView.h @@ -1,116 +1,116 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Deformation System -// -// Created: -// JL 11/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry, m_DrawBoneSystem, m_DrawOutline; - BOOL m_Defmode_TwoBone; - float m_AnimBlend; - t_Bone *m_SelectedBone; // THE CURRENTLY PICKED BONE - t_Bone m_Mesh; // THE MESH TO DEFORM - tColoredVertex *m_DeformedMesh; // HOLDS THE PREDEFORMED VERTICES - int *m_SelectFlags; - CRect m_SelectRect; - int m_ScreenWidth, m_ScreenHeight; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(BOOL drawSelectRect); - GLvoid drawSkeleton(t_Bone *rootBone); - GLvoid drawModel(t_Bone *baseBone, tColoredVertex *deformedMesh); - GLvoid DeformBone(t_Bone *rootBone, tColoredVertex *meshdata, tColoredVertex *defdata); - GLvoid DeformModel(t_Bone *rootBone); - void ModifyWeights(); - void LoadObjectFile(char *filename,t_Bone *bonePtr); - void ResetWeights(); - BOOL GetWeights(CString filename); - BOOL SaveWeights(CString filename); - void CreateBoneDLists(t_Bone *bone); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(char *who,char *which, char *version); - void SelectVertices(BOOL select); - void CompareBuffer(GLint size, GLfloat *buffer,BOOL select); - void UpdateStatus(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone *m_Skeleton; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnRButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Deformation System +// +// Created: +// JL 11/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry, m_DrawBoneSystem, m_DrawOutline; + BOOL m_Defmode_TwoBone; + float m_AnimBlend; + t_Bone *m_SelectedBone; // THE CURRENTLY PICKED BONE + t_Bone m_Mesh; // THE MESH TO DEFORM + tColoredVertex *m_DeformedMesh; // HOLDS THE PREDEFORMED VERTICES + int *m_SelectFlags; + CRect m_SelectRect; + int m_ScreenWidth, m_ScreenHeight; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(BOOL drawSelectRect); + GLvoid drawSkeleton(t_Bone *rootBone); + GLvoid drawModel(t_Bone *baseBone, tColoredVertex *deformedMesh); + GLvoid DeformBone(t_Bone *rootBone, tColoredVertex *meshdata, tColoredVertex *defdata); + GLvoid DeformModel(t_Bone *rootBone); + void ModifyWeights(); + void LoadObjectFile(char *filename,t_Bone *bonePtr); + void ResetWeights(); + BOOL GetWeights(CString filename); + BOOL SaveWeights(CString filename); + void CreateBoneDLists(t_Bone *bone); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(char *who,char *which, char *version); + void SelectVertices(BOOL select); + void CompareBuffer(GLint size, GLfloat *buffer,BOOL select); + void UpdateStatus(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone *m_Skeleton; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnRButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.cpp index 0b3186b..1deda70 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.cpp @@ -1,413 +1,413 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.cpp : Quaternion System structure implementation file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -// Sources: -// Shoemake, Ken, "Animating Rotations with Quaternion Curves" -// Computer Graphics 85, pp. 245-254 -// Watt and Watt, Advanced Animation and Rendering Techniques -// Addison Wesley, pp. 360-368 -// Shoemake, Graphic Gems II. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include "skeleton.h" -#include "quatern.h" - -#define M_PI 3.14159265358979323846 -#define HALF_PI 1.57079632679489661923 - -/////////////////////////////////////////////////////////////////////////////// -// Function: CopyVector -// Purpose: Copy a vector -// Arguments: pointer to destination and source -/////////////////////////////////////////////////////////////////////////////// -void CopyVector(tVector *dest, tVector *src) -{ - dest->x = src->x; - dest->y = src->y; - dest->z = src->z; -} -//// CopyVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ScaleVector -// Purpose: Scale a vector -// Arguments: pointer to vector and scale factor -/////////////////////////////////////////////////////////////////////////////// -void ScaleVector(tVector *vect, const float scale) -{ - vect->x *= scale; - vect->y *= scale; - vect->z *= scale; -} -//// ScaleVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: AddVectors -// Purpose: Add two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void AddVectors(const tVector *vect1, const tVector *vect2, tVector *dest) -{ - dest->x = vect1->x + vect2->x; - dest->y = vect1->y + vect2->y; - dest->z = vect1->z + vect2->z; -} -//// AddVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DotVectors -// Purpose: Compute the dot product of two vectors -// Arguments: pointer to vectors -// Returns: Dot product -/////////////////////////////////////////////////////////////////////////////// -float DotVectors(const tVector *vect1, const tVector *vect2) -{ - return (vect1->x * vect2->x) + - (vect1->y * vect2->y) + - (vect1->z * vect2->z); -} -//// DotVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossVectors -// Purpose: Computes the cross product of two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void CrossVectors(const tVector *vect1, const tVector *vect2, tVector *dest) -{ - // COMPUTE THE CROSS PRODUCT - dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); - dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); - dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); -} -//// CrossVectors ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions(const tQuaternion *quat1, const tQuaternion *quat2, tQuaternion *dest) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion v1,v2,v3,vf; -/////////////////////////////////////////////////////////////////////////////// - - CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); - - AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); - AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); - - vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); - - dest->x = vf.x; - dest->y = vf.y; - dest->z = vf.z; - dest->w = vf.w; -} -//// MultQuaternions ////////////////////////////////////////////////////////// - -/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR - I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY - THE MATH CHECKS OUT THOUGH */ -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions2 -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions2(const tQuaternion *quat1, const tQuaternion *quat2, tQuaternion *dest) -{ - tQuaternion tmp; - tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + - quat2->y * quat1->z - quat2->z * quat1->y; - tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + - quat2->z * quat1->x - quat2->x * quat1->z; - tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + - quat2->x * quat1->y - quat2->y * quat1->x; - tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - - quat2->y * quat1->y - quat2->z * quat1->z; - dest->x = tmp.x; dest->y = tmp.y; - dest->z = tmp.z; dest->w = tmp.w; -} -//// MultQuaternions2 ////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeQuaternion -// Purpose: Normalize a Quaternion -// Arguments: a quaternion to set -// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 -// This function insures this -/////////////////////////////////////////////////////////////////////////////// -void NormalizeQuaternion(tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float magnitude; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, FIND THE MAGNITUDE - magnitude = (quat->x * quat->x) + - (quat->y * quat->y) + - (quat->z * quat->z) + - (quat->w * quat->w); - - // DIVIDE BY THE MAGNITUDE TO NORMALIZE - quat->x = quat->x / magnitude; - quat->y = quat->y / magnitude; - quat->z = quat->z / magnitude; - quat->w = quat->w / magnitude; -} -// NormalizeQuaternion /////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT -// A SERIES OF ROTATIONS TO QUATERNIONS. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted. It is more efficient this way though. -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(const tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - tx = rx * (float)0.5; - ty = ry * (float)0.5; - tz = rz * (float)0.5; - cx = (float)cos(tx); - cy = (float)cos(ty); - cz = (float)cos(tz); - sx = (float)sin(tx); - sy = (float)sin(ty); - sz = (float)sin(tz); - - cc = cx * cz; - cs = cx * sz; - sc = sx * cz; - ss = sx * sz; - - quat->x = (cy * sc) - (sy * cs); - quat->y = (cy * ss) + (sy * cc); - quat->z = (cy * cs) - (sy * sc); - quat->w = (cy * cc) + (sy * ss); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(quat); -} -// EulerToQuaternion ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: This is a second variation. It creates a -// Series of quaternions and multiplies them together -// It would be easier to extend this for other rotation orders -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(const tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,ti,tj,tk; - tQuaternion qx,qy,qz,qf; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - ti = rx * (float)0.5; - tj = ry * (float)0.5; - tk = rz * (float)0.5; - - qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); - qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); - qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); - - MultQuaternions(&qx,&qy,&qf); - MultQuaternions(&qf,&qz,&qf); -// ANOTHER TEST VARIATION -// MultQuaternions2(&qx,&qy,&qf); -// MultQuaternions2(&qf,&qz,&qf); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(&qf); - - quat->x = qf.x; - quat->y = qf.y; - quat->z = qf.z; - quat->w = qf.w; - -} -// EulerToQuaternion2 ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(const tQuaternion *quat,tQuaternion *axisAngle) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float scale,tw; -/////////////////////////////////////////////////////////////////////////////// - tw = (float)acos(quat->w) * 2; - scale = (float)sin(tw / 2.0); - axisAngle->x = quat->x / scale; - axisAngle->y = quat->y / scale; - axisAngle->z = quat->z / scale; - - // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES - axisAngle->w = (tw * (360 / 2)) / (float)M_PI; -} -// QuatToAxisAngle ///////////////////////////////////////////////////////// - -#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat2(const tQuaternion *quat1,const tQuaternion *quat2,const float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion quat1b; - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // MAKE SURE WE ARE TRAVELING ALONG THE SHORTER PATH - if (cosom < 0.0) - { - // IF WE ARE NOT, REVERSE ONE OF THE QUATERNIONS - cosom = -cosom; - quat1b.x = - quat1->x; - quat1b.y = - quat1->y; - quat1b.z = - quat1->z; - quat1b.w = - quat1->w; - } else { - quat1b.x = quat1->x; - quat1b.y = quat1->y; - quat1b.z = quat1->z; - quat1b.w = quat1->w; - } - - - if ((1.0 - cosom) > DELTA) { - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - scale0 = 1.0 - slerp; - scale1 = slerp; - } - - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; -} -// SlerpQuat ///////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -// Notes: The comments explain the handling of the special cases. -// The comments in the magazine were wrong. Adjust the -// DELTA constant to play with the LERP vs. SLERP level -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // CHECK A COUPLE OF SPECIAL CASES. - // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) - if ((1.0 + cosom) > DELTA) - { - // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT - if ((1.0 - cosom) > DELTA) { - // YES, DO A SLERP - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1.0 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - // NOT A VERY BIG DIFFERENCE, DO A LERP - scale0 = 1.0 - slerp; - scale1 = slerp; - } - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; - } else { - // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR - // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION - result->x = -quat2->y; - result->y = quat2->x; - result->z = -quat2->w; - result->w = quat2->z; - scale0 = sin((1.0 - slerp) * (float)HALF_PI); - scale1 = sin(slerp * (float)HALF_PI); - result->x = scale0 * quat1->x + scale1 * result->x; - result->y = scale0 * quat1->y + scale1 * result->y; - result->z = scale0 * quat1->z + scale1 * result->z; - result->w = scale0 * quat1->w + scale1 * result->w; - } - -} -// SlerpQuat ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.cpp : Quaternion System structure implementation file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +// Sources: +// Shoemake, Ken, "Animating Rotations with Quaternion Curves" +// Computer Graphics 85, pp. 245-254 +// Watt and Watt, Advanced Animation and Rendering Techniques +// Addison Wesley, pp. 360-368 +// Shoemake, Graphic Gems II. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include "skeleton.h" +#include "quatern.h" + +#define M_PI 3.14159265358979323846 +#define HALF_PI 1.57079632679489661923 + +/////////////////////////////////////////////////////////////////////////////// +// Function: CopyVector +// Purpose: Copy a vector +// Arguments: pointer to destination and source +/////////////////////////////////////////////////////////////////////////////// +void CopyVector(tVector *dest, tVector *src) +{ + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} +//// CopyVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ScaleVector +// Purpose: Scale a vector +// Arguments: pointer to vector and scale factor +/////////////////////////////////////////////////////////////////////////////// +void ScaleVector(tVector *vect, const float scale) +{ + vect->x *= scale; + vect->y *= scale; + vect->z *= scale; +} +//// ScaleVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: AddVectors +// Purpose: Add two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void AddVectors(const tVector *vect1, const tVector *vect2, tVector *dest) +{ + dest->x = vect1->x + vect2->x; + dest->y = vect1->y + vect2->y; + dest->z = vect1->z + vect2->z; +} +//// AddVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DotVectors +// Purpose: Compute the dot product of two vectors +// Arguments: pointer to vectors +// Returns: Dot product +/////////////////////////////////////////////////////////////////////////////// +float DotVectors(const tVector *vect1, const tVector *vect2) +{ + return (vect1->x * vect2->x) + + (vect1->y * vect2->y) + + (vect1->z * vect2->z); +} +//// DotVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossVectors +// Purpose: Computes the cross product of two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void CrossVectors(const tVector *vect1, const tVector *vect2, tVector *dest) +{ + // COMPUTE THE CROSS PRODUCT + dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); + dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); + dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); +} +//// CrossVectors ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions(const tQuaternion *quat1, const tQuaternion *quat2, tQuaternion *dest) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion v1,v2,v3,vf; +/////////////////////////////////////////////////////////////////////////////// + + CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); + + AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); + AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); + + vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); + + dest->x = vf.x; + dest->y = vf.y; + dest->z = vf.z; + dest->w = vf.w; +} +//// MultQuaternions ////////////////////////////////////////////////////////// + +/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR + I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY + THE MATH CHECKS OUT THOUGH */ +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions2 +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions2(const tQuaternion *quat1, const tQuaternion *quat2, tQuaternion *dest) +{ + tQuaternion tmp; + tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + + quat2->y * quat1->z - quat2->z * quat1->y; + tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + + quat2->z * quat1->x - quat2->x * quat1->z; + tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + + quat2->x * quat1->y - quat2->y * quat1->x; + tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - + quat2->y * quat1->y - quat2->z * quat1->z; + dest->x = tmp.x; dest->y = tmp.y; + dest->z = tmp.z; dest->w = tmp.w; +} +//// MultQuaternions2 ////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeQuaternion +// Purpose: Normalize a Quaternion +// Arguments: a quaternion to set +// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 +// This function insures this +/////////////////////////////////////////////////////////////////////////////// +void NormalizeQuaternion(tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float magnitude; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, FIND THE MAGNITUDE + magnitude = (quat->x * quat->x) + + (quat->y * quat->y) + + (quat->z * quat->z) + + (quat->w * quat->w); + + // DIVIDE BY THE MAGNITUDE TO NORMALIZE + quat->x = quat->x / magnitude; + quat->y = quat->y / magnitude; + quat->z = quat->z / magnitude; + quat->w = quat->w / magnitude; +} +// NormalizeQuaternion /////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT +// A SERIES OF ROTATIONS TO QUATERNIONS. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted. It is more efficient this way though. +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(const tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + tx = rx * (float)0.5; + ty = ry * (float)0.5; + tz = rz * (float)0.5; + cx = (float)cos(tx); + cy = (float)cos(ty); + cz = (float)cos(tz); + sx = (float)sin(tx); + sy = (float)sin(ty); + sz = (float)sin(tz); + + cc = cx * cz; + cs = cx * sz; + sc = sx * cz; + ss = sx * sz; + + quat->x = (cy * sc) - (sy * cs); + quat->y = (cy * ss) + (sy * cc); + quat->z = (cy * cs) - (sy * sc); + quat->w = (cy * cc) + (sy * ss); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(quat); +} +// EulerToQuaternion ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: This is a second variation. It creates a +// Series of quaternions and multiplies them together +// It would be easier to extend this for other rotation orders +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(const tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,ti,tj,tk; + tQuaternion qx,qy,qz,qf; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + ti = rx * (float)0.5; + tj = ry * (float)0.5; + tk = rz * (float)0.5; + + qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); + qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); + qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); + + MultQuaternions(&qx,&qy,&qf); + MultQuaternions(&qf,&qz,&qf); +// ANOTHER TEST VARIATION +// MultQuaternions2(&qx,&qy,&qf); +// MultQuaternions2(&qf,&qz,&qf); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(&qf); + + quat->x = qf.x; + quat->y = qf.y; + quat->z = qf.z; + quat->w = qf.w; + +} +// EulerToQuaternion2 ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(const tQuaternion *quat,tQuaternion *axisAngle) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float scale,tw; +/////////////////////////////////////////////////////////////////////////////// + tw = (float)acos(quat->w) * 2; + scale = (float)sin(tw / 2.0); + axisAngle->x = quat->x / scale; + axisAngle->y = quat->y / scale; + axisAngle->z = quat->z / scale; + + // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES + axisAngle->w = (tw * (360 / 2)) / (float)M_PI; +} +// QuatToAxisAngle ///////////////////////////////////////////////////////// + +#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat2(const tQuaternion *quat1,const tQuaternion *quat2,const float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion quat1b; + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // MAKE SURE WE ARE TRAVELING ALONG THE SHORTER PATH + if (cosom < 0.0) + { + // IF WE ARE NOT, REVERSE ONE OF THE QUATERNIONS + cosom = -cosom; + quat1b.x = - quat1->x; + quat1b.y = - quat1->y; + quat1b.z = - quat1->z; + quat1b.w = - quat1->w; + } else { + quat1b.x = quat1->x; + quat1b.y = quat1->y; + quat1b.z = quat1->z; + quat1b.w = quat1->w; + } + + + if ((1.0 - cosom) > DELTA) { + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + scale0 = 1.0 - slerp; + scale1 = slerp; + } + + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; +} +// SlerpQuat ///////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +// Notes: The comments explain the handling of the special cases. +// The comments in the magazine were wrong. Adjust the +// DELTA constant to play with the LERP vs. SLERP level +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // CHECK A COUPLE OF SPECIAL CASES. + // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) + if ((1.0 + cosom) > DELTA) + { + // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT + if ((1.0 - cosom) > DELTA) { + // YES, DO A SLERP + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1.0 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + // NOT A VERY BIG DIFFERENCE, DO A LERP + scale0 = 1.0 - slerp; + scale1 = slerp; + } + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; + } else { + // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR + // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION + result->x = -quat2->y; + result->y = quat2->x; + result->z = -quat2->w; + result->w = quat2->z; + scale0 = sin((1.0 - slerp) * (float)HALF_PI); + scale1 = sin(slerp * (float)HALF_PI); + result->x = scale0 * quat1->x + scale1 * result->x; + result->y = scale0 * quat1->y + scale1 * result->y; + result->z = scale0 * quat1->z + scale1 * result->z; + result->w = scale0 * quat1->w + scale1 * result->w; + } + +} +// SlerpQuat ///////////////////////////////////////////////////////////////// diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.h index e841cdc..274526d 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Quatern.h @@ -1,61 +1,61 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.h : Quaternion System structure definition file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(QUATERN_H__INCLUDED_) -#define QUATERN_H__INCLUDED_ - -#include "Math.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(const tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(const tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(const tQuaternion *quat,tQuaternion *axisAngle); - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(const tQuaternion *quat1,const tQuaternion *quat2,const float slerp, tQuaternion *result); - -#endif // !defined(QUATERN_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.h : Quaternion System structure definition file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(QUATERN_H__INCLUDED_) +#define QUATERN_H__INCLUDED_ + +#include "Math.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(const tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(const tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(const tQuaternion *quat,tQuaternion *axisAngle); + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(const tQuaternion *quat1,const tQuaternion *quat2,const float slerp, tQuaternion *result); + +#endif // !defined(QUATERN_H__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/ReadMe.txt b/Real-time Skeletal Deformation/Code/OGL/SkinApp/ReadMe.txt index e113ca1..a6ed2c8 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/ReadMe.txt +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/ReadMe.txt @@ -1,113 +1,113 @@ -Skeletal Mesh Deformation April, 1998 - -This application demonstrates the use of weighted skeletal -mesh deformation in a real-time applications. - -There are two bones in the system; the upper arm and lower -arm. Well, really 3, but only two are able to be weighted. -The hand is just there to define the lower arm length. - -Controls: - -Select Bone to control via the Control menu options or -'1' or '2' to select upper arm or lower arm respectively. - -Mouse drag allows you to rotate the currently selected -bone. Left mouse button controls X and Y rotations and -Right mouse button controls Z rotation. - -CTRL+Drag allows you to move the system around the screen. - -SHIFT+Drag allows you select vertices to adjust the weighting -for. Left mouse button to select and Right mouse button to -deselect. - -SPACE to clear all vertex selections. - -Once vertices are selected, the Modify weights menu item brings -up a dialog that allows you to set the influence of each -bone on the selected vertices. Slide from 100% upper arm -control to 100% lower arm control. - -View can toggle on and off display of bones, geometry, and outline/ -filled polygon mode. - -File/Reset resets the system to the default of all vertices controlled -by upper arm. - -You can save and load weight files that hold the settings for the -system. - -There are three demo files created already: - -Arm.wgt = Fully weighted arm with vertices set to different percentages -Arm100%.wgt = Vertices are fully weighted to a bone. Either upper or lower arm -Arm50%.wgt = Vertices are fully weighted except a single row is 50-50 to each bone. - -This should allow you to easily see the problems with different setups. - -Source Code: - -This is the most complicated application I have provided so -far. There is a lot of code here but most of it is to try -and make a decent UI. The guts of the technique is quite -small really. I could make the code simpler but then the -app would be no fun. So bear with me on all the extra stuff. -Also, I know it is not real optimized but I wanted it very -clear what I was doing. Believe me when I say, I know most of -the tricks and my actual production code is faster but much -harder to get through. So please don't mail with comments like -"Your trig routines should use look-up tables." You guys -can have fun speeding it all up in your own individual projects. - -The main deformation routine is DeformBone in OGLView.cpp. -It is a recursive function that applies the deformation for -each bone to the main model. - -The code is set up with a three bones system. -Upper arm, Lower arm, and hand. -The hand is only there to define the length of the lower arm. -The engine would allow you to weight to the hand but the interface -would be a bunch more clumsy with relative weighting of three bones. -If you code the weightings yourself, you can set up as many bones and -weights as you like. I have tried up to 25 on a single mesh. - -There is also a second deformation that I used for debugging that I -left in there. It is the DeformModel function. It is a specific -case for a two bones system. It calculates the two positions and -linear interpolates based on the weight. It is faster since it -doesn't recurse through the full hierarchy. If you restrict your -system to have vertices only influenced by two bones, this may be -the way to go. - -To use the test case, remove the DEFORM_GENERAL_SOLUTION define -from the top of OGLView.cpp. - -The matrix code to do the non-OpenGL vector by matrix is called -MultVectorByMatrix in Matrix.cpp. - -The Quaternion code is also in here because I use it for my animation -system. It isn't really needed for this project. - -Things to do: - -You could pretty easily add these things to the source code making -the program more user friendly. - -Weighting Color Cues -It would be very easy to ID which bone influences which -vertex. Softimage does this by changing the colors of -vertex display to be the color of the bone that influences it. - -Weighting Dialog Defaults -Set the weighting dialog slider according to the average -weight of the selected vertices. - -DOF Restrictions -Use the Degree of Freedom variables in the bone structure -to store restrictions. In the User controls, use these -values to limit rotations. - -Any questions, email to jeffl@darwin3d.com - -Have fun. +Skeletal Mesh Deformation April, 1998 + +This application demonstrates the use of weighted skeletal +mesh deformation in a real-time applications. + +There are two bones in the system; the upper arm and lower +arm. Well, really 3, but only two are able to be weighted. +The hand is just there to define the lower arm length. + +Controls: + +Select Bone to control via the Control menu options or +'1' or '2' to select upper arm or lower arm respectively. + +Mouse drag allows you to rotate the currently selected +bone. Left mouse button controls X and Y rotations and +Right mouse button controls Z rotation. + +CTRL+Drag allows you to move the system around the screen. + +SHIFT+Drag allows you select vertices to adjust the weighting +for. Left mouse button to select and Right mouse button to +deselect. + +SPACE to clear all vertex selections. + +Once vertices are selected, the Modify weights menu item brings +up a dialog that allows you to set the influence of each +bone on the selected vertices. Slide from 100% upper arm +control to 100% lower arm control. + +View can toggle on and off display of bones, geometry, and outline/ +filled polygon mode. + +File/Reset resets the system to the default of all vertices controlled +by upper arm. + +You can save and load weight files that hold the settings for the +system. + +There are three demo files created already: + +Arm.wgt = Fully weighted arm with vertices set to different percentages +Arm100%.wgt = Vertices are fully weighted to a bone. Either upper or lower arm +Arm50%.wgt = Vertices are fully weighted except a single row is 50-50 to each bone. + +This should allow you to easily see the problems with different setups. + +Source Code: + +This is the most complicated application I have provided so +far. There is a lot of code here but most of it is to try +and make a decent UI. The guts of the technique is quite +small really. I could make the code simpler but then the +app would be no fun. So bear with me on all the extra stuff. +Also, I know it is not real optimized but I wanted it very +clear what I was doing. Believe me when I say, I know most of +the tricks and my actual production code is faster but much +harder to get through. So please don't mail with comments like +"Your trig routines should use look-up tables." You guys +can have fun speeding it all up in your own individual projects. + +The main deformation routine is DeformBone in OGLView.cpp. +It is a recursive function that applies the deformation for +each bone to the main model. + +The code is set up with a three bones system. +Upper arm, Lower arm, and hand. +The hand is only there to define the length of the lower arm. +The engine would allow you to weight to the hand but the interface +would be a bunch more clumsy with relative weighting of three bones. +If you code the weightings yourself, you can set up as many bones and +weights as you like. I have tried up to 25 on a single mesh. + +There is also a second deformation that I used for debugging that I +left in there. It is the DeformModel function. It is a specific +case for a two bones system. It calculates the two positions and +linear interpolates based on the weight. It is faster since it +doesn't recurse through the full hierarchy. If you restrict your +system to have vertices only influenced by two bones, this may be +the way to go. + +To use the test case, remove the DEFORM_GENERAL_SOLUTION define +from the top of OGLView.cpp. + +The matrix code to do the non-OpenGL vector by matrix is called +MultVectorByMatrix in Matrix.cpp. + +The Quaternion code is also in here because I use it for my animation +system. It isn't really needed for this project. + +Things to do: + +You could pretty easily add these things to the source code making +the program more user friendly. + +Weighting Color Cues +It would be very easy to ID which bone influences which +vertex. Softimage does this by changing the colors of +vertex display to be the color of the bone that influences it. + +Weighting Dialog Defaults +Set the weighting dialog slider according to the average +weight of the selected vertices. + +DOF Restrictions +Use the Degree of Freedom variables in the bone structure +to store restrictions. In the User controls, use these +values to limit rotations. + +Any questions, email to jeffl@darwin3d.com + +Have fun. diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.cpp index 1dd1fc4..bc8159e 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.cpp @@ -1,47 +1,47 @@ -// SetRot.cpp : implementation file -// - -#include "stdafx.h" -#include "SkinApp.h" -#include "SetRot.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSetRot dialog - - -CSetRot::CSetRot(CWnd* pParent /*=NULL*/) - : CDialog(CSetRot::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSetRot) - m_XAxis = 0.0f; - m_YAxis = 0.0f; - m_ZAxis = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSetRot::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSetRot) - DDX_Text(pDX, IDC_XAXIS, m_XAxis); - DDX_Text(pDX, IDC_YAXIS, m_YAxis); - DDX_Text(pDX, IDC_ZAXIS, m_ZAxis); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSetRot, CDialog) - //{{AFX_MSG_MAP(CSetRot) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSetRot message handlers +// SetRot.cpp : implementation file +// + +#include "stdafx.h" +#include "SkinApp.h" +#include "SetRot.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSetRot dialog + + +CSetRot::CSetRot(CWnd* pParent /*=NULL*/) + : CDialog(CSetRot::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSetRot) + m_XAxis = 0.0f; + m_YAxis = 0.0f; + m_ZAxis = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSetRot::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSetRot) + DDX_Text(pDX, IDC_XAXIS, m_XAxis); + DDX_Text(pDX, IDC_YAXIS, m_YAxis); + DDX_Text(pDX, IDC_ZAXIS, m_ZAxis); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSetRot, CDialog) + //{{AFX_MSG_MAP(CSetRot) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSetRot message handlers diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.h index bd7fd9f..2ec20f0 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SetRot.h @@ -1,48 +1,48 @@ -#if !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// SetRot.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSetRot dialog - -class CSetRot : public CDialog -{ -// Construction -public: - CSetRot(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSetRot) - enum { IDD = IDD_SETROTATE }; - float m_XAxis; - float m_YAxis; - float m_ZAxis; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSetRot) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSetRot) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) +#if !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// SetRot.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSetRot dialog + +class CSetRot : public CDialog +{ +// Construction +public: + CSetRot(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSetRot) + enum { IDD = IDD_SETROTATE }; + float m_XAxis; + float m_YAxis; + float m_ZAxis; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSetRot) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSetRot) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.cpp index 15e1f6e..4375717 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.cpp @@ -1,164 +1,164 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->p_scale.x = - bone->p_scale.y = - bone->p_scale.z = 1.0; - bone->s_scale.x = - bone->s_scale.y = - bone->s_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->p_rot.x = - bone->p_rot.y = - bone->p_rot.z = 0.0; - bone->s_rot.x = - bone->s_rot.y = - bone->s_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->p_trans.x = - bone->p_trans.y = - bone->p_trans.z = 0.0; - bone->s_trans.x = - bone->s_trans.y = - bone->s_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - bone->animBlend = 0.0; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->p_scale.x = + bone->p_scale.y = + bone->p_scale.z = 1.0; + bone->s_scale.x = + bone->s_scale.y = + bone->s_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->p_rot.x = + bone->p_rot.y = + bone->p_rot.z = 0.0; + bone->s_rot.x = + bone->s_rot.y = + bone->s_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->p_trans.x = + bone->p_trans.y = + bone->p_trans.z = 0.0; + bone->s_trans.x = + bone->s_trans.y = + bone->s_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + bone->animBlend = 0.0; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.h index 3dc62c6..8a40ebd 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Skeleton.h @@ -1,165 +1,165 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define MAX_FRAMES 100 /* MAXIMUM FRAMES PER DESC */ -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "Math.h" // GET THE TYPE FOR MATH STRUCTURES - -/// Structure Definitions /////////////////////////////////////////////////////// - -/* 3D OBJECT FRAME DEFINITION */ -typedef struct { - float *data; /* LIST OF DATA POINTS */ - tVector center; /* CALCED CENTER OF FRAME */ - long radius; /* MAX RADIUS FOR COLLISION */ -} tObjFrame; - -/* 3D OBJECT DESCRIPTION */ -typedef struct { - short cur_frame; /* WHAT FRAME AM I ON */ - short frameCnt; - long pointCnt; /* EACH DESCRIPTION MUST HAVE SAME POINT CNT */ - long polyCnt; - tObjFrame *frame[MAX_FRAMES]; /* LIST OF OBJECT FRAMES */ - long page_cnt; /* NUMBER OF TEXTURE PAGES */ - unsigned int glTex; /* TEXTURE ID */ - char textureName[80]; - long type; /* TYPE OF MODEL */ - long dataSize; /* SIZE OF A DATA ITEM */ -} tObjDesc; - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector p_scale; // PRIMARY SCALE FACTORS - tVector p_rot; // PRIMARY ROTATION FACTORS - tVector p_trans; // PRIMARY TRANSLATION FACTORS - tVector s_scale; // SECONDARY SCALE FACTORS - tVector s_rot; // SECONDARY ROTATION FACTORS - tVector s_trans; // SECONDARY TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - - // VISUAL ELEMENTS - long desc_count; /* NUMBER OF MIP MODELS */ - tObjDesc *desc; /* POINTER TO DESCRIPTIONS */ - long cur_desc; /* NUMBER OF MIP MODELS */ - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - long *visuals; // POINTER TO VISUALS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define MAX_FRAMES 100 /* MAXIMUM FRAMES PER DESC */ +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "Math.h" // GET THE TYPE FOR MATH STRUCTURES + +/// Structure Definitions /////////////////////////////////////////////////////// + +/* 3D OBJECT FRAME DEFINITION */ +typedef struct { + float *data; /* LIST OF DATA POINTS */ + tVector center; /* CALCED CENTER OF FRAME */ + long radius; /* MAX RADIUS FOR COLLISION */ +} tObjFrame; + +/* 3D OBJECT DESCRIPTION */ +typedef struct { + short cur_frame; /* WHAT FRAME AM I ON */ + short frameCnt; + long pointCnt; /* EACH DESCRIPTION MUST HAVE SAME POINT CNT */ + long polyCnt; + tObjFrame *frame[MAX_FRAMES]; /* LIST OF OBJECT FRAMES */ + long page_cnt; /* NUMBER OF TEXTURE PAGES */ + unsigned int glTex; /* TEXTURE ID */ + char textureName[80]; + long type; /* TYPE OF MODEL */ + long dataSize; /* SIZE OF A DATA ITEM */ +} tObjDesc; + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector p_scale; // PRIMARY SCALE FACTORS + tVector p_rot; // PRIMARY ROTATION FACTORS + tVector p_trans; // PRIMARY TRANSLATION FACTORS + tVector s_scale; // SECONDARY SCALE FACTORS + tVector s_rot; // SECONDARY ROTATION FACTORS + tVector s_trans; // SECONDARY TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + + // VISUAL ELEMENTS + long desc_count; /* NUMBER OF MIP MODELS */ + tObjDesc *desc; /* POINTER TO DESCRIPTIONS */ + long cur_desc; /* NUMBER OF MIP MODELS */ + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + long *visuals; // POINTER TO VISUALS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.cpp index b571f30..e34a603 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.cpp @@ -1,158 +1,158 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// SkinApp.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// Revisions: -// Integrated into Skinning Demo 2/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "SkinApp.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSkinApp - -BEGIN_MESSAGE_MAP(CSkinApp, CWinApp) - //{{AFX_MSG_MAP(CSkinApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands - ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) - ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSkinApp construction - -CSkinApp::CSkinApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSkinApp object - -CSkinApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSkinApp initialization - -BOOL CSkinApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - // SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSkinApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSkinApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// SkinApp.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// Revisions: +// Integrated into Skinning Demo 2/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "SkinApp.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSkinApp + +BEGIN_MESSAGE_MAP(CSkinApp, CWinApp) + //{{AFX_MSG_MAP(CSkinApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands + ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) + ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSkinApp construction + +CSkinApp::CSkinApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSkinApp object + +CSkinApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSkinApp initialization + +BOOL CSkinApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + // SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSkinApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSkinApp commands diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.h index f6bc20c..4913dc3 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/SkinApp.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// SkinApp.h : main header file for the SkinApp Demo -// -// Purpose: header of Main Application of Quaternion Animation System -// -// Created: -// JL 2/18/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SkinApp_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SkinApp_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CSkinApp: -// See SkinApp.cpp for the implementation of this class -// - -class CSkinApp : public CWinApp -{ -public: - CSkinApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSkinApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSkinApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SkinApp_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// SkinApp.h : main header file for the SkinApp Demo +// +// Purpose: header of Main Application of Quaternion Animation System +// +// Created: +// JL 2/18/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SkinApp_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SkinApp_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CSkinApp: +// See SkinApp.cpp for the implementation of this class +// + +class CSkinApp : public CWinApp +{ +public: + CSkinApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSkinApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSkinApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SkinApp_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.cpp index 3307002..228dea4 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Slash.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Slash.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.h index ddefdab..571c76c 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.cpp b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.cpp index 9b04672..73c4c1d 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.cpp +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.cpp @@ -1,68 +1,68 @@ -// Weight.cpp : implementation file -// - -#include "stdafx.h" -#include "skinapp.h" -#include "Weight.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CWeight dialog - - -CWeight::CWeight(CWnd* pParent /*=NULL*/) - : CDialog(CWeight::IDD, pParent) -{ - //{{AFX_DATA_INIT(CWeight) - // NOTE: the ClassWizard will add member initialization here - //}}AFX_DATA_INIT -} - - -void CWeight::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CWeight) - DDX_Control(pDX, IDC_SLIDER1, m_Slider); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CWeight, CDialog) - //{{AFX_MSG_MAP(CWeight) - ON_WM_CREATE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CWeight message handlers - -int CWeight::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CDialog::OnCreate(lpCreateStruct) == -1) - return -1; - - return 0; -} - -BOOL CWeight::DestroyWindow() -{ - m_pos = m_Slider.GetPos(); - return CDialog::DestroyWindow(); -} - -BOOL CWeight::OnInitDialog() -{ - CDialog::OnInitDialog(); - - m_Slider.SetRange( 0, 256, TRUE); -// m_Slider.SetSelection( 0, 256 ); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE -} +// Weight.cpp : implementation file +// + +#include "stdafx.h" +#include "skinapp.h" +#include "Weight.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CWeight dialog + + +CWeight::CWeight(CWnd* pParent /*=NULL*/) + : CDialog(CWeight::IDD, pParent) +{ + //{{AFX_DATA_INIT(CWeight) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void CWeight::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CWeight) + DDX_Control(pDX, IDC_SLIDER1, m_Slider); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CWeight, CDialog) + //{{AFX_MSG_MAP(CWeight) + ON_WM_CREATE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CWeight message handlers + +int CWeight::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CDialog::OnCreate(lpCreateStruct) == -1) + return -1; + + return 0; +} + +BOOL CWeight::DestroyWindow() +{ + m_pos = m_Slider.GetPos(); + return CDialog::DestroyWindow(); +} + +BOOL CWeight::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_Slider.SetRange( 0, 256, TRUE); +// m_Slider.SetSelection( 0, 256 ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.h index e502c03..b1f0cc5 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/Weight.h @@ -1,51 +1,51 @@ -#if !defined(AFX_WEIGHT_H__04F2D720_B669_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_WEIGHT_H__04F2D720_B669_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// Weight.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CWeight dialog - -class CWeight : public CDialog -{ -public: - int m_pos; -// Construction -public: - CWeight(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CWeight) - enum { IDD = IDD_SET_WEIGHTS }; - CSliderCtrl m_Slider; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CWeight) - public: - virtual BOOL DestroyWindow(); - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CWeight) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - virtual BOOL OnInitDialog(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_WEIGHT_H__04F2D720_B669_11D1_83A0_004005308EB5__INCLUDED_) +#if !defined(AFX_WEIGHT_H__04F2D720_B669_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_WEIGHT_H__04F2D720_B669_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// Weight.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CWeight dialog + +class CWeight : public CDialog +{ +public: + int m_pos; +// Construction +public: + CWeight(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CWeight) + enum { IDD = IDD_SET_WEIGHTS }; + CSliderCtrl m_Slider; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CWeight) + public: + virtual BOOL DestroyWindow(); + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CWeight) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_WEIGHT_H__04F2D720_B669_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Real-time Skeletal Deformation/Code/OGL/SkinApp/resource.h b/Real-time Skeletal Deformation/Code/OGL/SkinApp/resource.h index e49550b..adb10d5 100644 --- a/Real-time Skeletal Deformation/Code/OGL/SkinApp/resource.h +++ b/Real-time Skeletal Deformation/Code/OGL/SkinApp/resource.h @@ -1,40 +1,40 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by SkinApp.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SKINTYPE 129 -#define IDD_SETROTATE 130 -#define IDD_SET_WEIGHTS 132 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_ZAXIS 1002 -#define IDC_SLIDER1 1002 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_ENDKEY 32776 -#define ID_VIEW_BONESYSTEM 32777 -#define ID_CONTROL_UPPERARM 32778 -#define ID_CONTROL_LOWERARM 32779 -#define ID_VIEW_OUTLINE 32780 -#define ID_MODIFYWEIGHTS 32781 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_ROT3 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROTB 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 133 -#define _APS_NEXT_COMMAND_VALUE 32782 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by SkinApp.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SKINTYPE 129 +#define IDD_SETROTATE 130 +#define IDD_SET_WEIGHTS 132 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_ZAXIS 1002 +#define IDC_SLIDER1 1002 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_ENDKEY 32776 +#define ID_VIEW_BONESYSTEM 32777 +#define ID_CONTROL_UPPERARM 32778 +#define ID_CONTROL_LOWERARM 32779 +#define ID_VIEW_OUTLINE 32780 +#define ID_MODIFYWEIGHTS 32781 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_ROT3 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROTB 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 133 +#define _APS_NEXT_COMMAND_VALUE 32782 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Skeletal Deformation/Code/OGL/Skully/HierWin.cpp b/Skeletal Deformation/Code/OGL/Skully/HierWin.cpp index 9798153..902a633 100644 --- a/Skeletal Deformation/Code/OGL/Skully/HierWin.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/HierWin.cpp @@ -1,303 +1,303 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// HierWin.cpp : implementation file -// -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Skully.h" -#include "HierWin.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CHierWin - -CHierWin::CHierWin() -{ - m_Skeleton = NULL; -} - -CHierWin::~CHierWin() -{ -} - - -BOOL CHierWin::PreCreateWindow(CREATESTRUCT& cs) -{ - CString className; - HCURSOR arrow; - - arrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -// className = AfxRegisterWndClass(NULL, -// (HCURSOR)arrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), 0); //m_HArrow -// cs.lpszClass = className; - - return CTreeCtrl::PreCreateWindow(cs); -} - -int CHierWin::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) - return -1; - - ResetSkeleton(); - return 0; -} - -void CHierWin::ResetSkeleton() -{ - DeleteAllItems(); // CLEAR THE CONTROL - m_TreeRoot = InsertItem( "Skeleton", TVI_ROOT, TVI_LAST ); - // SET THE ROOT DATA TO NULL - SetItemData( m_TreeRoot, NULL ); -} - -void CHierWin::SetSkeleton(t_Bone *skeleton, HTREEITEM item) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; - HTREEITEM curItem; -/////////////////////////////////////////////////////////////////////////////// - - if (item == NULL) - { - item = m_TreeRoot; - m_Skeleton = skeleton; - SetItemData( item, (DWORD)m_Skeleton ); - } - - if (skeleton->childCnt > 0) - { - child = skeleton->children; - for (loop = 0; loop < skeleton->childCnt; loop++,child++) - { - curItem = InsertItem( child->name, item, TVI_LAST ); - SetItemData( curItem, (DWORD)child ); - EnsureVisible( curItem ); - if (child->childCnt > 0) - SetSkeleton(child,curItem); - } - } -} - -void CHierWin::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - // RESET FOCUS TO MAINFRAME - // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS - GetParent()->SetFocus( ); - //CTreeCtrl::OnKeyUp(nChar, nRepCnt, nFlags); -} - -void CHierWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - // RESET FOCUS TO MAINFRAME - // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS - GetParent()->SetFocus( ); - //CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags); -} - -BEGIN_MESSAGE_MAP(CHierWin, CTreeCtrl) - //{{AFX_MSG_MAP(CHierWin) - ON_WM_CREATE() - ON_WM_KEYUP() - ON_WM_KEYDOWN() - ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) - ON_WM_LBUTTONUP() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CHierWin message handlers - -void CHierWin::OnLButtonUp(UINT nFlags, CPoint point) -{ - // RESET FOCUS TO MAINFRAME - // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS - GetParent()->SetFocus( ); - - CTreeCtrl::OnLButtonUp(nFlags, point); -} - -void CHierWin::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - EditBone(); - CTreeCtrl::OnLButtonDblClk(nFlags, point); -} - -void CHierWin::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) -{ - NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; - if (m_Skeleton > NULL) - m_Skeleton->id = GetItemData(GetSelectedItem()); - GetParent()->Invalidate(TRUE ); - *pResult = 0; -} - -void CHierWin::AddBone() -{ -/// Local Variables /////////////////////////////////////////////////////////// - HTREEITEM item,curItem; - CBoneInfo dialog; - t_Bone *bonePtr; -/////////////////////////////////////////////////////////////////////////////// - item = GetSelectedItem(); - if (item == NULL) - { - dialog.m_Trans_X = m_Skeleton->trans.x; - dialog.m_Trans_Y = m_Skeleton->trans.y; - dialog.m_Trans_Z = m_Skeleton->trans.z; - dialog.m_Rot_X = m_Skeleton->rot.x; - dialog.m_Rot_Y = m_Skeleton->rot.y; - dialog.m_Rot_Z = m_Skeleton->rot.z; - } - else - { - bonePtr = (t_Bone *)GetItemData( item); - dialog.m_Rot_X = 0.0f; - dialog.m_Rot_Y = 0.0f; - dialog.m_Rot_Z = 0.0f; - dialog.m_Trans_X = 0.0f; - dialog.m_Trans_Y = 0.0f; - dialog.m_Trans_Z = 0.0f; - } - if (dialog.DoModal()) - { - if (item == NULL) - InsertItem( dialog.m_BoneName, TVI_ROOT, TVI_LAST ); - else - curItem = InsertItem( dialog.m_BoneName, item, TVI_LAST ); - EnsureVisible( curItem ); - } -} - -void CHierWin::EditBone() -{ -/// Local Variables /////////////////////////////////////////////////////////// - HTREEITEM item; - CBoneInfo dialog; - t_Bone *bonePtr; -/////////////////////////////////////////////////////////////////////////////// - item = GetSelectedItem(); - if (item != NULL) - { - bonePtr = (t_Bone *)GetItemData( item); - dialog.m_BoneName = bonePtr->name; - dialog.m_Trans_X = bonePtr->trans.x; - dialog.m_Trans_Y = bonePtr->trans.y; - dialog.m_Trans_Z = bonePtr->trans.z; - dialog.m_Rot_X = bonePtr->rot.x; - dialog.m_Rot_Y = bonePtr->rot.y; - dialog.m_Rot_Z = bonePtr->rot.z; - dialog.m_MinX = bonePtr->min_rx; - dialog.m_MaxX = bonePtr->max_rx; - dialog.m_MinY = bonePtr->min_ry; - dialog.m_MaxY = bonePtr->max_ry; - dialog.m_MinZ = bonePtr->min_rz; - dialog.m_MaxZ = bonePtr->max_rz; - dialog.m_DOF_Active = (bonePtr->flags & BONE_DOF_ACTIVE) > 0; - - dialog.m_Weight = bonePtr->animBlend; - if (dialog.DoModal()) - { - strcpy(bonePtr->name,(LPCTSTR)(dialog.m_BoneName)); - bonePtr->trans.x = dialog.m_Trans_X; - bonePtr->trans.y = dialog.m_Trans_Y; - bonePtr->trans.z = dialog.m_Trans_Z; - bonePtr->rot.x = dialog.m_Rot_X; - bonePtr->rot.y = dialog.m_Rot_Y; - bonePtr->rot.z = dialog.m_Rot_Z; - bonePtr->min_rx = dialog.m_MinX; - bonePtr->max_rx = dialog.m_MaxX; - bonePtr->min_ry = dialog.m_MinY; - bonePtr->max_ry = dialog.m_MaxY; - bonePtr->min_rz = dialog.m_MinZ; - bonePtr->max_rz = dialog.m_MaxZ; - bonePtr->animBlend = dialog.m_Weight; - if (dialog.m_DOF_Active) - bonePtr->flags |= BONE_DOF_ACTIVE; - else - bonePtr->flags = (bonePtr->flags & (~BONE_DOF_ACTIVE)); - } - } -} - -///////////////////////////////////////////////////////////////////////////// -// CBoneInfo dialog - - -CBoneInfo::CBoneInfo(CWnd* pParent /*=NULL*/) - : CDialog(CBoneInfo::IDD, pParent) -{ - //{{AFX_DATA_INIT(CBoneInfo) - m_BoneName = _T(""); - m_Rot_X = 0.0f; - m_Rot_Y = 0.0f; - m_Rot_Z = 0.0f; - m_Trans_X = 0.0f; - m_Trans_Y = 0.0f; - m_Trans_Z = 0.0f; - m_MaxX = 0.0f; - m_MaxY = 0.0f; - m_MaxZ = 0.0f; - m_MinX = 0.0f; - m_MinY = 0.0f; - m_MinZ = 0.0f; - m_DOF_Active = FALSE; - m_Weight = 0.0f; - //}}AFX_DATA_INIT -} - - -void CBoneInfo::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CBoneInfo) - DDX_Text(pDX, IDC_BONE_NAME, m_BoneName); - DDX_Text(pDX, IDC_ROT_X, m_Rot_X); - DDX_Text(pDX, IDC_ROT_Y, m_Rot_Y); - DDX_Text(pDX, IDC_ROT_Z, m_Rot_Z); - DDX_Text(pDX, IDC_TRANS_X, m_Trans_X); - DDX_Text(pDX, IDC_TRANS_Y, m_Trans_Y); - DDX_Text(pDX, IDC_TRANS_Z, m_Trans_Z); - DDX_Text(pDX, IDC_MAX_X, m_MaxX); - DDX_Text(pDX, IDC_MAX_Y, m_MaxY); - DDX_Text(pDX, IDC_MAX_Z, m_MaxZ); - DDX_Text(pDX, IDC_MIN_X, m_MinX); - DDX_Text(pDX, IDC_MIN_Y, m_MinY); - DDX_Text(pDX, IDC_MIN_Z, m_MinZ); - DDX_Check(pDX, IDC_DOF_ACTIVE, m_DOF_Active); - DDX_Text(pDX, IDC_BONEWEIGHT, m_Weight); - DDV_MinMaxFloat(pDX, m_Weight, 0.f, 1.f); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CBoneInfo, CDialog) - //{{AFX_MSG_MAP(CBoneInfo) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CBoneInfo message handlers -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. +/////////////////////////////////////////////////////////////////////////////// +// +// HierWin.cpp : implementation file +// +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Skully.h" +#include "HierWin.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CHierWin + +CHierWin::CHierWin() +{ + m_Skeleton = NULL; +} + +CHierWin::~CHierWin() +{ +} + + +BOOL CHierWin::PreCreateWindow(CREATESTRUCT& cs) +{ + CString className; + HCURSOR arrow; + + arrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +// className = AfxRegisterWndClass(NULL, +// (HCURSOR)arrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), 0); //m_HArrow +// cs.lpszClass = className; + + return CTreeCtrl::PreCreateWindow(cs); +} + +int CHierWin::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) + return -1; + + ResetSkeleton(); + return 0; +} + +void CHierWin::ResetSkeleton() +{ + DeleteAllItems(); // CLEAR THE CONTROL + m_TreeRoot = InsertItem( "Skeleton", TVI_ROOT, TVI_LAST ); + // SET THE ROOT DATA TO NULL + SetItemData( m_TreeRoot, NULL ); +} + +void CHierWin::SetSkeleton(t_Bone *skeleton, HTREEITEM item) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; + HTREEITEM curItem; +/////////////////////////////////////////////////////////////////////////////// + + if (item == NULL) + { + item = m_TreeRoot; + m_Skeleton = skeleton; + SetItemData( item, (DWORD)m_Skeleton ); + } + + if (skeleton->childCnt > 0) + { + child = skeleton->children; + for (loop = 0; loop < skeleton->childCnt; loop++,child++) + { + curItem = InsertItem( child->name, item, TVI_LAST ); + SetItemData( curItem, (DWORD)child ); + EnsureVisible( curItem ); + if (child->childCnt > 0) + SetSkeleton(child,curItem); + } + } +} + +void CHierWin::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + // RESET FOCUS TO MAINFRAME + // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS + GetParent()->SetFocus( ); + //CTreeCtrl::OnKeyUp(nChar, nRepCnt, nFlags); +} + +void CHierWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + // RESET FOCUS TO MAINFRAME + // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS + GetParent()->SetFocus( ); + //CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags); +} + +BEGIN_MESSAGE_MAP(CHierWin, CTreeCtrl) + //{{AFX_MSG_MAP(CHierWin) + ON_WM_CREATE() + ON_WM_KEYUP() + ON_WM_KEYDOWN() + ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) + ON_WM_LBUTTONUP() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CHierWin message handlers + +void CHierWin::OnLButtonUp(UINT nFlags, CPoint point) +{ + // RESET FOCUS TO MAINFRAME + // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS + GetParent()->SetFocus( ); + + CTreeCtrl::OnLButtonUp(nFlags, point); +} + +void CHierWin::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + EditBone(); + CTreeCtrl::OnLButtonDblClk(nFlags, point); +} + +void CHierWin::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; + if (m_Skeleton > NULL) + m_Skeleton->id = GetItemData(GetSelectedItem()); + GetParent()->Invalidate(TRUE ); + *pResult = 0; +} + +void CHierWin::AddBone() +{ +/// Local Variables /////////////////////////////////////////////////////////// + HTREEITEM item,curItem; + CBoneInfo dialog; + t_Bone *bonePtr; +/////////////////////////////////////////////////////////////////////////////// + item = GetSelectedItem(); + if (item == NULL) + { + dialog.m_Trans_X = m_Skeleton->trans.x; + dialog.m_Trans_Y = m_Skeleton->trans.y; + dialog.m_Trans_Z = m_Skeleton->trans.z; + dialog.m_Rot_X = m_Skeleton->rot.x; + dialog.m_Rot_Y = m_Skeleton->rot.y; + dialog.m_Rot_Z = m_Skeleton->rot.z; + } + else + { + bonePtr = (t_Bone *)GetItemData( item); + dialog.m_Rot_X = 0.0f; + dialog.m_Rot_Y = 0.0f; + dialog.m_Rot_Z = 0.0f; + dialog.m_Trans_X = 0.0f; + dialog.m_Trans_Y = 0.0f; + dialog.m_Trans_Z = 0.0f; + } + if (dialog.DoModal()) + { + if (item == NULL) + InsertItem( dialog.m_BoneName, TVI_ROOT, TVI_LAST ); + else + curItem = InsertItem( dialog.m_BoneName, item, TVI_LAST ); + EnsureVisible( curItem ); + } +} + +void CHierWin::EditBone() +{ +/// Local Variables /////////////////////////////////////////////////////////// + HTREEITEM item; + CBoneInfo dialog; + t_Bone *bonePtr; +/////////////////////////////////////////////////////////////////////////////// + item = GetSelectedItem(); + if (item != NULL) + { + bonePtr = (t_Bone *)GetItemData( item); + dialog.m_BoneName = bonePtr->name; + dialog.m_Trans_X = bonePtr->trans.x; + dialog.m_Trans_Y = bonePtr->trans.y; + dialog.m_Trans_Z = bonePtr->trans.z; + dialog.m_Rot_X = bonePtr->rot.x; + dialog.m_Rot_Y = bonePtr->rot.y; + dialog.m_Rot_Z = bonePtr->rot.z; + dialog.m_MinX = bonePtr->min_rx; + dialog.m_MaxX = bonePtr->max_rx; + dialog.m_MinY = bonePtr->min_ry; + dialog.m_MaxY = bonePtr->max_ry; + dialog.m_MinZ = bonePtr->min_rz; + dialog.m_MaxZ = bonePtr->max_rz; + dialog.m_DOF_Active = (bonePtr->flags & BONE_DOF_ACTIVE) > 0; + + dialog.m_Weight = bonePtr->animBlend; + if (dialog.DoModal()) + { + strcpy(bonePtr->name,(LPCTSTR)(dialog.m_BoneName)); + bonePtr->trans.x = dialog.m_Trans_X; + bonePtr->trans.y = dialog.m_Trans_Y; + bonePtr->trans.z = dialog.m_Trans_Z; + bonePtr->rot.x = dialog.m_Rot_X; + bonePtr->rot.y = dialog.m_Rot_Y; + bonePtr->rot.z = dialog.m_Rot_Z; + bonePtr->min_rx = dialog.m_MinX; + bonePtr->max_rx = dialog.m_MaxX; + bonePtr->min_ry = dialog.m_MinY; + bonePtr->max_ry = dialog.m_MaxY; + bonePtr->min_rz = dialog.m_MinZ; + bonePtr->max_rz = dialog.m_MaxZ; + bonePtr->animBlend = dialog.m_Weight; + if (dialog.m_DOF_Active) + bonePtr->flags |= BONE_DOF_ACTIVE; + else + bonePtr->flags = (bonePtr->flags & (~BONE_DOF_ACTIVE)); + } + } +} + +///////////////////////////////////////////////////////////////////////////// +// CBoneInfo dialog + + +CBoneInfo::CBoneInfo(CWnd* pParent /*=NULL*/) + : CDialog(CBoneInfo::IDD, pParent) +{ + //{{AFX_DATA_INIT(CBoneInfo) + m_BoneName = _T(""); + m_Rot_X = 0.0f; + m_Rot_Y = 0.0f; + m_Rot_Z = 0.0f; + m_Trans_X = 0.0f; + m_Trans_Y = 0.0f; + m_Trans_Z = 0.0f; + m_MaxX = 0.0f; + m_MaxY = 0.0f; + m_MaxZ = 0.0f; + m_MinX = 0.0f; + m_MinY = 0.0f; + m_MinZ = 0.0f; + m_DOF_Active = FALSE; + m_Weight = 0.0f; + //}}AFX_DATA_INIT +} + + +void CBoneInfo::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CBoneInfo) + DDX_Text(pDX, IDC_BONE_NAME, m_BoneName); + DDX_Text(pDX, IDC_ROT_X, m_Rot_X); + DDX_Text(pDX, IDC_ROT_Y, m_Rot_Y); + DDX_Text(pDX, IDC_ROT_Z, m_Rot_Z); + DDX_Text(pDX, IDC_TRANS_X, m_Trans_X); + DDX_Text(pDX, IDC_TRANS_Y, m_Trans_Y); + DDX_Text(pDX, IDC_TRANS_Z, m_Trans_Z); + DDX_Text(pDX, IDC_MAX_X, m_MaxX); + DDX_Text(pDX, IDC_MAX_Y, m_MaxY); + DDX_Text(pDX, IDC_MAX_Z, m_MaxZ); + DDX_Text(pDX, IDC_MIN_X, m_MinX); + DDX_Text(pDX, IDC_MIN_Y, m_MinY); + DDX_Text(pDX, IDC_MIN_Z, m_MinZ); + DDX_Check(pDX, IDC_DOF_ACTIVE, m_DOF_Active); + DDX_Text(pDX, IDC_BONEWEIGHT, m_Weight); + DDV_MinMaxFloat(pDX, m_Weight, 0.f, 1.f); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CBoneInfo, CDialog) + //{{AFX_MSG_MAP(CBoneInfo) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CBoneInfo message handlers +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. diff --git a/Skeletal Deformation/Code/OGL/Skully/Hierwin.h b/Skeletal Deformation/Code/OGL/Skully/Hierwin.h index 431a679..a47f082 100644 --- a/Skeletal Deformation/Code/OGL/Skully/Hierwin.h +++ b/Skeletal Deformation/Code/OGL/Skully/Hierwin.h @@ -1,124 +1,124 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// HierWin.h : class definition file -// -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// HierWin.h : header file -// -#include "Skeleton.h" - -///////////////////////////////////////////////////////////////////////////// -// CHierWin window - -class CHierWin : public CTreeCtrl -{ -// Construction -public: - CHierWin(); - -// Attributes -protected: - HTREEITEM m_TreeRoot; - t_Bone *m_Skeleton; -// Operations -public: - void ResetSkeleton(); - void SetSkeleton(t_Bone *skeleton, HTREEITEM item); - void AddBone(); - -protected: - void EditBone(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CHierWin) - protected: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CHierWin(); - - // Generated message map functions -protected: - //{{AFX_MSG(CHierWin) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CBoneInfo dialog - -class CBoneInfo : public CDialog -{ -// Construction -public: - CBoneInfo(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CBoneInfo) - enum { IDD = IDD_BONE_INFO }; - CString m_BoneName; - float m_Rot_X; - float m_Rot_Y; - float m_Rot_Z; - float m_Trans_X; - float m_Trans_Y; - float m_Trans_Z; - float m_MaxX; - float m_MaxY; - float m_MaxZ; - float m_MinX; - float m_MinY; - float m_MinZ; - BOOL m_DOF_Active; - float m_Weight; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CBoneInfo) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CBoneInfo) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -#endif // !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// HierWin.h : class definition file +// +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// HierWin.h : header file +// +#include "Skeleton.h" + +///////////////////////////////////////////////////////////////////////////// +// CHierWin window + +class CHierWin : public CTreeCtrl +{ +// Construction +public: + CHierWin(); + +// Attributes +protected: + HTREEITEM m_TreeRoot; + t_Bone *m_Skeleton; +// Operations +public: + void ResetSkeleton(); + void SetSkeleton(t_Bone *skeleton, HTREEITEM item); + void AddBone(); + +protected: + void EditBone(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CHierWin) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CHierWin(); + + // Generated message map functions +protected: + //{{AFX_MSG(CHierWin) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CBoneInfo dialog + +class CBoneInfo : public CDialog +{ +// Construction +public: + CBoneInfo(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CBoneInfo) + enum { IDD = IDD_BONE_INFO }; + CString m_BoneName; + float m_Rot_X; + float m_Rot_Y; + float m_Rot_Z; + float m_Trans_X; + float m_Trans_Y; + float m_Trans_Z; + float m_MaxX; + float m_MaxY; + float m_MaxZ; + float m_MinX; + float m_MinY; + float m_MinZ; + BOOL m_DOF_Active; + float m_Weight; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CBoneInfo) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CBoneInfo) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#endif // !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.cpp b/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.cpp index 1ec3730..2102a55 100644 --- a/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.cpp @@ -1,358 +1,358 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = (float)atof(words.GetAt(1)); - visual->Ka.g = (float)atof(words.GetAt(2)); - visual->Ka.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = (float)atof(words.GetAt(1)); - visual->Kd.g = (float)atof(words.GetAt(2)); - visual->Kd.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = (float)atof(words.GetAt(1)); - visual->Ks.g = (float)atof(words.GetAt(2)); - visual->Ks.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = (float)atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle anything other than -// 3-4 vertex polygons. -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loopcnt; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - loopcnt = words->GetSize(); - - // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < loopcnt; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } - face->flags = 0; - if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; - if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; - if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; - else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; - else - { - ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); - face->flags |= FACE_TYPE_TRI; - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(const char *filename,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = (float)atof(words.GetAt(1)); - normal[nPos].y = (float)atof(words.GetAt(2)); - normal[nPos].z = (float)atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = (float)atof(words.GetAt(1)); - texture[tPos].v = (float)atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = (float)atof(words.GetAt(1)); - vertex[vPos].y = (float)atof(words.GetAt(2)); - vertex[vPos].z = (float)atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 5) - { - sprintf(buffer,"Face %d has more than 4 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS - // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF - // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER - if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; - else visual->vPerFace = 4; - - if (nCnt > 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->deformData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->CV_select = (BOOL *)malloc(sizeof(BOOL) * visual->vSize * fPos * visual->vPerFace); - visual->faceCnt = fPos; - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->deformData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->CV_select = (BOOL *)malloc(sizeof(BOOL) * visual->vSize * fPos * visual->vPerFace); - visual->faceCnt = fPos; - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->deformData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->CV_select = (BOOL *)malloc(sizeof(BOOL) * visual->vSize * fPos * visual->vPerFace); - visual->faceCnt = fPos; - } - - visual->vertexCnt = visual->vPerFace * visual->faceCnt; // Set the vertex count - - data = visual->vertexData; - for (loop = 0; loop < fPos; loop++) - { - // ERROR CHECKING TO MAKE SURE - if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - - for (loop2 = 0; loop2 < visual->vPerFace; loop2++) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - - visual->CV_select[(loop * visual->vPerFace) + loop2] = FALSE; - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = (float)atof(words.GetAt(1)); + visual->Ka.g = (float)atof(words.GetAt(2)); + visual->Ka.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = (float)atof(words.GetAt(1)); + visual->Kd.g = (float)atof(words.GetAt(2)); + visual->Kd.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = (float)atof(words.GetAt(1)); + visual->Ks.g = (float)atof(words.GetAt(2)); + visual->Ks.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = (float)atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle anything other than +// 3-4 vertex polygons. +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loopcnt; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + loopcnt = words->GetSize(); + + // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < loopcnt; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } + face->flags = 0; + if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; + if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; + if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; + else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; + else + { + ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); + face->flags |= FACE_TYPE_TRI; + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(const char *filename,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = (float)atof(words.GetAt(1)); + normal[nPos].y = (float)atof(words.GetAt(2)); + normal[nPos].z = (float)atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = (float)atof(words.GetAt(1)); + texture[tPos].v = (float)atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = (float)atof(words.GetAt(1)); + vertex[vPos].y = (float)atof(words.GetAt(2)); + vertex[vPos].z = (float)atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 5) + { + sprintf(buffer,"Face %d has more than 4 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS + // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF + // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER + if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; + else visual->vPerFace = 4; + + if (nCnt > 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->deformData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->CV_select = (BOOL *)malloc(sizeof(BOOL) * visual->vSize * fPos * visual->vPerFace); + visual->faceCnt = fPos; + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->deformData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->CV_select = (BOOL *)malloc(sizeof(BOOL) * visual->vSize * fPos * visual->vPerFace); + visual->faceCnt = fPos; + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->deformData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->CV_select = (BOOL *)malloc(sizeof(BOOL) * visual->vSize * fPos * visual->vPerFace); + visual->faceCnt = fPos; + } + + visual->vertexCnt = visual->vPerFace * visual->faceCnt; // Set the vertex count + + data = visual->vertexData; + for (loop = 0; loop < fPos; loop++) + { + // ERROR CHECKING TO MAKE SURE + if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + + for (loop2 = 0; loop2 < visual->vPerFace; loop2++) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + + visual->CV_select[(loop * visual->vPerFace) + loop2] = FALSE; + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.h b/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.h index 19798a8..1b4bfe6 100644 --- a/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.h +++ b/Skeletal Deformation/Code/OGL/Skully/LoadOBJ.h @@ -1,39 +1,39 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS -typedef struct -{ - long v[4],n[4],t[4]; - int flags; // FACE TYPES -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(const char *filename,t_Visual *visual); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS +typedef struct +{ + long v[4],n[4],t[4]; + int flags; // FACE TYPES +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(const char *filename,t_Visual *visual); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/LoadSkel.cpp b/Skeletal Deformation/Code/OGL/Skully/LoadSkel.cpp index c962fb8..d5b1e93 100644 --- a/Skeletal Deformation/Code/OGL/Skully/LoadSkel.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/LoadSkel.cpp @@ -1,169 +1,169 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadSkel.cpp -// -// Purpose: implementation of the Custom Skeleton file Loader -// -// Created: -// JL 9/12/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "LoadSkel.h" - - -#define MAX_CHILDREN 8 -typedef struct -{ - void *parent; - void *child[MAX_CHILDREN]; - int childCnt; - float tx,ty,tz; - float rx,ry,rz; - char name[80]; -} tSkeletonNode; - - -/////////////////////////////////////////////////////////////////////////////// -// Fixes up the skeletal structure once it is loaded -/////////////////////////////////////////////////////////////////////////////// -void AddDarwinBranch(t_Bone *root, tSkeletonNode *curNode,tSkeletonNode *baseNode) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int i; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - root->children = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); - for (i = 0; i < root->childCnt; i++) - { - child = &root->children[i]; - ResetBone(child,root); - strcpy(child->name,baseNode[(int)curNode->child[i]].name); - child->trans.x = baseNode[(int)curNode->child[i]].tx; - child->trans.y = baseNode[(int)curNode->child[i]].ty; - child->trans.z = baseNode[(int)curNode->child[i]].tz; - child->rot.x = baseNode[(int)curNode->child[i]].rx; - child->rot.y = baseNode[(int)curNode->child[i]].ry; - child->rot.z = baseNode[(int)curNode->child[i]].rz; - child->b_trans.x = baseNode[(int)curNode->child[i]].tx; - child->b_trans.y = baseNode[(int)curNode->child[i]].ty; - child->b_trans.z = baseNode[(int)curNode->child[i]].tz; - child->b_rot.x = baseNode[(int)curNode->child[i]].rx; - child->b_rot.y = baseNode[(int)curNode->child[i]].ry; - child->b_rot.z = baseNode[(int)curNode->child[i]].rz; - child->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); - child->childCnt = baseNode[(int)curNode->child[i]].childCnt; - if (child->childCnt > 0) - { - AddDarwinBranch(child,&baseNode[(int)curNode->child[i]],baseNode); - } - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadSkeleton -// Purpose: Load a Darwin Format Skeleton -// Arguments: Name of the file to open and root skeleton to put it in -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadSkeleton(CString name,t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int i,j,boneCnt,parent; - FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS - tSkeletonNode *tempBone,*bonelist; - t_Bone *child; - char temp[5]; -/////////////////////////////////////////////////////////////////////////////// - if (fp = fopen((LPCTSTR)name,"rb")) { - fread(temp,sizeof(char),4,fp); - fread(&boneCnt,sizeof(int),1,fp); - bonelist = (tSkeletonNode *)malloc((boneCnt) * sizeof(tSkeletonNode)); - for (i = 0; i < boneCnt; i++) - { - tempBone = &bonelist[i]; - fread(tempBone->name,sizeof(char),80,fp); - fread(&tempBone->tx,sizeof(float),1,fp); - fread(&tempBone->ty,sizeof(float),1,fp); - fread(&tempBone->tz,sizeof(float),1,fp); - fread(&tempBone->rx,sizeof(float),1,fp); - fread(&tempBone->ry,sizeof(float),1,fp); - fread(&tempBone->rz,sizeof(float),1,fp); - // FIND THE PARENT - fread(&parent,sizeof(int),1,fp); - if (parent == -1) - tempBone->parent = NULL; - else - tempBone->parent = (t_Bone *)parent; - - fread(&tempBone->childCnt,sizeof(int),1,fp); - for (j = 0; j < tempBone->childCnt; j++) - { - fread(&tempBone->child[j],sizeof(int),1,fp); - } - } - fclose(fp); - - // SET UP ROOT -// strcpy(root->name,bonelist[0].name); - root->b_trans.x = bonelist[0].tx; - root->b_trans.y = bonelist[0].ty; - root->b_trans.z = bonelist[0].tz; - root->b_rot.x = bonelist[0].rx; - root->b_rot.y = bonelist[0].ry; - root->b_rot.z = bonelist[0].rz; - root->trans.x = bonelist[0].tx; - root->trans.y = bonelist[0].ty; - root->trans.z = bonelist[0].tz; - root->rot.x = bonelist[0].rx; - root->rot.y = bonelist[0].ry; - root->rot.z = bonelist[0].rz; - root->childCnt = bonelist[0].childCnt; - root->children = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); - root->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); - for (i = 0; i < root->childCnt; i++) - { - child = &root->children[i]; - ResetBone(child,root); - strcpy(child->name,bonelist[(int)bonelist[0].child[i]].name); - child->trans.x = bonelist[(int)bonelist[0].child[i]].tx; - child->trans.y = bonelist[(int)bonelist[0].child[i]].ty; - child->trans.z = bonelist[(int)bonelist[0].child[i]].tz; - child->rot.x = bonelist[(int)bonelist[0].child[i]].rx; - child->rot.y = bonelist[(int)bonelist[0].child[i]].ry; - child->rot.z = bonelist[(int)bonelist[0].child[i]].rz; - child->b_trans.x = bonelist[(int)bonelist[0].child[i]].tx; - child->b_trans.y = bonelist[(int)bonelist[0].child[i]].ty; - child->b_trans.z = bonelist[(int)bonelist[0].child[i]].tz; - child->b_rot.x = bonelist[(int)bonelist[0].child[i]].rx; - child->b_rot.y = bonelist[(int)bonelist[0].child[i]].ry; - child->b_rot.z = bonelist[(int)bonelist[0].child[i]].rz; - child->childCnt = bonelist[(int)bonelist[0].child[i]].childCnt; - child->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); - if (child->childCnt > 0) - { - AddDarwinBranch(child,&bonelist[(int)bonelist[0].child[i]],bonelist); - } - } - - free(bonelist); - - // Move the initial position so it can be seen - root->b_trans.x = 0.0f; - root->b_trans.y = -7.0f; - root->b_trans.z = -40.0f; - root->trans.x = 0.0f; - root->trans.y = -7.0f; - root->trans.z = -40.0f; - - } - return TRUE; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// LoadSkel.cpp +// +// Purpose: implementation of the Custom Skeleton file Loader +// +// Created: +// JL 9/12/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "LoadSkel.h" + + +#define MAX_CHILDREN 8 +typedef struct +{ + void *parent; + void *child[MAX_CHILDREN]; + int childCnt; + float tx,ty,tz; + float rx,ry,rz; + char name[80]; +} tSkeletonNode; + + +/////////////////////////////////////////////////////////////////////////////// +// Fixes up the skeletal structure once it is loaded +/////////////////////////////////////////////////////////////////////////////// +void AddDarwinBranch(t_Bone *root, tSkeletonNode *curNode,tSkeletonNode *baseNode) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int i; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + root->children = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); + for (i = 0; i < root->childCnt; i++) + { + child = &root->children[i]; + ResetBone(child,root); + strcpy(child->name,baseNode[(int)curNode->child[i]].name); + child->trans.x = baseNode[(int)curNode->child[i]].tx; + child->trans.y = baseNode[(int)curNode->child[i]].ty; + child->trans.z = baseNode[(int)curNode->child[i]].tz; + child->rot.x = baseNode[(int)curNode->child[i]].rx; + child->rot.y = baseNode[(int)curNode->child[i]].ry; + child->rot.z = baseNode[(int)curNode->child[i]].rz; + child->b_trans.x = baseNode[(int)curNode->child[i]].tx; + child->b_trans.y = baseNode[(int)curNode->child[i]].ty; + child->b_trans.z = baseNode[(int)curNode->child[i]].tz; + child->b_rot.x = baseNode[(int)curNode->child[i]].rx; + child->b_rot.y = baseNode[(int)curNode->child[i]].ry; + child->b_rot.z = baseNode[(int)curNode->child[i]].rz; + child->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); + child->childCnt = baseNode[(int)curNode->child[i]].childCnt; + if (child->childCnt > 0) + { + AddDarwinBranch(child,&baseNode[(int)curNode->child[i]],baseNode); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadSkeleton +// Purpose: Load a Darwin Format Skeleton +// Arguments: Name of the file to open and root skeleton to put it in +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadSkeleton(CString name,t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int i,j,boneCnt,parent; + FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS + tSkeletonNode *tempBone,*bonelist; + t_Bone *child; + char temp[5]; +/////////////////////////////////////////////////////////////////////////////// + if (fp = fopen((LPCTSTR)name,"rb")) { + fread(temp,sizeof(char),4,fp); + fread(&boneCnt,sizeof(int),1,fp); + bonelist = (tSkeletonNode *)malloc((boneCnt) * sizeof(tSkeletonNode)); + for (i = 0; i < boneCnt; i++) + { + tempBone = &bonelist[i]; + fread(tempBone->name,sizeof(char),80,fp); + fread(&tempBone->tx,sizeof(float),1,fp); + fread(&tempBone->ty,sizeof(float),1,fp); + fread(&tempBone->tz,sizeof(float),1,fp); + fread(&tempBone->rx,sizeof(float),1,fp); + fread(&tempBone->ry,sizeof(float),1,fp); + fread(&tempBone->rz,sizeof(float),1,fp); + // FIND THE PARENT + fread(&parent,sizeof(int),1,fp); + if (parent == -1) + tempBone->parent = NULL; + else + tempBone->parent = (t_Bone *)parent; + + fread(&tempBone->childCnt,sizeof(int),1,fp); + for (j = 0; j < tempBone->childCnt; j++) + { + fread(&tempBone->child[j],sizeof(int),1,fp); + } + } + fclose(fp); + + // SET UP ROOT +// strcpy(root->name,bonelist[0].name); + root->b_trans.x = bonelist[0].tx; + root->b_trans.y = bonelist[0].ty; + root->b_trans.z = bonelist[0].tz; + root->b_rot.x = bonelist[0].rx; + root->b_rot.y = bonelist[0].ry; + root->b_rot.z = bonelist[0].rz; + root->trans.x = bonelist[0].tx; + root->trans.y = bonelist[0].ty; + root->trans.z = bonelist[0].tz; + root->rot.x = bonelist[0].rx; + root->rot.y = bonelist[0].ry; + root->rot.z = bonelist[0].rz; + root->childCnt = bonelist[0].childCnt; + root->children = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); + root->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); + for (i = 0; i < root->childCnt; i++) + { + child = &root->children[i]; + ResetBone(child,root); + strcpy(child->name,bonelist[(int)bonelist[0].child[i]].name); + child->trans.x = bonelist[(int)bonelist[0].child[i]].tx; + child->trans.y = bonelist[(int)bonelist[0].child[i]].ty; + child->trans.z = bonelist[(int)bonelist[0].child[i]].tz; + child->rot.x = bonelist[(int)bonelist[0].child[i]].rx; + child->rot.y = bonelist[(int)bonelist[0].child[i]].ry; + child->rot.z = bonelist[(int)bonelist[0].child[i]].rz; + child->b_trans.x = bonelist[(int)bonelist[0].child[i]].tx; + child->b_trans.y = bonelist[(int)bonelist[0].child[i]].ty; + child->b_trans.z = bonelist[(int)bonelist[0].child[i]].tz; + child->b_rot.x = bonelist[(int)bonelist[0].child[i]].rx; + child->b_rot.y = bonelist[(int)bonelist[0].child[i]].ry; + child->b_rot.z = bonelist[(int)bonelist[0].child[i]].rz; + child->childCnt = bonelist[(int)bonelist[0].child[i]].childCnt; + child->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); + if (child->childCnt > 0) + { + AddDarwinBranch(child,&bonelist[(int)bonelist[0].child[i]],bonelist); + } + } + + free(bonelist); + + // Move the initial position so it can be seen + root->b_trans.x = 0.0f; + root->b_trans.y = -7.0f; + root->b_trans.z = -40.0f; + root->trans.x = 0.0f; + root->trans.y = -7.0f; + root->trans.z = -40.0f; + + } + return TRUE; +} + diff --git a/Skeletal Deformation/Code/OGL/Skully/LoadSkel.h b/Skeletal Deformation/Code/OGL/Skully/LoadSkel.h index 2085a58..e27e380 100644 --- a/Skeletal Deformation/Code/OGL/Skully/LoadSkel.h +++ b/Skeletal Deformation/Code/OGL/Skully/LoadSkel.h @@ -1,28 +1,28 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadSkel.h -// -// Purpose: implementation of the Custom Mesh file Loader -// -// Created: -// JL 9/12/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(LoadSkel_H__INCLUDED_) -#define LoadSkel_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#include "Skeleton.h" - -BOOL LoadSkeleton(CString name,t_Bone *root); - -#endif // !defined(LoadSkel_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadSkel.h +// +// Purpose: implementation of the Custom Mesh file Loader +// +// Created: +// JL 9/12/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(LoadSkel_H__INCLUDED_) +#define LoadSkel_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#include "Skeleton.h" + +BOOL LoadSkeleton(CString name,t_Bone *root); + +#endif // !defined(LoadSkel_H__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/MainFrm.cpp b/Skeletal Deformation/Code/OGL/Skully/MainFrm.cpp index ac796d3..d336d53 100644 --- a/Skeletal Deformation/Code/OGL/Skully/MainFrm.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/MainFrm.cpp @@ -1,371 +1,371 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// Modified: -// JL 7/10/99 Created skeleton Demo for Oct 99 GDMag -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "mmsystem.h" // NEED THIS FOR THE TIMEGETTIME -#include "Skully.h" -#include "HierWin.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Local Defines ///////////////////////////////////////////////////////////// -#define HIERWIN_START_X 0 // STARTING X POSITION OF HIERARCHY WINDOW -#define HIERWIN_START_Y 1 // STARTING Y POSITION OF HIERARCHY WINDOW -#define HIERWIN_WIDTH 160 // WIDTH OF HIERARCHY WINDOW -#define HIERWIN_BOTTOM 20 // BOTTOM BORDER OF HIERARCHY WINDOW -#define OGLWIN_START_X 162 // STARTING X POSITION OF OPENGL WINDOW -#define OGLWIN_START_Y 1 // STARTING Y POSITION OF OPENGL WINDOW -#define OGLWIN_WIDTH 164 // WIDTH OF OPENGL WINDOW SUBTRACTED FROM MAX -#define OGLWIN_BOTTOM 20 // BOTTOM BORDER OF OPENGL WINDOW -/////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_SIZE() - ON_WM_KEYUP() - ON_WM_KEYDOWN() - ON_WM_PAINT() - ON_COMMAND(ID_WHICHOGL, OnWhichogl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_SKELETON_RESETSKELETON, OnSkeletonResetskeleton) - ON_COMMAND(ID_VIEW_OUTLINE, OnViewOutline) - ON_UPDATE_COMMAND_UI(ID_VIEW_OUTLINE, OnUpdateViewOutline) - ON_COMMAND(ID_FILE_OPENCHARACTERMESH, OnFileOpencharactermesh) - ON_COMMAND(ID_VIEW_VIEWSKELETON, OnViewViewskeleton) - ON_UPDATE_COMMAND_UI(ID_VIEW_VIEWSKELETON, OnUpdateViewViewskeleton) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_VIEW_DRAWDEFORMED, OnViewDrawdeformed) - ON_UPDATE_COMMAND_UI(ID_VIEW_DRAWDEFORMED, OnUpdateViewDrawdeformed) - ON_COMMAND(ID_SKELETON_SETRESTPOSE, OnSkeletonSetrestpose) - ON_COMMAND(ID_SKELETON_SETBONEWEIGHTS, OnSkeletonSetboneweights) - ON_COMMAND(ID_FILE_OPENWEIGHT, OnFileOpenweight) - ON_COMMAND(ID_SKELETON_CLEARSELECTEDWEIGHTS, OnSkeletonClearselectedweights) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_FRAME2, // FOR DISPLAY OF FRAMECOUNT AND CURRENT FRAME - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_Wireframe = TRUE; - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -} - -CMainFrame::~CMainFrame() -{ - m_HierWin.DestroyWindow(); -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_HierWin.Create( WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS, - CRect(HIERWIN_START_X, HIERWIN_START_Y,HIERWIN_WIDTH,rect.bottom - HIERWIN_BOTTOM), this, 1001); - m_HierWin.ShowWindow(TRUE); - - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, - CRect(OGLWIN_START_X, OGLWIN_START_Y,rect.right - OGLWIN_WIDTH,rect.bottom - OGLWIN_BOTTOM),this,104); - m_OGLView.ShowWindow(TRUE); - - m_OGLView.m_StatusBar = &m_wndStatusBar; - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - HICON hicon; - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame implementation - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnWhichogl -// Purpose: Create dialog to Show which version of OGL is running -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnWhichogl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) -{ - - return CFrameWnd::OnCreateClient(lpcs, pContext); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnPaint -// Purpose: This routine grabs the message loop if I am animating and -// handles the messages. This way I can play back as fast -// as possible -// Reference: OpenGL Programming for Windows 95 by Ron Fosner -// Sort of a variation on that code -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(FALSE); -} -/// OnPaint //////////////////////////////////////////////////////////// - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - // RESET THE HierWin WINDOW SIZE - m_HierWin.SetWindowPos( &wndTopMost, HIERWIN_START_X, HIERWIN_START_Y, HIERWIN_WIDTH, cy - HIERWIN_BOTTOM, SWP_NOZORDER ); - // RESET THE m_OGLView WINDOW SIZE - m_OGLView.SetWindowPos( &wndTopMost, OGLWIN_START_X, OGLWIN_START_Y, cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM, SWP_NOZORDER ); - // RESET THE ACTUAL OPENGL WINDOW SIZE - m_OGLView.resize( cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM); - CFrameWnd::OnSize(nType, cx, cy); -} - -// HAVEN'T IMPLEMENTED ADDING A BONE -#if 0 -void CMainFrame::OnAddBone() -{ - m_HierWin.AddBone(); -} -#endif - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); - m_OGLView.HandleKeyUp(nChar); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -///////////////////////////////////////////////////////////////////////////// -// View Manipulation Functions - -///////////////////////////////////////////////////////////////////////////// - - -void CMainFrame::OnFileOpen() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Darwin Skeleton (*.dar)|*.dar||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(TRUE,"dar",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - m_OGLView.LoadSkeletonFile(dialog->GetPathName()); - m_HierWin.ResetSkeleton(); - m_HierWin.SetSkeleton(&m_OGLView.m_Skeleton, NULL); - m_OGLView.drawScene(FALSE); - m_OGLView.OnViewResetskeleton(); - } - delete dialog; - -} - -void CMainFrame::OnFileOpencharactermesh() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Character Mesh OBJ (*.obj)|*.obj||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(TRUE,"dcm",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - m_OGLView.LoadOBJModel(dialog->GetPathName()); - m_OGLView.drawScene(FALSE); - m_OGLView.OnViewResetskeleton(); - } - delete dialog; -} - -void CMainFrame::OnFileOpenweight() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Weight File (*.wgt)|*.wgt||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(TRUE,"wgt",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - m_OGLView.LoadWeights(dialog->GetPathName()); - } - delete dialog; -} - -void CMainFrame::OnFileSave() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Weight File (*.wgt)|*.wgt||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - dialog = new CFileDialog(FALSE,"wgt",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - m_OGLView.SaveWeights(dialog->GetPathName()); - } - delete dialog; -} - -void CMainFrame::OnSkeletonResetskeleton() -{ - // PASS THIS MESSAGE OFF TO THE OGL CLASS - m_OGLView.OnViewResetskeleton(); -} - -void CMainFrame::OnViewOutline() -{ - m_Wireframe = !m_Wireframe; - if (m_Wireframe) - glPolygonMode(GL_FRONT,GL_LINE); - else - glPolygonMode(GL_FRONT,GL_FILL); - Invalidate(TRUE ); -} - -void CMainFrame::OnUpdateViewOutline(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_Wireframe ); -} - -void CMainFrame::OnViewViewskeleton() -{ - m_OGLView.m_DrawSkeleton = !m_OGLView.m_DrawSkeleton; - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnUpdateViewViewskeleton(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawSkeleton ); -} - - -void CMainFrame::OnViewDrawdeformed() -{ - m_OGLView.m_DrawDeformed = !m_OGLView.m_DrawDeformed; - m_OGLView.drawScene(FALSE); -} - -void CMainFrame::OnUpdateViewDrawdeformed(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawDeformed ); -} - -void CMainFrame::OnSkeletonSetrestpose() -{ - m_OGLView.SetBasePose(); -} - -void CMainFrame::OnSkeletonSetboneweights() -{ - m_OGLView.WeightBones(); -} - - -void CMainFrame::OnSkeletonClearselectedweights() -{ - m_OGLView.ClearBoneWeights(&m_OGLView.m_Skeleton); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// Modified: +// JL 7/10/99 Created skeleton Demo for Oct 99 GDMag +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "mmsystem.h" // NEED THIS FOR THE TIMEGETTIME +#include "Skully.h" +#include "HierWin.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Local Defines ///////////////////////////////////////////////////////////// +#define HIERWIN_START_X 0 // STARTING X POSITION OF HIERARCHY WINDOW +#define HIERWIN_START_Y 1 // STARTING Y POSITION OF HIERARCHY WINDOW +#define HIERWIN_WIDTH 160 // WIDTH OF HIERARCHY WINDOW +#define HIERWIN_BOTTOM 20 // BOTTOM BORDER OF HIERARCHY WINDOW +#define OGLWIN_START_X 162 // STARTING X POSITION OF OPENGL WINDOW +#define OGLWIN_START_Y 1 // STARTING Y POSITION OF OPENGL WINDOW +#define OGLWIN_WIDTH 164 // WIDTH OF OPENGL WINDOW SUBTRACTED FROM MAX +#define OGLWIN_BOTTOM 20 // BOTTOM BORDER OF OPENGL WINDOW +/////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_KEYUP() + ON_WM_KEYDOWN() + ON_WM_PAINT() + ON_COMMAND(ID_WHICHOGL, OnWhichogl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_SKELETON_RESETSKELETON, OnSkeletonResetskeleton) + ON_COMMAND(ID_VIEW_OUTLINE, OnViewOutline) + ON_UPDATE_COMMAND_UI(ID_VIEW_OUTLINE, OnUpdateViewOutline) + ON_COMMAND(ID_FILE_OPENCHARACTERMESH, OnFileOpencharactermesh) + ON_COMMAND(ID_VIEW_VIEWSKELETON, OnViewViewskeleton) + ON_UPDATE_COMMAND_UI(ID_VIEW_VIEWSKELETON, OnUpdateViewViewskeleton) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_VIEW_DRAWDEFORMED, OnViewDrawdeformed) + ON_UPDATE_COMMAND_UI(ID_VIEW_DRAWDEFORMED, OnUpdateViewDrawdeformed) + ON_COMMAND(ID_SKELETON_SETRESTPOSE, OnSkeletonSetrestpose) + ON_COMMAND(ID_SKELETON_SETBONEWEIGHTS, OnSkeletonSetboneweights) + ON_COMMAND(ID_FILE_OPENWEIGHT, OnFileOpenweight) + ON_COMMAND(ID_SKELETON_CLEARSELECTEDWEIGHTS, OnSkeletonClearselectedweights) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_FRAME2, // FOR DISPLAY OF FRAMECOUNT AND CURRENT FRAME + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_Wireframe = TRUE; + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +} + +CMainFrame::~CMainFrame() +{ + m_HierWin.DestroyWindow(); +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_HierWin.Create( WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS, + CRect(HIERWIN_START_X, HIERWIN_START_Y,HIERWIN_WIDTH,rect.bottom - HIERWIN_BOTTOM), this, 1001); + m_HierWin.ShowWindow(TRUE); + + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, + CRect(OGLWIN_START_X, OGLWIN_START_Y,rect.right - OGLWIN_WIDTH,rect.bottom - OGLWIN_BOTTOM),this,104); + m_OGLView.ShowWindow(TRUE); + + m_OGLView.m_StatusBar = &m_wndStatusBar; + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + HICON hicon; + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame implementation + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnWhichogl +// Purpose: Create dialog to Show which version of OGL is running +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnWhichogl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) +{ + + return CFrameWnd::OnCreateClient(lpcs, pContext); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnPaint +// Purpose: This routine grabs the message loop if I am animating and +// handles the messages. This way I can play back as fast +// as possible +// Reference: OpenGL Programming for Windows 95 by Ron Fosner +// Sort of a variation on that code +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(FALSE); +} +/// OnPaint //////////////////////////////////////////////////////////// + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + // RESET THE HierWin WINDOW SIZE + m_HierWin.SetWindowPos( &wndTopMost, HIERWIN_START_X, HIERWIN_START_Y, HIERWIN_WIDTH, cy - HIERWIN_BOTTOM, SWP_NOZORDER ); + // RESET THE m_OGLView WINDOW SIZE + m_OGLView.SetWindowPos( &wndTopMost, OGLWIN_START_X, OGLWIN_START_Y, cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM, SWP_NOZORDER ); + // RESET THE ACTUAL OPENGL WINDOW SIZE + m_OGLView.resize( cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM); + CFrameWnd::OnSize(nType, cx, cy); +} + +// HAVEN'T IMPLEMENTED ADDING A BONE +#if 0 +void CMainFrame::OnAddBone() +{ + m_HierWin.AddBone(); +} +#endif + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); + m_OGLView.HandleKeyUp(nChar); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +///////////////////////////////////////////////////////////////////////////// +// View Manipulation Functions + +///////////////////////////////////////////////////////////////////////////// + + +void CMainFrame::OnFileOpen() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Darwin Skeleton (*.dar)|*.dar||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(TRUE,"dar",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + m_OGLView.LoadSkeletonFile(dialog->GetPathName()); + m_HierWin.ResetSkeleton(); + m_HierWin.SetSkeleton(&m_OGLView.m_Skeleton, NULL); + m_OGLView.drawScene(FALSE); + m_OGLView.OnViewResetskeleton(); + } + delete dialog; + +} + +void CMainFrame::OnFileOpencharactermesh() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Character Mesh OBJ (*.obj)|*.obj||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(TRUE,"dcm",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + m_OGLView.LoadOBJModel(dialog->GetPathName()); + m_OGLView.drawScene(FALSE); + m_OGLView.OnViewResetskeleton(); + } + delete dialog; +} + +void CMainFrame::OnFileOpenweight() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Weight File (*.wgt)|*.wgt||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(TRUE,"wgt",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + m_OGLView.LoadWeights(dialog->GetPathName()); + } + delete dialog; +} + +void CMainFrame::OnFileSave() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Weight File (*.wgt)|*.wgt||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + dialog = new CFileDialog(FALSE,"wgt",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + m_OGLView.SaveWeights(dialog->GetPathName()); + } + delete dialog; +} + +void CMainFrame::OnSkeletonResetskeleton() +{ + // PASS THIS MESSAGE OFF TO THE OGL CLASS + m_OGLView.OnViewResetskeleton(); +} + +void CMainFrame::OnViewOutline() +{ + m_Wireframe = !m_Wireframe; + if (m_Wireframe) + glPolygonMode(GL_FRONT,GL_LINE); + else + glPolygonMode(GL_FRONT,GL_FILL); + Invalidate(TRUE ); +} + +void CMainFrame::OnUpdateViewOutline(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_Wireframe ); +} + +void CMainFrame::OnViewViewskeleton() +{ + m_OGLView.m_DrawSkeleton = !m_OGLView.m_DrawSkeleton; + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnUpdateViewViewskeleton(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawSkeleton ); +} + + +void CMainFrame::OnViewDrawdeformed() +{ + m_OGLView.m_DrawDeformed = !m_OGLView.m_DrawDeformed; + m_OGLView.drawScene(FALSE); +} + +void CMainFrame::OnUpdateViewDrawdeformed(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawDeformed ); +} + +void CMainFrame::OnSkeletonSetrestpose() +{ + m_OGLView.SetBasePose(); +} + +void CMainFrame::OnSkeletonSetboneweights() +{ + m_OGLView.WeightBones(); +} + + +void CMainFrame::OnSkeletonClearselectedweights() +{ + m_OGLView.ClearBoneWeights(&m_OGLView.m_Skeleton); +} diff --git a/Skeletal Deformation/Code/OGL/Skully/MainFrm.h b/Skeletal Deformation/Code/OGL/Skully/MainFrm.h index 546999c..6375ab0 100644 --- a/Skeletal Deformation/Code/OGL/Skully/MainFrm.h +++ b/Skeletal Deformation/Code/OGL/Skully/MainFrm.h @@ -1,102 +1,102 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// Modified: -// JL 7/10/99 Created skeleton Demo for Oct 99 GDMag -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "HierWin.h" -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - CHierWin m_HierWin; - COGLView m_OGLView; - BOOL m_Wireframe; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - protected: - virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - CToolBar m_wndToolBar; - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnAddBone(); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnPaint(); - afx_msg void OnWhichogl(); - afx_msg void OnFileOpen(); - afx_msg void OnSkeletonResetskeleton(); - afx_msg void OnViewOutline(); - afx_msg void OnUpdateViewOutline(CCmdUI* pCmdUI); - afx_msg void OnFileOpencharactermesh(); - afx_msg void OnViewViewskeleton(); - afx_msg void OnUpdateViewViewskeleton(CCmdUI* pCmdUI); - afx_msg void OnFileSave(); - afx_msg void OnViewDrawdeformed(); - afx_msg void OnUpdateViewDrawdeformed(CCmdUI* pCmdUI); - afx_msg void OnSkeletonSetrestpose(); - afx_msg void OnSkeletonSetboneweights(); - afx_msg void OnFileOpenweight(); - afx_msg void OnSkeletonClearselectedweights(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// Modified: +// JL 7/10/99 Created skeleton Demo for Oct 99 GDMag +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "HierWin.h" +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + CHierWin m_HierWin; + COGLView m_OGLView; + BOOL m_Wireframe; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + protected: + virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnAddBone(); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnPaint(); + afx_msg void OnWhichogl(); + afx_msg void OnFileOpen(); + afx_msg void OnSkeletonResetskeleton(); + afx_msg void OnViewOutline(); + afx_msg void OnUpdateViewOutline(CCmdUI* pCmdUI); + afx_msg void OnFileOpencharactermesh(); + afx_msg void OnViewViewskeleton(); + afx_msg void OnUpdateViewViewskeleton(CCmdUI* pCmdUI); + afx_msg void OnFileSave(); + afx_msg void OnViewDrawdeformed(); + afx_msg void OnUpdateViewDrawdeformed(CCmdUI* pCmdUI); + afx_msg void OnSkeletonSetrestpose(); + afx_msg void OnSkeletonSetboneweights(); + afx_msg void OnFileOpenweight(); + afx_msg void OnSkeletonClearselectedweights(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif diff --git a/Skeletal Deformation/Code/OGL/Skully/MathDefs.cpp b/Skeletal Deformation/Code/OGL/Skully/MathDefs.cpp index af24ae6..2558e6b 100644 --- a/Skeletal Deformation/Code/OGL/Skully/MathDefs.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/MathDefs.cpp @@ -1,263 +1,263 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.cpp : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Two Utility functions that I pulled from the Mesa GL source -// This is a great source of information about the inner working of functions -// in OpenGL -// -// www.mesagl.com for info -// -// Adapted to work with my data types -/////////////////////////////////////////////////////////////////////////////// - -// Multiply two OpenGL Matrices together -void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b) -{ - /* This matmul was contributed by Thomas Malik */ - int i; - -#define A(row,col) a->m[(col<<2)+row] -#define B(row,col) b->m[(col<<2)+row] -#define P(row,col) product->m[(col<<2)+row] - - /* i-te Zeile */ - for (i = 0; i < 4; i++) { - float ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); - P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); - P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); - P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); - P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); - } - -#undef A -#undef B -#undef P -} - -// Invert an OpenGL 4x4 matrix -BOOL InvertMatrix(float *m, float *out ) -{ -/* NB. OpenGL Matrices are COLUMN major. */ -#define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } -#define MAT(m,r,c) (m)[(c)*4+(r)] - - float wtmp[4][8]; - float m0, m1, m2, m3, s; - float *r0, *r1, *r2, *r3; - - r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; - - r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), - r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), - r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, - - r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), - r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), - r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, - - r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), - r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), - r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, - - r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), - r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), - r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; - - /* choose pivot - or die */ - if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); - if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); - if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); - if (0.0 == r0[0]) return FALSE; - - /* eliminate first variable */ - m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; - s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; - s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; - s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; - s = r0[4]; - if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r0[5]; - if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r0[6]; - if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r0[7]; - if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); - if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); - if (0.0 == r1[1]) return FALSE; - - /* eliminate second variable */ - m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; - r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; - r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; - s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } - s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } - s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } - s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } - - /* choose pivot - or die */ - if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); - if (0.0 == r2[2]) return FALSE; - - /* eliminate third variable */ - m3 = r3[2]/r2[2]; - r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], - r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], - r3[7] -= m3 * r2[7]; - - /* last check */ - if (0.0 == r3[3]) return FALSE; - - s = 1.0/r3[3]; /* now back substitute row 3 */ - r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; - - m2 = r2[3]; /* now back substitute row 2 */ - s = 1.0/r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), - r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, - r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, - r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; - - m1 = r1[2]; /* now back substitute row 1 */ - s = 1.0/r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), - r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, - r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; - - m0 = r0[1]; /* now back substitute row 0 */ - s = 1.0/r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), - r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); - - MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], - MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], - MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], - MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], - MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], - MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], - MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], - MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; - - return TRUE; - -#undef MAT -#undef SWAP_ROWS -} - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void ScaleVector(tVector *v, float scale, tVector *result) -{ - result->x = v->x * scale; - result->y = v->y * scale; - result->z = v->z * scale; -} - -void VectorSum(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x + v2->x; - result->y = v1->y + v2->y; - result->z = v1->z + v2->z; -} - -void VectorDifference(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.cpp : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Two Utility functions that I pulled from the Mesa GL source +// This is a great source of information about the inner working of functions +// in OpenGL +// +// www.mesagl.com for info +// +// Adapted to work with my data types +/////////////////////////////////////////////////////////////////////////////// + +// Multiply two OpenGL Matrices together +void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b) +{ + /* This matmul was contributed by Thomas Malik */ + int i; + +#define A(row,col) a->m[(col<<2)+row] +#define B(row,col) b->m[(col<<2)+row] +#define P(row,col) product->m[(col<<2)+row] + + /* i-te Zeile */ + for (i = 0; i < 4; i++) { + float ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); + } + +#undef A +#undef B +#undef P +} + +// Invert an OpenGL 4x4 matrix +BOOL InvertMatrix(float *m, float *out ) +{ +/* NB. OpenGL Matrices are COLUMN major. */ +#define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } +#define MAT(m,r,c) (m)[(c)*4+(r)] + + float wtmp[4][8]; + float m0, m1, m2, m3, s; + float *r0, *r1, *r2, *r3; + + r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; + + r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), + r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), + r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, + + r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), + r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), + r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, + + r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), + r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), + r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, + + r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), + r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), + r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; + + /* choose pivot - or die */ + if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); + if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); + if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); + if (0.0 == r0[0]) return FALSE; + + /* eliminate first variable */ + m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; + s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; + s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; + s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r0[5]; + if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r0[6]; + if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r0[7]; + if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); + if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); + if (0.0 == r1[1]) return FALSE; + + /* eliminate second variable */ + m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; + r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; + s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); + if (0.0 == r2[2]) return FALSE; + + /* eliminate third variable */ + m3 = r3[2]/r2[2]; + r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], + r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], + r3[7] -= m3 * r2[7]; + + /* last check */ + if (0.0 == r3[3]) return FALSE; + + s = 1.0/r3[3]; /* now back substitute row 3 */ + r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; + + m2 = r2[3]; /* now back substitute row 2 */ + s = 1.0/r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), + r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, + r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, + r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; + + m1 = r1[2]; /* now back substitute row 1 */ + s = 1.0/r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), + r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, + r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; + + m0 = r0[1]; /* now back substitute row 0 */ + s = 1.0/r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), + r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); + + MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], + MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], + MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], + MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], + MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], + MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], + MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], + MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; + + return TRUE; + +#undef MAT +#undef SWAP_ROWS +} + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void ScaleVector(tVector *v, float scale, tVector *result) +{ + result->x = v->x * scale; + result->y = v->y * scale; + result->z = v->z * scale; +} + +void VectorSum(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x + v2->x; + result->y = v1->y + v2->y; + result->z = v1->z + v2->z; +} + +void VectorDifference(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/Skeletal Deformation/Code/OGL/Skully/MathDefs.h b/Skeletal Deformation/Code/OGL/Skully/MathDefs.h index 59d3ba5..12bed17 100644 --- a/Skeletal Deformation/Code/OGL/Skully/MathDefs.h +++ b/Skeletal Deformation/Code/OGL/Skully/MathDefs.h @@ -1,117 +1,117 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float nx,ny,nz; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b); -BOOL InvertMatrix(float *m, float *out ); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float nx,ny,nz; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultMatrix(tMatrix *product, tMatrix *a, tMatrix *b); +BOOL InvertMatrix(float *m, float *out ); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/Skeletal Deformation/Code/OGL/Skully/OGLView.cpp b/Skeletal Deformation/Code/OGL/Skully/OGLView.cpp index 4660eca..4c3b41a 100644 --- a/Skeletal Deformation/Code/OGL/Skully/OGLView.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/OGLView.cpp @@ -1,1268 +1,1268 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// Versions: -// 1.01 12/20/97 Fix perspective in OpenGL Resize Code -// 1.02 1/10/97 Change to display code to handle skeletal hierarchy -// Modified: -// JL 9/10/99 Created skeleton Demo for Oct 99 GDMag -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include "Skully.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "LoadSkel.h" // Skeleton loading - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define OGL_SELECTED_DLIST 2 // SELECTED BONE OPENGL DISPLAY LIST -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_StatusBar = NULL; // CLEAR THIS. IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT - m_DrawSkeleton = TRUE; - m_DrawDeformed = FALSE; - m_PickX = -1; - m_PickY = -1; - ResetBone(&m_Skeleton,NULL); - m_SelectedBone = &m_Skeleton; - - // INITIALIZE SOME OF THE CAMERA VARIABLES - ResetBone(&m_Camera, NULL); - m_Camera.id = -1; - strcpy(m_Camera.name,"Camera"); - m_Camera.rot.x = 0.0f; - m_Camera.rot.y = 0.0f; - m_Camera.rot.z = 0.0f; - m_Camera.b_trans.y = -6.0f; - m_Camera.b_trans.z = -50.0f; - m_Camera.trans.y = -6.0f; - m_Camera.trans.z = -50.0f; - - m_Model.vertexData = NULL; -} - -COGLView::~COGLView() -{ -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_MOVE() - ON_WM_LBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glEndList(); - - // CREATE THE DISPLAY LIST THE SELECTED BONE JUST A CUBE - glNewList(OGL_SELECTED_DLIST,GL_COMPILE); - glBegin(GL_QUADS); - glColor3f(1.0f, 1.0f, 0.0f); // YELLOW - // BOTTOM - glVertex3f(-0.05f, -0.05f, -0.05f); - glVertex3f( 0.05f, -0.05f, -0.05f); - glVertex3f( 0.05f, -0.05f, 0.05f); - glVertex3f(-0.05f, -0.05f, 0.05f); - // BACK - glVertex3f(-0.05f, 0.05f, -0.05f); - glVertex3f( 0.05f, 0.05f, -0.05f); - glVertex3f( 0.05f, -0.05f, -0.05f); - glVertex3f(-0.05f, -0.05f, -0.05f); - // FRONT - glVertex3f(-0.05f, -0.05f, 0.05f); - glVertex3f( 0.05f, -0.05f, 0.05f); - glVertex3f( 0.05f, 0.05f, 0.05f); - glVertex3f(-0.05f, 0.05f, 0.05f); - // RIGHT - glVertex3f(-0.05f, -0.05f, -0.05f); - glVertex3f(-0.05f, -0.05f, 0.05f); - glVertex3f(-0.05f, 0.05f, 0.05f); - glVertex3f(-0.05f, 0.05f, -0.05f); - // LEFT - glVertex3f( 0.05f, 0.05f, -0.05f); - glVertex3f( 0.05f, 0.05f, 0.05f); - glVertex3f( 0.05f, -0.05f, 0.05f); - glVertex3f( 0.05f, -0.05f, -0.05f); - // TOP - glVertex3f(-0.05f, 0.05f, 0.05f); - glVertex3f( 0.05f, 0.05f, 0.05f); - glVertex3f( 0.05f, 0.05f, -0.05f); - glVertex3f(-0.05f, 0.05f, -0.05f); - glEnd(); - glEndList(); - drawScene(FALSE); - return 0; -} - -/* OpenGL code */ - -/////////////////////////////////////////////////////////////////////////////// -// Function: resize -// Purpose: This code handles the windows resize for OpenGL -// Arguments: Width and heights of the view window -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(20.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - m_ScreenWidth = width; - m_ScreenHeight = height; - -} -//// resize ///////////////////////////////////////////////////////////////// - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; - GLfloat diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; - GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat lightpos[] = { 0.5, 0.5, 1.0, 0.0 }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LESS); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(60.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP -// glPolygonMode(GL_FRONT,GL_FILL); - glPolygonMode(GL_FRONT,GL_LINE); - glDepthFunc(GL_LESS); - glEnable(GL_CULL_FACE); - glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST); - glPointSize(8.0); // NICE BEEFY POINTS FOR THE VERTEX SELECTION - glDisable(GL_TEXTURE_2D); - - glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); - glMaterialfv(GL_FRONT,GL_SPECULAR, specular); - glMaterialf(GL_FRONT,GL_SHININESS, 25.0f); - glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - -} - -/////////////////////////////////////////////////////////////////////////////// -// At run-time, at each frame of animation, you need to get the -// current matrices for every bone. This is multiplied by the -// inverted matrix from the rest bone and stored. Must be -// recursive. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetSkeletonMat -// Purpose: Gets the Matrix values for the character -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::GetSkeletonMat(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; - tMatrix tempMatrix; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - // Set observer's orientation and position - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - - // Get the current matrix - glGetFloatv(GL_MODELVIEW_MATRIX,tempMatrix.m); - - // Multiply it by the inverted root bone and store - MultMatrix(curBone->curMatrix,&tempMatrix,&curBone->matrix); - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - GetSkeletonMat(curBone); - - glPopMatrix(); - - curBone++; - } -} -//// GetSkeletonMat /////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// When the base skeleton is set, the matrix for each bones must -// be grabbed, inverted, then stored for run time use. As the -// skeleton is a hierarchy, this must be done recursively -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetBaseSkeletonMat -// Purpose: Gets the Matrix values for the character -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::GetBaseSkeletonMat(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; - tMatrix tempMatrix; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - glTranslatef(curBone->b_trans.x, curBone->b_trans.y, curBone->b_trans.z); - - // Set observer's orientation and position - glRotatef(curBone->b_rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->b_rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->b_rot.x, 1.0f, 0.0f, 0.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,tempMatrix.m); - // Invert the matrix and store it for later - InvertMatrix(tempMatrix.m,curBone->matrix.m); - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - GetBaseSkeletonMat(curBone); - - glPopMatrix(); - - curBone++; - } -} -//// GetBaseSkeletonMat /////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// This function actually will deform a mesh given a -// skeletal system. At each bone, a combined matrix that -// tranforms the vertex from the rest bone space to the final -// bone space is stored. Each vertex is multiplied by this -// matrix then scaled by the weight. This is accumulated to -// give a fine vertex position -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DeformVertices -// Purpose: Bends the Bodies Based on the Vertices -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::DeformVertices(t_Bone *rootBone,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2; - t_Bone *curBone; - int vertex; - float weight; - tVector post; - float *deformData,*vertexData; -/////////////////////////////////////////////////////////////////////////////// - if (rootBone == &m_Skeleton && visual->vertexData != NULL) - { - // ZERO THE DEFORMATION - if (m_Skeleton.childCnt > 0) - { - for (loop = 0; loop < m_Skeleton.childCnt; loop++) - { - memcpy(visual->deformData,visual->vertexData,sizeof(float) * visual->vSize * visual->vertexCnt); - deformData = (float *)(visual->deformData + (visual->vSize - 3)); - for (loop2 = 0; loop2 < visual->vertexCnt; loop2++, deformData += visual->vSize) - { - deformData[0] = 0.0f; - deformData[1] = 0.0f; - deformData[2] = 0.0f; - } - } - } - } - - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - for (loop2 = 0; loop2 < visual->vertexCnt; loop2++) - { - // GET THE WEIGHT - weight = curBone->CV_weight[loop2].weight; - // The weight is between 0-1 - if (weight > 0.0f) - { - vertex = curBone->CV_weight[loop2].vertex; - - deformData = (float *)(visual->deformData + (visual->vSize * (vertex + 1)) - 3); - vertexData = (float *)(visual->vertexData + (visual->vSize * (vertex + 1)) - 3); - - // Multiply the vertex by the combined matrix - MultVectorByMatrix(curBone->curMatrix, (tVector *)vertexData, &post); -// Since the Matrix above is a combination of the rest and current matrices, it does -// the same as the following two calls would -// MultVectorByMatrix(&curBone->matrix, (tVector *)&vertexData[vertex].x, &pre); -// MultVectorByMatrix(curBone->curMatrix, &pre, &post); - - // Accumulate the result - deformData[0] += (post.x * weight); - deformData[1] += (post.y * weight); - deformData[2] += (post.z * weight); - } - } - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - DeformVertices(curBone, visual); - - curBone++; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawModel -// Purpose: Draw the Mesh model either deformed or not -// Arguments: Pointer to the model -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Visual *model) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tColoredVertex *cdata; - float *data; - int loop; -/////////////////////////////////////////////////////////////////////////////// - if (model->vertexData != NULL) - { - - glColor3f(1.0f, 1.0f, 1.0f); // NO MODULATION - - if (m_DrawDeformed) - data = (float *)model->deformData; - else - data = (float *)model->vertexData; - - // Declare the Array of Data - glInterleavedArrays(model->dataFormat,0,(GLvoid *)data); - if (model->vPerFace == 3) // Model is Triangles - glDrawArrays(GL_TRIANGLES,0,model->faceCnt * 3); - else - glDrawArrays(GL_QUADS,0,model->faceCnt * 4); - -/* Same as above but unrolled - cdata = (tColoredVertex *)data; - glBegin(GL_TRIANGLES); - for (loop = 0; loop < model->faceCnt; loop++) - { -// glTexCoord2f(data[loop * 3].u, data[loop * 3].v); - glNormal3fv((float *)&cdata[loop * 3].r); - glVertex3fv((float *)&cdata[loop * 3].x); -// glTexCoord2f(data[loop * 3 + 1].u, data[loop * 3 + 1].v); - glNormal3fv((float *)&cdata[loop * 3 + 1].r); - glVertex3fv((float *)&cdata[loop * 3 + 1].x); -// glTexCoord2f(data[loop * 3 + 2].u, data[loop * 3 + 2].v); - glNormal3fv((float *)&cdata[loop * 3 + 2].r); - glVertex3fv((float *)&cdata[loop * 3 + 2].x); - } - glEnd(); -*/ - - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - // NOW DRAW THE VERTEX MARKERS IF THEY ARE SELECTED - glColor3f(1.0f, 0.0f, 0.0f); // Selected Vertices are Red - glBegin(GL_POINTS); - for (loop = 0; loop < model->vertexCnt; loop++) - { - // IF A POINT IS SELECTED DRAW IT - if (model->CV_select[loop]) - { - glVertex3fv((float *)&data[((loop + 1) * model->vSize) - 3]); - } - } - glEnd(); - glEnable(GL_DEPTH_TEST); - glEnable(GL_LIGHTING); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawSkeleton -// Purpose: Actually draws the Skeleton it is recursive -// Arguments: Pointer to the bone -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawSkeleton(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - // Set observer's orientation and position - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION -// glGetFloatv(GL_MODELVIEW_MATRIX,curBone->matrix.m); - - // THE SCALE IS LOCAL SO I PUSH AND POP - glPushMatrix(); - glScalef(curBone->bsphere, curBone->bsphere, curBone->bsphere); - - if (m_DrawSkeleton) - { - // DRAW THE AXIS OGL OBJECT - glCallList(OGL_AXIS_DLIST); - // IF SOMETHING IS SELECTED, DRAW TAG BOX - if (m_Skeleton.id == (long)curBone) - { - glDisable(GL_CULL_FACE); - m_SelectedBone = curBone; - glCallList(OGL_SELECTED_DLIST); - glEnable(GL_CULL_FACE); - } - } - glPopMatrix(); - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - drawSkeleton(curBone); - - glPopMatrix(); - - curBone++; - } -} -//// drawSkeleton ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawScene -// Purpose: Actually draw the OpenGL Scene -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(BOOL drawSelectRect) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Camera.rot.y > 360.0f) m_Camera.rot.y -= 360.0f; - if (m_Camera.rot.x > 360.0f) m_Camera.rot.x -= 360.0f; - if (m_Camera.rot.z > 360.0f) m_Camera.rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); - - glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); - glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); - - glDisable(GL_LIGHTING); - drawSkeleton(&m_Skeleton); - glEnable(GL_LIGHTING); - - if (m_Skeleton.childCnt > 0) - { - DeformVertices(&m_Skeleton,&m_Model); - } - drawModel(&m_Model); - - m_PickX = -1; - m_PickY = -1; - - glPopMatrix(); - - GetSkeletonMat(&m_Skeleton); // GET THE SKELETON INFO - - // IF I AM DRAGGING A SELECTION BOX, DRAW IT - if (drawSelectRect) - { - glMatrixMode(GL_PROJECTION); // I WANT TO PLAY WITH THE PROJECTION - glPushMatrix(); // SAVE THE OLD ONE - glLoadIdentity(); // LOAD A NEW ONE - gluOrtho2D(0,m_ScreenWidth,0,m_ScreenHeight); // USE WINDOW SETTINGS - glColor3f(1.0f, 1.0f, 1.0f); // DRAW A WHITE BOX - glBegin(GL_LINE_STRIP); - glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); - glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.top); - glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.bottom); - glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.bottom); - glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); - glEnd(); - glPopMatrix(); // RESTORE THE OLD PROJECTION - glMatrixMode(GL_MODELVIEW); // BACK TO MODEL MODE - } - - // glFinish(); - - SwapBuffers(m_hDC); - - UpdateStatusBarFrameInfo(); -} -//// drawScene ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SelectVertices -// Purpose: Use Feedback to get all the vertices in the view -// Arguments: Should I select or de-select? -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SelectVertices(BOOL select) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat *feedBuffer; - GLint hitCount; - int loop2; - float *data; -/////////////////////////////////////////////////////////////////////////////// - if (m_Model.vertexData != NULL) - { - // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) - feedBuffer = (GLfloat *)malloc(sizeof(GLfloat) * m_Model.vertexCnt * 6); - // TELL OPENGL ABOUT THE BUFFER - glFeedbackBuffer(m_Model.vertexCnt * 6,GL_3D,feedBuffer); - (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); - - glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); - glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f); - - for (loop2 = 0; loop2 < m_Model.vertexCnt; loop2++) - { - if (m_DrawDeformed) - data = (float *)m_Model.deformData; - else - data = (float *)m_Model.vertexData; - // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS - glPassThrough((float)loop2); - // SEND THE VERTEX - glBegin(GL_POINTS); - glVertex3fv((float *)&data[(m_Model.vSize * (loop2 + 1)) - 3]); - glEnd(); - } - - glPopMatrix(); - hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET - CompareBuffer(hitCount,feedBuffer, select); // CHECK THEM AGAINST MY SELECTION - free(feedBuffer); // GET RID OF THE MEMORY - } -} -////// SelectVertices ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CompareBuffer -// Purpose: Check the feedback buffer to see if anything is tagged -// Arguments: Number of hits, pointer to buffer, Should I select or de-select -/////////////////////////////////////////////////////////////////////////////// -void COGLView::CompareBuffer(GLint size, GLfloat *buffer,BOOL select) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLint count; - GLfloat token,point[3]; - int loop,currentVertex; - int *data; -/////////////////////////////////////////////////////////////////////////////// - count = size; - while (count) - { - token = buffer[size - count]; // CHECK THE TOKEN - count--; - if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER - { - currentVertex = (int)buffer[size - count]; // WHAT VERTEX - count--; - } - else if (token == GL_POINT_TOKEN) - { - // THERE ARE THREE ELEMENTS TO A POINT TOKEN - for (loop = 0; loop < 3; loop++) - { - point[loop] = buffer[size - count]; - count--; - } - data = (BOOL *)m_Model.CV_select; - // CHECK IF THE POINT WAS IN MY SELECTION RECTANGLE - // FLOATS 0 AND 1 ARE SCREEN X AND Y - // NOTE: OPENGL SETS THE BOTTOM Y=0 - if (point[0] >= m_SelectRect.left && - point[0] <= m_SelectRect.right && - point[1] <= m_SelectRect.top && - point[1] >= m_SelectRect.bottom) - // SET THIS VERTEX TO THE CURRENT SELECTION VALUE - data[currentVertex] = select; - } - } -} -////// CompareBuffer ////////////////////////////////////////////////////////// - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(FALSE); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER - m_mousepos = point; - m_Grab_Rot_X = m_SelectedBone->rot.x; - m_Grab_Rot_Y = m_SelectedBone->rot.y; - m_Grab_Rot_Z = m_SelectedBone->rot.z; - m_Grab_Trans_X = m_SelectedBone->trans.x; - m_Grab_Trans_Y = m_SelectedBone->trans.y; - m_Grab_Trans_Z = m_SelectedBone->trans.z; - m_SelectRect.left = point.x; - m_SelectRect.top = m_ScreenHeight - point.y; - if ((nFlags & MK_CONTROL) == 0 && (nFlags & MK_SHIFT) == 0) - { - m_SelectRect.left = point.x; - m_SelectRect.top = m_ScreenHeight - point.y; - SetCapture( ); - } - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER - m_mousepos = point; - m_Grab_Rot_X = m_Camera.rot.x; - m_Grab_Rot_Y = m_Camera.rot.y; - m_Grab_Rot_Z = m_Camera.rot.z; - m_Grab_Trans_X = m_Camera.trans.x; - m_Grab_Trans_Y = m_Camera.trans.y; - m_Grab_Trans_Z = m_Camera.trans.z; - m_SelectRect.left = point.x; - m_SelectRect.top = m_ScreenHeight - point.y; - CWnd::OnRButtonDown(nFlags, point); -} - - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - if ((nFlags & MK_CONTROL) == 0 && (nFlags & MK_SHIFT) == 0) - - { - m_SelectRect.right = point.x; - m_SelectRect.bottom = m_ScreenHeight - point.y; - SelectVertices(TRUE); - drawScene(FALSE); - } - ReleaseCapture( ); - CWnd::OnLButtonUp(nFlags, point); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnMouseMove -// Purpose: Handler for the mouse. Handles movement when pressed -// Arguments: Flags for key masks and point -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - UpdateStatusBar(0); - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CTRL' BUTTON ROTATE IN Z - if ((nFlags & MK_CONTROL) > 0) - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - } - // ELSE "SHIFT" ROTATE THE BONE IN XY - else if ((nFlags & MK_SHIFT) > 0) - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - if ((point.y - m_mousepos.y) != 0) - { - m_SelectedBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(FALSE); - } - } - // ELSE MY SELECTION BOX - else - { - m_SelectRect.right = point.x; - m_SelectRect.bottom = m_ScreenHeight - point.y; - drawScene(TRUE); - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) // Handle the Camera - { - if ((nFlags & MK_CONTROL) > 0) // Move Camera in Z - { - UpdateStatusBar(2); - if ((point.x - m_mousepos.x) != 0) - { - m_Camera.trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - } - else if ((nFlags & MK_SHIFT) > 0) - { - UpdateStatusBar(2); - if ((point.x - m_mousepos.x) != 0) // Move Camera in X - { - m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - if ((point.y - m_mousepos.y) != 0) // Move Camera in Y - { - m_Camera.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(FALSE); - } - } - else - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) // Rotate Camera in Y - { - m_Camera.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(FALSE); - } - if ((point.y - m_mousepos.y) != 0) // Rotate Camera in X - { - m_Camera.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(FALSE); - } - } - } - - CWnd::OnMouseMove(nFlags, point); -} -//// OnMouseMove ////////////////////////////////////////////////////// - -void COGLView::OnMove(int x, int y) -{ - CWnd::OnMove(x, y); - - resize( x,y ); - -} - -// 0 = READY -// 1 = ROTATE -// 2 = TRANSLATE -void COGLView::UpdateStatusBar(int mode) -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - if (mode == 1) - { - strcpy(message,"Rotate"); - } - else if (mode == 2) - { - strcpy(message,"Translate"); - } - else - { - strcpy(message,"Ready"); - } - m_StatusBar->SetPaneText(0,message); -} - -void COGLView::UpdateStatusBarFrameInfo() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - if (m_StatusBar != NULL && m_Skeleton.children != NULL) - { - if (m_SelectedBone != NULL) - sprintf(message,"CurBone (%2.2f,%2.2f,%2.2f)", - m_SelectedBone->rot.x,m_SelectedBone->rot.y,m_SelectedBone->rot.z); - else - sprintf(message,"No CurBone"); - //m_StatusBar->SetPaneStyle(1,SBPS_POPOUT); - m_StatusBar->SetPaneText(1,message); - } -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop2; -/////////////////////////////////////////////////////////////////////////////// - switch (nChar) - { - case VK_SPACE: - if (m_Model.vertexData != NULL) - { - for (loop2 = 0; loop2 < m_Model.vertexCnt; loop2++) - m_Model.CV_select[loop2] = FALSE; - } - m_Skeleton.id = (long)&m_Skeleton; - break; - case 'W': - WeightBones(); - break; - case 'B': - break; - case 'R': - m_SelectedBone->rot.x = m_SelectedBone->b_rot.x; - m_SelectedBone->rot.y = m_SelectedBone->b_rot.y; - m_SelectedBone->rot.z = m_SelectedBone->b_rot.z; - break; - case 'D': - m_DrawDeformed = !m_DrawDeformed; - break; - case 'F': - break; - } - - Invalidate(TRUE); - -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnViewResetskeleton -// Purpose: Reset the view settings for the skeleton -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnViewResetskeleton() -{ - ResetSkeleton(&m_Skeleton); - drawScene(FALSE); - Invalidate(TRUE); -} -//// OnViewResetskeleton ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetGLInfo -// Purpose: Get the OpenGL Vendor and Renderer -/////////////////////////////////////////////////////////////////////////////// -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} -//// GetGLInfo ///////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetSkeletonList -// Purpose: Sets up the Weights in the Skeleton for all vertices. Recursive -// Arguments: Bone pointer -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SetSkeletonList(t_Bone *skeleton) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2; - long vptr; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - - if (skeleton->childCnt > 0 && m_Model.vertexData != NULL) - { - child = skeleton->children; - for (loop = 0; loop < skeleton->childCnt; loop++,child++) - { - if (child->CV_weight) free(child->CV_weight); - child->CV_weight = (t_VWeight *)malloc(sizeof(t_VWeight) * m_Model.vertexCnt); - vptr = 0; - for (loop2 = 0; loop2 < m_Model.vertexCnt; loop2++,vptr++) - { - child->CV_weight[vptr].vertex = loop2; - child->CV_weight[vptr].weight = 0.0f; - } - if (child->childCnt > 0) - SetSkeletonList(child); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetBasePose -// Purpose: Lock the current pose as the base for deformation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SetBasePose() -{ - FreezeSkeleton(&m_Skeleton); - GetBaseSkeletonMat(&m_Skeleton); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: WeightBones -// Purpose: Set the weighting for a selected bone -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::WeightBones() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop3; - long vptr; -/////////////////////////////////////////////////////////////////////////////// - if (m_Model.vertexData != NULL) - { - vptr = 0; - for (loop3 = 0; loop3 < m_Model.vertexCnt; loop3++,vptr++) - { - // IF A POINT IS SELECTED SET THE WEIGHT - if (m_Model.CV_select[loop3]) - { - m_SelectedBone->CV_weight[loop3].weight = m_SelectedBone->animBlend; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: ClearBoneWeights -// Purpose: Go through bones and clear weights for any selected vertex -// Arguments: Bone pointer -/////////////////////////////////////////////////////////////////////////////// -void COGLView::ClearBoneWeights(t_Bone *skeleton) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - - if (skeleton->childCnt > 0 && m_Model.vertexData != NULL) - { - child = skeleton->children; - for (loop = 0; loop < skeleton->childCnt; loop++,child++) - { - for (int loop3 = 0; loop3 < m_Model.vertexCnt; loop3++) - { - // IF A POINT IS SELECTED SET THE WEIGHT - if (m_Model.CV_select[loop3]) - { - child->CV_weight[loop3].weight = 0.0f; - } - } - - // Recurse through Hierarchy - if (child->childCnt > 0) - ClearBoneWeights(child); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: IterateBoneWeights -// Purpose: Go through bones and either read or write weight values -// Arguments: Bone pointer, read or write BOOL, and file pointer -/////////////////////////////////////////////////////////////////////////////// -void COGLView::IterateBoneWeights(t_Bone *skeleton, BOOL read, FILE *fp) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - - if (skeleton->childCnt > 0 && m_Model.vertexData != NULL) - { - child = skeleton->children; - for (loop = 0; loop < skeleton->childCnt; loop++,child++) - { - if (read) - fread(child->CV_weight,sizeof(t_VWeight),m_Model.vertexCnt, fp); - else - fwrite(child->CV_weight,sizeof(t_VWeight),m_Model.vertexCnt, fp); - - // Recurse through Hierarchy - if (child->childCnt > 0) - IterateBoneWeights(child, read, fp); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadWeights -// Purpose: Load a Weight File -// Arguments: Name of the file to open -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::LoadWeights(CString name) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS - int count; -/////////////////////////////////////////////////////////////////////////////// - if (fp = fopen((LPCTSTR)name,"rb")) { - fread(&count,sizeof(int),1,fp); - if (m_Model.vertexCnt == count) - { - IterateBoneWeights(&m_Skeleton, TRUE, fp); - } - else - { - ::MessageBox(NULL,"Weight File Vertex Count Doesn't Match Model","Weight File Load Error",MB_OK); - } - - // Assume if a Weight File is loaded it should be deformed - m_DrawDeformed = TRUE; - - fclose(fp); - } - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SaveWeights -// Purpose: Save a Set of Weight Files -// Arguments: Name of the file to save -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::SaveWeights(CString name) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS -/////////////////////////////////////////////////////////////////////////////// - if (fp = fopen((LPCTSTR)name,"wb")) { - fwrite(&m_Model.vertexCnt,sizeof(int),1,fp); - IterateBoneWeights(&m_Skeleton, FALSE, fp); - fclose(fp); - } - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadOBJModel -// Purpose: Load an OBJ Model into the system -// Arguments: Name of the file to open -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::LoadOBJModel(CString name) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - if (m_Model.vertexData != NULL) // Free model data if exists - { - free(m_Model.vertexData); - free(m_Model.deformData); - free(m_Model.CV_select); - m_Model.vertexData = NULL; - m_Model.deformData = NULL; - m_Model.CV_select = NULL; - } - LoadOBJ((LPCSTR)name,&m_Model); - SetSkeletonList(&m_Skeleton); // Set up Weights - SetBasePose(); // Lock in the Rest State - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadSkeletonFile -// Purpose: Load a Skeleton into the system -// Arguments: Name of the file to open -/////////////////////////////////////////////////////////////////////////////// -BOOL COGLView::LoadSkeletonFile(CString name) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - DestroySkeleton(&m_Skeleton); - LoadSkeleton(name,&m_Skeleton); - SetSkeletonList(&m_Skeleton); // Set up Weights - return TRUE; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// Versions: +// 1.01 12/20/97 Fix perspective in OpenGL Resize Code +// 1.02 1/10/97 Change to display code to handle skeletal hierarchy +// Modified: +// JL 9/10/99 Created skeleton Demo for Oct 99 GDMag +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include "Skully.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "LoadSkel.h" // Skeleton loading + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define OGL_SELECTED_DLIST 2 // SELECTED BONE OPENGL DISPLAY LIST +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_StatusBar = NULL; // CLEAR THIS. IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT + m_DrawSkeleton = TRUE; + m_DrawDeformed = FALSE; + m_PickX = -1; + m_PickY = -1; + ResetBone(&m_Skeleton,NULL); + m_SelectedBone = &m_Skeleton; + + // INITIALIZE SOME OF THE CAMERA VARIABLES + ResetBone(&m_Camera, NULL); + m_Camera.id = -1; + strcpy(m_Camera.name,"Camera"); + m_Camera.rot.x = 0.0f; + m_Camera.rot.y = 0.0f; + m_Camera.rot.z = 0.0f; + m_Camera.b_trans.y = -6.0f; + m_Camera.b_trans.z = -50.0f; + m_Camera.trans.y = -6.0f; + m_Camera.trans.z = -50.0f; + + m_Model.vertexData = NULL; +} + +COGLView::~COGLView() +{ +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_MOVE() + ON_WM_LBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glEndList(); + + // CREATE THE DISPLAY LIST THE SELECTED BONE JUST A CUBE + glNewList(OGL_SELECTED_DLIST,GL_COMPILE); + glBegin(GL_QUADS); + glColor3f(1.0f, 1.0f, 0.0f); // YELLOW + // BOTTOM + glVertex3f(-0.05f, -0.05f, -0.05f); + glVertex3f( 0.05f, -0.05f, -0.05f); + glVertex3f( 0.05f, -0.05f, 0.05f); + glVertex3f(-0.05f, -0.05f, 0.05f); + // BACK + glVertex3f(-0.05f, 0.05f, -0.05f); + glVertex3f( 0.05f, 0.05f, -0.05f); + glVertex3f( 0.05f, -0.05f, -0.05f); + glVertex3f(-0.05f, -0.05f, -0.05f); + // FRONT + glVertex3f(-0.05f, -0.05f, 0.05f); + glVertex3f( 0.05f, -0.05f, 0.05f); + glVertex3f( 0.05f, 0.05f, 0.05f); + glVertex3f(-0.05f, 0.05f, 0.05f); + // RIGHT + glVertex3f(-0.05f, -0.05f, -0.05f); + glVertex3f(-0.05f, -0.05f, 0.05f); + glVertex3f(-0.05f, 0.05f, 0.05f); + glVertex3f(-0.05f, 0.05f, -0.05f); + // LEFT + glVertex3f( 0.05f, 0.05f, -0.05f); + glVertex3f( 0.05f, 0.05f, 0.05f); + glVertex3f( 0.05f, -0.05f, 0.05f); + glVertex3f( 0.05f, -0.05f, -0.05f); + // TOP + glVertex3f(-0.05f, 0.05f, 0.05f); + glVertex3f( 0.05f, 0.05f, 0.05f); + glVertex3f( 0.05f, 0.05f, -0.05f); + glVertex3f(-0.05f, 0.05f, -0.05f); + glEnd(); + glEndList(); + drawScene(FALSE); + return 0; +} + +/* OpenGL code */ + +/////////////////////////////////////////////////////////////////////////////// +// Function: resize +// Purpose: This code handles the windows resize for OpenGL +// Arguments: Width and heights of the view window +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(20.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + m_ScreenWidth = width; + m_ScreenHeight = height; + +} +//// resize ///////////////////////////////////////////////////////////////// + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; + GLfloat diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; + GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat lightpos[] = { 0.5, 0.5, 1.0, 0.0 }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LESS); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(60.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP +// glPolygonMode(GL_FRONT,GL_FILL); + glPolygonMode(GL_FRONT,GL_LINE); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST); + glPointSize(8.0); // NICE BEEFY POINTS FOR THE VERTEX SELECTION + glDisable(GL_TEXTURE_2D); + + glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); + glMaterialfv(GL_FRONT,GL_SPECULAR, specular); + glMaterialf(GL_FRONT,GL_SHININESS, 25.0f); + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + +} + +/////////////////////////////////////////////////////////////////////////////// +// At run-time, at each frame of animation, you need to get the +// current matrices for every bone. This is multiplied by the +// inverted matrix from the rest bone and stored. Must be +// recursive. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetSkeletonMat +// Purpose: Gets the Matrix values for the character +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::GetSkeletonMat(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; + tMatrix tempMatrix; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + // Set observer's orientation and position + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + + // Get the current matrix + glGetFloatv(GL_MODELVIEW_MATRIX,tempMatrix.m); + + // Multiply it by the inverted root bone and store + MultMatrix(curBone->curMatrix,&tempMatrix,&curBone->matrix); + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + GetSkeletonMat(curBone); + + glPopMatrix(); + + curBone++; + } +} +//// GetSkeletonMat /////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// When the base skeleton is set, the matrix for each bones must +// be grabbed, inverted, then stored for run time use. As the +// skeleton is a hierarchy, this must be done recursively +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetBaseSkeletonMat +// Purpose: Gets the Matrix values for the character +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::GetBaseSkeletonMat(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; + tMatrix tempMatrix; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + glTranslatef(curBone->b_trans.x, curBone->b_trans.y, curBone->b_trans.z); + + // Set observer's orientation and position + glRotatef(curBone->b_rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->b_rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->b_rot.x, 1.0f, 0.0f, 0.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,tempMatrix.m); + // Invert the matrix and store it for later + InvertMatrix(tempMatrix.m,curBone->matrix.m); + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + GetBaseSkeletonMat(curBone); + + glPopMatrix(); + + curBone++; + } +} +//// GetBaseSkeletonMat /////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// This function actually will deform a mesh given a +// skeletal system. At each bone, a combined matrix that +// tranforms the vertex from the rest bone space to the final +// bone space is stored. Each vertex is multiplied by this +// matrix then scaled by the weight. This is accumulated to +// give a fine vertex position +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DeformVertices +// Purpose: Bends the Bodies Based on the Vertices +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::DeformVertices(t_Bone *rootBone,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2; + t_Bone *curBone; + int vertex; + float weight; + tVector post; + float *deformData,*vertexData; +/////////////////////////////////////////////////////////////////////////////// + if (rootBone == &m_Skeleton && visual->vertexData != NULL) + { + // ZERO THE DEFORMATION + if (m_Skeleton.childCnt > 0) + { + for (loop = 0; loop < m_Skeleton.childCnt; loop++) + { + memcpy(visual->deformData,visual->vertexData,sizeof(float) * visual->vSize * visual->vertexCnt); + deformData = (float *)(visual->deformData + (visual->vSize - 3)); + for (loop2 = 0; loop2 < visual->vertexCnt; loop2++, deformData += visual->vSize) + { + deformData[0] = 0.0f; + deformData[1] = 0.0f; + deformData[2] = 0.0f; + } + } + } + } + + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + for (loop2 = 0; loop2 < visual->vertexCnt; loop2++) + { + // GET THE WEIGHT + weight = curBone->CV_weight[loop2].weight; + // The weight is between 0-1 + if (weight > 0.0f) + { + vertex = curBone->CV_weight[loop2].vertex; + + deformData = (float *)(visual->deformData + (visual->vSize * (vertex + 1)) - 3); + vertexData = (float *)(visual->vertexData + (visual->vSize * (vertex + 1)) - 3); + + // Multiply the vertex by the combined matrix + MultVectorByMatrix(curBone->curMatrix, (tVector *)vertexData, &post); +// Since the Matrix above is a combination of the rest and current matrices, it does +// the same as the following two calls would +// MultVectorByMatrix(&curBone->matrix, (tVector *)&vertexData[vertex].x, &pre); +// MultVectorByMatrix(curBone->curMatrix, &pre, &post); + + // Accumulate the result + deformData[0] += (post.x * weight); + deformData[1] += (post.y * weight); + deformData[2] += (post.z * weight); + } + } + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + DeformVertices(curBone, visual); + + curBone++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawModel +// Purpose: Draw the Mesh model either deformed or not +// Arguments: Pointer to the model +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Visual *model) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tColoredVertex *cdata; + float *data; + int loop; +/////////////////////////////////////////////////////////////////////////////// + if (model->vertexData != NULL) + { + + glColor3f(1.0f, 1.0f, 1.0f); // NO MODULATION + + if (m_DrawDeformed) + data = (float *)model->deformData; + else + data = (float *)model->vertexData; + + // Declare the Array of Data + glInterleavedArrays(model->dataFormat,0,(GLvoid *)data); + if (model->vPerFace == 3) // Model is Triangles + glDrawArrays(GL_TRIANGLES,0,model->faceCnt * 3); + else + glDrawArrays(GL_QUADS,0,model->faceCnt * 4); + +/* Same as above but unrolled + cdata = (tColoredVertex *)data; + glBegin(GL_TRIANGLES); + for (loop = 0; loop < model->faceCnt; loop++) + { +// glTexCoord2f(data[loop * 3].u, data[loop * 3].v); + glNormal3fv((float *)&cdata[loop * 3].r); + glVertex3fv((float *)&cdata[loop * 3].x); +// glTexCoord2f(data[loop * 3 + 1].u, data[loop * 3 + 1].v); + glNormal3fv((float *)&cdata[loop * 3 + 1].r); + glVertex3fv((float *)&cdata[loop * 3 + 1].x); +// glTexCoord2f(data[loop * 3 + 2].u, data[loop * 3 + 2].v); + glNormal3fv((float *)&cdata[loop * 3 + 2].r); + glVertex3fv((float *)&cdata[loop * 3 + 2].x); + } + glEnd(); +*/ + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + // NOW DRAW THE VERTEX MARKERS IF THEY ARE SELECTED + glColor3f(1.0f, 0.0f, 0.0f); // Selected Vertices are Red + glBegin(GL_POINTS); + for (loop = 0; loop < model->vertexCnt; loop++) + { + // IF A POINT IS SELECTED DRAW IT + if (model->CV_select[loop]) + { + glVertex3fv((float *)&data[((loop + 1) * model->vSize) - 3]); + } + } + glEnd(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawSkeleton +// Purpose: Actually draws the Skeleton it is recursive +// Arguments: Pointer to the bone +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawSkeleton(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + // Set observer's orientation and position + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION +// glGetFloatv(GL_MODELVIEW_MATRIX,curBone->matrix.m); + + // THE SCALE IS LOCAL SO I PUSH AND POP + glPushMatrix(); + glScalef(curBone->bsphere, curBone->bsphere, curBone->bsphere); + + if (m_DrawSkeleton) + { + // DRAW THE AXIS OGL OBJECT + glCallList(OGL_AXIS_DLIST); + // IF SOMETHING IS SELECTED, DRAW TAG BOX + if (m_Skeleton.id == (long)curBone) + { + glDisable(GL_CULL_FACE); + m_SelectedBone = curBone; + glCallList(OGL_SELECTED_DLIST); + glEnable(GL_CULL_FACE); + } + } + glPopMatrix(); + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + drawSkeleton(curBone); + + glPopMatrix(); + + curBone++; + } +} +//// drawSkeleton ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawScene +// Purpose: Actually draw the OpenGL Scene +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(BOOL drawSelectRect) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Camera.rot.y > 360.0f) m_Camera.rot.y -= 360.0f; + if (m_Camera.rot.x > 360.0f) m_Camera.rot.x -= 360.0f; + if (m_Camera.rot.z > 360.0f) m_Camera.rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); + + glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); + glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); + + glDisable(GL_LIGHTING); + drawSkeleton(&m_Skeleton); + glEnable(GL_LIGHTING); + + if (m_Skeleton.childCnt > 0) + { + DeformVertices(&m_Skeleton,&m_Model); + } + drawModel(&m_Model); + + m_PickX = -1; + m_PickY = -1; + + glPopMatrix(); + + GetSkeletonMat(&m_Skeleton); // GET THE SKELETON INFO + + // IF I AM DRAGGING A SELECTION BOX, DRAW IT + if (drawSelectRect) + { + glMatrixMode(GL_PROJECTION); // I WANT TO PLAY WITH THE PROJECTION + glPushMatrix(); // SAVE THE OLD ONE + glLoadIdentity(); // LOAD A NEW ONE + gluOrtho2D(0,m_ScreenWidth,0,m_ScreenHeight); // USE WINDOW SETTINGS + glColor3f(1.0f, 1.0f, 1.0f); // DRAW A WHITE BOX + glBegin(GL_LINE_STRIP); + glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); + glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.top); + glVertex2s((short)m_SelectRect.right,(short)m_SelectRect.bottom); + glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.bottom); + glVertex2s((short)m_SelectRect.left,(short)m_SelectRect.top); + glEnd(); + glPopMatrix(); // RESTORE THE OLD PROJECTION + glMatrixMode(GL_MODELVIEW); // BACK TO MODEL MODE + } + + // glFinish(); + + SwapBuffers(m_hDC); + + UpdateStatusBarFrameInfo(); +} +//// drawScene ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SelectVertices +// Purpose: Use Feedback to get all the vertices in the view +// Arguments: Should I select or de-select? +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SelectVertices(BOOL select) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat *feedBuffer; + GLint hitCount; + int loop2; + float *data; +/////////////////////////////////////////////////////////////////////////////// + if (m_Model.vertexData != NULL) + { + // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) + feedBuffer = (GLfloat *)malloc(sizeof(GLfloat) * m_Model.vertexCnt * 6); + // TELL OPENGL ABOUT THE BUFFER + glFeedbackBuffer(m_Model.vertexCnt * 6,GL_3D,feedBuffer); + (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); + + glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); + glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f); + + for (loop2 = 0; loop2 < m_Model.vertexCnt; loop2++) + { + if (m_DrawDeformed) + data = (float *)m_Model.deformData; + else + data = (float *)m_Model.vertexData; + // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS + glPassThrough((float)loop2); + // SEND THE VERTEX + glBegin(GL_POINTS); + glVertex3fv((float *)&data[(m_Model.vSize * (loop2 + 1)) - 3]); + glEnd(); + } + + glPopMatrix(); + hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET + CompareBuffer(hitCount,feedBuffer, select); // CHECK THEM AGAINST MY SELECTION + free(feedBuffer); // GET RID OF THE MEMORY + } +} +////// SelectVertices ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CompareBuffer +// Purpose: Check the feedback buffer to see if anything is tagged +// Arguments: Number of hits, pointer to buffer, Should I select or de-select +/////////////////////////////////////////////////////////////////////////////// +void COGLView::CompareBuffer(GLint size, GLfloat *buffer,BOOL select) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLint count; + GLfloat token,point[3]; + int loop,currentVertex; + int *data; +/////////////////////////////////////////////////////////////////////////////// + count = size; + while (count) + { + token = buffer[size - count]; // CHECK THE TOKEN + count--; + if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER + { + currentVertex = (int)buffer[size - count]; // WHAT VERTEX + count--; + } + else if (token == GL_POINT_TOKEN) + { + // THERE ARE THREE ELEMENTS TO A POINT TOKEN + for (loop = 0; loop < 3; loop++) + { + point[loop] = buffer[size - count]; + count--; + } + data = (BOOL *)m_Model.CV_select; + // CHECK IF THE POINT WAS IN MY SELECTION RECTANGLE + // FLOATS 0 AND 1 ARE SCREEN X AND Y + // NOTE: OPENGL SETS THE BOTTOM Y=0 + if (point[0] >= m_SelectRect.left && + point[0] <= m_SelectRect.right && + point[1] <= m_SelectRect.top && + point[1] >= m_SelectRect.bottom) + // SET THIS VERTEX TO THE CURRENT SELECTION VALUE + data[currentVertex] = select; + } + } +} +////// CompareBuffer ////////////////////////////////////////////////////////// + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(FALSE); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER + m_mousepos = point; + m_Grab_Rot_X = m_SelectedBone->rot.x; + m_Grab_Rot_Y = m_SelectedBone->rot.y; + m_Grab_Rot_Z = m_SelectedBone->rot.z; + m_Grab_Trans_X = m_SelectedBone->trans.x; + m_Grab_Trans_Y = m_SelectedBone->trans.y; + m_Grab_Trans_Z = m_SelectedBone->trans.z; + m_SelectRect.left = point.x; + m_SelectRect.top = m_ScreenHeight - point.y; + if ((nFlags & MK_CONTROL) == 0 && (nFlags & MK_SHIFT) == 0) + { + m_SelectRect.left = point.x; + m_SelectRect.top = m_ScreenHeight - point.y; + SetCapture( ); + } + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER + m_mousepos = point; + m_Grab_Rot_X = m_Camera.rot.x; + m_Grab_Rot_Y = m_Camera.rot.y; + m_Grab_Rot_Z = m_Camera.rot.z; + m_Grab_Trans_X = m_Camera.trans.x; + m_Grab_Trans_Y = m_Camera.trans.y; + m_Grab_Trans_Z = m_Camera.trans.z; + m_SelectRect.left = point.x; + m_SelectRect.top = m_ScreenHeight - point.y; + CWnd::OnRButtonDown(nFlags, point); +} + + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + if ((nFlags & MK_CONTROL) == 0 && (nFlags & MK_SHIFT) == 0) + + { + m_SelectRect.right = point.x; + m_SelectRect.bottom = m_ScreenHeight - point.y; + SelectVertices(TRUE); + drawScene(FALSE); + } + ReleaseCapture( ); + CWnd::OnLButtonUp(nFlags, point); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnMouseMove +// Purpose: Handler for the mouse. Handles movement when pressed +// Arguments: Flags for key masks and point +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + UpdateStatusBar(0); + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CTRL' BUTTON ROTATE IN Z + if ((nFlags & MK_CONTROL) > 0) + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + } + // ELSE "SHIFT" ROTATE THE BONE IN XY + else if ((nFlags & MK_SHIFT) > 0) + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + if ((point.y - m_mousepos.y) != 0) + { + m_SelectedBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(FALSE); + } + } + // ELSE MY SELECTION BOX + else + { + m_SelectRect.right = point.x; + m_SelectRect.bottom = m_ScreenHeight - point.y; + drawScene(TRUE); + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) // Handle the Camera + { + if ((nFlags & MK_CONTROL) > 0) // Move Camera in Z + { + UpdateStatusBar(2); + if ((point.x - m_mousepos.x) != 0) + { + m_Camera.trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + } + else if ((nFlags & MK_SHIFT) > 0) + { + UpdateStatusBar(2); + if ((point.x - m_mousepos.x) != 0) // Move Camera in X + { + m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + if ((point.y - m_mousepos.y) != 0) // Move Camera in Y + { + m_Camera.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(FALSE); + } + } + else + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) // Rotate Camera in Y + { + m_Camera.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(FALSE); + } + if ((point.y - m_mousepos.y) != 0) // Rotate Camera in X + { + m_Camera.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(FALSE); + } + } + } + + CWnd::OnMouseMove(nFlags, point); +} +//// OnMouseMove ////////////////////////////////////////////////////// + +void COGLView::OnMove(int x, int y) +{ + CWnd::OnMove(x, y); + + resize( x,y ); + +} + +// 0 = READY +// 1 = ROTATE +// 2 = TRANSLATE +void COGLView::UpdateStatusBar(int mode) +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + if (mode == 1) + { + strcpy(message,"Rotate"); + } + else if (mode == 2) + { + strcpy(message,"Translate"); + } + else + { + strcpy(message,"Ready"); + } + m_StatusBar->SetPaneText(0,message); +} + +void COGLView::UpdateStatusBarFrameInfo() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + if (m_StatusBar != NULL && m_Skeleton.children != NULL) + { + if (m_SelectedBone != NULL) + sprintf(message,"CurBone (%2.2f,%2.2f,%2.2f)", + m_SelectedBone->rot.x,m_SelectedBone->rot.y,m_SelectedBone->rot.z); + else + sprintf(message,"No CurBone"); + //m_StatusBar->SetPaneStyle(1,SBPS_POPOUT); + m_StatusBar->SetPaneText(1,message); + } +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop2; +/////////////////////////////////////////////////////////////////////////////// + switch (nChar) + { + case VK_SPACE: + if (m_Model.vertexData != NULL) + { + for (loop2 = 0; loop2 < m_Model.vertexCnt; loop2++) + m_Model.CV_select[loop2] = FALSE; + } + m_Skeleton.id = (long)&m_Skeleton; + break; + case 'W': + WeightBones(); + break; + case 'B': + break; + case 'R': + m_SelectedBone->rot.x = m_SelectedBone->b_rot.x; + m_SelectedBone->rot.y = m_SelectedBone->b_rot.y; + m_SelectedBone->rot.z = m_SelectedBone->b_rot.z; + break; + case 'D': + m_DrawDeformed = !m_DrawDeformed; + break; + case 'F': + break; + } + + Invalidate(TRUE); + +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnViewResetskeleton +// Purpose: Reset the view settings for the skeleton +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnViewResetskeleton() +{ + ResetSkeleton(&m_Skeleton); + drawScene(FALSE); + Invalidate(TRUE); +} +//// OnViewResetskeleton ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetGLInfo +// Purpose: Get the OpenGL Vendor and Renderer +/////////////////////////////////////////////////////////////////////////////// +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} +//// GetGLInfo ///////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetSkeletonList +// Purpose: Sets up the Weights in the Skeleton for all vertices. Recursive +// Arguments: Bone pointer +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SetSkeletonList(t_Bone *skeleton) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2; + long vptr; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + + if (skeleton->childCnt > 0 && m_Model.vertexData != NULL) + { + child = skeleton->children; + for (loop = 0; loop < skeleton->childCnt; loop++,child++) + { + if (child->CV_weight) free(child->CV_weight); + child->CV_weight = (t_VWeight *)malloc(sizeof(t_VWeight) * m_Model.vertexCnt); + vptr = 0; + for (loop2 = 0; loop2 < m_Model.vertexCnt; loop2++,vptr++) + { + child->CV_weight[vptr].vertex = loop2; + child->CV_weight[vptr].weight = 0.0f; + } + if (child->childCnt > 0) + SetSkeletonList(child); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetBasePose +// Purpose: Lock the current pose as the base for deformation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SetBasePose() +{ + FreezeSkeleton(&m_Skeleton); + GetBaseSkeletonMat(&m_Skeleton); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: WeightBones +// Purpose: Set the weighting for a selected bone +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::WeightBones() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop3; + long vptr; +/////////////////////////////////////////////////////////////////////////////// + if (m_Model.vertexData != NULL) + { + vptr = 0; + for (loop3 = 0; loop3 < m_Model.vertexCnt; loop3++,vptr++) + { + // IF A POINT IS SELECTED SET THE WEIGHT + if (m_Model.CV_select[loop3]) + { + m_SelectedBone->CV_weight[loop3].weight = m_SelectedBone->animBlend; + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: ClearBoneWeights +// Purpose: Go through bones and clear weights for any selected vertex +// Arguments: Bone pointer +/////////////////////////////////////////////////////////////////////////////// +void COGLView::ClearBoneWeights(t_Bone *skeleton) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + + if (skeleton->childCnt > 0 && m_Model.vertexData != NULL) + { + child = skeleton->children; + for (loop = 0; loop < skeleton->childCnt; loop++,child++) + { + for (int loop3 = 0; loop3 < m_Model.vertexCnt; loop3++) + { + // IF A POINT IS SELECTED SET THE WEIGHT + if (m_Model.CV_select[loop3]) + { + child->CV_weight[loop3].weight = 0.0f; + } + } + + // Recurse through Hierarchy + if (child->childCnt > 0) + ClearBoneWeights(child); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: IterateBoneWeights +// Purpose: Go through bones and either read or write weight values +// Arguments: Bone pointer, read or write BOOL, and file pointer +/////////////////////////////////////////////////////////////////////////////// +void COGLView::IterateBoneWeights(t_Bone *skeleton, BOOL read, FILE *fp) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + + if (skeleton->childCnt > 0 && m_Model.vertexData != NULL) + { + child = skeleton->children; + for (loop = 0; loop < skeleton->childCnt; loop++,child++) + { + if (read) + fread(child->CV_weight,sizeof(t_VWeight),m_Model.vertexCnt, fp); + else + fwrite(child->CV_weight,sizeof(t_VWeight),m_Model.vertexCnt, fp); + + // Recurse through Hierarchy + if (child->childCnt > 0) + IterateBoneWeights(child, read, fp); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadWeights +// Purpose: Load a Weight File +// Arguments: Name of the file to open +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::LoadWeights(CString name) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS + int count; +/////////////////////////////////////////////////////////////////////////////// + if (fp = fopen((LPCTSTR)name,"rb")) { + fread(&count,sizeof(int),1,fp); + if (m_Model.vertexCnt == count) + { + IterateBoneWeights(&m_Skeleton, TRUE, fp); + } + else + { + ::MessageBox(NULL,"Weight File Vertex Count Doesn't Match Model","Weight File Load Error",MB_OK); + } + + // Assume if a Weight File is loaded it should be deformed + m_DrawDeformed = TRUE; + + fclose(fp); + } + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SaveWeights +// Purpose: Save a Set of Weight Files +// Arguments: Name of the file to save +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::SaveWeights(CString name) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS +/////////////////////////////////////////////////////////////////////////////// + if (fp = fopen((LPCTSTR)name,"wb")) { + fwrite(&m_Model.vertexCnt,sizeof(int),1,fp); + IterateBoneWeights(&m_Skeleton, FALSE, fp); + fclose(fp); + } + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadOBJModel +// Purpose: Load an OBJ Model into the system +// Arguments: Name of the file to open +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::LoadOBJModel(CString name) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + if (m_Model.vertexData != NULL) // Free model data if exists + { + free(m_Model.vertexData); + free(m_Model.deformData); + free(m_Model.CV_select); + m_Model.vertexData = NULL; + m_Model.deformData = NULL; + m_Model.CV_select = NULL; + } + LoadOBJ((LPCSTR)name,&m_Model); + SetSkeletonList(&m_Skeleton); // Set up Weights + SetBasePose(); // Lock in the Rest State + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadSkeletonFile +// Purpose: Load a Skeleton into the system +// Arguments: Name of the file to open +/////////////////////////////////////////////////////////////////////////////// +BOOL COGLView::LoadSkeletonFile(CString name) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + DestroySkeleton(&m_Skeleton); + LoadSkeleton(name,&m_Skeleton); + SetSkeletonList(&m_Skeleton); // Set up Weights + return TRUE; +} + diff --git a/Skeletal Deformation/Code/OGL/Skully/OGLView.h b/Skeletal Deformation/Code/OGL/Skully/OGLView.h index 07cea78..673d076 100644 --- a/Skeletal Deformation/Code/OGL/Skully/OGLView.h +++ b/Skeletal Deformation/Code/OGL/Skully/OGLView.h @@ -1,118 +1,118 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Hierarchical Animation System -// -// Created: -// JL 9/12/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - CStatusBar *m_StatusBar; - CRect m_SelectRect; - int m_ScreenWidth, m_ScreenHeight; - BOOL m_DrawSkeleton; - BOOL m_DrawDeformed; - int m_PickX, m_PickY; - int m_BoneCnt; - t_Bone m_Camera,*m_SelectedBone; // For the Camera and Pointer to Current Bone - t_Bone m_Skeleton; // Storage for the Skeletal system - t_Visual m_Model; // Actual Model to be deformed -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - void LoadActor(CString filename); - GLvoid drawModel(t_Visual *model); - GLvoid drawSkeleton(t_Bone *rootBone); - GLvoid drawScene(BOOL drawSelectRect); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void CompareBuffer(GLint size, GLfloat *buffer,BOOL select); - void SelectVertices(BOOL select); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - void OnViewResetskeleton(); - void SetSkeletonList(t_Bone *skeleton); - GLvoid GetSkeletonMat(t_Bone *rootBone); - GLvoid GetBaseSkeletonMat(t_Bone *rootBone); - GLvoid WeightBones(); - GLvoid DeformVertices(t_Bone *rootBone,t_Visual *visual); - void IterateBoneWeights(t_Bone *skeleton, BOOL read, FILE *fp) ; - void ClearBoneWeights(t_Bone *skeleton); - BOOL LoadWeights(CString name); - BOOL SaveWeights(CString name); - BOOL LoadOBJModel(CString name); - BOOL LoadSkeletonFile(CString name); - void SetBasePose(); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - void UpdateStatusBar(int mode); - void UpdateStatusBarFrameInfo(); - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnMove(int x, int y); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Hierarchical Animation System +// +// Created: +// JL 9/12/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + CStatusBar *m_StatusBar; + CRect m_SelectRect; + int m_ScreenWidth, m_ScreenHeight; + BOOL m_DrawSkeleton; + BOOL m_DrawDeformed; + int m_PickX, m_PickY; + int m_BoneCnt; + t_Bone m_Camera,*m_SelectedBone; // For the Camera and Pointer to Current Bone + t_Bone m_Skeleton; // Storage for the Skeletal system + t_Visual m_Model; // Actual Model to be deformed +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + void LoadActor(CString filename); + GLvoid drawModel(t_Visual *model); + GLvoid drawSkeleton(t_Bone *rootBone); + GLvoid drawScene(BOOL drawSelectRect); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void CompareBuffer(GLint size, GLfloat *buffer,BOOL select); + void SelectVertices(BOOL select); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + void OnViewResetskeleton(); + void SetSkeletonList(t_Bone *skeleton); + GLvoid GetSkeletonMat(t_Bone *rootBone); + GLvoid GetBaseSkeletonMat(t_Bone *rootBone); + GLvoid WeightBones(); + GLvoid DeformVertices(t_Bone *rootBone,t_Visual *visual); + void IterateBoneWeights(t_Bone *skeleton, BOOL read, FILE *fp) ; + void ClearBoneWeights(t_Bone *skeleton); + BOOL LoadWeights(CString name); + BOOL SaveWeights(CString name); + BOOL LoadOBJModel(CString name); + BOOL LoadSkeletonFile(CString name); + void SetBasePose(); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + void UpdateStatusBar(int mode); + void UpdateStatusBarFrameInfo(); + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnMove(int x, int y); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/Skeleton.cpp b/Skeletal Deformation/Code/OGL/Skully/Skeleton.cpp index 31d68b7..7e9e239 100644 --- a/Skeletal Deformation/Code/OGL/Skully/Skeleton.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/Skeleton.cpp @@ -1,257 +1,257 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: DestroySkeleton -// Purpose: Clear memory for a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - if (child->curMatrix) - free(child->curMatrix); - } - free(root->children); - if (root->curMatrix) - free(root->curMatrix); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->CV_select = NULL; // POINTER TO WEIGHTS - root->CV_weight = NULL; // POINTER TO VISUALS - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} -//// DestroySkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ResetSkeleton -// Purpose: Reset a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void ResetSkeleton(t_Bone *bone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - bone->rot.x = bone->b_rot.x; - bone->rot.y = bone->b_rot.y; - bone->rot.z = bone->b_rot.z; - - bone->trans.x = bone->b_trans.x; - bone->trans.y = bone->b_trans.y; - bone->trans.z = bone->b_trans.z; - - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - ResetSkeleton(child); - } - } -} -//// ResetSkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: FreezeSkeleton -// Purpose: Freeze a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void FreezeSkeleton(t_Bone *bone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - bone->b_rot.x = bone->rot.x; - bone->b_rot.y = bone->rot.y; - bone->b_rot.z = bone->rot.z; - - bone->b_trans.x = bone->trans.x; - bone->b_trans.y = bone->trans.y; - bone->b_trans.z = bone->trans.z; - - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - FreezeSkeleton(child); - } - } -} -//// FreezeSkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ResetBone -// Purpose: Reset the bone system and set the parent bone -// Arguments: Pointer to bone system, and parent bone (could be null) -/////////////////////////////////////////////////////////////////////////////// -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - bone->animBlend = 0.0f; - - bone->bsphere = 1.0f; - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER - bone->parent = parent; - bone->CV_select = NULL; // POINTER TO WEIGHTS - bone->CV_weight = NULL; // POINTER TO VISUALS - bone->curMatrix = NULL; -} -//// ResetBone //////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: BoneSetFrame -// Purpose: Set the animation stream for a bone -// Arguments: Pointer to bone system, frame to set to -/////////////////////////////////////////////////////////////////////////////// -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - // THIS HANDLES THE INDIVIDUAL STREAM TYPES. ONLY ONE NOW. - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - -// I DON'T REALLY WANT MY ANIMATION TO DEAL WITH SCALE RIGHT NOW -// EVEN THOUGH IT IS IN THE BVA FILE -// bone->scale.x = offset[6]; -// bone->scale.y = offset[7]; -// bone->scale.z = offset[8]; - break; - - } - } -} -//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: BoneAdvanceFrame -// Purpose: Increment the animation stream for a bone and possible the -// children attached to that bone1 -// Arguments: Pointer to bone system, Delta frame value to move, if it is recursive -/////////////////////////////////////////////////////////////////////////////// -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - // THERE MUST BE SOME THINGS TO ADVANCE - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - // ADVANCE THE STREAM - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } -} -//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: DestroySkeleton +// Purpose: Clear memory for a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + if (child->curMatrix) + free(child->curMatrix); + } + free(root->children); + if (root->curMatrix) + free(root->curMatrix); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->CV_select = NULL; // POINTER TO WEIGHTS + root->CV_weight = NULL; // POINTER TO VISUALS + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} +//// DestroySkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ResetSkeleton +// Purpose: Reset a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void ResetSkeleton(t_Bone *bone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + bone->rot.x = bone->b_rot.x; + bone->rot.y = bone->b_rot.y; + bone->rot.z = bone->b_rot.z; + + bone->trans.x = bone->b_trans.x; + bone->trans.y = bone->b_trans.y; + bone->trans.z = bone->b_trans.z; + + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + ResetSkeleton(child); + } + } +} +//// ResetSkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: FreezeSkeleton +// Purpose: Freeze a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void FreezeSkeleton(t_Bone *bone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + bone->b_rot.x = bone->rot.x; + bone->b_rot.y = bone->rot.y; + bone->b_rot.z = bone->rot.z; + + bone->b_trans.x = bone->trans.x; + bone->b_trans.y = bone->trans.y; + bone->b_trans.z = bone->trans.z; + + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + FreezeSkeleton(child); + } + } +} +//// FreezeSkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ResetBone +// Purpose: Reset the bone system and set the parent bone +// Arguments: Pointer to bone system, and parent bone (could be null) +/////////////////////////////////////////////////////////////////////////////// +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + bone->animBlend = 0.0f; + + bone->bsphere = 1.0f; + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER + bone->parent = parent; + bone->CV_select = NULL; // POINTER TO WEIGHTS + bone->CV_weight = NULL; // POINTER TO VISUALS + bone->curMatrix = NULL; +} +//// ResetBone //////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: BoneSetFrame +// Purpose: Set the animation stream for a bone +// Arguments: Pointer to bone system, frame to set to +/////////////////////////////////////////////////////////////////////////////// +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + // THIS HANDLES THE INDIVIDUAL STREAM TYPES. ONLY ONE NOW. + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + +// I DON'T REALLY WANT MY ANIMATION TO DEAL WITH SCALE RIGHT NOW +// EVEN THOUGH IT IS IN THE BVA FILE +// bone->scale.x = offset[6]; +// bone->scale.y = offset[7]; +// bone->scale.z = offset[8]; + break; + + } + } +} +//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: BoneAdvanceFrame +// Purpose: Increment the animation stream for a bone and possible the +// children attached to that bone1 +// Arguments: Pointer to bone system, Delta frame value to move, if it is recursive +/////////////////////////////////////////////////////////////////////////////// +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + // THERE MUST BE SOME THINGS TO ADVANCE + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + // ADVANCE THE STREAM + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } +} +//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// diff --git a/Skeletal Deformation/Code/OGL/Skully/Skeleton.h b/Skeletal Deformation/Code/OGL/Skully/Skeleton.h index 1954b01..1efd70e 100644 --- a/Skeletal Deformation/Code/OGL/Skully/Skeleton.h +++ b/Skeletal Deformation/Code/OGL/Skully/Skeleton.h @@ -1,206 +1,206 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -#include "MathDefs.h" - -#define ushort unsigned short -#define uint unsigned int -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Bone Definitions ////////////////////////////////////////////////////////// -#define BONE_DOF_ACTIVE 256 // APPLY DOF -#define BONE_HIDDEN 512 // APPLY DOF - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -typedef struct -{ - float r,g,b,a; -} tColor; - -typedef struct -{ - float u,v; -} t2DCoord; - -typedef struct { - t2DCoord t1[4],t2[4]; - unsigned int TexNdx1; - unsigned int TexNdx2; - unsigned short index[4]; - long type; - long color[4]; // RGB VERTEX COLOR -} tPrimPoly; - -/// Structure Definitions /////////////////////////////////////////////////////// -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - BOOL *CV_select; // Vertex is selected - float *deformData; // DEFORMED VERTEX DATA - int vSize; // NUMBER OF FLOATS IN A VERTEX - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *faceNormal; // POINTER TO FACE NORMALS - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tColor Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - uint glTex; - long *texData; // - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -}; - -struct t_VWeight -{ - int vertex; - float weight; -}; - -/// Structure Definitions /////////////////////////////////////////////////////// - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - float min_rx, max_rx; // ROTATION X LIMITS - float min_ry, max_ry; // ROTATION Y LIMITS - float min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_select; // POINTER TO CONTROL VERTICES - t_VWeight *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - tMatrix *curMatrix; // STORE THE CURRENT MATRIX -// float elast; // ELASTICITY -}; - -struct t_NewBone -{ - // HIERARCHY INFO - t_NewBone *parent; // Pointer to bone base - int childCnt; // Count of Children - t_NewBone *children; // Pointer to Children - // TRANSFORMATION INFO - tVector b_scale; // Base Scale - tVector b_rot; // Base Rotations - tVector b_trans; // Base Translation - tMatrix baseToWorldMat; // Base to World Origin Transformation - tVector scale; // Current Bone Scale - tVector rot; // Current Bone Rotation - tVector trans; // Current Bone Translation - tMatrix baseToModelMat; // Combined Base to new Model Pose -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetSkeleton(t_Bone *root); -void FreezeSkeleton(t_Bone *bone); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +#include "MathDefs.h" + +#define ushort unsigned short +#define uint unsigned int +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Bone Definitions ////////////////////////////////////////////////////////// +#define BONE_DOF_ACTIVE 256 // APPLY DOF +#define BONE_HIDDEN 512 // APPLY DOF + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +typedef struct +{ + float r,g,b,a; +} tColor; + +typedef struct +{ + float u,v; +} t2DCoord; + +typedef struct { + t2DCoord t1[4],t2[4]; + unsigned int TexNdx1; + unsigned int TexNdx2; + unsigned short index[4]; + long type; + long color[4]; // RGB VERTEX COLOR +} tPrimPoly; + +/// Structure Definitions /////////////////////////////////////////////////////// +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + BOOL *CV_select; // Vertex is selected + float *deformData; // DEFORMED VERTEX DATA + int vSize; // NUMBER OF FLOATS IN A VERTEX + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *faceNormal; // POINTER TO FACE NORMALS + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tColor Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + uint glTex; + long *texData; // + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +}; + +struct t_VWeight +{ + int vertex; + float weight; +}; + +/// Structure Definitions /////////////////////////////////////////////////////// + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + float min_rx, max_rx; // ROTATION X LIMITS + float min_ry, max_ry; // ROTATION Y LIMITS + float min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_select; // POINTER TO CONTROL VERTICES + t_VWeight *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + tMatrix *curMatrix; // STORE THE CURRENT MATRIX +// float elast; // ELASTICITY +}; + +struct t_NewBone +{ + // HIERARCHY INFO + t_NewBone *parent; // Pointer to bone base + int childCnt; // Count of Children + t_NewBone *children; // Pointer to Children + // TRANSFORMATION INFO + tVector b_scale; // Base Scale + tVector b_rot; // Base Rotations + tVector b_trans; // Base Translation + tMatrix baseToWorldMat; // Base to World Origin Transformation + tVector scale; // Current Bone Scale + tVector rot; // Current Bone Rotation + tVector trans; // Current Bone Translation + tMatrix baseToModelMat; // Combined Base to new Model Pose +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetSkeleton(t_Bone *root); +void FreezeSkeleton(t_Bone *bone); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/Skully.cpp b/Skeletal Deformation/Code/OGL/Skully/Skully.cpp index cc80ef6..65c04ae 100644 --- a/Skeletal Deformation/Code/OGL/Skully/Skully.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/Skully.cpp @@ -1,158 +1,158 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skully.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Skully.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSkullyApp - -BEGIN_MESSAGE_MAP(CSkullyApp, CWinApp) - //{{AFX_MSG_MAP(CSkullyApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSkullyApp construction - -CSkullyApp::CSkullyApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSkullyApp object - -CSkullyApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSkullyApp initialization - -BOOL CSkullyApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Skully")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - - // Enable drag/drop open - m_pMainWnd->DragAcceptFiles(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSkullyApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSkullyApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Skully.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Skully.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSkullyApp + +BEGIN_MESSAGE_MAP(CSkullyApp, CWinApp) + //{{AFX_MSG_MAP(CSkullyApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSkullyApp construction + +CSkullyApp::CSkullyApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSkullyApp object + +CSkullyApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSkullyApp initialization + +BOOL CSkullyApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Skully")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + + // Enable drag/drop open + m_pMainWnd->DragAcceptFiles(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSkullyApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSkullyApp commands diff --git a/Skeletal Deformation/Code/OGL/Skully/Skully.h b/Skeletal Deformation/Code/OGL/Skully/Skully.h index 1bf2bf0..5ce98b4 100644 --- a/Skeletal Deformation/Code/OGL/Skully/Skully.h +++ b/Skeletal Deformation/Code/OGL/Skully/Skully.h @@ -1,67 +1,67 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skully.h : main header file for the Skully application -// -// Purpose: header of Main Application of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Skully_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Skully_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID - -///////////////////////////////////////////////////////////////////////////// -// CSkullyApp: -// See Skully.cpp for the implementation of this class -// - -class CSkullyApp : public CWinApp -{ -public: - CSkullyApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSkullyApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSkullyApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Skully_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skully.h : main header file for the Skully application +// +// Purpose: header of Main Application of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Skully_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Skully_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID + +///////////////////////////////////////////////////////////////////////////// +// CSkullyApp: +// See Skully.cpp for the implementation of this class +// + +class CSkullyApp : public CWinApp +{ +public: + CSkullyApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSkullyApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSkullyApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Skully_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/StdAfx.cpp b/Skeletal Deformation/Code/OGL/Skully/StdAfx.cpp index ef1dfd5..ae3f87e 100644 --- a/Skeletal Deformation/Code/OGL/Skully/StdAfx.cpp +++ b/Skeletal Deformation/Code/OGL/Skully/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Skully.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Skully.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Skeletal Deformation/Code/OGL/Skully/StdAfx.h b/Skeletal Deformation/Code/OGL/Skully/StdAfx.h index ed96a91..f78606a 100644 --- a/Skeletal Deformation/Code/OGL/Skully/StdAfx.h +++ b/Skeletal Deformation/Code/OGL/Skully/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Skeletal Deformation/Code/OGL/Skully/readme.txt b/Skeletal Deformation/Code/OGL/Skully/readme.txt index f6c4a04..2d3c2a1 100644 --- a/Skeletal Deformation/Code/OGL/Skully/readme.txt +++ b/Skeletal Deformation/Code/OGL/Skully/readme.txt @@ -1,141 +1,141 @@ - -Finally, I have posted source for Skeletal deformation in -OpenGL. It is a pretty complex sample as you need to have an -interface to select vertices, manipulate bones, set weights, and -lots of other stuff. It was much easier with the simple arm -two bone system from last year. - -Realize, when I create characters for my work (and most others -doing this) use animation packages and exporters so they don't -need all this tool stuff. But if you don't have access to a nice -package, this is a start. It will take some work to study though -as there is a lot going on here. - -Here is how it works. - -Loading an Object, Skeleton, and Weight system ---------------------------------------------------------------------- -I have included one skeletal system with a model in three resolutions -(so it will perform on most systems) with weight files. - -The process is: - -1. Load the Skeletal system with "Open Skeleton" and select Femme.dar -2. Load the Mesh with "Open Mesh File" Select one of the three models. - -The mesh is now loaded and associated with the skeleton. If you select -"View/Draw Deformed" it will vanish. This is because the weights are -not set. You could set the weights manually (instructions later) or -load a weight file. - -3. "Load Weight File" to get the weighting for the model. You need to -select the correct file for the model you selected or it will give an -error. - -This automatically selects "Draw Deformed" so you can start manipulating -the character. - - -Manipulating the View ---------------------------------------------------------------------- -You can change the view by using the Right Mouse Button -Click and drag to orbit view. -Hold CTRL and drag RMB to change Z view distance -Hold SHIFT and drag RMB to Move Camera in XY - - -Manipulating the Object ---------------------------------------------------------------------- -Select a Bone from the Hierarchy window. -SHIFT + LMB drag to rotate the bone in XY -CTRL + LMB drag to rotate in Z - -Note: There is no way to translate the bone without double clicking -in the hierarchy window and editing the box. A better interface would -make that easier. But, it is really only need when building the skeleton -originally. - -If "Draw Deformed" is selected and the weights are set, rotating the -bones will deform the model. - - -Setting the Weights ---------------------------------------------------------------------- -Ones you have loaded a model and skeleton you need to set the -rest frame. In most cases it will match in the import. If not, -manipulate the skeleton until it matches the mesh. Then select -"Skeleton/Set Rest Pose" This sets the rest postion that the -deformation is performed from. - -To set the weights: - -1. Select the Bone that you want to work with by selecting it in -the heirarchy. -2. Double Click on the Bone name to bring up the editing window. -Set the weight value that will influence that bone. Value of 1 is -full influence, .5 is 50%, etc. -3. Select the Vertices to influence by LMB drag a selection box on -the mesh. -4. Select "Skeleton/Set Bone Weights" to lock in those vertices into -the selected bone. -5. Do this for each bone and each vertex making sure that the sum -for each vertex is 100% (1.0). - -You need to make sure that if you weight a vertex .5 to one bone, it -must be .5 to another bone or group of bones. This is a place where -the interface needs lots of work. If I was better at windows controls, -I would put a percentage slider after each bone and make it so they -must add up to 100 %. - -If you screw up, select the vertex and hit "Skeleton/Clear Selected Weights" -this will reset it to 0. - -Once you like it, "File/Save Weight File" to store. - - - -Todo (ideas and things needed) ---------------------------------------------------------------------- -Fix Screwy interface. Controls are wacky and need work. -Put in Paint on weighting system like Maya and Sumatra. -Add Bone creation and deletion functions. -Allow Save Skeleton -Allow Save "Object" which includes Mesh+Skeleton+Weights -Allow save and load of Poses and/or animation -Add texture loading "uv coords" are already supported in OBJ loader -Possibly add automatic weighting based on bone layout. -Support for other load formats (other then OBJ) -Integrate the 3D IK techniques from last year (pretty easy really) -Lighting is not correct for deformation (know the fix? it is easy but requires some CPU) - - - -Notes ---------------------------------------------------------------------- - -For the sample models, I roughly set up the weights. Some are 50-50 but -most are 100% to a single bone. It could be refined a lot more to fix -problems. This software method is totally flexible. This is not true -of the DX7 and GL-HW T&L version. The restrictions mean I need to add -some filters. - -DX7 is still in Beta and completely broken on all 3D cards -as of last week. I have new drivers I need to install and -test but for now, my Direct X sample will no longer work. -I will post the DX7 version as soon as it stablizes. - -For people trying to develop DX apps, this must be a pretty -frustrating time. - -I also want to get a version working with the NVidia OpenGL -Extension. Watch for word of that one. I need to get a card -first to try it out.... - -The OpenGL code is a complete software solution and as such -works on both Windows 95/98 as well as NT4.0/W2K. - - -Email with questions or issues. I am sure there will be plenty. - - -Jeff jeffl@darwin3d.com + +Finally, I have posted source for Skeletal deformation in +OpenGL. It is a pretty complex sample as you need to have an +interface to select vertices, manipulate bones, set weights, and +lots of other stuff. It was much easier with the simple arm +two bone system from last year. + +Realize, when I create characters for my work (and most others +doing this) use animation packages and exporters so they don't +need all this tool stuff. But if you don't have access to a nice +package, this is a start. It will take some work to study though +as there is a lot going on here. + +Here is how it works. + +Loading an Object, Skeleton, and Weight system +--------------------------------------------------------------------- +I have included one skeletal system with a model in three resolutions +(so it will perform on most systems) with weight files. + +The process is: + +1. Load the Skeletal system with "Open Skeleton" and select Femme.dar +2. Load the Mesh with "Open Mesh File" Select one of the three models. + +The mesh is now loaded and associated with the skeleton. If you select +"View/Draw Deformed" it will vanish. This is because the weights are +not set. You could set the weights manually (instructions later) or +load a weight file. + +3. "Load Weight File" to get the weighting for the model. You need to +select the correct file for the model you selected or it will give an +error. + +This automatically selects "Draw Deformed" so you can start manipulating +the character. + + +Manipulating the View +--------------------------------------------------------------------- +You can change the view by using the Right Mouse Button +Click and drag to orbit view. +Hold CTRL and drag RMB to change Z view distance +Hold SHIFT and drag RMB to Move Camera in XY + + +Manipulating the Object +--------------------------------------------------------------------- +Select a Bone from the Hierarchy window. +SHIFT + LMB drag to rotate the bone in XY +CTRL + LMB drag to rotate in Z + +Note: There is no way to translate the bone without double clicking +in the hierarchy window and editing the box. A better interface would +make that easier. But, it is really only need when building the skeleton +originally. + +If "Draw Deformed" is selected and the weights are set, rotating the +bones will deform the model. + + +Setting the Weights +--------------------------------------------------------------------- +Ones you have loaded a model and skeleton you need to set the +rest frame. In most cases it will match in the import. If not, +manipulate the skeleton until it matches the mesh. Then select +"Skeleton/Set Rest Pose" This sets the rest postion that the +deformation is performed from. + +To set the weights: + +1. Select the Bone that you want to work with by selecting it in +the heirarchy. +2. Double Click on the Bone name to bring up the editing window. +Set the weight value that will influence that bone. Value of 1 is +full influence, .5 is 50%, etc. +3. Select the Vertices to influence by LMB drag a selection box on +the mesh. +4. Select "Skeleton/Set Bone Weights" to lock in those vertices into +the selected bone. +5. Do this for each bone and each vertex making sure that the sum +for each vertex is 100% (1.0). + +You need to make sure that if you weight a vertex .5 to one bone, it +must be .5 to another bone or group of bones. This is a place where +the interface needs lots of work. If I was better at windows controls, +I would put a percentage slider after each bone and make it so they +must add up to 100 %. + +If you screw up, select the vertex and hit "Skeleton/Clear Selected Weights" +this will reset it to 0. + +Once you like it, "File/Save Weight File" to store. + + + +Todo (ideas and things needed) +--------------------------------------------------------------------- +Fix Screwy interface. Controls are wacky and need work. +Put in Paint on weighting system like Maya and Sumatra. +Add Bone creation and deletion functions. +Allow Save Skeleton +Allow Save "Object" which includes Mesh+Skeleton+Weights +Allow save and load of Poses and/or animation +Add texture loading "uv coords" are already supported in OBJ loader +Possibly add automatic weighting based on bone layout. +Support for other load formats (other then OBJ) +Integrate the 3D IK techniques from last year (pretty easy really) +Lighting is not correct for deformation (know the fix? it is easy but requires some CPU) + + + +Notes +--------------------------------------------------------------------- + +For the sample models, I roughly set up the weights. Some are 50-50 but +most are 100% to a single bone. It could be refined a lot more to fix +problems. This software method is totally flexible. This is not true +of the DX7 and GL-HW T&L version. The restrictions mean I need to add +some filters. + +DX7 is still in Beta and completely broken on all 3D cards +as of last week. I have new drivers I need to install and +test but for now, my Direct X sample will no longer work. +I will post the DX7 version as soon as it stablizes. + +For people trying to develop DX apps, this must be a pretty +frustrating time. + +I also want to get a version working with the NVidia OpenGL +Extension. Watch for word of that one. I need to get a card +first to try it out.... + +The OpenGL code is a complete software solution and as such +works on both Windows 95/98 as well as NT4.0/W2K. + + +Email with questions or issues. I am sure there will be plenty. + + +Jeff jeffl@darwin3d.com diff --git a/Skeletal Deformation/Code/OGL/Skully/resource.h b/Skeletal Deformation/Code/OGL/Skully/resource.h index 7fe433b..32a0d4a 100644 --- a/Skeletal Deformation/Code/OGL/Skully/resource.h +++ b/Skeletal Deformation/Code/OGL/Skully/resource.h @@ -1,81 +1,81 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Skully.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SKULLYTYPE 129 -#define IDD_BONE_INFO 132 -#define IDD_SPEED 133 -#define IDD_SIMPROP 134 -#define IDD_ADDSPHERE 138 -#define IDD_WEIGHT 164 -#define IDC_BONE_NAME 1001 -#define IDC_TRANS_X 1002 -#define IDC_TRANS_Y 1003 -#define IDC_PLAYBACK_SPEED 1003 -#define IDC_TRANS_Z 1004 -#define IDC_GRAVX 1004 -#define IDC_XPOS 1004 -#define IDC_ROT_X 1005 -#define IDC_GRAVY 1005 -#define IDC_YPOS 1005 -#define IDC_ROT_Y 1006 -#define IDC_GRAVZ 1006 -#define IDC_ZPOS 1006 -#define IDC_ROT_Z 1007 -#define IDC_COEFREST 1007 -#define IDC_RADIUS 1007 -#define IDC_MIN_X 1008 -#define IDC_SPRINGCONST 1008 -#define IDC_MAX_X 1009 -#define IDC_Damping 1009 -#define IDC_MIN_Y 1010 -#define IDC_SPRINGDAMP 1010 -#define IDC_MAX_Y 1011 -#define IDC_USERFORCEMAG 1011 -#define IDC_MIN_Z 1012 -#define IDC_MAX_Z 1013 -#define IDC_BSPHERE 1014 -#define IDC_BONEWEIGHT 1014 -#define IDC_DOF_ACTIVE 1015 -#define IDC_SCRIPTLIST 1232 -#define ID_PLAY_FORWARD 32777 -#define ID_FORWARD_FRAME 32778 -#define ID_STOP 32779 -#define ID_BACK_FRAME 32780 -#define ID_PLAY_BACK 32781 -#define ID_ADD_BONE 32782 -#define ID_DELETE_BONE 32783 -#define ID_VIEW_RESETSKELETON 32784 -#define ID_FILE_LOADANIM 32785 -#define ID_ANIMATION_PLAYBACKSPEED 32788 -#define ID_WHICHOGL 32789 -#define ID_SKELETON_RESETSKELETON 32790 -#define ID_VIEW_OUTLINE 32791 -#define ID_FILE_OPENCHARACTERMESH 32792 -#define ID_VIEW_VIEWSKELETON 32793 -#define ID_VIEW_VIEWPARTICLES 32794 -#define ID_FILE_OPENPARTICLESYSTEM 32795 -#define ID_FILE_SAVE_PART 32796 -#define ID_MODEL_REPLACEMESH 32798 -#define ID_MODEL_REPLACETEXTURE 32799 -#define ID_VIEW_DRAWDEFORMED 32800 -#define ID_SKELETON_SETRESTPOSE 32801 -#define ID_SKELETON_SETBONEWEIGHTS 32802 -#define ID_FILE_OPENWEIGHT 32803 -#define ID_SKELETON_CLEARSELECTEDWEIGHTS 32804 -#define ID_INDICATOR_FRAME 59142 -#define ID_INDICATOR_FRAME2 59143 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 134 -#define _APS_NEXT_COMMAND_VALUE 32805 -#define _APS_NEXT_CONTROL_VALUE 1016 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Skully.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SKULLYTYPE 129 +#define IDD_BONE_INFO 132 +#define IDD_SPEED 133 +#define IDD_SIMPROP 134 +#define IDD_ADDSPHERE 138 +#define IDD_WEIGHT 164 +#define IDC_BONE_NAME 1001 +#define IDC_TRANS_X 1002 +#define IDC_TRANS_Y 1003 +#define IDC_PLAYBACK_SPEED 1003 +#define IDC_TRANS_Z 1004 +#define IDC_GRAVX 1004 +#define IDC_XPOS 1004 +#define IDC_ROT_X 1005 +#define IDC_GRAVY 1005 +#define IDC_YPOS 1005 +#define IDC_ROT_Y 1006 +#define IDC_GRAVZ 1006 +#define IDC_ZPOS 1006 +#define IDC_ROT_Z 1007 +#define IDC_COEFREST 1007 +#define IDC_RADIUS 1007 +#define IDC_MIN_X 1008 +#define IDC_SPRINGCONST 1008 +#define IDC_MAX_X 1009 +#define IDC_Damping 1009 +#define IDC_MIN_Y 1010 +#define IDC_SPRINGDAMP 1010 +#define IDC_MAX_Y 1011 +#define IDC_USERFORCEMAG 1011 +#define IDC_MIN_Z 1012 +#define IDC_MAX_Z 1013 +#define IDC_BSPHERE 1014 +#define IDC_BONEWEIGHT 1014 +#define IDC_DOF_ACTIVE 1015 +#define IDC_SCRIPTLIST 1232 +#define ID_PLAY_FORWARD 32777 +#define ID_FORWARD_FRAME 32778 +#define ID_STOP 32779 +#define ID_BACK_FRAME 32780 +#define ID_PLAY_BACK 32781 +#define ID_ADD_BONE 32782 +#define ID_DELETE_BONE 32783 +#define ID_VIEW_RESETSKELETON 32784 +#define ID_FILE_LOADANIM 32785 +#define ID_ANIMATION_PLAYBACKSPEED 32788 +#define ID_WHICHOGL 32789 +#define ID_SKELETON_RESETSKELETON 32790 +#define ID_VIEW_OUTLINE 32791 +#define ID_FILE_OPENCHARACTERMESH 32792 +#define ID_VIEW_VIEWSKELETON 32793 +#define ID_VIEW_VIEWPARTICLES 32794 +#define ID_FILE_OPENPARTICLESYSTEM 32795 +#define ID_FILE_SAVE_PART 32796 +#define ID_MODEL_REPLACEMESH 32798 +#define ID_MODEL_REPLACETEXTURE 32799 +#define ID_VIEW_DRAWDEFORMED 32800 +#define ID_SKELETON_SETRESTPOSE 32801 +#define ID_SKELETON_SETBONEWEIGHTS 32802 +#define ID_FILE_OPENWEIGHT 32803 +#define ID_SKELETON_CLEARSELECTEDWEIGHTS 32804 +#define ID_INDICATOR_FRAME 59142 +#define ID_INDICATOR_FRAME2 59143 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 32805 +#define _APS_NEXT_CONTROL_VALUE 1016 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.cpp index 8748d5c..fd85474 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Friction.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of OpenGL Window of Friction Demonstration -// -// Created: -// JL 6/01/99 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Friction.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CFrictionApp - -BEGIN_MESSAGE_MAP(CFrictionApp, CWinApp) - //{{AFX_MSG_MAP(CFrictionApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CFrictionApp construction - -CFrictionApp::CFrictionApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CFrictionApp object - -CFrictionApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CFrictionApp initialization - -BOOL CFrictionApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CFrictionApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CFrictionApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Friction.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of OpenGL Window of Friction Demonstration +// +// Created: +// JL 6/01/99 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Friction.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CFrictionApp + +BEGIN_MESSAGE_MAP(CFrictionApp, CWinApp) + //{{AFX_MSG_MAP(CFrictionApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CFrictionApp construction + +CFrictionApp::CFrictionApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CFrictionApp object + +CFrictionApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CFrictionApp initialization + +BOOL CFrictionApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CFrictionApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CFrictionApp commands diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.h index 7bd6aad..a574f56 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.h @@ -1,64 +1,64 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Purpose: Implementation of OpenGL Window of Friction Demonstration -// -// Created: -// JL 11/20/98 -// JL 06/01/99 Modified from other code -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_Friction_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_Friction_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CFrictionApp: -// See Friction.cpp for the implementation of this class -// - -class CFrictionApp : public CWinApp -{ -public: - CFrictionApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CFrictionApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CFrictionApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_Friction_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Purpose: Implementation of OpenGL Window of Friction Demonstration +// +// Created: +// JL 11/20/98 +// JL 06/01/99 Modified from other code +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Friction_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_Friction_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CFrictionApp: +// See Friction.cpp for the implementation of this class +// + +class CFrictionApp : public CWinApp +{ +public: + CFrictionApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CFrictionApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CFrictionApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_Friction_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.mak b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.mak index 8224b6e..61d0fce 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.mak +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Friction.mak @@ -1,342 +1,342 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Friction.dsp -!IF "$(CFG)" == "" -CFG=Friction - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Friction - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Friction - Win32 Release" && "$(CFG)" != "Friction - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Friction.mak" CFG="Friction - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Friction - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Friction - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "Squashy - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\Squashy.obj" - -@erase "$(INTDIR)\Squashy.pch" - -@erase "$(INTDIR)\Squashy.res" - -@erase "$(INTDIR)\Squashy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PickObj.obj" - -@erase "$(INTDIR)\PickObj.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\Squashy.bsc" - -@erase "$(OUTDIR)\Squashy.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\Squashy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PickObj.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Squashy.pdb" /machine:I386 /out:"$(OUTDIR)\Squashy.exe" -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\Squashy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PickObj.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Squashy.res" - -"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" - - -CLEAN : - -@erase "$(INTDIR)\Bitmap.obj" - -@erase "$(INTDIR)\Bitmap.sbr" - -@erase "$(INTDIR)\Squashy.obj" - -@erase "$(INTDIR)\Squashy.pch" - -@erase "$(INTDIR)\Squashy.res" - -@erase "$(INTDIR)\Squashy.sbr" - -@erase "$(INTDIR)\LoadOBJ.obj" - -@erase "$(INTDIR)\LoadOBJ.sbr" - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\MainFrm.sbr" - -@erase "$(INTDIR)\MathDefs.obj" - -@erase "$(INTDIR)\MathDefs.sbr" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\OGLView.sbr" - -@erase "$(INTDIR)\PickObj.obj" - -@erase "$(INTDIR)\PickObj.sbr" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Skeleton.sbr" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\StdAfx.sbr" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(OUTDIR)\Squashy.bsc" - -@erase "$(OUTDIR)\Squashy.exe" - -@erase "$(OUTDIR)\Squashy.ilk" - -@erase "$(OUTDIR)\Squashy.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -RSC=rc.exe -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" -BSC32_SBRS= \ - "$(INTDIR)\Bitmap.sbr" \ - "$(INTDIR)\Squashy.sbr" \ - "$(INTDIR)\LoadOBJ.sbr" \ - "$(INTDIR)\MainFrm.sbr" \ - "$(INTDIR)\MathDefs.sbr" \ - "$(INTDIR)\OGLView.sbr" \ - "$(INTDIR)\PickObj.sbr" \ - "$(INTDIR)\Skeleton.sbr" \ - "$(INTDIR)\StdAfx.sbr" - -"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Squashy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Squashy.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\Bitmap.obj" \ - "$(INTDIR)\Squashy.obj" \ - "$(INTDIR)\LoadOBJ.obj" \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\MathDefs.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\PickObj.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\StdAfx.obj" \ - "$(INTDIR)\Squashy.res" - -"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("Squashy.dep") -!INCLUDE "Squashy.dep" -!ELSE -!MESSAGE Warning: cannot find "Squashy.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "Squashy - Win32 Release" || "$(CFG)" == "Squashy - Win32 Debug" -SOURCE=.\Bitmap.cpp - -"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Squashy.cpp - -"$(INTDIR)\Squashy.obj" "$(INTDIR)\Squashy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Squashy.rc - -"$(INTDIR)\Squashy.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\LoadOBJ.cpp - -"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\MainFrm.cpp - -"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\MathDefs.cpp - -"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\OGLView.cpp - -"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\PickObj.cpp - -"$(INTDIR)\PickObj.obj" "$(INTDIR)\PickObj.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\Skeleton.cpp - -"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" - - -SOURCE=.\StdAfx.cpp - -!IF "$(CFG)" == "Squashy - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Friction.dsp +!IF "$(CFG)" == "" +CFG=Friction - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Friction - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Friction - Win32 Release" && "$(CFG)" != "Friction - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Friction.mak" CFG="Friction - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Friction - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Friction - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "Squashy - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\Squashy.obj" + -@erase "$(INTDIR)\Squashy.pch" + -@erase "$(INTDIR)\Squashy.res" + -@erase "$(INTDIR)\Squashy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PickObj.obj" + -@erase "$(INTDIR)\PickObj.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\Squashy.bsc" + -@erase "$(OUTDIR)\Squashy.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\Squashy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PickObj.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\Squashy.pdb" /machine:I386 /out:"$(OUTDIR)\Squashy.exe" +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\Squashy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PickObj.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Squashy.res" + +"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : "$(OUTDIR)\Squashy.exe" "$(OUTDIR)\Squashy.bsc" + + +CLEAN : + -@erase "$(INTDIR)\Bitmap.obj" + -@erase "$(INTDIR)\Bitmap.sbr" + -@erase "$(INTDIR)\Squashy.obj" + -@erase "$(INTDIR)\Squashy.pch" + -@erase "$(INTDIR)\Squashy.res" + -@erase "$(INTDIR)\Squashy.sbr" + -@erase "$(INTDIR)\LoadOBJ.obj" + -@erase "$(INTDIR)\LoadOBJ.sbr" + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\MainFrm.sbr" + -@erase "$(INTDIR)\MathDefs.obj" + -@erase "$(INTDIR)\MathDefs.sbr" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\OGLView.sbr" + -@erase "$(INTDIR)\PickObj.obj" + -@erase "$(INTDIR)\PickObj.sbr" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Skeleton.sbr" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\StdAfx.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\Squashy.bsc" + -@erase "$(OUTDIR)\Squashy.exe" + -@erase "$(OUTDIR)\Squashy.ilk" + -@erase "$(OUTDIR)\Squashy.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +RSC=rc.exe +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Squashy.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Squashy.bsc" +BSC32_SBRS= \ + "$(INTDIR)\Bitmap.sbr" \ + "$(INTDIR)\Squashy.sbr" \ + "$(INTDIR)\LoadOBJ.sbr" \ + "$(INTDIR)\MainFrm.sbr" \ + "$(INTDIR)\MathDefs.sbr" \ + "$(INTDIR)\OGLView.sbr" \ + "$(INTDIR)\PickObj.sbr" \ + "$(INTDIR)\Skeleton.sbr" \ + "$(INTDIR)\StdAfx.sbr" + +"$(OUTDIR)\Squashy.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=dsound.lib winmm.lib opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\Squashy.pdb" /debug /machine:I386 /out:"$(OUTDIR)\Squashy.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\Bitmap.obj" \ + "$(INTDIR)\Squashy.obj" \ + "$(INTDIR)\LoadOBJ.obj" \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\MathDefs.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\PickObj.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\StdAfx.obj" \ + "$(INTDIR)\Squashy.res" + +"$(OUTDIR)\Squashy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("Squashy.dep") +!INCLUDE "Squashy.dep" +!ELSE +!MESSAGE Warning: cannot find "Squashy.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "Squashy - Win32 Release" || "$(CFG)" == "Squashy - Win32 Debug" +SOURCE=.\Bitmap.cpp + +"$(INTDIR)\Bitmap.obj" "$(INTDIR)\Bitmap.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Squashy.cpp + +"$(INTDIR)\Squashy.obj" "$(INTDIR)\Squashy.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Squashy.rc + +"$(INTDIR)\Squashy.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\LoadOBJ.cpp + +"$(INTDIR)\LoadOBJ.obj" "$(INTDIR)\LoadOBJ.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\MainFrm.cpp + +"$(INTDIR)\MainFrm.obj" "$(INTDIR)\MainFrm.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\MathDefs.cpp + +"$(INTDIR)\MathDefs.obj" "$(INTDIR)\MathDefs.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\OGLView.cpp + +"$(INTDIR)\OGLView.obj" "$(INTDIR)\OGLView.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\PickObj.cpp + +"$(INTDIR)\PickObj.obj" "$(INTDIR)\PickObj.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\Skeleton.cpp + +"$(INTDIR)\Skeleton.obj" "$(INTDIR)\Skeleton.sbr" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\Squashy.pch" + + +SOURCE=.\StdAfx.cpp + +!IF "$(CFG)" == "Squashy - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Squashy - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Squashy.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\StdAfx.sbr" "$(INTDIR)\Squashy.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.cpp index 144fb4e..29c273c 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.cpp @@ -1,376 +1,376 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -// Notes: This version doesn't used shared vertices in a vertex array. That -// would be a faster way of doing things. This creates 3 vertices per -// triangle. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include -#include "loadOBJ.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadMaterialLib -// Purpose: Handles the Loading of a Material library -// Arguments: Name of the Material Library -/////////////////////////////////////////////////////////////////////////////// -void LoadMaterialLib(CString name,t_Visual *visual) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - strcpy(visual->map,""); - fp = fopen((LPCTSTR)name,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp == "Ka") // AMBIENT - { - visual->Ka.r = (float)atof(words.GetAt(1)); - visual->Ka.g = (float)atof(words.GetAt(2)); - visual->Ka.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Kd") // DIFFUSE COLOR - { - visual->Kd.r = (float)atof(words.GetAt(1)); - visual->Kd.g = (float)atof(words.GetAt(2)); - visual->Kd.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ks") // SPECULAR COLOR - { - visual->Ks.r = (float)atof(words.GetAt(1)); - visual->Ks.g = (float)atof(words.GetAt(2)); - visual->Ks.b = (float)atof(words.GetAt(3)); - } - else if (temp == "Ns") // SPECULAR COEFFICIENT - { - visual->Ns = (float)atof(words.GetAt(1)); - } - else if (temp == "map_Kd") // TEXTURE MAP NAME - { - strcpy(visual->map,(LPCTSTR)words.GetAt(1)); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - fclose(fp); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: HandleFace -// Purpose: Handles the Face Line in an OBJ file. Extracts index info to -// a face Structure -// Arguments: Array of words from the face line, place to put the data -// Notes: Not an Official OBJ loader as it doesn't handle anything other than -// 3-4 vertex polygons. -/////////////////////////////////////////////////////////////////////////////// -void HandleFace(CStringArray *words,t_faceIndex *face) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loopcnt; - CString temp; - CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS - int nPos,tPos; -/////////////////////////////////////////////////////////////////////////////// - loopcnt = words->GetSize(); - - // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' - for (loop = 1; loop < loopcnt; loop++) - { - temp = words->GetAt(loop); // GRAB THE NEXT WORD - // FACE DATA IS IN THE FORMAT vertex/texture/normal - tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE - vStr = temp.Left(tPos); // GET THE VERTEX NUMBER - temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN - nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL - tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER - nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER - face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX - face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE - face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL - } - face->flags = 0; - if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; - if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; - if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; - else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; - else - { - ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); - face->flags |= FACE_TYPE_TRI; - } -} -///// HandleFace ////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadOBJ -// Purpose: Load an OBJ file into the current bone visual -// Arguments: Name of 0BJ file and pointer to bone, flags of what to load -// Notes: Not an Official OBJ loader as it doesn't handle more then -// 3 vertex polygons or multiple objects per file. -// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - FILE *fp; - long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; - long vPos = 0, nPos = 0, tPos = 0, fPos = 0; - tVector *vertex = NULL,*normal = NULL,*texture = NULL; - t_faceIndex *face = NULL; - float *data; - unsigned short *indexData; -/////////////////////////////////////////////////////////////////////////////// - fp = fopen(filename,"r"); - if (fp != NULL) - { - // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE - ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS - if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE - { - temp = words.GetAt(0); // CHECK THE FIRST WORK - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL - nCnt++; - else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE - tCnt++; - else - vCnt++; // v IS A VERTEX - } - else if (temp[0] == 'f') - fCnt++; // f IS A FACE - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT - if (vCnt > 0) - { - vertex = (tVector *)malloc(vCnt * sizeof(tVector)); - if (nCnt > 0) - normal = (tVector *)malloc(nCnt * sizeof(tVector)); - if (tCnt > 0) - texture = (tVector *)malloc(tCnt * sizeof(tVector)); - if (fCnt > 0) - face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); - - fseek(fp,0,SEEK_SET); - - // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt > 0) - { - temp = words.GetAt(0); - if (temp.GetLength() > 0) - { - if (temp[0] == 'v') // WORDS STARTING WITH v - { - if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS - { - normal[nPos].x = (float)atof(words.GetAt(1)); - normal[nPos].y = (float)atof(words.GetAt(2)); - normal[nPos].z = (float)atof(words.GetAt(3)); - nPos++; - } - else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES - { - texture[tPos].u = (float)atof(words.GetAt(1)); - texture[tPos].v = (float)atof(words.GetAt(2)); - tPos++; - } - else // VERTICES - { - vertex[vPos].x = (float)atof(words.GetAt(1)); - vertex[vPos].y = (float)atof(words.GetAt(2)); - vertex[vPos].z = (float)atof(words.GetAt(3)); - vPos++; - } - } - else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE - { - if (words.GetSize() > 5) - { - sprintf(buffer,"Face %d has more than 4 vertices",fPos); - MessageBox(NULL,buffer,"ERROR",MB_OK); - } - HandleFace(&words,&face[fPos]); - fPos++; - } - else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY - { - LoadMaterialLib(words.GetAt(1),visual); - } - } - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS - // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF - // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER - if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; - else visual->vPerFace = 4; - - if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) - { - if (tCnt > 0) - { - visual->dataFormat = GL_T2F_N3F_V3F; - visual->vSize = 8; // 2 texture, 3 normal, 3 vertex - } - else - { - visual->dataFormat = GL_N3F_V3F; - visual->vSize = 6; // 3 floats for normal, 3 for vertex - } - } - else - { - visual->dataFormat = GL_V3F; - visual->vSize = 3; // 3 floats for vertex - } - visual->faceCnt = fPos; - if ((flags & LOADOBJ_REUSEVERTICES) > 0) - { - visual->reuseVertices = TRUE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); - visual->vertexCnt = vPos; - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); - if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA - { - memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); - } - else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS - { - visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT - } - } - else - { - visual->reuseVertices = FALSE; - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); - visual->vertexCnt = fPos * visual->vPerFace; - visual->faceIndex = NULL; - } - - data = visual->vertexData; - indexData = visual->faceIndex; - for (loop = 0; loop < fPos; loop++) - { - // ERROR CHECKING TO MAKE SURE - if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) - ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); - - for (loop2 = 0; loop2 < visual->vPerFace; loop2++) - { - // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT - if ((flags & LOADOBJ_REUSEVERTICES) == 0) - { - // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 - if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE - { - *data++ = texture[face[loop].t[loop2] - 1].u; - *data++ = texture[face[loop].t[loop2] - 1].v; - } - if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT - { - *data++ = normal[face[loop].n[loop2] - 1].x; - *data++ = normal[face[loop].n[loop2] - 1].y; - *data++ = normal[face[loop].n[loop2] - 1].z; - } - *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES - *data++ = vertex[face[loop].v[loop2] - 1].y; - *data++ = vertex[face[loop].v[loop2] - 1].z; - } - else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE - { - *indexData++ = face[loop].v[loop2] - 1; - } - } - } - - if (vertex) free(vertex); - if (normal) free(normal); - if (texture) free(texture); - if (face) free(face); - } - - fclose(fp); - } - else - return FALSE; - return TRUE; +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +// Notes: This version doesn't used shared vertices in a vertex array. That +// would be a faster way of doing things. This creates 3 vertices per +// triangle. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include +#include "loadOBJ.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadMaterialLib +// Purpose: Handles the Loading of a Material library +// Arguments: Name of the Material Library +/////////////////////////////////////////////////////////////////////////////// +void LoadMaterialLib(CString name,t_Visual *visual) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + strcpy(visual->map,""); + fp = fopen((LPCTSTR)name,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp == "Ka") // AMBIENT + { + visual->Ka.r = (float)atof(words.GetAt(1)); + visual->Ka.g = (float)atof(words.GetAt(2)); + visual->Ka.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Kd") // DIFFUSE COLOR + { + visual->Kd.r = (float)atof(words.GetAt(1)); + visual->Kd.g = (float)atof(words.GetAt(2)); + visual->Kd.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ks") // SPECULAR COLOR + { + visual->Ks.r = (float)atof(words.GetAt(1)); + visual->Ks.g = (float)atof(words.GetAt(2)); + visual->Ks.b = (float)atof(words.GetAt(3)); + } + else if (temp == "Ns") // SPECULAR COEFFICIENT + { + visual->Ns = (float)atof(words.GetAt(1)); + } + else if (temp == "map_Kd") // TEXTURE MAP NAME + { + strcpy(visual->map,(LPCTSTR)words.GetAt(1)); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + fclose(fp); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: HandleFace +// Purpose: Handles the Face Line in an OBJ file. Extracts index info to +// a face Structure +// Arguments: Array of words from the face line, place to put the data +// Notes: Not an Official OBJ loader as it doesn't handle anything other than +// 3-4 vertex polygons. +/////////////////////////////////////////////////////////////////////////////// +void HandleFace(CStringArray *words,t_faceIndex *face) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loopcnt; + CString temp; + CString vStr,nStr,tStr; // HOLD POINTERS TO ELEMENT POINTERS + int nPos,tPos; +/////////////////////////////////////////////////////////////////////////////// + loopcnt = words->GetSize(); + + // LOOP THROUGH THE 3 - 4 WORDS OF THE FACELIST LINE, WORD 0 HAS 'f' + for (loop = 1; loop < loopcnt; loop++) + { + temp = words->GetAt(loop); // GRAB THE NEXT WORD + // FACE DATA IS IN THE FORMAT vertex/texture/normal + tPos = temp.Find('/'); // FIND THE '/' SEPARATING VERTEX AND TEXTURE + vStr = temp.Left(tPos); // GET THE VERTEX NUMBER + temp.SetAt(tPos,' '); // CHANGE THE '/' TO A SPACE SO I CAN TRY AGAIN + nPos = temp.Find('/'); // FIND THE '/' SEPARATING TEXTURE AND NORMAL + tStr = temp.Mid(tPos + 1, nPos - tPos - 1); // GET THE TEXTURE NUMBER + nStr = temp.Right(temp.GetLength() - nPos - 1); // GET THE NORMAL NUMBER + face->v[loop - 1] = atoi(vStr); // STORE OFF THE INDEX FOR THE VERTEX + face->t[loop - 1] = atoi(tStr); // STORE OFF THE INDEX FOR THE TEXTURE + face->n[loop - 1] = atoi(nStr); // STORE OFF THE INDEX FOR THE NORMAL + } + face->flags = 0; + if (tStr.GetLength() > 0) face->flags |= FACE_TYPE_TEXTURE; + if (nStr.GetLength() > 0) face->flags |= FACE_TYPE_NORMAL; + if (loopcnt == 4) face->flags |= FACE_TYPE_TRI; + else if (loopcnt == 5) face->flags |= FACE_TYPE_QUAD; + else + { + ::MessageBox(NULL,"Face found larger then a Quad\nSubstituting a Tri","ERROR",MB_OK); + face->flags |= FACE_TYPE_TRI; + } +} +///// HandleFace ////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadOBJ +// Purpose: Load an OBJ file into the current bone visual +// Arguments: Name of 0BJ file and pointer to bone, flags of what to load +// Notes: Not an Official OBJ loader as it doesn't handle more then +// 3 vertex polygons or multiple objects per file. +// Current flags are only (NULL, LOADOBJ_VERTEXONLY,LOADOBJ_REUSEVERTICES) +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + FILE *fp; + long vCnt = 0, nCnt = 0, tCnt = 0, fCnt = 0; + long vPos = 0, nPos = 0, tPos = 0, fPos = 0; + tVector *vertex = NULL,*normal = NULL,*texture = NULL; + t_faceIndex *face = NULL; + float *data; + unsigned short *indexData; +/////////////////////////////////////////////////////////////////////////////// + fp = fopen(filename,"r"); + if (fp != NULL) + { + // FIRST PASS SETS UP THE NUMBER OF OBJECTS IN THE FILE + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); // GET A STRING FROM THE FILE + ParseString(buffer,&words,&cnt); // BREAK THE STRING INTO cnt WORDS + if (cnt > 0) // MAKE SURE SOME WORDS ARE THERE + { + temp = words.GetAt(0); // CHECK THE FIRST WORK + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // ONLY LOOK AT WORDS THAT START WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn IS A NORMAL + nCnt++; + else if (temp.GetLength() > 1 && temp[1] == 't') // vt IS A TEXTURE + tCnt++; + else + vCnt++; // v IS A VERTEX + } + else if (temp[0] == 'f') + fCnt++; // f IS A FACE + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // NOW THAT I KNOW HOW MANY, ALLOCATE ROOM FOR IT + if (vCnt > 0) + { + vertex = (tVector *)malloc(vCnt * sizeof(tVector)); + if (nCnt > 0) + normal = (tVector *)malloc(nCnt * sizeof(tVector)); + if (tCnt > 0) + texture = (tVector *)malloc(tCnt * sizeof(tVector)); + if (fCnt > 0) + face = (t_faceIndex *)malloc(fCnt * sizeof(t_faceIndex)); + + fseek(fp,0,SEEK_SET); + + // NOW THAT IT IS ALL ALLOC'ED. GRAB THE REAL DATA + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt > 0) + { + temp = words.GetAt(0); + if (temp.GetLength() > 0) + { + if (temp[0] == 'v') // WORDS STARTING WITH v + { + if (temp.GetLength() > 1 && temp[1] == 'n') // vn NORMALS + { + normal[nPos].x = (float)atof(words.GetAt(1)); + normal[nPos].y = (float)atof(words.GetAt(2)); + normal[nPos].z = (float)atof(words.GetAt(3)); + nPos++; + } + else if (temp.GetLength() > 1 && temp[1] == 't') // vt TEXTURES + { + texture[tPos].u = (float)atof(words.GetAt(1)); + texture[tPos].v = (float)atof(words.GetAt(2)); + tPos++; + } + else // VERTICES + { + vertex[vPos].x = (float)atof(words.GetAt(1)); + vertex[vPos].y = (float)atof(words.GetAt(2)); + vertex[vPos].z = (float)atof(words.GetAt(3)); + vPos++; + } + } + else if (temp[0] == 'f') // f v/t/n v/t/n v/t/n FACE LINE + { + if (words.GetSize() > 5) + { + sprintf(buffer,"Face %d has more than 4 vertices",fPos); + MessageBox(NULL,buffer,"ERROR",MB_OK); + } + HandleFace(&words,&face[fPos]); + fPos++; + } + else if (temp == "mtllib") // HANDLE THE MATERIAL LIBRARY + { + LoadMaterialLib(words.GetAt(1),visual); + } + } + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // THIS IS BAD. THINGS RUN NICER IF ALL THE POLYGONS HAVE THE SAME VERTEX COUNTS + // ASSUME ALL HAVE THE SAME AS THE FIRST. IT SHOULD TESSELATE QUADS TO TRIS IF + // THERE ARE SOME TRIS, BUT I KNOW MY DATABASE SO I MAKE MY LIFE EASIER + if ((face[0].flags & FACE_TYPE_TRI)> 0) visual->vPerFace = 3; + else visual->vPerFace = 4; + + if (nCnt > 0 && (flags & LOADOBJ_VERTEXONLY) == 0) + { + if (tCnt > 0) + { + visual->dataFormat = GL_T2F_N3F_V3F; + visual->vSize = 8; // 2 texture, 3 normal, 3 vertex + } + else + { + visual->dataFormat = GL_N3F_V3F; + visual->vSize = 6; // 3 floats for normal, 3 for vertex + } + } + else + { + visual->dataFormat = GL_V3F; + visual->vSize = 3; // 3 floats for vertex + } + visual->faceCnt = fPos; + if ((flags & LOADOBJ_REUSEVERTICES) > 0) + { + visual->reuseVertices = TRUE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * vPos); + visual->vertexCnt = vPos; + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * fPos * visual->vPerFace); + if ((flags & LOADOBJ_VERTEXONLY) > 0) // COPY VERTEX DATA + { + memcpy(visual->vertexData,vertex,sizeof(float) * visual->vSize * vPos); + } + else // SHOULD HANDLE CASE WHERE THERE IS NORMALS AND TEXTURE COORDS + { + visual->vertexData = NULL; // TODO: I DON'T WANT TO DEAL WITH IT + } + } + else + { + visual->reuseVertices = FALSE; + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * fPos * visual->vPerFace); + visual->vertexCnt = fPos * visual->vPerFace; + visual->faceIndex = NULL; + } + + data = visual->vertexData; + indexData = visual->faceIndex; + for (loop = 0; loop < fPos; loop++) + { + // ERROR CHECKING TO MAKE SURE + if ((face[loop].flags & FACE_TYPE_TRI)> 0 && visual->vPerFace == 4) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + if ((face[loop].flags & FACE_TYPE_QUAD)> 0 && visual->vPerFace == 3) + ::MessageBox(NULL,"Face Vertex Count does not match","ERROR",MB_OK); + + for (loop2 = 0; loop2 < visual->vPerFace; loop2++) + { + // IF I DON'T WANT TO REUSE VERTICES, FILL IT ALL OUT + if ((flags & LOADOBJ_REUSEVERTICES) == 0) + { + // ALL FACE INDICES ARE 1 BASED INSTEAD OF 0 + if (tCnt > 0) // IF TEXTURE COORDS WRITE OUT THOSE + { + *data++ = texture[face[loop].t[loop2] - 1].u; + *data++ = texture[face[loop].t[loop2] - 1].v; + } + if (nCnt > 0) // IF THERE ARE NORMALS WRITE THOSE OUT + { + *data++ = normal[face[loop].n[loop2] - 1].x; + *data++ = normal[face[loop].n[loop2] - 1].y; + *data++ = normal[face[loop].n[loop2] - 1].z; + } + *data++ = vertex[face[loop].v[loop2] - 1].x; // SAVE OUT VERTICES + *data++ = vertex[face[loop].v[loop2] - 1].y; + *data++ = vertex[face[loop].v[loop2] - 1].z; + } + else // REUSE VERTICES SO JUST FILL OUT THE INDEX STRUCTURE + { + *indexData++ = face[loop].v[loop2] - 1; + } + } + } + + if (vertex) free(vertex); + if (normal) free(normal); + if (texture) free(texture); + if (face) free(face); + } + + fclose(fp); + } + else + return FALSE; + return TRUE; } \ No newline at end of file diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.h index 2b75bb3..8184168 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/LoadOBJ.h @@ -1,46 +1,46 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadOBJ.h : header file -// -// Purpose: Header of OpenGL Window of OBJ Loader -// -// Created: -// JL 9/23/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(LoadOBJ_H__INCLUDED_) -#define LoadOBJ_H__INCLUDED_ - -#define MAX_STRINGLENGTH 255 - -#define FACE_TYPE_TRI 1 -#define FACE_TYPE_QUAD 2 -#define FACE_TYPE_NORMAL 4 -#define FACE_TYPE_TEXTURE 8 - -enum LOAD_OBJFLAGS -{ - LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO - LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA - LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS -}; - -// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS -typedef struct -{ - long v[4],n[4],t[4]; - int flags; // FACE TYPES -} t_faceIndex; - -#include "Skeleton.h" - -BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); - -#endif // !defined(LoadOBJ_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadOBJ.h : header file +// +// Purpose: Header of OpenGL Window of OBJ Loader +// +// Created: +// JL 9/23/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(LoadOBJ_H__INCLUDED_) +#define LoadOBJ_H__INCLUDED_ + +#define MAX_STRINGLENGTH 255 + +#define FACE_TYPE_TRI 1 +#define FACE_TYPE_QUAD 2 +#define FACE_TYPE_NORMAL 4 +#define FACE_TYPE_TEXTURE 8 + +enum LOAD_OBJFLAGS +{ + LOADOBJ_ALLDATA = 0, // NORMAL MODE, LOAD ALL AVAIL INFO + LOADOBJ_VERTEXONLY = 1, // I ONLY WANT VERTEX DATA + LOADOBJ_REUSEVERTICES = 2 // USE INDEX ARRAYS +}; + +// MODIFIED FROM THE DECEMBER CODE TO HANDLE QUADS AND TRIS +typedef struct +{ + long v[4],n[4],t[4]; + int flags; // FACE TYPES +} t_faceIndex; + +#include "Skeleton.h" + +BOOL LoadOBJ(char *filename,t_Visual *visual, int flags); + +#endif // !defined(LoadOBJ_H__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.cpp index 8a43ca7..969417a 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.cpp @@ -1,382 +1,382 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of Friction Demonstration -// -// Created: -// JL 11/20/98 -// JL 06/01/99 Modified from other code -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Friction.h" -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_FILE_OPEN, OnFileOpen) - ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) - ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) - ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) - ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) - ON_COMMAND(ID_FILE_SAVE, OnFileSave) - ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) - ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) - ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) - ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) - ON_WM_CLOSE() - ON_COMMAND(ID_SIMULATION_SETVERTEXMASS, OnSimulationSetvertexmass) - ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) - ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) - ON_COMMAND(ID_INTEGRATOR_EULER, OnIntegratorEuler) - ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_EULER, OnUpdateIntegratorEuler) - ON_COMMAND(ID_INTEGRATOR_MIDPOINT, OnIntegratorMidpoint) - ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_MIDPOINT, OnUpdateIntegratorMidpoint) - ON_COMMAND(ID_INTEGRATOR_RUNGEKUTTA4, OnIntegratorRungekutta4) - ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_RUNGEKUTTA4, OnUpdateIntegratorRungekutta4) - ON_COMMAND(ID_SIMULATION_USEFRICTION, OnSimulationUsefriction) - ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEFRICTION, OnUpdateSimulationUsefriction) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); -} - -CMainFrame::~CMainFrame() -{ -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom - - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case ' ': - break; - } - m_OGLView.HandleKeyUp(nChar); -// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -} - - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - - -void CMainFrame::OnFileNewsystem() -{ - m_OGLView.NewSystem(); -} - -void CMainFrame::OnFileOpen() -{ - char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnFileSave() -{ - char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| - CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); - CString name; - if (dialog.DoModal()) - { - m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); - m_OGLView.Invalidate(TRUE); - } -} - -void CMainFrame::OnSimulationRunning() -{ - m_OGLView.HandleKeyUp('R'); // FORCE SYSTEM TO START RUNNING THROUGH KEYPRESS -} - -void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_SimRunning ); -} - -void CMainFrame::OnSimulationReset() -{ - m_OGLView.m_PhysEnv.ResetWorld(); - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnSimulationSetsimproperties() -{ - m_OGLView.OnSimulationSetsimproperties(); -} - -void CMainFrame::OnSimulationSettimingproperties() -{ - m_OGLView.OnSetTimeProperties(); -} - -void CMainFrame::OnSimulationSetvertexmass() -{ - m_OGLView.OnSimulationSetVertexMass(); -} - -void CMainFrame::OnSimulationUsegravity() -{ - m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); -} - -void CMainFrame::OnSimulationUsefriction() -{ - m_OGLView.m_PhysEnv.m_UseFriction = !m_OGLView.m_PhysEnv.m_UseFriction; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateSimulationUsefriction(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseFriction ); -} - -void CMainFrame::OnViewShowgeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -void CMainFrame::OnViewShowsprings() -{ - m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); -} - -void CMainFrame::OnViewShowvertices() -{ - m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); -} - -void CMainFrame::OnClose() -{ - m_OGLView.m_SimRunning = FALSE; - - CFrameWnd::OnClose(); -} - -BOOL CMainFrame::DestroyWindow() -{ - - return CFrameWnd::DestroyWindow(); -} - -void CMainFrame::OnIntegratorEuler() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = EULER_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntegratorEuler(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == EULER_INTEGRATOR ); -} - -void CMainFrame::OnIntegratorMidpoint() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = MIDPOINT_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == MIDPOINT_INTEGRATOR ); -} - -void CMainFrame::OnIntegratorRungekutta4() -{ - m_OGLView.m_PhysEnv.m_IntegratorType = RK4_INTEGRATOR; - m_OGLView.Invalidate(TRUE); -} - -void CMainFrame::OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == RK4_INTEGRATOR ); -} - +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of Friction Demonstration +// +// Created: +// JL 11/20/98 +// JL 06/01/99 Modified from other code +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Friction.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_FILE_OPEN, OnFileOpen) + ON_COMMAND(ID_SIMULATION_RUNNING, OnSimulationRunning) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_RUNNING, OnUpdateSimulationRunning) + ON_COMMAND(ID_SIMULATION_RESET, OnSimulationReset) + ON_COMMAND(ID_SIMULATION_SETSIMPROPERTIES, OnSimulationSetsimproperties) + ON_COMMAND(ID_SIMULATION_USEGRAVITY, OnSimulationUsegravity) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEGRAVITY, OnUpdateSimulationUsegravity) + ON_COMMAND(ID_FILE_SAVE, OnFileSave) + ON_COMMAND(ID_VIEW_SHOWGEOMETRY, OnViewShowgeometry) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWGEOMETRY, OnUpdateViewShowgeometry) + ON_COMMAND(ID_VIEW_SHOWSPRINGS, OnViewShowsprings) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSPRINGS, OnUpdateViewShowsprings) + ON_COMMAND(ID_VIEW_SHOWVERTICES, OnViewShowvertices) + ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWVERTICES, OnUpdateViewShowvertices) + ON_WM_CLOSE() + ON_COMMAND(ID_SIMULATION_SETVERTEXMASS, OnSimulationSetvertexmass) + ON_COMMAND(ID_FILE_NEWSYSTEM, OnFileNewsystem) + ON_COMMAND(ID_SIMULATION_SETTIMINGPROPERTIES, OnSimulationSettimingproperties) + ON_COMMAND(ID_INTEGRATOR_EULER, OnIntegratorEuler) + ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_EULER, OnUpdateIntegratorEuler) + ON_COMMAND(ID_INTEGRATOR_MIDPOINT, OnIntegratorMidpoint) + ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_MIDPOINT, OnUpdateIntegratorMidpoint) + ON_COMMAND(ID_INTEGRATOR_RUNGEKUTTA4, OnIntegratorRungekutta4) + ON_UPDATE_COMMAND_UI(ID_INTEGRATOR_RUNGEKUTTA4, OnUpdateIntegratorRungekutta4) + ON_COMMAND(ID_SIMULATION_USEFRICTION, OnSimulationUsefriction) + ON_UPDATE_COMMAND_UI(ID_SIMULATION_USEFRICTION, OnUpdateSimulationUsefriction) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); +} + +CMainFrame::~CMainFrame() +{ +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 21 , SWP_NOZORDER ); // -60 bottom + + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case ' ': + break; + } + m_OGLView.HandleKeyUp(nChar); +// CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +} + + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + + +void CMainFrame::OnFileNewsystem() +{ + m_OGLView.NewSystem(); +} + +void CMainFrame::OnFileOpen() +{ + char szFilter[] = "DPS files (*.dps)|*.dps|OBJ files (*.obj)|*.obj||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( TRUE, ".obj", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.LoadFile(dialog.GetFileName( ),dialog.GetFileTitle( ),dialog.GetFileExt() ); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnFileSave() +{ + char szFilter[] = "DPS files (*.dps)|*.dps||"; // WILL INCLUDE Biovision Hierarchy BVH (*.bvh)|*.bvh| + CFileDialog dialog( FALSE, ".dps", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CString name; + if (dialog.DoModal()) + { + m_OGLView.SaveFile(dialog.GetFileName( ),dialog.GetFileTitle( )); + m_OGLView.Invalidate(TRUE); + } +} + +void CMainFrame::OnSimulationRunning() +{ + m_OGLView.HandleKeyUp('R'); // FORCE SYSTEM TO START RUNNING THROUGH KEYPRESS +} + +void CMainFrame::OnUpdateSimulationRunning(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_SimRunning ); +} + +void CMainFrame::OnSimulationReset() +{ + m_OGLView.m_PhysEnv.ResetWorld(); + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnSimulationSetsimproperties() +{ + m_OGLView.OnSimulationSetsimproperties(); +} + +void CMainFrame::OnSimulationSettimingproperties() +{ + m_OGLView.OnSetTimeProperties(); +} + +void CMainFrame::OnSimulationSetvertexmass() +{ + m_OGLView.OnSimulationSetVertexMass(); +} + +void CMainFrame::OnSimulationUsegravity() +{ + m_OGLView.m_PhysEnv.m_UseGravity = !m_OGLView.m_PhysEnv.m_UseGravity; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateSimulationUsegravity(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseGravity ); +} + +void CMainFrame::OnSimulationUsefriction() +{ + m_OGLView.m_PhysEnv.m_UseFriction = !m_OGLView.m_PhysEnv.m_UseFriction; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateSimulationUsefriction(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_UseFriction ); +} + +void CMainFrame::OnViewShowgeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowgeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +void CMainFrame::OnViewShowsprings() +{ + m_OGLView.m_PhysEnv.m_DrawSprings = !m_OGLView.m_PhysEnv.m_DrawSprings; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowsprings(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawSprings ); +} + +void CMainFrame::OnViewShowvertices() +{ + m_OGLView.m_PhysEnv.m_DrawVertices = !m_OGLView.m_PhysEnv.m_DrawVertices; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateViewShowvertices(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_DrawVertices ); +} + +void CMainFrame::OnClose() +{ + m_OGLView.m_SimRunning = FALSE; + + CFrameWnd::OnClose(); +} + +BOOL CMainFrame::DestroyWindow() +{ + + return CFrameWnd::DestroyWindow(); +} + +void CMainFrame::OnIntegratorEuler() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = EULER_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntegratorEuler(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == EULER_INTEGRATOR ); +} + +void CMainFrame::OnIntegratorMidpoint() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = MIDPOINT_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == MIDPOINT_INTEGRATOR ); +} + +void CMainFrame::OnIntegratorRungekutta4() +{ + m_OGLView.m_PhysEnv.m_IntegratorType = RK4_INTEGRATOR; + m_OGLView.Invalidate(TRUE); +} + +void CMainFrame::OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_PhysEnv.m_IntegratorType == RK4_INTEGRATOR ); +} + diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.h index d209282..b56454f 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MainFrm.h @@ -1,111 +1,111 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of OpenGL Window of 3D Collision Detection -// -// Created: -// JL 11/20/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - virtual BOOL DestroyWindow(); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnFileOpen(); - afx_msg void OnSimulationRunning(); - afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); - afx_msg void OnSimulationReset(); - afx_msg void OnSimulationSetsimproperties(); - afx_msg void OnSimulationUsegravity(); - afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); - afx_msg void OnFileSave(); - afx_msg void OnViewShowgeometry(); - afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); - afx_msg void OnViewShowsprings(); - afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); - afx_msg void OnViewShowvertices(); - afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); - afx_msg void OnClose(); - afx_msg void OnSimulationSetvertexmass(); - afx_msg void OnFileNewsystem(); - afx_msg void OnSimulationSettimingproperties(); - afx_msg void OnIntegratorEuler(); - afx_msg void OnUpdateIntegratorEuler(CCmdUI* pCmdUI); - afx_msg void OnIntegratorMidpoint(); - afx_msg void OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI); - afx_msg void OnIntegratorRungekutta4(); - afx_msg void OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI); - afx_msg void OnSimulationUsefriction(); - afx_msg void OnUpdateSimulationUsefriction(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of OpenGL Window of 3D Collision Detection +// +// Created: +// JL 11/20/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL DestroyWindow(); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnFileOpen(); + afx_msg void OnSimulationRunning(); + afx_msg void OnUpdateSimulationRunning(CCmdUI* pCmdUI); + afx_msg void OnSimulationReset(); + afx_msg void OnSimulationSetsimproperties(); + afx_msg void OnSimulationUsegravity(); + afx_msg void OnUpdateSimulationUsegravity(CCmdUI* pCmdUI); + afx_msg void OnFileSave(); + afx_msg void OnViewShowgeometry(); + afx_msg void OnUpdateViewShowgeometry(CCmdUI* pCmdUI); + afx_msg void OnViewShowsprings(); + afx_msg void OnUpdateViewShowsprings(CCmdUI* pCmdUI); + afx_msg void OnViewShowvertices(); + afx_msg void OnUpdateViewShowvertices(CCmdUI* pCmdUI); + afx_msg void OnClose(); + afx_msg void OnSimulationSetvertexmass(); + afx_msg void OnFileNewsystem(); + afx_msg void OnSimulationSettimingproperties(); + afx_msg void OnIntegratorEuler(); + afx_msg void OnUpdateIntegratorEuler(CCmdUI* pCmdUI); + afx_msg void OnIntegratorMidpoint(); + afx_msg void OnUpdateIntegratorMidpoint(CCmdUI* pCmdUI); + afx_msg void OnIntegratorRungekutta4(); + afx_msg void OnUpdateIntegratorRungekutta4(CCmdUI* pCmdUI); + afx_msg void OnSimulationUsefriction(); + afx_msg void OnUpdateSimulationUsefriction(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.cpp index 564425b..178aa8d 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.c : implementation file -// -// Purpose: Implementation of Math Routines -// -// Created: -// JL 2/18/98 -// Revisions: -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "mathdefs.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: IdentityMatrix -// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format -// Arguments: Matrix -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void IdentityMatrix(tMatrix *mat) -{ -///// Local Variables ///////////////////////////////////////////////////////// - int loop; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < 16; loop++) - mat->m[loop] = 0.0f; - mat->m[0] = - mat->m[5] = - mat->m[10] = - mat->m[15] = - 1.0f; -} -//// IdentityMatrix /////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByMatrix -// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z) + - mat->m[12]; - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z) + - mat->m[13]; - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z) + - mat->m[14]; -} -//// MultVectorByMatrix ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultVectorByRotMatrix -// Purpose: Multiplies a vector by a 4x4 Rotation Matrix in OpenGL Format -// Arguments: Matrix, Vector in, and result Vector -// Notes: This routing is tweaked to handle OpenGLs column-major format -// This is one obvious place for optimization perhaps asm code -/////////////////////////////////////////////////////////////////////////////// -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) -{ - result->x = (mat->m[0] * v->x) + - (mat->m[4] * v->y) + - (mat->m[8] * v->z); - result->y = (mat->m[1] * v->x) + - (mat->m[5] * v->y) + - (mat->m[9] * v->z); - result->z = (mat->m[2] * v->x) + - (mat->m[6] * v->y) + - (mat->m[10] * v->z); -} -//// MultVectorByRotMatrix /////////////////////////////////////////////////// - -/* returns squared length of input vector */ -double VectorSquaredLength(tVector *v) -{ - return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); -} - -/* returns length of input vector */ -double VectorLength(tVector *v) -{ - return(sqrt(VectorSquaredLength(v))); -} - -/* destructively normalizes the input vector */ -void NormalizeVector(tVector *v) -{ - float len = (float)VectorLength(v); - if (len != 0.0) - { - v->x /= len; - v->y /= len; - v->z /= len; - } -} - -double DotProduct(tVector *v1, tVector *v2) -{ - return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); -} - -/* return the cross product result = v1 cross v2 */ -void CrossProduct(tVector *v1, tVector *v2, tVector *result) -{ - result->x = (v1->y * v2->z) - (v1->z * v2->y); - result->y = (v1->z * v2->x) - (v1->x * v2->z); - result->z = (v1->x * v2->y) - (v1->y * v2->x); -} - -double VectorSquaredDistance(tVector *v1, tVector *v2) -{ - return( ((v1->x - v2->x) * (v1->x - v2->x)) + - ((v1->y - v2->y) * (v1->y - v2->y)) + - ((v1->z - v2->z) * (v1->z - v2->z)) ); -} - -void ScaleVector(tVector *v, float scale, tVector *result) -{ - result->x = v->x * scale; - result->y = v->y * scale; - result->z = v->z * scale; -} - -void VectorSum(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x + v2->x; - result->y = v1->y + v2->y; - result->z = v1->z + v2->z; -} - -void VectorDifference(tVector *v1, tVector *v2, tVector *result) -{ - result->x = v1->x - v2->x; - result->y = v1->y - v2->y; - result->z = v1->z - v2->z; -} +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.c : implementation file +// +// Purpose: Implementation of Math Routines +// +// Created: +// JL 2/18/98 +// Revisions: +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "mathdefs.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: IdentityMatrix +// Purpose: Creates and Identity 4x4 Matrix in OpenGL Format +// Arguments: Matrix +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void IdentityMatrix(tMatrix *mat) +{ +///// Local Variables ///////////////////////////////////////////////////////// + int loop; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < 16; loop++) + mat->m[loop] = 0.0f; + mat->m[0] = + mat->m[5] = + mat->m[10] = + mat->m[15] = + 1.0f; +} +//// IdentityMatrix /////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByMatrix +// Purpose: Multiplies a vector by a 4x4 Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z) + + mat->m[12]; + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z) + + mat->m[13]; + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z) + + mat->m[14]; +} +//// MultVectorByMatrix ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultVectorByRotMatrix +// Purpose: Multiplies a vector by a 4x4 Rotation Matrix in OpenGL Format +// Arguments: Matrix, Vector in, and result Vector +// Notes: This routing is tweaked to handle OpenGLs column-major format +// This is one obvious place for optimization perhaps asm code +/////////////////////////////////////////////////////////////////////////////// +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result) +{ + result->x = (mat->m[0] * v->x) + + (mat->m[4] * v->y) + + (mat->m[8] * v->z); + result->y = (mat->m[1] * v->x) + + (mat->m[5] * v->y) + + (mat->m[9] * v->z); + result->z = (mat->m[2] * v->x) + + (mat->m[6] * v->y) + + (mat->m[10] * v->z); +} +//// MultVectorByRotMatrix /////////////////////////////////////////////////// + +/* returns squared length of input vector */ +double VectorSquaredLength(tVector *v) +{ + return((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); +} + +/* returns length of input vector */ +double VectorLength(tVector *v) +{ + return(sqrt(VectorSquaredLength(v))); +} + +/* destructively normalizes the input vector */ +void NormalizeVector(tVector *v) +{ + float len = (float)VectorLength(v); + if (len != 0.0) + { + v->x /= len; + v->y /= len; + v->z /= len; + } +} + +double DotProduct(tVector *v1, tVector *v2) +{ + return ((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); +} + +/* return the cross product result = v1 cross v2 */ +void CrossProduct(tVector *v1, tVector *v2, tVector *result) +{ + result->x = (v1->y * v2->z) - (v1->z * v2->y); + result->y = (v1->z * v2->x) - (v1->x * v2->z); + result->z = (v1->x * v2->y) - (v1->y * v2->x); +} + +double VectorSquaredDistance(tVector *v1, tVector *v2) +{ + return( ((v1->x - v2->x) * (v1->x - v2->x)) + + ((v1->y - v2->y) * (v1->y - v2->y)) + + ((v1->z - v2->z) * (v1->z - v2->z)) ); +} + +void ScaleVector(tVector *v, float scale, tVector *result) +{ + result->x = v->x * scale; + result->y = v->y * scale; + result->z = v->z * scale; +} + +void VectorSum(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x + v2->x; + result->y = v1->y + v2->y; + result->z = v1->z + v2->z; +} + +void VectorDifference(tVector *v1, tVector *v2, tVector *result) +{ + result->x = v1->x - v2->x; + result->y = v1->y - v2->y; + result->z = v1->z - v2->z; +} diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.h index 60a8d95..efd75ea 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/MathDefs.h @@ -1,117 +1,117 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MathDefs.h : Math Structure Header File -// -// Purpose: Declare Basic Math Structures -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// Revisions: -// Integrated into Kine Demo 8/18/98 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(MATHDEFS_H__INCLUDED_) -#define MATHDEFS_H__INCLUDED_ - -#define M_PI 3.14159265358979323846f -#define HALF_PI 1.57079632679489661923f - -/// Trig Macros /////////////////////////////////////////////////////////////// -#define DEGTORAD(A) ((A * M_PI) / 180.0f) -#define RADTODEG(A) ((A * 180.0f) / M_PI) -/////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - union { - float x; - float u; - float r; - }; - union { - float y; - float v; - float g; - }; - union { - float z; - float w; - float b; - }; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY -typedef struct -{ - float r,g,b; - float x,y,z; -} tColoredVertex; - -typedef struct -{ - float u,v; - float x,y,z; -} tTexturedVertex; - -typedef struct -{ - float u,v; - float r,g,b; - float x,y,z; -} tTexturedColoredVertex; - -typedef struct -{ - float nx,ny,nz; - float x,y,z; -} tNormalVertex; - -typedef struct -{ - float u,v; - float nx,ny,nz; - float x,y,z; -} tTexturedNormalVertex; - - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; -/////////////////////////////////////////////////////////////////////////////// - -#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; - -void IdentityMatrix(tMatrix *mat); -void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); -void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); -double VectorSquaredLength(tVector *v); -double VectorLength(tVector *v); -void NormalizeVector(tVector *v); -double DotProduct(tVector *v1, tVector *v2); -void CrossProduct(tVector *v1, tVector *v2, tVector *result); -double VectorSquaredDistance(tVector *v1, tVector *v2); -void ScaleVector(tVector *v, float scale, tVector *result); -void VectorSum(tVector *v1, tVector *v2, tVector *result); -void VectorDifference(tVector *v1, tVector *v2, tVector *result); - -#endif // !defined(MATH_H__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MathDefs.h : Math Structure Header File +// +// Purpose: Declare Basic Math Structures +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// Revisions: +// Integrated into Kine Demo 8/18/98 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(MATHDEFS_H__INCLUDED_) +#define MATHDEFS_H__INCLUDED_ + +#define M_PI 3.14159265358979323846f +#define HALF_PI 1.57079632679489661923f + +/// Trig Macros /////////////////////////////////////////////////////////////// +#define DEGTORAD(A) ((A * M_PI) / 180.0f) +#define RADTODEG(A) ((A * 180.0f) / M_PI) +/////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + union { + float x; + float u; + float r; + }; + union { + float y; + float v; + float g; + }; + union { + float z; + float w; + float b; + }; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +// SOME STRUCTURES TO HELP ME ACCESS VERTEX DATA IN AN ARRAY +typedef struct +{ + float r,g,b; + float x,y,z; +} tColoredVertex; + +typedef struct +{ + float u,v; + float x,y,z; +} tTexturedVertex; + +typedef struct +{ + float u,v; + float r,g,b; + float x,y,z; +} tTexturedColoredVertex; + +typedef struct +{ + float nx,ny,nz; + float x,y,z; +} tNormalVertex; + +typedef struct +{ + float u,v; + float nx,ny,nz; + float x,y,z; +} tTexturedNormalVertex; + + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; +/////////////////////////////////////////////////////////////////////////////// + +#define MAKEVECTOR(a,vx,vy,vz) a.x = vx; a.y = vy; a.z = vz; + +void IdentityMatrix(tMatrix *mat); +void MultVectorByMatrix(tMatrix *mat, tVector *v,tVector *result); +void MultVectorByRotMatrix(tMatrix *mat, tVector *v,tVector *result); +double VectorSquaredLength(tVector *v); +double VectorLength(tVector *v); +void NormalizeVector(tVector *v); +double DotProduct(tVector *v1, tVector *v2); +void CrossProduct(tVector *v1, tVector *v2, tVector *result); +double VectorSquaredDistance(tVector *v1, tVector *v2); +void ScaleVector(tVector *v, float scale, tVector *result); +void VectorSum(tVector *v1, tVector *v2, tVector *result); +void VectorDifference(tVector *v1, tVector *v2, tVector *result); + +#endif // !defined(MATH_H__INCLUDED_) + diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.cpp index 4dfd66c..2773423 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.cpp @@ -1,856 +1,856 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Friction Demonstration -// -// Created: -// JL 11/20/98 -// JL 06/01/99 Modified from other code -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include "Friction.h" -#include "OGLView.h" -#include "LoadOBJ.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION - -#define LERP(a,b,c) (a + ((b - a) * c)) -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_SimRunning = FALSE; - m_CurBone = NULL; - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.b_trans.z = -100.0f; - m_Skeleton.trans.z = -100.0f; - - m_FrameCnt = 0; - - m_TimeIterations = 10; - m_UseFixedTimeStep = FALSE; - m_MaxTimeStep = 0.01f; - - m_hDC = NULL; - - m_PickX = -1; - m_PickY = -1; -} - -COGLView::~COGLView() -{ - DestroySkeleton(&m_Skeleton); -} - - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual = NULL; -/////////////////////////////////////////////////////////////////////////////// - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - ON_WM_CLOSE() - ON_WM_LBUTTONUP() - ON_WM_MBUTTONDOWN() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -float COGLView::GetTime( void ) -{ - static DWORD StartMilliseconds; - if(!StartMilliseconds) - { - // yes, the first time through will be a 0 timestep - StartMilliseconds = timeGetTime(); - } - - DWORD CurrentMilliseconds = timeGetTime(); - return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; -} - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - glDisable(GL_TEXTURE_2D); - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 - GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); -// glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); -// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - glLineWidth(2.0f); - glPointSize(8.0f); - glDisable(GL_LINE_SMOOTH); - glDepthFunc(GL_LEQUAL); - glDisable(GL_CULL_FACE); - -// glShadeModel(GL_SMOOTH); -// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - -// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); -// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); -// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); -// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 -// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); - glDisable(GL_LIGHTING); -// glEnable(GL_LIGHT0); - -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: RunSim -// Purpose: Actual simulation loop -// Notes: Allows you to adjust the rate of simulation or to change it -// to fixed time steps or actual timesteps. -/////////////////////////////////////////////////////////////////////////////// -void COGLView::RunSim() -{ -/// Local Variables /////////////////////////////////////////////////////////// - float Time; - float DeltaTime; -/////////////////////////////////////////////////////////////////////////////// - - if (m_UseFixedTimeStep) - Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); - else - Time = GetTime() * m_TimeIterations; - - if (m_SimRunning) - { - while(m_LastTime < Time) - { - DeltaTime = Time - m_LastTime; - if(DeltaTime > m_MaxTimeStep) - { - DeltaTime = m_MaxTimeStep; - } - - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - m_LastTime += DeltaTime; - } - m_LastTime = Time; - } - else - { - m_PhysEnv.Simulate(DeltaTime,m_SimRunning); - } -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ - if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) - { - glColor3f(1.0f,1.0f,1.0f); - // Declare the Array of Data - glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); - if (curBone->visuals[0].reuseVertices) - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - else - glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); - } - else - { - // HANDLE EITHER QUADS OR TRIS - if (curBone->visuals[0].vPerFace == 3) - glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); - else - glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); - } - } -} -// drawModel - - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; - if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; - if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; - - // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); - - // ROTATE THE ROOT - glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); - - // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION - glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); - - if (m_PickX > -1) - m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); - - RunSim(); - - m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION - - glPopMatrix(); - glFinish(); - - if (m_hDC) - SwapBuffers(m_hDC); - -// PLAYING WITH CHECKING FRAMETIMING -/* if (m_SimRunning) - { - m_FrameCnt++; - char message[80]; - DWORD end = timeGetTime(); - float diff = (float)(m_FrameCnt * 1000)/(float)(end - m_StartTime); - - sprintf(message,"%.2f",diff); - m_ptrStatusBar->SetPaneText(0,message); - }*/ - m_PickX = -1; - m_PickY = -1; -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - m_ScreenWidth = cx; - m_ScreenHeight = cy; - resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - if ((nFlags & MK_SHIFT) == 0) - { - m_PickX = point.x; - m_PickY = m_ScreenHeight - point.y; - drawScene(); - } - SetCapture( ); - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnLButtonUp(UINT nFlags, CPoint point) -{ - m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE - ReleaseCapture(); - CWnd::OnLButtonUp(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Base_Rot_X = m_Skeleton.rot.x; - m_Base_Rot_Y = m_Skeleton.rot.y; - m_Base_Rot_Z = m_Skeleton.rot.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - tVector userforce; - switch (nChar) - { - case 13: - m_PhysEnv.AddSpring(); - break; - case 'G': - m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; - break; - case '1': m_curVisual = 0; - break; - case '2': m_curVisual = 1; - break; - case 'O': - glPolygonMode(GL_FRONT,GL_LINE); -// glPolygonMode(GL_FRONT,GL_FILL); - break; - case 'F': - m_PhysEnv.m_UseFriction = !m_PhysEnv.m_UseFriction; - break; - case 'R': - m_SimRunning = !m_SimRunning; - if (m_SimRunning) - m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM - m_StartTime = timeGetTime(); - m_FrameCnt = 0; - break; - case 'T': - m_PhysEnv.ResetWorld(); - break; - case VK_HOME: - userforce.x = m_Skeleton.matrix.m[1]; - userforce.y = m_Skeleton.matrix.m[5]; - userforce.z = m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_END: - userforce.x = -m_Skeleton.matrix.m[1]; - userforce.y = -m_Skeleton.matrix.m[5]; - userforce.z = -m_Skeleton.matrix.m[9]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_RIGHT: - userforce.x = m_Skeleton.matrix.m[0]; - userforce.y = m_Skeleton.matrix.m[4]; - userforce.z = m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_LEFT: - userforce.x = -m_Skeleton.matrix.m[0]; - userforce.y = -m_Skeleton.matrix.m[4]; - userforce.z = -m_Skeleton.matrix.m[8]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_UP: - userforce.x = -m_Skeleton.matrix.m[2]; - userforce.y = -m_Skeleton.matrix.m[6]; - userforce.z = -m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - case VK_DOWN: - userforce.x = m_Skeleton.matrix.m[2]; - userforce.y = m_Skeleton.matrix.m[6]; - userforce.z = m_Skeleton.matrix.m[10]; - m_PhysEnv.ApplyUserForce(&userforce); - break; - } - - MSG msg; - - if (m_SimRunning) - { - while (m_SimRunning == TRUE) - { - while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - m_SimRunning = FALSE; - m_hDC = NULL; - PostQuitMessage(0); - break; - } - if (msg.message == WM_CLOSE) - { - m_SimRunning = FALSE; - } - - // Dispatch any messages as needed - if (!AfxGetApp()->PreTranslateMessage(&msg)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - // Give the Idle system some time - AfxGetApp()->OnIdle(0); - AfxGetApp()->OnIdle(1); - - } - if (m_SimRunning) drawScene(); - } - } - else - Invalidate(TRUE); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - tVector localX,localY; - - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CONTROL' BUTTON ROTATE - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - // ELSE ROTATE THE BONE - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS - { - // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES - localY.x = m_Skeleton.matrix.m[1]; - localY.y = m_Skeleton.matrix.m[5]; - localY.z = m_Skeleton.matrix.m[9]; - - localX.x = m_Skeleton.matrix.m[0]; - localX.y = m_Skeleton.matrix.m[4]; - localX.z = m_Skeleton.matrix.m[8]; - - m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); - m_PhysEnv.m_MouseForceActive = TRUE; - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) - { - } - else if ((nFlags & MK_SHIFT) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: NewSystem -// Purpose: Clears the Simulation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::NewSystem() -{ - m_PhysEnv.FreeSystem(); - m_SimRunning = FALSE; - if (m_Skeleton.childCnt > 0) - { - if (m_Skeleton.children->visuals->vertexData) - free(m_Skeleton.children->visuals->vertexData); - if (m_Skeleton.children->visuals->faceIndex) - free(m_Skeleton.children->visuals->faceIndex); - free(m_Skeleton.children->visuals); - free(m_Skeleton.children); - m_Skeleton.childCnt = 0; - } - drawScene(); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: LoadFiles -// Purpose: Loads the OBJ files into memory -/////////////////////////////////////////////////////////////////////////////// -void COGLView::LoadFile(CString file1,CString baseName,CString ext) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *children; - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - ext.MakeUpper(); - if (ext == "OBJ") - { - visual = (t_Visual *)malloc(sizeof(t_Visual)); - NewSystem(); // CLEAR WHAT DATA IS THERE - // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT - if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, - LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) - { - // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SetWorldParticles((tVector *)visual->vertexData,visual->vertexCnt); - - children = (t_Bone *)malloc(sizeof(t_Bone)); - m_CurBone = &children[m_Skeleton.childCnt]; - ResetBone(m_CurBone,&m_Skeleton); - strcpy(m_CurBone->name,(LPCTSTR)baseName); - m_CurBone->visuals = visual; - m_CurBone->visualCnt = 1; - m_Skeleton.childCnt = 1; - m_Skeleton.children = children; - } - else - { - MessageBox("Must Be A Valid OBJ File","Error",MB_OK); - free(visual); - } - } - else // LOAD SIM SYSTEM - { - if (file1.GetLength()) - { - fp = fopen(file1,"rb"); - if (fp != NULL) - { - NewSystem(); // CLEAR WHAT DATA IS THERE - fread(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); - fread(m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); - visual = m_Skeleton.children->visuals; - fread(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); - visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); - fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.LoadData(fp); - } - } - fclose(fp); - } - } - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: SaveFiles -// Purpose: Saves the Particle System -/////////////////////////////////////////////////////////////////////////////// -void COGLView::SaveFile(CString file1,CString baseName) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Visual *visual; - FILE *fp; -/////////////////////////////////////////////////////////////////////////////// - if (file1.GetLength() > 0) - { - fp = fopen(file1,"wb"); - if (fp != NULL) - { - fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); - if (m_Skeleton.childCnt > 0) - { - fwrite(m_Skeleton.children,sizeof(t_Bone),1,fp); - if (m_Skeleton.children->visualCnt > 0) - { - visual = m_Skeleton.children->visuals; - fwrite(visual,sizeof(t_Visual),1,fp); - if (visual->reuseVertices) - { - fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); - fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); - } - // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES - m_PhysEnv.SaveData(fp); - } - } - fclose(fp); - } - } -} - -void COGLView::OnClose() -{ - - CWnd::OnClose(); -} - -void COGLView::OnSimulationSetsimproperties() -{ - m_PhysEnv.SetWorldProperties(); -} - -void COGLView::OnSimulationSetVertexMass() -{ - m_PhysEnv.SetVertexMass(); -} - -void COGLView::OnSetTimeProperties() -{ - CTimeProps dialog; - dialog.m_Iterations = m_TimeIterations; - dialog.m_FixedTimeSteps = m_UseFixedTimeStep; - dialog.m_MaxTimeStep = m_MaxTimeStep; - if (dialog.DoModal()) - { - m_TimeIterations = dialog.m_Iterations; - m_UseFixedTimeStep = dialog.m_FixedTimeSteps; - m_MaxTimeStep = dialog.m_MaxTimeStep; - } -} - - -void COGLView::OnMButtonDown(UINT nFlags, CPoint point) -{ - - CWnd::OnMButtonDown(nFlags, point); -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Friction Demonstration +// +// Created: +// JL 11/20/98 +// JL 06/01/99 Modified from other code +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include "Friction.h" +#include "OGLView.h" +#include "LoadOBJ.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION + +#define LERP(a,b,c) (a + ((b - a) * c)) +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_SimRunning = FALSE; + m_CurBone = NULL; + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.b_trans.z = -100.0f; + m_Skeleton.trans.z = -100.0f; + + m_FrameCnt = 0; + + m_TimeIterations = 10; + m_UseFixedTimeStep = FALSE; + m_MaxTimeStep = 0.01f; + + m_hDC = NULL; + + m_PickX = -1; + m_PickY = -1; +} + +COGLView::~COGLView() +{ + DestroySkeleton(&m_Skeleton); +} + + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual = NULL; +/////////////////////////////////////////////////////////////////////////////// + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_CLOSE() + ON_WM_LBUTTONUP() + ON_WM_MBUTTONDOWN() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +float COGLView::GetTime( void ) +{ + static DWORD StartMilliseconds; + if(!StartMilliseconds) + { + // yes, the first time through will be a 0 timestep + StartMilliseconds = timeGetTime(); + } + + DWORD CurrentMilliseconds = timeGetTime(); + return float(CurrentMilliseconds - StartMilliseconds) / 1000.0f; +} + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + glDisable(GL_TEXTURE_2D); + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat lightpos[] = { 0.30f, 0.3f, 1.0f, 0.0f }; // .5 .5 1.0 + GLfloat ambient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); +// glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); +// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glLineWidth(2.0f); + glPointSize(8.0f); + glDisable(GL_LINE_SMOOTH); + glDepthFunc(GL_LEQUAL); + glDisable(GL_CULL_FACE); + +// glShadeModel(GL_SMOOTH); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// glMaterialfv(GL_FRONT,GL_AMBIENT, ambient); +// glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuse); +// glMaterialfv(GL_FRONT,GL_SPECULAR, specular); +// glMaterialf(GL_FRONT,GL_SHININESS, 100.0f); // 12 +// glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glDisable(GL_LIGHTING); +// glEnable(GL_LIGHT0); + +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: RunSim +// Purpose: Actual simulation loop +// Notes: Allows you to adjust the rate of simulation or to change it +// to fixed time steps or actual timesteps. +/////////////////////////////////////////////////////////////////////////////// +void COGLView::RunSim() +{ +/// Local Variables /////////////////////////////////////////////////////////// + float Time; + float DeltaTime; +/////////////////////////////////////////////////////////////////////////////// + + if (m_UseFixedTimeStep) + Time = m_LastTime + (m_MaxTimeStep * m_TimeIterations); + else + Time = GetTime() * m_TimeIterations; + + if (m_SimRunning) + { + while(m_LastTime < Time) + { + DeltaTime = Time - m_LastTime; + if(DeltaTime > m_MaxTimeStep) + { + DeltaTime = m_MaxTimeStep; + } + + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + m_LastTime += DeltaTime; + } + m_LastTime = Time; + } + else + { + m_PhysEnv.Simulate(DeltaTime,m_SimRunning); + } +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ + if (curBone->visualCnt > 0 && curBone->visuals[0].vertexData != NULL) + { + glColor3f(1.0f,1.0f,1.0f); + // Declare the Array of Data + glInterleavedArrays(curBone->visuals[0].dataFormat,0,(GLvoid *)curBone->visuals[0].vertexData); + if (curBone->visuals[0].reuseVertices) + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawElements(GL_TRIANGLES,curBone->visuals[0].faceCnt * 3,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + else + glDrawElements(GL_QUADS,curBone->visuals[0].faceCnt * 4,GL_UNSIGNED_SHORT,curBone->visuals[0].faceIndex); + } + else + { + // HANDLE EITHER QUADS OR TRIS + if (curBone->visuals[0].vPerFace == 3) + glDrawArrays(GL_TRIANGLES,0,curBone->visuals[0].faceCnt * 3); + else + glDrawArrays(GL_QUADS,0,curBone->visuals[0].faceCnt * 4); + } + } +} +// drawModel + + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton.rot.y > 360.0f) m_Skeleton.rot.y -= 360.0f; + if (m_Skeleton.rot.x > 360.0f) m_Skeleton.rot.x -= 360.0f; + if (m_Skeleton.rot.z > 360.0f) m_Skeleton.rot.z -= 360.0f; + + // glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +// glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton.trans.x, m_Skeleton.trans.y, m_Skeleton.trans.z); + + // ROTATE THE ROOT + glRotatef(m_Skeleton.rot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton.rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton.rot.x, 0.0f, 0.0f, 1.0f); + + // GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION + glGetFloatv(GL_MODELVIEW_MATRIX,m_Skeleton.matrix.m); + + if (m_PickX > -1) + m_PhysEnv.GetNearestPoint(m_PickX,m_PickY); + + RunSim(); + + m_PhysEnv.RenderWorld(); // DRAW THE SIMULATION + + glPopMatrix(); + glFinish(); + + if (m_hDC) + SwapBuffers(m_hDC); + +// PLAYING WITH CHECKING FRAMETIMING +/* if (m_SimRunning) + { + m_FrameCnt++; + char message[80]; + DWORD end = timeGetTime(); + float diff = (float)(m_FrameCnt * 1000)/(float)(end - m_StartTime); + + sprintf(message,"%.2f",diff); + m_ptrStatusBar->SetPaneText(0,message); + }*/ + m_PickX = -1; + m_PickY = -1; +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + m_ScreenWidth = cx; + m_ScreenHeight = cy; + resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + if ((nFlags & MK_SHIFT) == 0) + { + m_PickX = point.x; + m_PickY = m_ScreenHeight - point.y; + drawScene(); + } + SetCapture( ); + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnLButtonUp(UINT nFlags, CPoint point) +{ + m_PhysEnv.m_MouseForceActive = FALSE; // STOP APPLYING MOUSE FORCE + ReleaseCapture(); + CWnd::OnLButtonUp(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Base_Rot_X = m_Skeleton.rot.x; + m_Base_Rot_Y = m_Skeleton.rot.y; + m_Base_Rot_Z = m_Skeleton.rot.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + tVector userforce; + switch (nChar) + { + case 13: + m_PhysEnv.AddSpring(); + break; + case 'G': + m_PhysEnv.m_UseGravity = !m_PhysEnv.m_UseGravity; + break; + case '1': m_curVisual = 0; + break; + case '2': m_curVisual = 1; + break; + case 'O': + glPolygonMode(GL_FRONT,GL_LINE); +// glPolygonMode(GL_FRONT,GL_FILL); + break; + case 'F': + m_PhysEnv.m_UseFriction = !m_PhysEnv.m_UseFriction; + break; + case 'R': + m_SimRunning = !m_SimRunning; + if (m_SimRunning) + m_LastTime = GetTime() * m_TimeIterations; // RESET THE SIM + m_StartTime = timeGetTime(); + m_FrameCnt = 0; + break; + case 'T': + m_PhysEnv.ResetWorld(); + break; + case VK_HOME: + userforce.x = m_Skeleton.matrix.m[1]; + userforce.y = m_Skeleton.matrix.m[5]; + userforce.z = m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_END: + userforce.x = -m_Skeleton.matrix.m[1]; + userforce.y = -m_Skeleton.matrix.m[5]; + userforce.z = -m_Skeleton.matrix.m[9]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_RIGHT: + userforce.x = m_Skeleton.matrix.m[0]; + userforce.y = m_Skeleton.matrix.m[4]; + userforce.z = m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_LEFT: + userforce.x = -m_Skeleton.matrix.m[0]; + userforce.y = -m_Skeleton.matrix.m[4]; + userforce.z = -m_Skeleton.matrix.m[8]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_UP: + userforce.x = -m_Skeleton.matrix.m[2]; + userforce.y = -m_Skeleton.matrix.m[6]; + userforce.z = -m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + case VK_DOWN: + userforce.x = m_Skeleton.matrix.m[2]; + userforce.y = m_Skeleton.matrix.m[6]; + userforce.z = m_Skeleton.matrix.m[10]; + m_PhysEnv.ApplyUserForce(&userforce); + break; + } + + MSG msg; + + if (m_SimRunning) + { + while (m_SimRunning == TRUE) + { + while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + m_SimRunning = FALSE; + m_hDC = NULL; + PostQuitMessage(0); + break; + } + if (msg.message == WM_CLOSE) + { + m_SimRunning = FALSE; + } + + // Dispatch any messages as needed + if (!AfxGetApp()->PreTranslateMessage(&msg)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + // Give the Idle system some time + AfxGetApp()->OnIdle(0); + AfxGetApp()->OnIdle(1); + + } + if (m_SimRunning) drawScene(); + } + } + else + Invalidate(TRUE); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + tVector localX,localY; + + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CONTROL' BUTTON ROTATE + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + // ELSE ROTATE THE BONE + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + else if (m_SimRunning) // NO MODIFIERS, JUST DRAG SO USE MOUSESPRINGS + { + // NEED TO GET THE VECTORS FOR THE LOCAL X AND Y AXES + localY.x = m_Skeleton.matrix.m[1]; + localY.y = m_Skeleton.matrix.m[5]; + localY.z = m_Skeleton.matrix.m[9]; + + localX.x = m_Skeleton.matrix.m[0]; + localX.y = m_Skeleton.matrix.m[4]; + localX.z = m_Skeleton.matrix.m[8]; + + m_PhysEnv.SetMouseForce(point.x - m_mousepos.x,point.y - m_mousepos.y,&localX,&localY); + m_PhysEnv.m_MouseForceActive = TRUE; + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0 && m_CurBone != NULL) + { + } + else if ((nFlags & MK_SHIFT) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.x = m_Base_Rot_X + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton.rot.y = m_Base_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton.rot.z = m_Base_Rot_Z + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: NewSystem +// Purpose: Clears the Simulation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::NewSystem() +{ + m_PhysEnv.FreeSystem(); + m_SimRunning = FALSE; + if (m_Skeleton.childCnt > 0) + { + if (m_Skeleton.children->visuals->vertexData) + free(m_Skeleton.children->visuals->vertexData); + if (m_Skeleton.children->visuals->faceIndex) + free(m_Skeleton.children->visuals->faceIndex); + free(m_Skeleton.children->visuals); + free(m_Skeleton.children); + m_Skeleton.childCnt = 0; + } + drawScene(); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: LoadFiles +// Purpose: Loads the OBJ files into memory +/////////////////////////////////////////////////////////////////////////////// +void COGLView::LoadFile(CString file1,CString baseName,CString ext) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *children; + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + ext.MakeUpper(); + if (ext == "OBJ") + { + visual = (t_Visual *)malloc(sizeof(t_Visual)); + NewSystem(); // CLEAR WHAT DATA IS THERE + // I WANT TO LOAD JUST THE VERTICES AND PUT THEM IN A INDEXED FORMAT + if (file1.GetLength() > 0 && LoadOBJ((char *)(LPCTSTR)file1 ,visual, + LOADOBJ_VERTEXONLY | LOADOBJ_REUSEVERTICES)) + { + // INFORM THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SetWorldParticles((tVector *)visual->vertexData,visual->vertexCnt); + + children = (t_Bone *)malloc(sizeof(t_Bone)); + m_CurBone = &children[m_Skeleton.childCnt]; + ResetBone(m_CurBone,&m_Skeleton); + strcpy(m_CurBone->name,(LPCTSTR)baseName); + m_CurBone->visuals = visual; + m_CurBone->visualCnt = 1; + m_Skeleton.childCnt = 1; + m_Skeleton.children = children; + } + else + { + MessageBox("Must Be A Valid OBJ File","Error",MB_OK); + free(visual); + } + } + else // LOAD SIM SYSTEM + { + if (file1.GetLength()) + { + fp = fopen(file1,"rb"); + if (fp != NULL) + { + NewSystem(); // CLEAR WHAT DATA IS THERE + fread(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + m_Skeleton.children = (t_Bone *)malloc(sizeof(t_Bone)); + fread(m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + m_Skeleton.children->visuals = (t_Visual *)malloc(sizeof(t_Visual)); + visual = m_Skeleton.children->visuals; + fread(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + visual->vertexData = (float *)malloc(sizeof(float) * visual->vSize * visual->vertexCnt); + visual->faceIndex = (unsigned short *)malloc(sizeof(unsigned short) * visual->faceCnt * visual->vPerFace); + fread(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fread(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.LoadData(fp); + } + } + fclose(fp); + } + } + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: SaveFiles +// Purpose: Saves the Particle System +/////////////////////////////////////////////////////////////////////////////// +void COGLView::SaveFile(CString file1,CString baseName) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Visual *visual; + FILE *fp; +/////////////////////////////////////////////////////////////////////////////// + if (file1.GetLength() > 0) + { + fp = fopen(file1,"wb"); + if (fp != NULL) + { + fwrite(&m_Skeleton,sizeof(t_Bone),1,fp); + if (m_Skeleton.childCnt > 0) + { + fwrite(m_Skeleton.children,sizeof(t_Bone),1,fp); + if (m_Skeleton.children->visualCnt > 0) + { + visual = m_Skeleton.children->visuals; + fwrite(visual,sizeof(t_Visual),1,fp); + if (visual->reuseVertices) + { + fwrite(visual->vertexData,sizeof(float),visual->vSize * visual->vertexCnt,fp); + fwrite(visual->faceIndex,sizeof(unsigned short),visual->faceCnt * visual->vPerFace,fp); + } + // SAVE THE PHYSICAL SIMULATION OF THE PARTICLES + m_PhysEnv.SaveData(fp); + } + } + fclose(fp); + } + } +} + +void COGLView::OnClose() +{ + + CWnd::OnClose(); +} + +void COGLView::OnSimulationSetsimproperties() +{ + m_PhysEnv.SetWorldProperties(); +} + +void COGLView::OnSimulationSetVertexMass() +{ + m_PhysEnv.SetVertexMass(); +} + +void COGLView::OnSetTimeProperties() +{ + CTimeProps dialog; + dialog.m_Iterations = m_TimeIterations; + dialog.m_FixedTimeSteps = m_UseFixedTimeStep; + dialog.m_MaxTimeStep = m_MaxTimeStep; + if (dialog.DoModal()) + { + m_TimeIterations = dialog.m_Iterations; + m_UseFixedTimeStep = dialog.m_FixedTimeSteps; + m_MaxTimeStep = dialog.m_MaxTimeStep; + } +} + + +void COGLView::OnMButtonDown(UINT nFlags, CPoint point) +{ + + CWnd::OnMButtonDown(nFlags, point); +} diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.h index 3c7df6d..504ef50 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/OGLView.h @@ -1,124 +1,124 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of 3D Morphing System -// -// Created: -// JL 10/1/98 -// -// The function morphModel() does the main morphing work. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -#include "PhysEnv.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry,m_SimRunning; - int m_curVisual; - float m_MorphPos; - DWORD m_StartTime; - DWORD m_FrameCnt; - int m_TimeIterations; - BOOL m_UseFixedTimeStep; - float m_MaxTimeStep; - float m_LastTime; - - - CPhysEnv m_PhysEnv; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - void OnSimulationSetVertexMass(); - void OnSimulationSetsimproperties(); - void OnSetTimeProperties(); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - GLvoid morphModel(t_Bone *curBone); - GLvoid LoadBoneTexture(t_Bone *curBone); - void NewSystem(); - void LoadFile(CString file1,CString baseName,CString ext); - void SaveFile(CString file1,CString baseName); - void RunSim(); - float GetTime( void ); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone m_Skeleton,*m_CurBone; - int m_PickX, m_PickY; - int m_ScreenWidth; - int m_ScreenHeight; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnClose(); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnMButtonDown(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of 3D Morphing System +// +// Created: +// JL 10/1/98 +// +// The function morphModel() does the main morphing work. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +#include "PhysEnv.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Base_Rot_X,m_Base_Rot_Y,m_Base_Rot_Z; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry,m_SimRunning; + int m_curVisual; + float m_MorphPos; + DWORD m_StartTime; + DWORD m_FrameCnt; + int m_TimeIterations; + BOOL m_UseFixedTimeStep; + float m_MaxTimeStep; + float m_LastTime; + + + CPhysEnv m_PhysEnv; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + void OnSimulationSetVertexMass(); + void OnSimulationSetsimproperties(); + void OnSetTimeProperties(); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + GLvoid morphModel(t_Bone *curBone); + GLvoid LoadBoneTexture(t_Bone *curBone); + void NewSystem(); + void LoadFile(CString file1,CString baseName,CString ext); + void SaveFile(CString file1,CString baseName); + void RunSim(); + float GetTime( void ); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone m_Skeleton,*m_CurBone; + int m_PickX, m_PickY; + int m_ScreenWidth; + int m_ScreenHeight; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnClose(); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnMButtonDown(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.cpp index 827e27a..c7cbba8 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.cpp @@ -1,1151 +1,1151 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// PhysEnv.cpp : Physical World implementation file -// -// Purpose: Implementation of Particle Physics System -// -// Created: -// JL 12/1/98 -// Modified: -// JL 3/6/99 - FIXED GRAVITY FORCE CALCULATION BUG -// JL 3/8/99 - ADDED MORE POSSIBLE CONTACTS AS EACH VERTEX CAN CONTACT MORE -// THEN ONE COLLISION SURFACE (SHOULD IT BE DYNAMICALLY ALLOC'ED?) -// JL 3/20/99 - ADDED THE MIDPOINT AND RK INTEGRATOR NEEDED TO ALLOC 5 TEMP PARTICLE ARRAYS -// JL 6/01/99 - Modified for the Friction code with a Contact model -// Friction is added int the Apply forces code -// Contact is determined in CheckForCollisions -// World Damping was reduced so friction is more evident -// -// Notes: A bit of this along with the organization comes from Chris Hecker's -// Physics Articles from last year. Hopefully this will get everyone -// back up to speed before we dig deeper into the world of Dynamics. -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1998-1999 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include -#include -#include -#include - -#include "Friction.h" -#include "PhysEnv.h" -#include "SimProps.h" -#include "VertMass.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT - -///////////////////////////////////////////////////////////////////////////// -// CPhysEnv - -// INITIALIZE THE SIMULATION WORLD -CPhysEnv::CPhysEnv() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - m_ParticleSys[0] = NULL; - m_ParticleSys[1] = NULL; - m_ParticleSys[2] = NULL; // RESET BUFFER - - // THESE TEMP PARTICLE BUFFERS ARE NEEDED FOR THE MIDPOINT AND RK4 INTEGRATOR - for (int i = 0; i < 5; i++) - m_TempSys[i] = NULL; - m_ParticleCnt = 0; - m_Contact = NULL; - m_Spring = NULL; - m_SpringCnt = 0; - - m_UseGravity = TRUE; - m_UseFriction = TRUE; - m_DrawSprings = TRUE; - m_DrawVertices = TRUE; - m_MouseForceActive = FALSE; - - MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) - m_UserForceMag = 100.0; - m_UserForceActive = FALSE; - m_Kd = 0.02f; // DAMPING FACTOR - m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT - m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT - m_Ksd = 0.1f; // SPRING DAMPING CONSTANT - - m_Csf = 0.9f; // Default Static Friction - m_Ckf = 0.7f; // Default Kinetic Friction - m_MouseForceKs = 0.08f; // MOUSE SPRING CONSTANT - - // CREATE THE SIZE FOR THE SIMULATION WORLD - m_WorldSizeX = 15.0f; - m_WorldSizeY = 15.0f; - m_WorldSizeZ = 15.0f; - - m_IntegratorType = EULER_INTEGRATOR; - - m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); - m_CollisionPlaneCnt = 6; - - // MAKE THE TOP PLANE (CEILING) - MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) - m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; - - // MAKE THE BOTTOM PLANE (FLOOR) - MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) - m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; - - // MAKE THE LEFT PLANE - MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) - m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; - - // MAKE THE RIGHT PLANE - MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) - m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; - - // MAKE THE FRONT PLANE - MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) - m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; - - // MAKE THE BACK PLANE - MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) - m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; - - m_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION -} - -CPhysEnv::~CPhysEnv() -{ - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - free(m_TempSys[i]); - } - if (m_Contact) - free(m_Contact); - if (m_Spring) - free(m_Spring); - free(m_CollisionPlane); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RenderWorld -// Purpose: Draw the current system (particles, springs, userforces) -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::RenderWorld() -{ - tParticle *tempParticle; - tSpring *tempSpring; - - // FIRST DRAW THE WORLD CONTAINER - glColor3f(1.0f,1.0f,1.0f); - // do a big linestrip to get most of edges - glBegin(GL_LINE_STRIP); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glEnd(); - // fill in the stragglers - glBegin(GL_LINES); - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - - glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - - glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - - // draw floor - glDisable(GL_CULL_FACE); - glBegin(GL_QUADS); - glColor3f(0.0f,0.0f,0.5f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); - glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); - glEnd(); - glEnable(GL_CULL_FACE); - - - if (m_ParticleSys) - { - if (m_Spring && m_DrawSprings) - { - glBegin(GL_LINES); - glColor3f(0.0f,0.8f,0.8f); - tempSpring = m_Spring; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); - glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); - tempSpring++; - } - if (m_MouseForceActive) // DRAW MOUSESPRING FORCE - { - if (m_Pick[0] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); - glVertex3fv((float *)&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - glColor3f(0.8f,0.0f,0.8f); - glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); - glVertex3fv((float *)&m_MouseDragPos[1]); - } - } - glEnd(); - } - if (m_DrawVertices) - { - glBegin(GL_POINTS); - tempParticle = m_CurrentSys; - for (int loop = 0; loop < m_ParticleCnt; loop++) - { - // Picked particles are green then red for 1 and 2 - if (loop == m_Pick[0]) - glColor3f(0.0f,0.8f,0.0f); - else if (loop == m_Pick[1]) - glColor3f(0.8f,0.0f,0.0f); - // If particles are in contact, Draw them in Orange - else if (tempParticle->contacting && m_UseFriction) - glColor3f(1.0f,0.5f,0.0f); - // Normally Yellow - else - glColor3f(0.8f,0.8f,0.0f); - - glVertex3fv((float *)&tempParticle->pos); - tempParticle++; - } - glEnd(); - } - } - -} -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetNearestPoint -// Purpose: Use OpenGL Feedback to find the closest point to a mouseclick -// Arguments: Screen coordinates of the hit -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::GetNearestPoint(int x, int y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *feedBuffer; - int hitCount; - tParticle *tempParticle; - int loop; -/////////////////////////////////////////////////////////////////////////////// - // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) - feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); - // TELL OPENGL ABOUT THE BUFFER - glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); - (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE - - tempParticle = m_CurrentSys; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS - glPassThrough((float)loop); - // SEND THE VERTEX - glBegin(GL_POINTS); - glVertex3fv((float *)&tempParticle->pos); - glEnd(); - tempParticle++; - } - hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET - CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT - free(feedBuffer); // GET RID OF THE MEMORY -} -////// GetNearestPoint //////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CompareBuffer -// Purpose: Check the feedback buffer to see if anything is hit -// Arguments: Number of hits, pointer to buffer, point to test -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLint count; - GLfloat token,point[3]; - int loop,currentVertex,result = -1; - long nearest = -1, dist; -/////////////////////////////////////////////////////////////////////////////// - count = size; - while (count) - { - token = buffer[size - count]; // CHECK THE TOKEN - count--; - if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER - { - currentVertex = (int)buffer[size - count]; // WHAT VERTEX - count--; - } - else if (token == GL_POINT_TOKEN) - { - // THERE ARE THREE ELEMENTS TO A POINT TOKEN - for (loop = 0; loop < 3; loop++) - { - point[loop] = buffer[size - count]; - count--; - } - dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); - if (result == -1 || dist < nearest) - { - nearest = dist; - result = currentVertex; - } - } - } - - if (nearest < 50.0f) - { - if (m_Pick[0] == -1) - m_Pick[0] = result; - else if (m_Pick[1] == -1) - m_Pick[1] = result; - else - { - m_Pick[0] = result; - m_Pick[1] = -1; - } - } -} -////// CompareBuffer ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetWorldParticles -// Purpose: Inform the System of the particles under control -// Arguments: List of vertices and count -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetWorldParticles(tVector *coords,int particleCnt) -{ - tParticle *tempParticle; - - if (m_ParticleSys[0]) - free(m_ParticleSys[0]); - if (m_ParticleSys[1]) - free(m_ParticleSys[1]); - if (m_ParticleSys[2]) - free(m_ParticleSys[2]); - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - free(m_TempSys[i]); - } - if (m_Contact) - free(m_Contact); - // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - for (i = 0; i < 5; i++) - { - m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); - } - m_ParticleCnt = particleCnt; - - // MULTIPLIED PARTICLE COUNT * 2 SINCE THEY CAN COLLIDE WITH MULTIPLE WALLS - m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt * 2); - m_ContactCnt = 0; - - tempParticle = m_CurrentSys; - for (int loop = 0; loop < particleCnt; loop++) - { - MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) - MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) - MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) - tempParticle->oneOverM = 1.0f; // MASS OF 1 - tempParticle->contacting = FALSE; - tempParticle++; - coords++; - } - - // COPY THE SYSTEM TO THE SECOND ONE ALSO - memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); - // COPY THE SYSTEM TO THE RESET BUFFER ALSO - memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); - - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; -} -////// SetWorldParticles ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: FreeSystem -// Purpose: Remove all particles and clear it out -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::FreeSystem() -{ - m_Pick[0] = -1; - m_Pick[1] = -1; - if (m_ParticleSys[0]) - { - m_ParticleSys[0] = NULL; - free(m_ParticleSys[0]); - } - if (m_ParticleSys[1]) - { - free(m_ParticleSys[1]); - m_ParticleSys[1] = NULL; - } - if (m_ParticleSys[2]) - { - free(m_ParticleSys[2]); - m_ParticleSys[2] = NULL; // RESET BUFFER - } - for (int i = 0; i < 5; i++) - { - if (m_TempSys[i]) - { - free(m_TempSys[i]); - m_TempSys[i] = NULL; // RESET BUFFER - } - } - if (m_Contact) - { - free(m_Contact); - m_Contact = NULL; - } - if (m_Spring) - { - free(m_Spring); - m_Spring = NULL; - } - m_SpringCnt = 0; - m_ParticleCnt = 0; -} -////// FreeSystem ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadData -// Purpose: Load a simulation system -// Arguments: File pointer -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::LoadData(FILE *fp) -{ - fread(&m_UseGravity,sizeof(BOOL),1,fp); - fread(&m_UseDamping,sizeof(BOOL),1,fp); - fread(&m_UserForceActive,sizeof(BOOL),1,fp); - fread(&m_Gravity,sizeof(tVector),1,fp); - fread(&m_UserForce,sizeof(tVector),1,fp); - fread(&m_UserForceMag,sizeof(float),1,fp); - fread(&m_Kd,sizeof(float),1,fp); - fread(&m_Kr,sizeof(float),1,fp); - fread(&m_Ksh,sizeof(float),1,fp); - fread(&m_Ksd,sizeof(float),1,fp); - fread(&m_ParticleCnt,sizeof(int),1,fp); - m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - for (int i = 0; i < 5; i++) - { - m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); - } - m_ParticleSys[0] = m_CurrentSys; - m_ParticleSys[1] = m_TargetSys; - m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); - fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fread(&m_SpringCnt,sizeof(int),1,fp); - m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); - fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fread(m_Pick,sizeof(int),2,fp); -} -////// LoadData ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SaveData -// Purpose: Save a simulation system -// Arguments: File pointer -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SaveData(FILE *fp) -{ - fwrite(&m_UseGravity,sizeof(BOOL),1,fp); - fwrite(&m_UseDamping,sizeof(BOOL),1,fp); - fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); - fwrite(&m_Gravity,sizeof(tVector),1,fp); - fwrite(&m_UserForce,sizeof(tVector),1,fp); - fwrite(&m_UserForceMag,sizeof(float),1,fp); - fwrite(&m_Kd,sizeof(float),1,fp); - fwrite(&m_Kr,sizeof(float),1,fp); - fwrite(&m_Ksh,sizeof(float),1,fp); - fwrite(&m_Ksd,sizeof(float),1,fp); - fwrite(&m_ParticleCnt,sizeof(int),1,fp); - fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); - fwrite(&m_SpringCnt,sizeof(int),1,fp); - fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); - fwrite(m_Pick,sizeof(int),2,fp); -} -////// SaveData ////////////////////////////////////////////////////////////// - -// RESET THE SIM TO INITIAL VALUES -void CPhysEnv::ResetWorld() -{ - memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); - memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); -} - -void CPhysEnv::SetWorldProperties() -{ - CSimProps dialog; - dialog.m_CoefRest = m_Kr; - dialog.m_Damping = m_Kd; - dialog.m_GravX = m_Gravity.x; - dialog.m_GravY = m_Gravity.y; - dialog.m_GravZ = m_Gravity.z; - dialog.m_SpringConst = m_Ksh; - dialog.m_SpringDamp = m_Ksd; - dialog.m_UserForceMag = m_UserForceMag; - dialog.m_MouseSpring = m_MouseForceKs; - // Set up the Friction Values - dialog.m_CoefStaticFriction = m_Csf; - dialog.m_CoefKineticFriction = m_Ckf; - - if (dialog.DoModal() == IDOK) - { - m_Kr = dialog.m_CoefRest; - m_Kd = dialog.m_Damping; - m_Gravity.x = dialog.m_GravX; - m_Gravity.y = dialog.m_GravY; - m_Gravity.z = dialog.m_GravZ; - m_UserForceMag = dialog.m_UserForceMag; - m_Ksh = dialog.m_SpringConst; - m_Ksd = dialog.m_SpringDamp; - for (int loop = 0; loop < m_SpringCnt; loop++) - { - m_Spring[loop].Ks = m_Ksh; - m_Spring[loop].Kd = m_Ksd; - } - m_Csf = dialog.m_CoefStaticFriction; - m_Ckf = dialog.m_CoefKineticFriction; - - // GET THE NEW MOUSESPRING FORCE - m_MouseForceKs = dialog.m_MouseSpring; - } -} - - -void CPhysEnv::SetVertexMass() -{ - CVertMass dialog; - dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; - if (dialog.DoModal() == IDOK) - { - m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; - m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; - } -} - -void CPhysEnv::ApplyUserForce(tVector *force) -{ - ScaleVector(force, m_UserForceMag, &m_UserForce); - m_UserForceActive = TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: SetMouseForce -// Purpose: Allows the user to interact with selected points by dragging -// Arguments: Delta distance from clicked point, local x and y axes -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tVector tempX,tempY; -/////////////////////////////////////////////////////////////////////////////// - ScaleVector(localX, (float)deltaX * 0.03f, &tempX); - ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); - if (m_Pick[0] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); - VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); - } - if (m_Pick[1] > -1) - { - VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); - VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); - } -} -/// SetMouseForce ///////////////////////////////////////////////////////////// - -void CPhysEnv::AddSpring() -{ - tSpring *spring; - // MAKE SURE TWO PARTICLES ARE PICKED - if (m_Pick[0] > -1 && m_Pick[1] > -1) - { - spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); - if (m_Spring != NULL) - memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); - m_Spring = spring; - spring = &m_Spring[m_SpringCnt++]; - spring->Ks = m_Ksh; - spring->Kd = m_Ksd; - spring->p1 = m_Pick[0]; - spring->p2 = m_Pick[1]; - spring->restLen = - sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, - &m_CurrentSys[m_Pick[1]].pos)); - } -} - -// Velocity Threshold that decides between Static and Kinetic Friction -#define STATIC_THRESHOLD 0.03f - -void CPhysEnv::ComputeForces( tParticle *system, BOOL duringIntegration ) -{ - int loop; - tParticle *curParticle,*p1, *p2; - tSpring *spring; - float dist, Hterm, Dterm; - tVector springForce,deltaV,deltaP; - float FdotN,VdotN,Vmag; - tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE - - curParticle = system; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR - - if (m_UseGravity && curParticle->oneOverM != 0) // && curParticle->type != CONTACTING) - { - curParticle->f.x += (m_Gravity.x / curParticle->oneOverM); - curParticle->f.y += (m_Gravity.y / curParticle->oneOverM); - curParticle->f.z += (m_Gravity.z / curParticle->oneOverM); - } - - if (m_UseDamping) - { - curParticle->f.x += (-m_Kd * curParticle->v.x); - curParticle->f.y += (-m_Kd * curParticle->v.y); - curParticle->f.z += (-m_Kd * curParticle->v.z); - } - else - { - curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); - curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); - curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); - } - - // Handle Friction forces for Particles in contact with collision plane - // Do not apply friction During integration phase - if (curParticle->contacting && !duringIntegration && m_UseFriction) - { - // Calculate Fn - FdotN = DotProduct(&curParticle->contactN,&curParticle->f); - // Calculate Vt Velocity Tangent to Normal Plane - VdotN = DotProduct(&curParticle->contactN,&curParticle->v); - ScaleVector(&curParticle->contactN, VdotN, &Vn); - VectorDifference(&curParticle->v, &Vn, &Vt); - Vmag = VectorSquaredLength(&Vt); - // Check if Velocity is faster then threshold - if (Vmag > STATIC_THRESHOLD) // Use Kinetic Friction model - { - NormalizeVector(&Vt); - ScaleVector(&Vt, (FdotN * m_Ckf), &Vt); - VectorSum(&curParticle->f,&Vt,&curParticle->f); - } - else // Use Static Friction Model - { - Vmag = Vmag / STATIC_THRESHOLD; - NormalizeVector(&Vt); - ScaleVector(&Vt, (FdotN * m_Csf * Vmag), &Vt); // Scale Friction by Velocity - VectorSum(&curParticle->f,&Vt,&curParticle->f); - } - curParticle->contacting = FALSE; - } - curParticle++; - } - - // CHECK IF THERE IS A USER FORCE BEING APPLIED - if (m_UserForceActive) - { - if (m_Pick[0] != -1) - { - VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); - } - if (m_Pick[1] != -1) - { - VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); - } - MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE - } - - // NOW DO ALL THE SPRINGS - spring = m_Spring; - for (loop = 0; loop < m_SpringCnt; loop++) - { - p1 = &system[spring->p1]; - p2 = &system[spring->p2]; - VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) - - VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector - Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 - spring++; // DO THE NEXT SPRING - } - - // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE - if (m_MouseForceActive) - { - // APPLY TO EACH PICKED PARTICLE - if (m_Pick[0] > -1) - { - p1 = &system[m_Pick[0]]; - VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - if (m_Pick[1] > -1) - { - p1 = &system[m_Pick[1]]; - VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance - dist = VectorLength(&deltaP); // Magnitude of deltaP - - if (dist != 0.0f) - { - Hterm = (dist) * m_MouseForceKs; // Ks * dist - - ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force - VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - } - } - } - -} - - - -/////////////////////////////////////////////////////////////////////////////// -// Function: IntegrateSysOverTime -// Purpose: Does the Integration for all the points in a system -// Arguments: Initial Position, Source and Target Particle Systems and Time -// Notes: Computes a single integration step -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float deltaTimeMass; -/////////////////////////////////////////////////////////////////////////////// - for (loop = 0; loop < m_ParticleCnt; loop++) - { - deltaTimeMass = deltaTime * initial->oneOverM; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = initial->v.x + (source->f.x * deltaTimeMass); - target->v.y = initial->v.y + (source->f.y * deltaTimeMass); - target->v.z = initial->v.z + (source->f.z * deltaTimeMass); - - target->oneOverM = initial->oneOverM; - - // SET THE NEW POSITION - target->pos.x = initial->pos.x + (deltaTime * source->v.x); - target->pos.y = initial->pos.y + (deltaTime * source->v.y); - target->pos.z = initial->pos.z + (deltaTime * source->v.z); - - initial++; - source++; - target++; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses Euler's method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::EulerIntegrate( float DeltaTime) -{ - // JUST TAKE A SINGLE STEP - IntegrateSysOverTime(m_CurrentSys,m_CurrentSys, m_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: MidPointIntegrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Midpoint method -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::MidPointIntegrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float halfDeltaT; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; - - // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION - IntegrateSysOverTime(m_CurrentSys,m_CurrentSys,m_TempSys[0],halfDeltaT); - - // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES - ComputeForces(m_TempSys[0],TRUE); - - // TAKE THE FULL STEP WITH THIS NEW INFORMATION - IntegrateSysOverTime(m_CurrentSys,m_TempSys[0],m_TargetSys,DeltaTime); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: RK4Integrate -// Purpose: Calculate new Positions and Velocities given a deltatime -// Arguments: DeltaTime that has passed since last iteration -// Notes: This integrator uses the Runga-Kutta 4 method -// This could use a generic function 4 times instead of unrolled -// but it was easier for me to debug. Fun for you to optimize. -/////////////////////////////////////////////////////////////////////////////// -void CPhysEnv::RK4Integrate( float DeltaTime) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - float halfDeltaT,sixthDeltaT; - tParticle *source,*target,*accum1,*accum2,*accum3,*accum4; -/////////////////////////////////////////////////////////////////////////////// - halfDeltaT = DeltaTime / 2.0f; // SOME TIME VALUES I WILL NEED - sixthDeltaT = 1.0f / 6.0f; - - // FIRST STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[1]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - accum1->f.x = halfDeltaT * source->f.x * source->oneOverM; - accum1->f.y = halfDeltaT * source->f.y * source->oneOverM; - accum1->f.z = halfDeltaT * source->f.z * source->oneOverM; - - accum1->v.x = halfDeltaT * source->v.x; - accum1->v.y = halfDeltaT * source->v.y; - accum1->v.z = halfDeltaT * source->v.z; - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE OVER 1/2 TIME - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0],TRUE); // COMPUTE THE NEW FORCES - - // SECOND STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[2]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - accum1->f.x = halfDeltaT * target->f.x * source->oneOverM; - accum1->f.y = halfDeltaT * target->f.y * source->oneOverM; - accum1->f.z = halfDeltaT * target->f.z * source->oneOverM; - accum1->v.x = halfDeltaT * target->v.x; - accum1->v.y = halfDeltaT * target->v.y; - accum1->v.z = halfDeltaT * target->v.z; - - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0],TRUE); // COMPUTE THE NEW FORCES - - // THIRD STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[3]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // NOTICE I USE THE FULL DELTATIME THIS STEP - accum1->f.x = DeltaTime * target->f.x * source->oneOverM; - accum1->f.y = DeltaTime * target->f.y * source->oneOverM; - accum1->f.z = DeltaTime * target->f.z * source->oneOverM; - accum1->v.x = DeltaTime * target->v.x; - accum1->v.y = DeltaTime * target->v.y; - accum1->v.z = DeltaTime * target->v.z; - - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE - target->v.x = source->v.x + (accum1->f.x); - target->v.y = source->v.y + (accum1->f.y); - target->v.z = source->v.z + (accum1->f.z); - - target->oneOverM = source->oneOverM; - - // SET THE NEW POSITION - target->pos.x = source->pos.x + (accum1->v.x); - target->pos.y = source->pos.y + (accum1->v.y); - target->pos.z = source->pos.z + (accum1->v.z); - - source++; - target++; - accum1++; - } - - ComputeForces(m_TempSys[0],TRUE); // COMPUTE THE NEW FORCES - - // FOURTH STEP - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION - accum1 = m_TempSys[4]; // ACCUMULATE THE INTEGRATED VALUES - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // NOTICE I USE THE FULL DELTATIME THIS STEP - accum1->f.x = DeltaTime * target->f.x * source->oneOverM; - accum1->f.y = DeltaTime * target->f.y * source->oneOverM; - accum1->f.z = DeltaTime * target->f.z * source->oneOverM; - - accum1->v.x = DeltaTime * target->v.x; - accum1->v.y = DeltaTime * target->v.y; - accum1->v.z = DeltaTime * target->v.z; - - // THIS TIME I DON'T NEED TO COMPUTE THE TEMPORARY POSITIONS - source++; - target++; - accum1++; - } - - source = m_CurrentSys; // CURRENT STATE OF PARTICLE - target = m_TargetSys; - accum1 = m_TempSys[1]; - accum2 = m_TempSys[2]; - accum3 = m_TempSys[3]; - accum4 = m_TempSys[4]; - for (loop = 0; loop < m_ParticleCnt; loop++) - { - // DETERMINE THE NEW VELOCITY FOR THE PARTICLE USING RK4 FORMULA - target->v.x = source->v.x + ((accum1->f.x + ((accum2->f.x + accum3->f.x) * 2.0f) + accum4->f.x) * sixthDeltaT); - target->v.y = source->v.y + ((accum1->f.y + ((accum2->f.y + accum3->f.y) * 2.0f) + accum4->f.y) * sixthDeltaT); - target->v.z = source->v.z + ((accum1->f.z + ((accum2->f.z + accum3->f.z) * 2.0f) + accum4->f.z) * sixthDeltaT); - // DETERMINE THE NEW POSITION FOR THE PARTICLE USING RK4 FORMULA - target->pos.x = source->pos.x + ((accum1->v.x + ((accum2->v.x + accum3->v.x) * 2.0f) + accum4->v.x) * sixthDeltaT); - target->pos.y = source->pos.y + ((accum1->v.y + ((accum2->v.y + accum3->v.y) * 2.0f) + accum4->v.y) * sixthDeltaT); - target->pos.z = source->pos.z + ((accum1->v.z + ((accum2->v.z + accum3->v.z) * 2.0f) + accum4->v.z) * sixthDeltaT); - - source++; - target++; - accum1++; - accum2++; - accum3++; - accum4++; - } - -} - -int CPhysEnv::CheckForCollisions( tParticle *system ) -{ - // be optimistic! - int collisionState = NOT_COLLIDING; - float const depthEpsilon = 0.001f; - float const contactEpsilon = 0.01f; // Threshold for particle in contact - - int loop; - tParticle *curParticle; - - m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS - - curParticle = system; - for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); - loop++,curParticle++) - { - for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && - (collisionState != PENETRATING);planeIndex++) - { - tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; - - float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; - - if(axbyczd < -depthEpsilon) - { - // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP - collisionState = PENETRATING; - } - else - if(axbyczd < depthEpsilon) - { - float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); - if(relativeVelocity < 0.0f) - { - collisionState = COLLIDING; - m_Contact[m_ContactCnt].type = COLLIDING; - m_Contact[m_ContactCnt].particle = loop; - memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); - m_ContactCnt++; - } - } - // Check if the Particles are in contact and need friction applied - if (axbyczd < contactEpsilon) - { - curParticle->contacting = TRUE; - // Save the contact normal for later - memcpy(&curParticle->contactN,&plane->normal,sizeof(tVector)); - } - } - } - - return collisionState; -} - -void CPhysEnv::ResolveCollisions( tParticle *system ) -{ - tContact *contact; - tParticle *particle; // THE PARTICLE COLLIDING - float VdotN; - tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE - contact = m_Contact; - for (int loop = 0; loop < m_ContactCnt; loop++,contact++) - { - particle = &system[contact->particle]; - // CALCULATE Vn - VdotN = DotProduct(&contact->normal,&particle->v); - ScaleVector(&contact->normal, VdotN, &Vn); - // CALCULATE Vt - VectorDifference(&particle->v, &Vn, &Vt); - // SCALE Vn BY COEFFICIENT OF RESTITUTION - ScaleVector(&Vn, m_Kr, &Vn); - // SET THE VELOCITY TO BE THE NEW IMPULSE - VectorDifference(&Vt, &Vn, &particle->v); - } -} - -void CPhysEnv::Simulate(float DeltaTime, BOOL running) -{ - float CurrentTime = 0.0f; - float TargetTime = DeltaTime; - tParticle *tempSys; - int collisionState; - - while(CurrentTime < DeltaTime) - { - if (running) - { - ComputeForces(m_CurrentSys, FALSE); - - // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK - // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, - // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. - // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY - if (m_CollisionRootFinding) - { - EulerIntegrate(TargetTime-CurrentTime); - } - else - { - switch (m_IntegratorType) - { - case EULER_INTEGRATOR: - EulerIntegrate(TargetTime-CurrentTime); - break; - case MIDPOINT_INTEGRATOR: - MidPointIntegrate(TargetTime-CurrentTime); - break; - case RK4_INTEGRATOR: - RK4Integrate(TargetTime-CurrentTime); - break; - } - } - } - - collisionState = CheckForCollisions(m_TargetSys); - - if(collisionState == PENETRATING) - { - // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER - m_CollisionRootFinding = TRUE; - // we simulated too far, so subdivide time and try again - TargetTime = (CurrentTime + TargetTime) / 2.0f; - - // blow up if we aren't moving forward each step, which is - // probably caused by interpenetration at the frame start - assert(fabs(TargetTime - CurrentTime) > EPSILON); - } - else - { - // either colliding or clear - if(collisionState == COLLIDING) - { - int Counter = 0; - do - { - ResolveCollisions(m_TargetSys); - Counter++; - } while((CheckForCollisions(m_TargetSys) == - COLLIDING) && (Counter < 100)); - - assert(Counter < 100); - m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT BACK TO NORMAL - } - - // we made a successful step, so swap configurations - // to "save" the data for the next step - - CurrentTime = TargetTime; - TargetTime = DeltaTime; - - // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN - tempSys = m_CurrentSys; - m_CurrentSys = m_TargetSys; - m_TargetSys = tempSys; - } - } -} +/////////////////////////////////////////////////////////////////////////////// +// +// PhysEnv.cpp : Physical World implementation file +// +// Purpose: Implementation of Particle Physics System +// +// Created: +// JL 12/1/98 +// Modified: +// JL 3/6/99 - FIXED GRAVITY FORCE CALCULATION BUG +// JL 3/8/99 - ADDED MORE POSSIBLE CONTACTS AS EACH VERTEX CAN CONTACT MORE +// THEN ONE COLLISION SURFACE (SHOULD IT BE DYNAMICALLY ALLOC'ED?) +// JL 3/20/99 - ADDED THE MIDPOINT AND RK INTEGRATOR NEEDED TO ALLOC 5 TEMP PARTICLE ARRAYS +// JL 6/01/99 - Modified for the Friction code with a Contact model +// Friction is added int the Apply forces code +// Contact is determined in CheckForCollisions +// World Damping was reduced so friction is more evident +// +// Notes: A bit of this along with the organization comes from Chris Hecker's +// Physics Articles from last year. Hopefully this will get everyone +// back up to speed before we dig deeper into the world of Dynamics. +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1998-1999 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include +#include +#include +#include + +#include "Friction.h" +#include "PhysEnv.h" +#include "SimProps.h" +#include "VertMass.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#pragma warning (disable:4244) // I NEED TO CONVERT FROM DOUBLE TO FLOAT + +///////////////////////////////////////////////////////////////////////////// +// CPhysEnv + +// INITIALIZE THE SIMULATION WORLD +CPhysEnv::CPhysEnv() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + m_ParticleSys[0] = NULL; + m_ParticleSys[1] = NULL; + m_ParticleSys[2] = NULL; // RESET BUFFER + + // THESE TEMP PARTICLE BUFFERS ARE NEEDED FOR THE MIDPOINT AND RK4 INTEGRATOR + for (int i = 0; i < 5; i++) + m_TempSys[i] = NULL; + m_ParticleCnt = 0; + m_Contact = NULL; + m_Spring = NULL; + m_SpringCnt = 0; + + m_UseGravity = TRUE; + m_UseFriction = TRUE; + m_DrawSprings = TRUE; + m_DrawVertices = TRUE; + m_MouseForceActive = FALSE; + + MAKEVECTOR(m_Gravity, 0.0f, -0.2f, 0.0f) + m_UserForceMag = 100.0; + m_UserForceActive = FALSE; + m_Kd = 0.02f; // DAMPING FACTOR + m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT + m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT + m_Ksd = 0.1f; // SPRING DAMPING CONSTANT + + m_Csf = 0.9f; // Default Static Friction + m_Ckf = 0.7f; // Default Kinetic Friction + m_MouseForceKs = 0.08f; // MOUSE SPRING CONSTANT + + // CREATE THE SIZE FOR THE SIMULATION WORLD + m_WorldSizeX = 15.0f; + m_WorldSizeY = 15.0f; + m_WorldSizeZ = 15.0f; + + m_IntegratorType = EULER_INTEGRATOR; + + m_CollisionPlane = (tCollisionPlane *)malloc(sizeof(tCollisionPlane) * 6); + m_CollisionPlaneCnt = 6; + + // MAKE THE TOP PLANE (CEILING) + MAKEVECTOR(m_CollisionPlane[0].normal,0.0f, -1.0f, 0.0f) + m_CollisionPlane[0].d = m_WorldSizeY / 2.0f; + + // MAKE THE BOTTOM PLANE (FLOOR) + MAKEVECTOR(m_CollisionPlane[1].normal,0.0f, 1.0f, 0.0f) + m_CollisionPlane[1].d = m_WorldSizeY / 2.0f; + + // MAKE THE LEFT PLANE + MAKEVECTOR(m_CollisionPlane[2].normal,-1.0f, 0.0f, 0.0f) + m_CollisionPlane[2].d = m_WorldSizeX / 2.0f; + + // MAKE THE RIGHT PLANE + MAKEVECTOR(m_CollisionPlane[3].normal,1.0f, 0.0f, 0.0f) + m_CollisionPlane[3].d = m_WorldSizeX / 2.0f; + + // MAKE THE FRONT PLANE + MAKEVECTOR(m_CollisionPlane[4].normal,0.0f, 0.0f, -1.0f) + m_CollisionPlane[4].d = m_WorldSizeZ / 2.0f; + + // MAKE THE BACK PLANE + MAKEVECTOR(m_CollisionPlane[5].normal,0.0f, 0.0f, 1.0f) + m_CollisionPlane[5].d = m_WorldSizeZ / 2.0f; + + m_CollisionRootFinding = FALSE; // ONLY SET WHEN FINDING A COLLISION +} + +CPhysEnv::~CPhysEnv() +{ + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + free(m_TempSys[i]); + } + if (m_Contact) + free(m_Contact); + if (m_Spring) + free(m_Spring); + free(m_CollisionPlane); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RenderWorld +// Purpose: Draw the current system (particles, springs, userforces) +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::RenderWorld() +{ + tParticle *tempParticle; + tSpring *tempSpring; + + // FIRST DRAW THE WORLD CONTAINER + glColor3f(1.0f,1.0f,1.0f); + // do a big linestrip to get most of edges + glBegin(GL_LINE_STRIP); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glEnd(); + // fill in the stragglers + glBegin(GL_LINES); + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + + glVertex3f( m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + + glVertex3f(-m_WorldSizeX/2.0f, m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + + // draw floor + glDisable(GL_CULL_FACE); + glBegin(GL_QUADS); + glColor3f(0.0f,0.0f,0.5f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f,-m_WorldSizeZ/2.0f); + glVertex3f( m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glVertex3f(-m_WorldSizeX/2.0f,-m_WorldSizeY/2.0f, m_WorldSizeZ/2.0f); + glEnd(); + glEnable(GL_CULL_FACE); + + + if (m_ParticleSys) + { + if (m_Spring && m_DrawSprings) + { + glBegin(GL_LINES); + glColor3f(0.0f,0.8f,0.8f); + tempSpring = m_Spring; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + glVertex3fv((float *)&m_CurrentSys[tempSpring->p1].pos); + glVertex3fv((float *)&m_CurrentSys[tempSpring->p2].pos); + tempSpring++; + } + if (m_MouseForceActive) // DRAW MOUSESPRING FORCE + { + if (m_Pick[0] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[0]].pos); + glVertex3fv((float *)&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + glColor3f(0.8f,0.0f,0.8f); + glVertex3fv((float *)&m_CurrentSys[m_Pick[1]].pos); + glVertex3fv((float *)&m_MouseDragPos[1]); + } + } + glEnd(); + } + if (m_DrawVertices) + { + glBegin(GL_POINTS); + tempParticle = m_CurrentSys; + for (int loop = 0; loop < m_ParticleCnt; loop++) + { + // Picked particles are green then red for 1 and 2 + if (loop == m_Pick[0]) + glColor3f(0.0f,0.8f,0.0f); + else if (loop == m_Pick[1]) + glColor3f(0.8f,0.0f,0.0f); + // If particles are in contact, Draw them in Orange + else if (tempParticle->contacting && m_UseFriction) + glColor3f(1.0f,0.5f,0.0f); + // Normally Yellow + else + glColor3f(0.8f,0.8f,0.0f); + + glVertex3fv((float *)&tempParticle->pos); + tempParticle++; + } + glEnd(); + } + } + +} +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetNearestPoint +// Purpose: Use OpenGL Feedback to find the closest point to a mouseclick +// Arguments: Screen coordinates of the hit +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::GetNearestPoint(int x, int y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *feedBuffer; + int hitCount; + tParticle *tempParticle; + int loop; +/////////////////////////////////////////////////////////////////////////////// + // INITIALIZE A PLACE TO PUT ALL THE FEEDBACK INFO (3 DATA, 1 TAG, 2 TOKENS) + feedBuffer = (float *)malloc(sizeof(GLfloat) * m_ParticleCnt * 6); + // TELL OPENGL ABOUT THE BUFFER + glFeedbackBuffer(m_ParticleCnt * 6,GL_3D,feedBuffer); + (void)glRenderMode(GL_FEEDBACK); // SET IT IN FEEDBACK MODE + + tempParticle = m_CurrentSys; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // PASS THROUGH A MARKET LETTING ME KNOW WHAT VERTEX IT WAS + glPassThrough((float)loop); + // SEND THE VERTEX + glBegin(GL_POINTS); + glVertex3fv((float *)&tempParticle->pos); + glEnd(); + tempParticle++; + } + hitCount = glRenderMode(GL_RENDER); // HOW MANY HITS DID I GET + CompareBuffer(hitCount,feedBuffer,(float)x,(float)y); // CHECK THE HIT + free(feedBuffer); // GET RID OF THE MEMORY +} +////// GetNearestPoint //////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CompareBuffer +// Purpose: Check the feedback buffer to see if anything is hit +// Arguments: Number of hits, pointer to buffer, point to test +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::CompareBuffer(int size, float *buffer,float x, float y) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLint count; + GLfloat token,point[3]; + int loop,currentVertex,result = -1; + long nearest = -1, dist; +/////////////////////////////////////////////////////////////////////////////// + count = size; + while (count) + { + token = buffer[size - count]; // CHECK THE TOKEN + count--; + if (token == GL_PASS_THROUGH_TOKEN) // VERTEX MARKER + { + currentVertex = (int)buffer[size - count]; // WHAT VERTEX + count--; + } + else if (token == GL_POINT_TOKEN) + { + // THERE ARE THREE ELEMENTS TO A POINT TOKEN + for (loop = 0; loop < 3; loop++) + { + point[loop] = buffer[size - count]; + count--; + } + dist = ((x - point[0]) * (x - point[0])) + ((y - point[1]) * (y - point[1])); + if (result == -1 || dist < nearest) + { + nearest = dist; + result = currentVertex; + } + } + } + + if (nearest < 50.0f) + { + if (m_Pick[0] == -1) + m_Pick[0] = result; + else if (m_Pick[1] == -1) + m_Pick[1] = result; + else + { + m_Pick[0] = result; + m_Pick[1] = -1; + } + } +} +////// CompareBuffer ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetWorldParticles +// Purpose: Inform the System of the particles under control +// Arguments: List of vertices and count +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetWorldParticles(tVector *coords,int particleCnt) +{ + tParticle *tempParticle; + + if (m_ParticleSys[0]) + free(m_ParticleSys[0]); + if (m_ParticleSys[1]) + free(m_ParticleSys[1]); + if (m_ParticleSys[2]) + free(m_ParticleSys[2]); + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + free(m_TempSys[i]); + } + if (m_Contact) + free(m_Contact); + // THE SYSTEM IS DOUBLE BUFFERED TO MAKE THINGS EASIER + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + for (i = 0; i < 5; i++) + { + m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * particleCnt); + } + m_ParticleCnt = particleCnt; + + // MULTIPLIED PARTICLE COUNT * 2 SINCE THEY CAN COLLIDE WITH MULTIPLE WALLS + m_Contact = (tContact *)malloc(sizeof(tContact) * particleCnt * 2); + m_ContactCnt = 0; + + tempParticle = m_CurrentSys; + for (int loop = 0; loop < particleCnt; loop++) + { + MAKEVECTOR(tempParticle->pos, coords->x, coords->y, coords->z) + MAKEVECTOR(tempParticle->v, 0.0f, 0.0f, 0.0f) + MAKEVECTOR(tempParticle->f, 0.0f, 0.0f, 0.0f) + tempParticle->oneOverM = 1.0f; // MASS OF 1 + tempParticle->contacting = FALSE; + tempParticle++; + coords++; + } + + // COPY THE SYSTEM TO THE SECOND ONE ALSO + memcpy(m_TargetSys,m_CurrentSys,sizeof(tParticle) * particleCnt); + // COPY THE SYSTEM TO THE RESET BUFFER ALSO + memcpy(m_ParticleSys[2],m_CurrentSys,sizeof(tParticle) * particleCnt); + + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; +} +////// SetWorldParticles ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: FreeSystem +// Purpose: Remove all particles and clear it out +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::FreeSystem() +{ + m_Pick[0] = -1; + m_Pick[1] = -1; + if (m_ParticleSys[0]) + { + m_ParticleSys[0] = NULL; + free(m_ParticleSys[0]); + } + if (m_ParticleSys[1]) + { + free(m_ParticleSys[1]); + m_ParticleSys[1] = NULL; + } + if (m_ParticleSys[2]) + { + free(m_ParticleSys[2]); + m_ParticleSys[2] = NULL; // RESET BUFFER + } + for (int i = 0; i < 5; i++) + { + if (m_TempSys[i]) + { + free(m_TempSys[i]); + m_TempSys[i] = NULL; // RESET BUFFER + } + } + if (m_Contact) + { + free(m_Contact); + m_Contact = NULL; + } + if (m_Spring) + { + free(m_Spring); + m_Spring = NULL; + } + m_SpringCnt = 0; + m_ParticleCnt = 0; +} +////// FreeSystem ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadData +// Purpose: Load a simulation system +// Arguments: File pointer +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::LoadData(FILE *fp) +{ + fread(&m_UseGravity,sizeof(BOOL),1,fp); + fread(&m_UseDamping,sizeof(BOOL),1,fp); + fread(&m_UserForceActive,sizeof(BOOL),1,fp); + fread(&m_Gravity,sizeof(tVector),1,fp); + fread(&m_UserForce,sizeof(tVector),1,fp); + fread(&m_UserForceMag,sizeof(float),1,fp); + fread(&m_Kd,sizeof(float),1,fp); + fread(&m_Kr,sizeof(float),1,fp); + fread(&m_Ksh,sizeof(float),1,fp); + fread(&m_Ksd,sizeof(float),1,fp); + fread(&m_ParticleCnt,sizeof(int),1,fp); + m_CurrentSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_TargetSys = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + m_ParticleSys[2] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + for (int i = 0; i < 5; i++) + { + m_TempSys[i] = (tParticle *)malloc(sizeof(tParticle) * m_ParticleCnt); + } + m_ParticleSys[0] = m_CurrentSys; + m_ParticleSys[1] = m_TargetSys; + m_Contact = (tContact *)malloc(sizeof(tContact) * m_ParticleCnt); + fread(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fread(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fread(&m_SpringCnt,sizeof(int),1,fp); + m_Spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt)); + fread(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fread(m_Pick,sizeof(int),2,fp); +} +////// LoadData ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SaveData +// Purpose: Save a simulation system +// Arguments: File pointer +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SaveData(FILE *fp) +{ + fwrite(&m_UseGravity,sizeof(BOOL),1,fp); + fwrite(&m_UseDamping,sizeof(BOOL),1,fp); + fwrite(&m_UserForceActive,sizeof(BOOL),1,fp); + fwrite(&m_Gravity,sizeof(tVector),1,fp); + fwrite(&m_UserForce,sizeof(tVector),1,fp); + fwrite(&m_UserForceMag,sizeof(float),1,fp); + fwrite(&m_Kd,sizeof(float),1,fp); + fwrite(&m_Kr,sizeof(float),1,fp); + fwrite(&m_Ksh,sizeof(float),1,fp); + fwrite(&m_Ksd,sizeof(float),1,fp); + fwrite(&m_ParticleCnt,sizeof(int),1,fp); + fwrite(m_ParticleSys[0],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[1],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(m_ParticleSys[2],sizeof(tParticle),m_ParticleCnt,fp); + fwrite(&m_SpringCnt,sizeof(int),1,fp); + fwrite(m_Spring,sizeof(tSpring),m_SpringCnt,fp); + fwrite(m_Pick,sizeof(int),2,fp); +} +////// SaveData ////////////////////////////////////////////////////////////// + +// RESET THE SIM TO INITIAL VALUES +void CPhysEnv::ResetWorld() +{ + memcpy(m_CurrentSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); + memcpy(m_TargetSys,m_ParticleSys[2],sizeof(tParticle) * m_ParticleCnt); +} + +void CPhysEnv::SetWorldProperties() +{ + CSimProps dialog; + dialog.m_CoefRest = m_Kr; + dialog.m_Damping = m_Kd; + dialog.m_GravX = m_Gravity.x; + dialog.m_GravY = m_Gravity.y; + dialog.m_GravZ = m_Gravity.z; + dialog.m_SpringConst = m_Ksh; + dialog.m_SpringDamp = m_Ksd; + dialog.m_UserForceMag = m_UserForceMag; + dialog.m_MouseSpring = m_MouseForceKs; + // Set up the Friction Values + dialog.m_CoefStaticFriction = m_Csf; + dialog.m_CoefKineticFriction = m_Ckf; + + if (dialog.DoModal() == IDOK) + { + m_Kr = dialog.m_CoefRest; + m_Kd = dialog.m_Damping; + m_Gravity.x = dialog.m_GravX; + m_Gravity.y = dialog.m_GravY; + m_Gravity.z = dialog.m_GravZ; + m_UserForceMag = dialog.m_UserForceMag; + m_Ksh = dialog.m_SpringConst; + m_Ksd = dialog.m_SpringDamp; + for (int loop = 0; loop < m_SpringCnt; loop++) + { + m_Spring[loop].Ks = m_Ksh; + m_Spring[loop].Kd = m_Ksd; + } + m_Csf = dialog.m_CoefStaticFriction; + m_Ckf = dialog.m_CoefKineticFriction; + + // GET THE NEW MOUSESPRING FORCE + m_MouseForceKs = dialog.m_MouseSpring; + } +} + + +void CPhysEnv::SetVertexMass() +{ + CVertMass dialog; + dialog.m_VertexMass = m_CurrentSys[m_Pick[0]].oneOverM; + if (dialog.DoModal() == IDOK) + { + m_ParticleSys[0][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[0][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[1][m_Pick[1]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[0]].oneOverM = dialog.m_VertexMass; + m_ParticleSys[2][m_Pick[1]].oneOverM = dialog.m_VertexMass; + } +} + +void CPhysEnv::ApplyUserForce(tVector *force) +{ + ScaleVector(force, m_UserForceMag, &m_UserForce); + m_UserForceActive = TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: SetMouseForce +// Purpose: Allows the user to interact with selected points by dragging +// Arguments: Delta distance from clicked point, local x and y axes +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tVector tempX,tempY; +/////////////////////////////////////////////////////////////////////////////// + ScaleVector(localX, (float)deltaX * 0.03f, &tempX); + ScaleVector(localY, -(float)deltaY * 0.03f, &tempY); + if (m_Pick[0] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[0]].pos,&tempX,&m_MouseDragPos[0]); + VectorSum(&m_MouseDragPos[0],&tempY,&m_MouseDragPos[0]); + } + if (m_Pick[1] > -1) + { + VectorSum(&m_CurrentSys[m_Pick[1]].pos,&tempX,&m_MouseDragPos[1]); + VectorSum(&m_MouseDragPos[1],&tempY,&m_MouseDragPos[1]); + } +} +/// SetMouseForce ///////////////////////////////////////////////////////////// + +void CPhysEnv::AddSpring() +{ + tSpring *spring; + // MAKE SURE TWO PARTICLES ARE PICKED + if (m_Pick[0] > -1 && m_Pick[1] > -1) + { + spring = (tSpring *)malloc(sizeof(tSpring) * (m_SpringCnt + 1)); + if (m_Spring != NULL) + memcpy(spring,m_Spring,sizeof(tSpring) * m_SpringCnt); + m_Spring = spring; + spring = &m_Spring[m_SpringCnt++]; + spring->Ks = m_Ksh; + spring->Kd = m_Ksd; + spring->p1 = m_Pick[0]; + spring->p2 = m_Pick[1]; + spring->restLen = + sqrt(VectorSquaredDistance(&m_CurrentSys[m_Pick[0]].pos, + &m_CurrentSys[m_Pick[1]].pos)); + } +} + +// Velocity Threshold that decides between Static and Kinetic Friction +#define STATIC_THRESHOLD 0.03f + +void CPhysEnv::ComputeForces( tParticle *system, BOOL duringIntegration ) +{ + int loop; + tParticle *curParticle,*p1, *p2; + tSpring *spring; + float dist, Hterm, Dterm; + tVector springForce,deltaV,deltaP; + float FdotN,VdotN,Vmag; + tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE + + curParticle = system; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + MAKEVECTOR(curParticle->f,0.0f,0.0f,0.0f) // CLEAR FORCE VECTOR + + if (m_UseGravity && curParticle->oneOverM != 0) // && curParticle->type != CONTACTING) + { + curParticle->f.x += (m_Gravity.x / curParticle->oneOverM); + curParticle->f.y += (m_Gravity.y / curParticle->oneOverM); + curParticle->f.z += (m_Gravity.z / curParticle->oneOverM); + } + + if (m_UseDamping) + { + curParticle->f.x += (-m_Kd * curParticle->v.x); + curParticle->f.y += (-m_Kd * curParticle->v.y); + curParticle->f.z += (-m_Kd * curParticle->v.z); + } + else + { + curParticle->f.x += (-DEFAULT_DAMPING * curParticle->v.x); + curParticle->f.y += (-DEFAULT_DAMPING * curParticle->v.y); + curParticle->f.z += (-DEFAULT_DAMPING * curParticle->v.z); + } + + // Handle Friction forces for Particles in contact with collision plane + // Do not apply friction During integration phase + if (curParticle->contacting && !duringIntegration && m_UseFriction) + { + // Calculate Fn + FdotN = DotProduct(&curParticle->contactN,&curParticle->f); + // Calculate Vt Velocity Tangent to Normal Plane + VdotN = DotProduct(&curParticle->contactN,&curParticle->v); + ScaleVector(&curParticle->contactN, VdotN, &Vn); + VectorDifference(&curParticle->v, &Vn, &Vt); + Vmag = VectorSquaredLength(&Vt); + // Check if Velocity is faster then threshold + if (Vmag > STATIC_THRESHOLD) // Use Kinetic Friction model + { + NormalizeVector(&Vt); + ScaleVector(&Vt, (FdotN * m_Ckf), &Vt); + VectorSum(&curParticle->f,&Vt,&curParticle->f); + } + else // Use Static Friction Model + { + Vmag = Vmag / STATIC_THRESHOLD; + NormalizeVector(&Vt); + ScaleVector(&Vt, (FdotN * m_Csf * Vmag), &Vt); // Scale Friction by Velocity + VectorSum(&curParticle->f,&Vt,&curParticle->f); + } + curParticle->contacting = FALSE; + } + curParticle++; + } + + // CHECK IF THERE IS A USER FORCE BEING APPLIED + if (m_UserForceActive) + { + if (m_Pick[0] != -1) + { + VectorSum(&system[m_Pick[0]].f,&m_UserForce,&system[m_Pick[0]].f); + } + if (m_Pick[1] != -1) + { + VectorSum(&system[m_Pick[1]].f,&m_UserForce,&system[m_Pick[1]].f); + } + MAKEVECTOR(m_UserForce,0.0f,0.0f,0.0f); // CLEAR USER FORCE + } + + // NOW DO ALL THE SPRINGS + spring = m_Spring; + for (loop = 0; loop < m_SpringCnt; loop++) + { + p1 = &system[spring->p1]; + p2 = &system[spring->p2]; + VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) + + VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector + Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 + spring++; // DO THE NEXT SPRING + } + + // APPLY THE MOUSE DRAG FORCES IF THEY ARE ACTIVE + if (m_MouseForceActive) + { + // APPLY TO EACH PICKED PARTICLE + if (m_Pick[0] > -1) + { + p1 = &system[m_Pick[0]]; + VectorDifference(&p1->pos,&m_MouseDragPos[0],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + if (m_Pick[1] > -1) + { + p1 = &system[m_Pick[1]]; + VectorDifference(&p1->pos,&m_MouseDragPos[1],&deltaP); // Vector distance + dist = VectorLength(&deltaP); // Magnitude of deltaP + + if (dist != 0.0f) + { + Hterm = (dist) * m_MouseForceKs; // Ks * dist + + ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + ScaleVector(&springForce,-(Hterm),&springForce); // Calc Force + VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + } + } + } + +} + + + +/////////////////////////////////////////////////////////////////////////////// +// Function: IntegrateSysOverTime +// Purpose: Does the Integration for all the points in a system +// Arguments: Initial Position, Source and Target Particle Systems and Time +// Notes: Computes a single integration step +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float deltaTimeMass; +/////////////////////////////////////////////////////////////////////////////// + for (loop = 0; loop < m_ParticleCnt; loop++) + { + deltaTimeMass = deltaTime * initial->oneOverM; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = initial->v.x + (source->f.x * deltaTimeMass); + target->v.y = initial->v.y + (source->f.y * deltaTimeMass); + target->v.z = initial->v.z + (source->f.z * deltaTimeMass); + + target->oneOverM = initial->oneOverM; + + // SET THE NEW POSITION + target->pos.x = initial->pos.x + (deltaTime * source->v.x); + target->pos.y = initial->pos.y + (deltaTime * source->v.y); + target->pos.z = initial->pos.z + (deltaTime * source->v.z); + + initial++; + source++; + target++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses Euler's method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::EulerIntegrate( float DeltaTime) +{ + // JUST TAKE A SINGLE STEP + IntegrateSysOverTime(m_CurrentSys,m_CurrentSys, m_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: MidPointIntegrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Midpoint method +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::MidPointIntegrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float halfDeltaT; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; + + // TAKE A HALF STEP AND UPDATE VELOCITY AND POSITION + IntegrateSysOverTime(m_CurrentSys,m_CurrentSys,m_TempSys[0],halfDeltaT); + + // COMPUTE FORCES USING THESE NEW POSITIONS AND VELOCITIES + ComputeForces(m_TempSys[0],TRUE); + + // TAKE THE FULL STEP WITH THIS NEW INFORMATION + IntegrateSysOverTime(m_CurrentSys,m_TempSys[0],m_TargetSys,DeltaTime); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: RK4Integrate +// Purpose: Calculate new Positions and Velocities given a deltatime +// Arguments: DeltaTime that has passed since last iteration +// Notes: This integrator uses the Runga-Kutta 4 method +// This could use a generic function 4 times instead of unrolled +// but it was easier for me to debug. Fun for you to optimize. +/////////////////////////////////////////////////////////////////////////////// +void CPhysEnv::RK4Integrate( float DeltaTime) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + float halfDeltaT,sixthDeltaT; + tParticle *source,*target,*accum1,*accum2,*accum3,*accum4; +/////////////////////////////////////////////////////////////////////////////// + halfDeltaT = DeltaTime / 2.0f; // SOME TIME VALUES I WILL NEED + sixthDeltaT = 1.0f / 6.0f; + + // FIRST STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[1]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + accum1->f.x = halfDeltaT * source->f.x * source->oneOverM; + accum1->f.y = halfDeltaT * source->f.y * source->oneOverM; + accum1->f.z = halfDeltaT * source->f.z * source->oneOverM; + + accum1->v.x = halfDeltaT * source->v.x; + accum1->v.y = halfDeltaT * source->v.y; + accum1->v.z = halfDeltaT * source->v.z; + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE OVER 1/2 TIME + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0],TRUE); // COMPUTE THE NEW FORCES + + // SECOND STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[2]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + accum1->f.x = halfDeltaT * target->f.x * source->oneOverM; + accum1->f.y = halfDeltaT * target->f.y * source->oneOverM; + accum1->f.z = halfDeltaT * target->f.z * source->oneOverM; + accum1->v.x = halfDeltaT * target->v.x; + accum1->v.y = halfDeltaT * target->v.y; + accum1->v.z = halfDeltaT * target->v.z; + + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0],TRUE); // COMPUTE THE NEW FORCES + + // THIRD STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[3]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // NOTICE I USE THE FULL DELTATIME THIS STEP + accum1->f.x = DeltaTime * target->f.x * source->oneOverM; + accum1->f.y = DeltaTime * target->f.y * source->oneOverM; + accum1->f.z = DeltaTime * target->f.z * source->oneOverM; + accum1->v.x = DeltaTime * target->v.x; + accum1->v.y = DeltaTime * target->v.y; + accum1->v.z = DeltaTime * target->v.z; + + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE + target->v.x = source->v.x + (accum1->f.x); + target->v.y = source->v.y + (accum1->f.y); + target->v.z = source->v.z + (accum1->f.z); + + target->oneOverM = source->oneOverM; + + // SET THE NEW POSITION + target->pos.x = source->pos.x + (accum1->v.x); + target->pos.y = source->pos.y + (accum1->v.y); + target->pos.z = source->pos.z + (accum1->v.z); + + source++; + target++; + accum1++; + } + + ComputeForces(m_TempSys[0],TRUE); // COMPUTE THE NEW FORCES + + // FOURTH STEP + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TempSys[0]; // TEMP STORAGE FOR NEW POSITION + accum1 = m_TempSys[4]; // ACCUMULATE THE INTEGRATED VALUES + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // NOTICE I USE THE FULL DELTATIME THIS STEP + accum1->f.x = DeltaTime * target->f.x * source->oneOverM; + accum1->f.y = DeltaTime * target->f.y * source->oneOverM; + accum1->f.z = DeltaTime * target->f.z * source->oneOverM; + + accum1->v.x = DeltaTime * target->v.x; + accum1->v.y = DeltaTime * target->v.y; + accum1->v.z = DeltaTime * target->v.z; + + // THIS TIME I DON'T NEED TO COMPUTE THE TEMPORARY POSITIONS + source++; + target++; + accum1++; + } + + source = m_CurrentSys; // CURRENT STATE OF PARTICLE + target = m_TargetSys; + accum1 = m_TempSys[1]; + accum2 = m_TempSys[2]; + accum3 = m_TempSys[3]; + accum4 = m_TempSys[4]; + for (loop = 0; loop < m_ParticleCnt; loop++) + { + // DETERMINE THE NEW VELOCITY FOR THE PARTICLE USING RK4 FORMULA + target->v.x = source->v.x + ((accum1->f.x + ((accum2->f.x + accum3->f.x) * 2.0f) + accum4->f.x) * sixthDeltaT); + target->v.y = source->v.y + ((accum1->f.y + ((accum2->f.y + accum3->f.y) * 2.0f) + accum4->f.y) * sixthDeltaT); + target->v.z = source->v.z + ((accum1->f.z + ((accum2->f.z + accum3->f.z) * 2.0f) + accum4->f.z) * sixthDeltaT); + // DETERMINE THE NEW POSITION FOR THE PARTICLE USING RK4 FORMULA + target->pos.x = source->pos.x + ((accum1->v.x + ((accum2->v.x + accum3->v.x) * 2.0f) + accum4->v.x) * sixthDeltaT); + target->pos.y = source->pos.y + ((accum1->v.y + ((accum2->v.y + accum3->v.y) * 2.0f) + accum4->v.y) * sixthDeltaT); + target->pos.z = source->pos.z + ((accum1->v.z + ((accum2->v.z + accum3->v.z) * 2.0f) + accum4->v.z) * sixthDeltaT); + + source++; + target++; + accum1++; + accum2++; + accum3++; + accum4++; + } + +} + +int CPhysEnv::CheckForCollisions( tParticle *system ) +{ + // be optimistic! + int collisionState = NOT_COLLIDING; + float const depthEpsilon = 0.001f; + float const contactEpsilon = 0.01f; // Threshold for particle in contact + + int loop; + tParticle *curParticle; + + m_ContactCnt = 0; // THERE ARE CURRENTLY NO CONTACTS + + curParticle = system; + for (loop = 0; (loop < m_ParticleCnt) && (collisionState != PENETRATING); + loop++,curParticle++) + { + for(int planeIndex = 0;(planeIndex < m_CollisionPlaneCnt) && + (collisionState != PENETRATING);planeIndex++) + { + tCollisionPlane *plane = &m_CollisionPlane[planeIndex]; + + float axbyczd = DotProduct(&curParticle->pos,&plane->normal) + plane->d; + + if(axbyczd < -depthEpsilon) + { + // ONCE ANY PARTICLE PENETRATES, QUIT THE LOOP + collisionState = PENETRATING; + } + else + if(axbyczd < depthEpsilon) + { + float relativeVelocity = DotProduct(&plane->normal,&curParticle->v); + if(relativeVelocity < 0.0f) + { + collisionState = COLLIDING; + m_Contact[m_ContactCnt].type = COLLIDING; + m_Contact[m_ContactCnt].particle = loop; + memcpy(&m_Contact[m_ContactCnt].normal,&plane->normal,sizeof(tVector)); + m_ContactCnt++; + } + } + // Check if the Particles are in contact and need friction applied + if (axbyczd < contactEpsilon) + { + curParticle->contacting = TRUE; + // Save the contact normal for later + memcpy(&curParticle->contactN,&plane->normal,sizeof(tVector)); + } + } + } + + return collisionState; +} + +void CPhysEnv::ResolveCollisions( tParticle *system ) +{ + tContact *contact; + tParticle *particle; // THE PARTICLE COLLIDING + float VdotN; + tVector Vn,Vt; // CONTACT RESOLUTION IMPULSE + contact = m_Contact; + for (int loop = 0; loop < m_ContactCnt; loop++,contact++) + { + particle = &system[contact->particle]; + // CALCULATE Vn + VdotN = DotProduct(&contact->normal,&particle->v); + ScaleVector(&contact->normal, VdotN, &Vn); + // CALCULATE Vt + VectorDifference(&particle->v, &Vn, &Vt); + // SCALE Vn BY COEFFICIENT OF RESTITUTION + ScaleVector(&Vn, m_Kr, &Vn); + // SET THE VELOCITY TO BE THE NEW IMPULSE + VectorDifference(&Vt, &Vn, &particle->v); + } +} + +void CPhysEnv::Simulate(float DeltaTime, BOOL running) +{ + float CurrentTime = 0.0f; + float TargetTime = DeltaTime; + tParticle *tempSys; + int collisionState; + + while(CurrentTime < DeltaTime) + { + if (running) + { + ComputeForces(m_CurrentSys, FALSE); + + // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK + // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, + // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. + // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY + if (m_CollisionRootFinding) + { + EulerIntegrate(TargetTime-CurrentTime); + } + else + { + switch (m_IntegratorType) + { + case EULER_INTEGRATOR: + EulerIntegrate(TargetTime-CurrentTime); + break; + case MIDPOINT_INTEGRATOR: + MidPointIntegrate(TargetTime-CurrentTime); + break; + case RK4_INTEGRATOR: + RK4Integrate(TargetTime-CurrentTime); + break; + } + } + } + + collisionState = CheckForCollisions(m_TargetSys); + + if(collisionState == PENETRATING) + { + // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER + m_CollisionRootFinding = TRUE; + // we simulated too far, so subdivide time and try again + TargetTime = (CurrentTime + TargetTime) / 2.0f; + + // blow up if we aren't moving forward each step, which is + // probably caused by interpenetration at the frame start + assert(fabs(TargetTime - CurrentTime) > EPSILON); + } + else + { + // either colliding or clear + if(collisionState == COLLIDING) + { + int Counter = 0; + do + { + ResolveCollisions(m_TargetSys); + Counter++; + } while((CheckForCollisions(m_TargetSys) == + COLLIDING) && (Counter < 100)); + + assert(Counter < 100); + m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT BACK TO NORMAL + } + + // we made a successful step, so swap configurations + // to "save" the data for the next step + + CurrentTime = TargetTime; + TargetTime = DeltaTime; + + // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN + tempSys = m_CurrentSys; + m_CurrentSys = m_TargetSys; + m_TargetSys = tempSys; + } + } +} diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.h index eb2c030..99d97ea 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/PhysEnv.h @@ -1,138 +1,138 @@ -#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) -#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// PhysEnv.h : header file -// -#include "MathDefs.h" - -#define EPSILON 0.00001f // ERROR TERM -#define DEFAULT_DAMPING 0.002f - -enum tCollisionTypes -{ - NOT_COLLIDING, - PENETRATING, - COLLIDING -}; - -enum tIntegratorTypes -{ - EULER_INTEGRATOR, - MIDPOINT_INTEGRATOR, - RK4_INTEGRATOR -}; - - -// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH -struct tCollisionPlane -{ - tVector normal; // inward pointing - float d; // ax + by + cz + d = 0 -}; - -// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM -struct tParticle -{ - tVector pos; // Position of Particle - tVector v; // Velocity of Particle - tVector f; // Force Acting on Particle - float oneOverM; // 1 / Mass of Particle - tVector contactN; // Normal of Contact - BOOL contacting; -}; - -// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM -struct tContact -{ - int particle; // Particle Index - tVector normal; // Normal of Collision plane - int type; // COLLIDING OR CONTACT -}; - -// TYPE FOR SPRINGS IN SYSTEM -struct tSpring -{ - int p1,p2; // PARTICLE INDEX FOR ENDS - float restLen; // LENGTH OF SPRING AT REST - float Ks; // SPRING CONSTANT - float Kd; // SPRING DAMPING -}; - -class CPhysEnv -{ -// Construction -public: - CPhysEnv(); - void RenderWorld(); - void SetWorldParticles(tVector *coords,int particleCnt); - void ResetWorld(); - void Simulate(float DeltaTime,BOOL running); - void ApplyUserForce(tVector *force); - void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); - void GetNearestPoint(int x, int y); - void AddSpring(); - void SetVertexMass(); - void SetWorldProperties(); - void FreeSystem(); - void LoadData(FILE *fp); - void SaveData(FILE *fp); - BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN - BOOL m_UseFriction; // SHOULD FRICTION BE USED - BOOL m_UseDamping; // SHOULD DAMPING BE ON - BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED - BOOL m_DrawSprings; // DRAW THE SPRING LINES - BOOL m_DrawVertices; // DRAW VERTICES - BOOL m_MouseForceActive; // MOUSE DRAG FORCE - BOOL m_CollisionRootFinding; // TRYING TO FIND A COLLISION - int m_IntegratorType; - -// Attributes -private: - float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; - tVector m_Gravity; // GRAVITY FORCE VECTOR - tVector m_UserForce; // USER FORCE VECTOR - float m_UserForceMag; // MAGNITUDE OF USER FORCE - float m_Kd; // DAMPING FACTOR - float m_Kr; // COEFFICIENT OF RESTITUTION - float m_Ksh; // HOOK'S SPRING CONSTANT - float m_Ksd; // SPRING DAMPING - float m_Csf, m_Ckf; // Static and Kinetic Friction - float m_MouseForceKs; // MOUSE SPRING COEFFICIENT - tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES - int m_CollisionPlaneCnt; - tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS - int m_ContactCnt; // COLLISION COUNT - tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES - tParticle *m_CurrentSys,*m_TargetSys; - tParticle *m_TempSys[5]; // SETUP FOR TEMP PARTICLES USED WHILE INTEGRATING - int m_ParticleCnt; - tSpring *m_Spring; // VALID SPRINGS IN SYSTEM - int m_SpringCnt; - int m_Pick[2]; // INDEX COUNTERS FOR SELECTING - tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR -// Operations -private: - void IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime); - void RK4Integrate( float DeltaTime); - void MidPointIntegrate( float DeltaTime); - void EulerIntegrate( float DeltaTime); - void ComputeForces( tParticle *system, BOOL duringIntegration ); - int CheckForCollisions( tParticle *system ); - void ResolveCollisions( tParticle *system ); - void CompareBuffer(int size, float *buffer,float x, float y); - -// Implementation -public: - virtual ~CPhysEnv(); - -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#if !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) +#define AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// PhysEnv.h : header file +// +#include "MathDefs.h" + +#define EPSILON 0.00001f // ERROR TERM +#define DEFAULT_DAMPING 0.002f + +enum tCollisionTypes +{ + NOT_COLLIDING, + PENETRATING, + COLLIDING +}; + +enum tIntegratorTypes +{ + EULER_INTEGRATOR, + MIDPOINT_INTEGRATOR, + RK4_INTEGRATOR +}; + + +// TYPE FOR A PLANE THAT THE SYSTEM WILL COLLIDE WITH +struct tCollisionPlane +{ + tVector normal; // inward pointing + float d; // ax + by + cz + d = 0 +}; + +// TYPE FOR A PHYSICAL PARTICLE IN THE SYSTEM +struct tParticle +{ + tVector pos; // Position of Particle + tVector v; // Velocity of Particle + tVector f; // Force Acting on Particle + float oneOverM; // 1 / Mass of Particle + tVector contactN; // Normal of Contact + BOOL contacting; +}; + +// TYPE FOR CONTACTS THAT ARE FOUND DURING SIM +struct tContact +{ + int particle; // Particle Index + tVector normal; // Normal of Collision plane + int type; // COLLIDING OR CONTACT +}; + +// TYPE FOR SPRINGS IN SYSTEM +struct tSpring +{ + int p1,p2; // PARTICLE INDEX FOR ENDS + float restLen; // LENGTH OF SPRING AT REST + float Ks; // SPRING CONSTANT + float Kd; // SPRING DAMPING +}; + +class CPhysEnv +{ +// Construction +public: + CPhysEnv(); + void RenderWorld(); + void SetWorldParticles(tVector *coords,int particleCnt); + void ResetWorld(); + void Simulate(float DeltaTime,BOOL running); + void ApplyUserForce(tVector *force); + void SetMouseForce(int deltaX,int deltaY, tVector *localX, tVector *localY); + void GetNearestPoint(int x, int y); + void AddSpring(); + void SetVertexMass(); + void SetWorldProperties(); + void FreeSystem(); + void LoadData(FILE *fp); + void SaveData(FILE *fp); + BOOL m_UseGravity; // SHOULD GRAVITY BE ADDED IN + BOOL m_UseFriction; // SHOULD FRICTION BE USED + BOOL m_UseDamping; // SHOULD DAMPING BE ON + BOOL m_UserForceActive; // WHEN USER FORCE IS APPLIED + BOOL m_DrawSprings; // DRAW THE SPRING LINES + BOOL m_DrawVertices; // DRAW VERTICES + BOOL m_MouseForceActive; // MOUSE DRAG FORCE + BOOL m_CollisionRootFinding; // TRYING TO FIND A COLLISION + int m_IntegratorType; + +// Attributes +private: + float m_WorldSizeX,m_WorldSizeY,m_WorldSizeZ; + tVector m_Gravity; // GRAVITY FORCE VECTOR + tVector m_UserForce; // USER FORCE VECTOR + float m_UserForceMag; // MAGNITUDE OF USER FORCE + float m_Kd; // DAMPING FACTOR + float m_Kr; // COEFFICIENT OF RESTITUTION + float m_Ksh; // HOOK'S SPRING CONSTANT + float m_Ksd; // SPRING DAMPING + float m_Csf, m_Ckf; // Static and Kinetic Friction + float m_MouseForceKs; // MOUSE SPRING COEFFICIENT + tCollisionPlane *m_CollisionPlane; // LIST OF COLLISION PLANES + int m_CollisionPlaneCnt; + tContact *m_Contact; // LIST OF POSSIBLE COLLISIONS + int m_ContactCnt; // COLLISION COUNT + tParticle *m_ParticleSys[3]; // LIST OF PHYSICAL PARTICLES + tParticle *m_CurrentSys,*m_TargetSys; + tParticle *m_TempSys[5]; // SETUP FOR TEMP PARTICLES USED WHILE INTEGRATING + int m_ParticleCnt; + tSpring *m_Spring; // VALID SPRINGS IN SYSTEM + int m_SpringCnt; + int m_Pick[2]; // INDEX COUNTERS FOR SELECTING + tVector m_MouseDragPos[2]; // POSITION OF DRAGGED MOUSE VECTOR +// Operations +private: + void IntegrateSysOverTime(tParticle *initial,tParticle *source, tParticle *target, float deltaTime); + void RK4Integrate( float DeltaTime); + void MidPointIntegrate( float DeltaTime); + void EulerIntegrate( float DeltaTime); + void ComputeForces( tParticle *system, BOOL duringIntegration ); + int CheckForCollisions( tParticle *system ); + void ResolveCollisions( tParticle *system ); + void CompareBuffer(int size, float *buffer,float x, float y); + +// Implementation +public: + virtual ~CPhysEnv(); + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PhysEnv_H__3DC11AC3_95FB_11D2_9D83_00105A124906__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/ReadMe.txt b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/ReadMe.txt index 0c63c33..8d06037 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/ReadMe.txt +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/ReadMe.txt @@ -1,108 +1,108 @@ -3D Real-time Soft Body Friction Demonstration July, 1999 --------------------------------------------------------- -v. 1.0 With Friction - -This is a quick demonstration to show how the Coulomb method -of dry friction can be applied to a dynamic simulation. - -The demo is built on the same soft body code from earlier in -the year. However, there have been some key changes. - -1. A contact model has been added. This required changing -the particle structure so models from the previous version will -not work. I create the cube and diamond for this demo. The -contact model checks to see if distance from the particle to the -contact surface is below the contactEpsilon threshold (currently 0.01f). -If so, the particle is marked and the contact normal is saved. - -2. Friction force is added via the Coulomb model during -ComputeForces. If the relative velocity is greater then the -threshold STATIC_THRESHOLD, the kinetic friction is applied. -Otherwise, static friction is used. - -Notes: - -In order to see the friction force in action, world damping -has been reduced. You can toggle friction on and off to -see how it halts the object (F key or Menu switch). - -Obviously particles are not the best thing for showing off -friction. Friction works better on rigid bodies with larger -masses. I will address this next month when I start building -a Billiards simulation with rigid spheres. - -In the meantime, you can play with the coefficients and -contact model. Switch integrators and see the effects. -If you are ambitions, add this into the cloth demo from -a few months ago to the sphere collision routines. - -Also think about creating a list of contacts and storing -friction coefficients with the contact. I wanted to do -it that way but ran out of time. - -Next month, the app will have a totally different look. -Much more like a production game with less MFC style stuff. -Brush up on your billiards... - -Jeff - -v. 1.0 Jan 1999 - -This program simulates soft body dynamics of a particle system -with particles connected with springs. - -This program is fairly complicated. In order to show off the -features I wanted to demonstrate, I needed to create quite a -number of functions and UI. I appologize for all the extra junk -but it was as clear as I could make it in the time allowed. -All the major functions for the actual dynamic simulation are in -the files: PhysEnv.h and PhysEnv.cpp. Some of the timing -and display code is in OGLView.h and OGLView.cpp. Most of -the UI is passed through MainFrm.cpp to OGLView. - -All of the simulation constants can be set through the -Simulation Properties dialog. Any changes to the spring constants -are applied to all springs in the simulation. There is currently -no way to change the settings for an individual spring. - -You can load in one of the pre-made simulations or create a -new one by loading in an OBJ. The OBJ needs to be scaled -within a +-5 unit cube world so it fits within the world boundaries. -An OBJ file loads as a point cloud. You then can connect the dots -by selecting vertices two at a time. Press "ENTER" to connect the -points with a spring. The normal length of the spring is the distance -at the time of spring creation. - -You can select one or two vertices and apply an user force to -the selected vertex/vertices. Once selected, a user force is -applied with the arrow keys for X-axis and Z-axis and HOME/END -applies the force to the Y-axis. The magnitude of the user force -is set in the sim properties dialog. - -You can also click and drag the LMB to apply a force in the local -X and Y axis. The mousespring force is set in the sim properties -dialog. The force will apply to the one or two vertices selected. - -Demos: - - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I compiled the code with Visual C++ 6.0. It has been tested -with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL -Drivers, Riva 128, TNT, TNT2, AccelGalaxy, -and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -Also, depending on how well GLlines are drawn on your system, the -sim should run too fast, too slow, or just right. I try to lock -it to the clock except to set the timesteps. If it is strange, -adjust COGLView::RunSim(). - +3D Real-time Soft Body Friction Demonstration July, 1999 +-------------------------------------------------------- +v. 1.0 With Friction + +This is a quick demonstration to show how the Coulomb method +of dry friction can be applied to a dynamic simulation. + +The demo is built on the same soft body code from earlier in +the year. However, there have been some key changes. + +1. A contact model has been added. This required changing +the particle structure so models from the previous version will +not work. I create the cube and diamond for this demo. The +contact model checks to see if distance from the particle to the +contact surface is below the contactEpsilon threshold (currently 0.01f). +If so, the particle is marked and the contact normal is saved. + +2. Friction force is added via the Coulomb model during +ComputeForces. If the relative velocity is greater then the +threshold STATIC_THRESHOLD, the kinetic friction is applied. +Otherwise, static friction is used. + +Notes: + +In order to see the friction force in action, world damping +has been reduced. You can toggle friction on and off to +see how it halts the object (F key or Menu switch). + +Obviously particles are not the best thing for showing off +friction. Friction works better on rigid bodies with larger +masses. I will address this next month when I start building +a Billiards simulation with rigid spheres. + +In the meantime, you can play with the coefficients and +contact model. Switch integrators and see the effects. +If you are ambitions, add this into the cloth demo from +a few months ago to the sphere collision routines. + +Also think about creating a list of contacts and storing +friction coefficients with the contact. I wanted to do +it that way but ran out of time. + +Next month, the app will have a totally different look. +Much more like a production game with less MFC style stuff. +Brush up on your billiards... + +Jeff + +v. 1.0 Jan 1999 + +This program simulates soft body dynamics of a particle system +with particles connected with springs. + +This program is fairly complicated. In order to show off the +features I wanted to demonstrate, I needed to create quite a +number of functions and UI. I appologize for all the extra junk +but it was as clear as I could make it in the time allowed. +All the major functions for the actual dynamic simulation are in +the files: PhysEnv.h and PhysEnv.cpp. Some of the timing +and display code is in OGLView.h and OGLView.cpp. Most of +the UI is passed through MainFrm.cpp to OGLView. + +All of the simulation constants can be set through the +Simulation Properties dialog. Any changes to the spring constants +are applied to all springs in the simulation. There is currently +no way to change the settings for an individual spring. + +You can load in one of the pre-made simulations or create a +new one by loading in an OBJ. The OBJ needs to be scaled +within a +-5 unit cube world so it fits within the world boundaries. +An OBJ file loads as a point cloud. You then can connect the dots +by selecting vertices two at a time. Press "ENTER" to connect the +points with a spring. The normal length of the spring is the distance +at the time of spring creation. + +You can select one or two vertices and apply an user force to +the selected vertex/vertices. Once selected, a user force is +applied with the arrow keys for X-axis and Z-axis and HOME/END +applies the force to the Y-axis. The magnitude of the user force +is set in the sim properties dialog. + +You can also click and drag the LMB to apply a force in the local +X and Y axis. The mousespring force is set in the sim properties +dialog. The force will apply to the one or two vertices selected. + +Demos: + + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I compiled the code with Visual C++ 6.0. It has been tested +with Microsoft OpenGL, SGI OpenGL for Windows, Permidia 1 and 2 OpenGL +Drivers, Riva 128, TNT, TNT2, AccelGalaxy, +and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +Also, depending on how well GLlines are drawn on your system, the +sim should run too fast, too slow, or just right. I try to lock +it to the clock except to set the timesteps. If it is strange, +adjust COGLView::RunSim(). + diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.cpp index 60bab39..79006ea 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.cpp @@ -1,62 +1,62 @@ -// SimProps.cpp : implementation file -// - -#include "stdafx.h" -#include "Friction.h" -#include "SimProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - - -CSimProps::CSimProps(CWnd* pParent /*=NULL*/) - : CDialog(CSimProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSimProps) - m_CoefRest = 0.0f; - m_Damping = 0.0f; - m_GravX = 0.0f; - m_GravY = 0.0f; - m_GravZ = 0.0f; - m_SpringConst = 0.0f; - m_SpringDamp = 0.0f; - m_UserForceMag = 0.0f; - m_MouseSpring = 0.0f; - m_CoefKineticFriction = 0.0f; - m_CoefStaticFriction = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSimProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSimProps) - DDX_Text(pDX, IDC_COEFREST, m_CoefRest); - DDX_Text(pDX, IDC_Damping, m_Damping); - DDX_Text(pDX, IDC_GRAVX, m_GravX); - DDX_Text(pDX, IDC_GRAVY, m_GravY); - DDX_Text(pDX, IDC_GRAVZ, m_GravZ); - DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); - DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); - DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); - DDX_Text(pDX, IDC_MOUSESPRING, m_MouseSpring); - DDX_Text(pDX, IDC_KINETICFRICTION, m_CoefKineticFriction); - DDX_Text(pDX, IDC_STATICFRICTION, m_CoefStaticFriction); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSimProps, CDialog) - //{{AFX_MSG_MAP(CSimProps) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSimProps message handlers +// SimProps.cpp : implementation file +// + +#include "stdafx.h" +#include "Friction.h" +#include "SimProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + + +CSimProps::CSimProps(CWnd* pParent /*=NULL*/) + : CDialog(CSimProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSimProps) + m_CoefRest = 0.0f; + m_Damping = 0.0f; + m_GravX = 0.0f; + m_GravY = 0.0f; + m_GravZ = 0.0f; + m_SpringConst = 0.0f; + m_SpringDamp = 0.0f; + m_UserForceMag = 0.0f; + m_MouseSpring = 0.0f; + m_CoefKineticFriction = 0.0f; + m_CoefStaticFriction = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSimProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSimProps) + DDX_Text(pDX, IDC_COEFREST, m_CoefRest); + DDX_Text(pDX, IDC_Damping, m_Damping); + DDX_Text(pDX, IDC_GRAVX, m_GravX); + DDX_Text(pDX, IDC_GRAVY, m_GravY); + DDX_Text(pDX, IDC_GRAVZ, m_GravZ); + DDX_Text(pDX, IDC_SPRINGCONST, m_SpringConst); + DDX_Text(pDX, IDC_SPRINGDAMP, m_SpringDamp); + DDX_Text(pDX, IDC_USERFORCEMAG, m_UserForceMag); + DDX_Text(pDX, IDC_MOUSESPRING, m_MouseSpring); + DDX_Text(pDX, IDC_KINETICFRICTION, m_CoefKineticFriction); + DDX_Text(pDX, IDC_STATICFRICTION, m_CoefStaticFriction); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSimProps, CDialog) + //{{AFX_MSG_MAP(CSimProps) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSimProps message handlers diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.h index 80ef5f5..0d4f11a 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/SimProps.h @@ -1,55 +1,55 @@ -#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) -#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// SimProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSimProps dialog - -class CSimProps : public CDialog -{ -// Construction -public: - CSimProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSimProps) - enum { IDD = IDD_SIMPROP }; - float m_CoefRest; - float m_Damping; - float m_GravX; - float m_GravY; - float m_GravZ; - float m_SpringConst; - float m_SpringDamp; - float m_UserForceMag; - float m_MouseSpring; - float m_CoefKineticFriction; - float m_CoefStaticFriction; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSimProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSimProps) - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#if !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) +#define AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// SimProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSimProps dialog + +class CSimProps : public CDialog +{ +// Construction +public: + CSimProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSimProps) + enum { IDD = IDD_SIMPROP }; + float m_CoefRest; + float m_Damping; + float m_GravX; + float m_GravY; + float m_GravZ; + float m_SpringConst; + float m_SpringDamp; + float m_UserForceMag; + float m_MouseSpring; + float m_CoefKineticFriction; + float m_CoefStaticFriction; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSimProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSimProps) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SIMPROPS_H__6D91A591_983A_11D2_9D88_00105A124906__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.cpp index 68cf8c4..ac13a71 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.cpp @@ -1,166 +1,166 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { -// free(child->primChannel); - child->primChannel = NULL; - } - if (child->visualCnt > 0) - { - free(child->visuals->vertexData); - if (child->visuals->faceIndex) - free(child->visuals->faceIndex); - free(child->visuals); - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - if (root->visualCnt > 0) - { - free(root->visuals->vertexData); - if (root->visuals->faceIndex) - free(root->visuals->faceIndex); - free(root->visuals); - } - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { +// free(child->primChannel); + child->primChannel = NULL; + } + if (child->visualCnt > 0) + { + free(child->visuals->vertexData); + if (child->visuals->faceIndex) + free(child->visuals->faceIndex); + free(child->visuals); + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + if (root->visualCnt > 0) + { + free(root->visuals->vertexData); + if (root->visuals->faceIndex) + free(root->visuals->faceIndex); + free(root->visuals); + } + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.h index 46b5d27..87139bd 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/Skeleton.h @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -#define ushort unsigned short -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -#include "MathDefs.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -struct t_Visual -{ - int dataFormat; - float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT - long vertexCnt; // NUMBER OF VERTICES IN VISUAL - BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS - ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED - int vSize; // NUMBER OF FLOATS IN A VERTEX - long faceCnt; // NUMBER OF FACES IN VISUAL - tVector *faceNormal; // POINTER TO FACE NORMALS - long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 - tVector Ka,Kd,Ks; // COLOR FOR OBJECT - float Ns; // SPECULAR COEFFICIENT - char map[255]; - int glTex; - tVector bbox[8]; // BBOX COORDS - tVector transBBox[8]; -}; - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - t_Visual *visuals; // POINTER TO VISUALS/BITMAPS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +#define ushort unsigned short +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +#include "MathDefs.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +struct t_Visual +{ + int dataFormat; + float *vertexData; // INTERLEAVED VERTEX DATA IN DATAFORMAT + long vertexCnt; // NUMBER OF VERTICES IN VISUAL + BOOL reuseVertices; // DO I WANT TO USED INDEXED ARRAYS + ushort *faceIndex; // INDEXED VERTEX DATA IF VERTICES ARE REUSED + int vSize; // NUMBER OF FLOATS IN A VERTEX + long faceCnt; // NUMBER OF FACES IN VISUAL + tVector *faceNormal; // POINTER TO FACE NORMALS + long vPerFace; // VERTICES PER FACE, EITHER 3 OR 4 + tVector Ka,Kd,Ks; // COLOR FOR OBJECT + float Ns; // SPECULAR COEFFICIENT + char map[255]; + int glTex; + tVector bbox[8]; // BBOX COORDS + tVector transBBox[8]; +}; + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + long primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + long secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + t_Visual *visuals; // POINTER TO VISUALS/BITMAPS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.cpp index 7144a67..2673f5f 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Friction.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Friction.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.h index ddefdab..571c76c 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.cpp index ca7e8c1..a4e51fa 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.cpp @@ -1,48 +1,48 @@ -// TimeProps.cpp : implementation file -// - -#include "stdafx.h" -#include "Friction.h" -#include "TimeProps.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - - -CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) - : CDialog(CTimeProps::IDD, pParent) -{ - //{{AFX_DATA_INIT(CTimeProps) - m_FixedTimeSteps = FALSE; - m_Iterations = 0; - m_MaxTimeStep = 0.0f; - //}}AFX_DATA_INIT -} - - -void CTimeProps::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CTimeProps) - DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); - DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); - DDV_MinMaxInt(pDX, m_Iterations, 1, 100); - DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CTimeProps, CDialog) - //{{AFX_MSG_MAP(CTimeProps) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps message handlers +// TimeProps.cpp : implementation file +// + +#include "stdafx.h" +#include "Friction.h" +#include "TimeProps.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + + +CTimeProps::CTimeProps(CWnd* pParent /*=NULL*/) + : CDialog(CTimeProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTimeProps) + m_FixedTimeSteps = FALSE; + m_Iterations = 0; + m_MaxTimeStep = 0.0f; + //}}AFX_DATA_INIT +} + + +void CTimeProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTimeProps) + DDX_Check(pDX, IDC_FIXEDTIME, m_FixedTimeSteps); + DDX_Text(pDX, IDC_ITERATIONS, m_Iterations); + DDV_MinMaxInt(pDX, m_Iterations, 1, 100); + DDX_Text(pDX, IDC_MAXTIMESTEP, m_MaxTimeStep); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CTimeProps, CDialog) + //{{AFX_MSG_MAP(CTimeProps) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps message handlers diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.h index 07041d8..2222823 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/TimeProps.h @@ -1,48 +1,48 @@ -#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// TimeProps.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CTimeProps dialog - -class CTimeProps : public CDialog -{ -// Construction -public: - CTimeProps(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CTimeProps) - enum { IDD = IDD_SIMTIMING }; - BOOL m_FixedTimeSteps; - int m_Iterations; - float m_MaxTimeStep; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CTimeProps) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CTimeProps) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// TimeProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CTimeProps dialog + +class CTimeProps : public CDialog +{ +// Construction +public: + CTimeProps(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTimeProps) + enum { IDD = IDD_SIMTIMING }; + BOOL m_FixedTimeSteps; + int m_Iterations; + float m_MaxTimeStep; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTimeProps) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CTimeProps) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TIMEPROPS_H__A1CA3701_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.cpp b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.cpp index 55eef21..8ff7d8c 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.cpp +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.cpp @@ -1,43 +1,43 @@ -// VertMass.cpp : implementation file -// - -#include "stdafx.h" -#include "Friction.h" -#include "VertMass.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CVertMass dialog - - -CVertMass::CVertMass(CWnd* pParent /*=NULL*/) - : CDialog(CVertMass::IDD, pParent) -{ - //{{AFX_DATA_INIT(CVertMass) - m_VertexMass = 0.0f; - //}}AFX_DATA_INIT -} - - -void CVertMass::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CVertMass) - DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CVertMass, CDialog) - //{{AFX_MSG_MAP(CVertMass) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CVertMass message handlers +// VertMass.cpp : implementation file +// + +#include "stdafx.h" +#include "Friction.h" +#include "VertMass.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CVertMass dialog + + +CVertMass::CVertMass(CWnd* pParent /*=NULL*/) + : CDialog(CVertMass::IDD, pParent) +{ + //{{AFX_DATA_INIT(CVertMass) + m_VertexMass = 0.0f; + //}}AFX_DATA_INIT +} + + +void CVertMass::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CVertMass) + DDX_Text(pDX, IDC_VERTEXMASS, m_VertexMass); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CVertMass, CDialog) + //{{AFX_MSG_MAP(CVertMass) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CVertMass message handlers diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.h index d721109..57035f5 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/VertMass.h @@ -1,46 +1,46 @@ -#if !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) -#define AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// VertMass.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CVertMass dialog - -class CVertMass : public CDialog -{ -// Construction -public: - CVertMass(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CVertMass) - enum { IDD = IDD_VERTEXMASS }; - float m_VertexMass; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CVertMass) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CVertMass) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#if !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) +#define AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// VertMass.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CVertMass dialog + +class CVertMass : public CDialog +{ +// Construction +public: + CVertMass(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CVertMass) + enum { IDD = IDD_VERTEXMASS }; + float m_VertexMass; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CVertMass) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CVertMass) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_VERTMASS_H__A1CA3700_C1F8_11D2_8A1C_00105A124906__INCLUDED_) diff --git a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/resource.h b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/resource.h index 3321b06..bbfcf6e 100644 --- a/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/resource.h +++ b/The Trials of Tribology- Friction Forces in the Particle System/Code/OGL/Friction/resource.h @@ -1,83 +1,83 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Friction.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_FRICTIONTYPE 129 -#define IDD_SETROTATE 130 -#define IDB_HUP 131 -#define IDB_HDN 132 -#define IDD_DIALOG1 132 -#define IDB_HUPP 133 -#define IDD_LOADOBJ 133 -#define IDD_PICKOBJ 133 -#define IDB_HDNP 134 -#define IDD_SIMPROP 134 -#define IDB_VDN 135 -#define IDD_VERTEXMASS 135 -#define IDB_VUP 136 -#define IDD_SIMTIMING 136 -#define IDB_VUPP 137 -#define IDB_VDNP 138 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_BUTTON1 1001 -#define IDC_BROWSE1 1001 -#define IDC_ZAXIS 1002 -#define IDC_BROWSE2 1002 -#define IDC_SLIDER1 1003 -#define IDC_EDIT1 1004 -#define IDC_GRAVX 1004 -#define IDC_MAXTIMESTEP 1004 -#define IDC_EDIT2 1005 -#define IDC_OBJLIST 1005 -#define IDC_GRAVY 1005 -#define IDC_ITERATIONS 1005 -#define IDC_GRAVZ 1006 -#define IDC_COEFREST 1007 -#define IDC_SPRINGCONST 1008 -#define IDC_Damping 1009 -#define IDC_SPRINGDAMP 1010 -#define IDC_USERFORCEMAG 1011 -#define IDC_VERTEXMASS 1012 -#define IDC_KINETICFRICTION 1012 -#define IDC_MOUSESPRING 1013 -#define IDC_FIXEDTIME 1014 -#define IDC_STATICFRICTION 1014 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_METHOD_FASTBBOX 32775 -#define ID_VIEW_SHOWBBOX 32776 -#define ID_VIEW_SHOWOBBOX 32777 -#define ID_VIEW_SHOWSPRINGS 32778 -#define ID_VIEW_SHOWGEOMETRY 32779 -#define ID_SIMULATION_RUNNING 32780 -#define ID_SIMULATION_RESET 32781 -#define ID_SIMULATION_SETSIMPROPERTIES 32782 -#define ID_SIMULATION_USEGRAVITY 32783 -#define ID_VIEW_SHOWVERTICES 32785 -#define ID_FILE_NEWSYSTEM 32786 -#define ID_SIMULATION_SETVERTEXMASS 32787 -#define ID_SIMULATION_SETTIMINGPROPERTIES 32788 -#define ID_INTEGRATOR_EULER 32789 -#define ID_INTEGRATOR_MIDPOINT 32790 -#define ID_INTEGRATOR_RUNGEKUTTA4 32791 -#define ID_SIMULATION_USEFRICTION 32792 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 137 -#define _APS_NEXT_COMMAND_VALUE 32793 -#define _APS_NEXT_CONTROL_VALUE 1015 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Friction.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_FRICTIONTYPE 129 +#define IDD_SETROTATE 130 +#define IDB_HUP 131 +#define IDB_HDN 132 +#define IDD_DIALOG1 132 +#define IDB_HUPP 133 +#define IDD_LOADOBJ 133 +#define IDD_PICKOBJ 133 +#define IDB_HDNP 134 +#define IDD_SIMPROP 134 +#define IDB_VDN 135 +#define IDD_VERTEXMASS 135 +#define IDB_VUP 136 +#define IDD_SIMTIMING 136 +#define IDB_VUPP 137 +#define IDB_VDNP 138 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_BUTTON1 1001 +#define IDC_BROWSE1 1001 +#define IDC_ZAXIS 1002 +#define IDC_BROWSE2 1002 +#define IDC_SLIDER1 1003 +#define IDC_EDIT1 1004 +#define IDC_GRAVX 1004 +#define IDC_MAXTIMESTEP 1004 +#define IDC_EDIT2 1005 +#define IDC_OBJLIST 1005 +#define IDC_GRAVY 1005 +#define IDC_ITERATIONS 1005 +#define IDC_GRAVZ 1006 +#define IDC_COEFREST 1007 +#define IDC_SPRINGCONST 1008 +#define IDC_Damping 1009 +#define IDC_SPRINGDAMP 1010 +#define IDC_USERFORCEMAG 1011 +#define IDC_VERTEXMASS 1012 +#define IDC_KINETICFRICTION 1012 +#define IDC_MOUSESPRING 1013 +#define IDC_FIXEDTIME 1014 +#define IDC_STATICFRICTION 1014 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_METHOD_FASTBBOX 32775 +#define ID_VIEW_SHOWBBOX 32776 +#define ID_VIEW_SHOWOBBOX 32777 +#define ID_VIEW_SHOWSPRINGS 32778 +#define ID_VIEW_SHOWGEOMETRY 32779 +#define ID_SIMULATION_RUNNING 32780 +#define ID_SIMULATION_RESET 32781 +#define ID_SIMULATION_SETSIMPROPERTIES 32782 +#define ID_SIMULATION_USEGRAVITY 32783 +#define ID_VIEW_SHOWVERTICES 32785 +#define ID_FILE_NEWSYSTEM 32786 +#define ID_SIMULATION_SETVERTEXMASS 32787 +#define ID_SIMULATION_SETTIMINGPROPERTIES 32788 +#define ID_INTEGRATOR_EULER 32789 +#define ID_INTEGRATOR_MIDPOINT 32790 +#define ID_INTEGRATOR_RUNGEKUTTA4 32791 +#define ID_SIMULATION_USEFRICTION 32792 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 137 +#define _APS_NEXT_COMMAND_VALUE 32793 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.cpp index 03d1895..a75aae8 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.cpp @@ -1,349 +1,349 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Quaternion Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Slash.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - ON_COMMAND(ID_ENDKEY, OnEndkey) - ON_COMMAND(ID_CONTROL_UPPERARM, OnControlUpperarm) - ON_UPDATE_COMMAND_UI(ID_CONTROL_UPPERARM, OnUpdateControlUpperarm) - ON_COMMAND(ID_CONTROL_LOWERARM, OnControlLowerarm) - ON_UPDATE_COMMAND_UI(ID_CONTROL_LOWERARM, OnUpdateControlLowerarm) - ON_COMMAND(ID_CONTROL_HAND, OnControlHand) - ON_UPDATE_COMMAND_UI(ID_CONTROL_HAND, OnUpdateControlHand) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_STATUS, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_ROT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_QUAT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - - InitializeSkeleton(); -} - -CMainFrame::~CMainFrame() -{ - DestroySkeleton(&m_Skeleton); -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_Slider.Create(TBS_NOTICKS | TBS_BOTH | WS_CHILD | WS_VISIBLE, CRect(1, rect.bottom - 40,rect.right - 3,rect.bottom - 20),this,105); - - m_Slider.ShowWindow(TRUE); - - m_Slider.Invalidate(TRUE); - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Skeleton,&m_Slider); - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 46 , SWP_NOZORDER ); // -60 bottom - m_Slider.SetWindowPos( &wndTopMost, 1, cy - 44, cx - 3, 25 , SWP_NOZORDER ); // -60 bottom - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions -void CMainFrame::LoadObjectFile(char *filename,t_Bone *bonePtr) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; - tObjDesc *desc; /* Pointer to Desc */ - tObjFrame *frame; /* Pointer to Desc */ - short loop2; - char tempstr[80]; -/////////////////////////////////////////////////////////////////////////////// - - fp = fopen(filename,"rb"); - if (fp != NULL) - { - fread(tempstr,1,4,fp); // FDAT - if (strncmp(tempstr,"DARW",4)!= 0) - { - MessageBox("Not a Valid DGF File","Load File", MB_OK|MB_ICONEXCLAMATION); - return; - } - fread(tempstr,1,4,fp); // FDAT - - fread(bonePtr,sizeof(t_Bone),1,fp); - fread(tempstr,1,4,fp); // FDAT - bonePtr->desc = (tObjDesc *)malloc(sizeof(tObjDesc)); - desc = bonePtr->desc; - fread(desc,sizeof(tObjDesc),1,fp); - for (loop2 = 0; loop2 < desc->frameCnt; loop2++) - { - fread(tempstr,1,4,fp); // FDAT - desc->frame[loop2] = (tObjFrame *)malloc(sizeof(tObjFrame)); - frame = desc->frame[loop2]; - fread(frame,sizeof(tObjFrame),1,fp); - frame->data = (float *)malloc(sizeof(float) * desc->dataSize * desc->pointCnt); - fread(frame->data,sizeof(float),desc->dataSize * desc->pointCnt,fp); - } - bonePtr->cur_desc = 0; - fclose(fp); - } -} - -void CMainFrame::InitializeSkeleton() -{ - -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *tempBones; -/////////////////////////////////////////////////////////////////////////////// - - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.p_trans.x = 5.0f; - m_Skeleton.p_trans.y = -4.0f; - m_Skeleton.p_trans.z = -10.0f; - m_Skeleton.trans.x = 5.0f; - m_Skeleton.trans.y = -4.0f; - m_Skeleton.trans.z = -10.0f; - - // ALLOC ROOM FOR BONES - tempBones = (t_Bone *)malloc(3 * sizeof(t_Bone)); - - ResetBone(&tempBones[0], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - ResetBone(&tempBones[1], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - ResetBone(&tempBones[2], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - - m_Skeleton.childCnt = 1; - m_Skeleton.children = tempBones; - - // THIS IS THE BONE FOR THE UPPER ARM - LoadObjectFile("uparm.dgf",&tempBones[0]); - strcpy(tempBones[0].name,"UpperArm"); - tempBones[0].id = 100; // GIVE IT A UNIQUE ID - tempBones[0].childCnt = 1; - tempBones[0].children = &tempBones[1]; - tempBones[0].trans.x = 0.0; - tempBones[0].trans.y = 0.0; - tempBones[0].trans.z = 0.0; - // SET UP SOME NICE DEFAULT MOVES - tempBones[0].rot.x = 35.0; - tempBones[0].rot.y = -40.0; - tempBones[0].rot.z = 0.0; - tempBones[0].p_rot.x = 35.0; - tempBones[0].p_rot.y = -40.0; - tempBones[0].p_rot.z = 0.0; - tempBones[0].s_rot.x = -1.0; - tempBones[0].s_rot.y = 40.0; - tempBones[0].s_rot.z = 0.0; - - // THIS IS THE BONE FOR THE LOWER ARM - LoadObjectFile("lowarm.dgf",&tempBones[1]); - strcpy(tempBones[1].name,"LowerArm"); - tempBones[1].id = 101; // GIVE IT A UNIQUE ID - tempBones[1].trans.x = 0.0; - tempBones[1].trans.y = 0.0; - // SET UP SOME NICE DEFAULT MOVES - tempBones[1].trans.z = -5.0; - tempBones[1].rot.x = -332.0; - tempBones[1].rot.y = 27.0; - tempBones[1].rot.z = -253.0; - tempBones[1].p_rot.x = -332.0; - tempBones[1].p_rot.y = 27.0; - tempBones[1].p_rot.z = -253.0; - tempBones[1].s_rot.x = -6.0; - tempBones[1].s_rot.y = 51.0; - tempBones[1].s_rot.z = 0.0; - tempBones[1].childCnt = 1; - tempBones[1].children = &tempBones[2]; - - // THIS IS THE BONE FOR THE HAND - LoadObjectFile("hand.dgf",&tempBones[2]); - strcpy(tempBones[2].name,"Hand"); - tempBones[2].id = 102; // GIVE IT A UNIQUE ID - tempBones[2].trans.x = 0.0; - tempBones[2].trans.y = 0.0; - tempBones[2].trans.z = -4.0; - // SET UP SOME NICE DEFAULT MOVES - tempBones[2].rot.x = -21.0; - tempBones[2].rot.y = -47.0; - tempBones[2].rot.z = -35.0; - tempBones[2].p_rot.x = -21.0; - tempBones[2].p_rot.y = 12.0; - tempBones[2].p_rot.z = -47.0; - tempBones[2].s_rot.x = -22.0; - tempBones[2].s_rot.y = -7.0; - tempBones[2].s_rot.z = -84.0; -} - -void CMainFrame::OnEndkey() -{ - m_OGLView.SetEndKey(); -} - -// SELECTION CONTROLS FOR THE MENU OPTIONS -// THESE ROUTINES CONTROL WHICH BONE IS UNDER UI CONTROL -void CMainFrame::OnControlUpperarm() -{ - m_OGLView.m_CurBone = &m_Skeleton.children[0]; -} - -void CMainFrame::OnUpdateControlUpperarm(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(m_OGLView.m_CurBone == &m_Skeleton.children[0]); -} - -void CMainFrame::OnControlLowerarm() -{ - m_OGLView.m_CurBone = &m_Skeleton.children[1]; -} - -void CMainFrame::OnUpdateControlLowerarm(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(m_OGLView.m_CurBone == &m_Skeleton.children[1]); -} - -void CMainFrame::OnControlHand() -{ - m_OGLView.m_CurBone = &m_Skeleton.children[2]; -} - -void CMainFrame::OnUpdateControlHand(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck(m_OGLView.m_CurBone == &m_Skeleton.children[2]); -} +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Quaternion Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Slash.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + ON_COMMAND(ID_ENDKEY, OnEndkey) + ON_COMMAND(ID_CONTROL_UPPERARM, OnControlUpperarm) + ON_UPDATE_COMMAND_UI(ID_CONTROL_UPPERARM, OnUpdateControlUpperarm) + ON_COMMAND(ID_CONTROL_LOWERARM, OnControlLowerarm) + ON_UPDATE_COMMAND_UI(ID_CONTROL_LOWERARM, OnUpdateControlLowerarm) + ON_COMMAND(ID_CONTROL_HAND, OnControlHand) + ON_UPDATE_COMMAND_UI(ID_CONTROL_HAND, OnUpdateControlHand) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_STATUS, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_ROT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_QUAT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + + InitializeSkeleton(); +} + +CMainFrame::~CMainFrame() +{ + DestroySkeleton(&m_Skeleton); +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_Slider.Create(TBS_NOTICKS | TBS_BOTH | WS_CHILD | WS_VISIBLE, CRect(1, rect.bottom - 40,rect.right - 3,rect.bottom - 20),this,105); + + m_Slider.ShowWindow(TRUE); + + m_Slider.Invalidate(TRUE); + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Skeleton,&m_Slider); + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 46 , SWP_NOZORDER ); // -60 bottom + m_Slider.SetWindowPos( &wndTopMost, 1, cy - 44, cx - 3, 25 , SWP_NOZORDER ); // -60 bottom + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions +void CMainFrame::LoadObjectFile(char *filename,t_Bone *bonePtr) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; + tObjDesc *desc; /* Pointer to Desc */ + tObjFrame *frame; /* Pointer to Desc */ + short loop2; + char tempstr[80]; +/////////////////////////////////////////////////////////////////////////////// + + fp = fopen(filename,"rb"); + if (fp != NULL) + { + fread(tempstr,1,4,fp); // FDAT + if (strncmp(tempstr,"DARW",4)!= 0) + { + MessageBox("Not a Valid DGF File","Load File", MB_OK|MB_ICONEXCLAMATION); + return; + } + fread(tempstr,1,4,fp); // FDAT + + fread(bonePtr,sizeof(t_Bone),1,fp); + fread(tempstr,1,4,fp); // FDAT + bonePtr->desc = (tObjDesc *)malloc(sizeof(tObjDesc)); + desc = bonePtr->desc; + fread(desc,sizeof(tObjDesc),1,fp); + for (loop2 = 0; loop2 < desc->frameCnt; loop2++) + { + fread(tempstr,1,4,fp); // FDAT + desc->frame[loop2] = (tObjFrame *)malloc(sizeof(tObjFrame)); + frame = desc->frame[loop2]; + fread(frame,sizeof(tObjFrame),1,fp); + frame->data = (float *)malloc(sizeof(float) * desc->dataSize * desc->pointCnt); + fread(frame->data,sizeof(float),desc->dataSize * desc->pointCnt,fp); + } + bonePtr->cur_desc = 0; + fclose(fp); + } +} + +void CMainFrame::InitializeSkeleton() +{ + +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *tempBones; +/////////////////////////////////////////////////////////////////////////////// + + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.p_trans.x = 5.0f; + m_Skeleton.p_trans.y = -4.0f; + m_Skeleton.p_trans.z = -10.0f; + m_Skeleton.trans.x = 5.0f; + m_Skeleton.trans.y = -4.0f; + m_Skeleton.trans.z = -10.0f; + + // ALLOC ROOM FOR BONES + tempBones = (t_Bone *)malloc(3 * sizeof(t_Bone)); + + ResetBone(&tempBones[0], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + ResetBone(&tempBones[1], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + ResetBone(&tempBones[2], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + + m_Skeleton.childCnt = 1; + m_Skeleton.children = tempBones; + + // THIS IS THE BONE FOR THE UPPER ARM + LoadObjectFile("uparm.dgf",&tempBones[0]); + strcpy(tempBones[0].name,"UpperArm"); + tempBones[0].id = 100; // GIVE IT A UNIQUE ID + tempBones[0].childCnt = 1; + tempBones[0].children = &tempBones[1]; + tempBones[0].trans.x = 0.0; + tempBones[0].trans.y = 0.0; + tempBones[0].trans.z = 0.0; + // SET UP SOME NICE DEFAULT MOVES + tempBones[0].rot.x = 35.0; + tempBones[0].rot.y = -40.0; + tempBones[0].rot.z = 0.0; + tempBones[0].p_rot.x = 35.0; + tempBones[0].p_rot.y = -40.0; + tempBones[0].p_rot.z = 0.0; + tempBones[0].s_rot.x = -1.0; + tempBones[0].s_rot.y = 40.0; + tempBones[0].s_rot.z = 0.0; + + // THIS IS THE BONE FOR THE LOWER ARM + LoadObjectFile("lowarm.dgf",&tempBones[1]); + strcpy(tempBones[1].name,"LowerArm"); + tempBones[1].id = 101; // GIVE IT A UNIQUE ID + tempBones[1].trans.x = 0.0; + tempBones[1].trans.y = 0.0; + // SET UP SOME NICE DEFAULT MOVES + tempBones[1].trans.z = -5.0; + tempBones[1].rot.x = -332.0; + tempBones[1].rot.y = 27.0; + tempBones[1].rot.z = -253.0; + tempBones[1].p_rot.x = -332.0; + tempBones[1].p_rot.y = 27.0; + tempBones[1].p_rot.z = -253.0; + tempBones[1].s_rot.x = -6.0; + tempBones[1].s_rot.y = 51.0; + tempBones[1].s_rot.z = 0.0; + tempBones[1].childCnt = 1; + tempBones[1].children = &tempBones[2]; + + // THIS IS THE BONE FOR THE HAND + LoadObjectFile("hand.dgf",&tempBones[2]); + strcpy(tempBones[2].name,"Hand"); + tempBones[2].id = 102; // GIVE IT A UNIQUE ID + tempBones[2].trans.x = 0.0; + tempBones[2].trans.y = 0.0; + tempBones[2].trans.z = -4.0; + // SET UP SOME NICE DEFAULT MOVES + tempBones[2].rot.x = -21.0; + tempBones[2].rot.y = -47.0; + tempBones[2].rot.z = -35.0; + tempBones[2].p_rot.x = -21.0; + tempBones[2].p_rot.y = 12.0; + tempBones[2].p_rot.z = -47.0; + tempBones[2].s_rot.x = -22.0; + tempBones[2].s_rot.y = -7.0; + tempBones[2].s_rot.z = -84.0; +} + +void CMainFrame::OnEndkey() +{ + m_OGLView.SetEndKey(); +} + +// SELECTION CONTROLS FOR THE MENU OPTIONS +// THESE ROUTINES CONTROL WHICH BONE IS UNDER UI CONTROL +void CMainFrame::OnControlUpperarm() +{ + m_OGLView.m_CurBone = &m_Skeleton.children[0]; +} + +void CMainFrame::OnUpdateControlUpperarm(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_OGLView.m_CurBone == &m_Skeleton.children[0]); +} + +void CMainFrame::OnControlLowerarm() +{ + m_OGLView.m_CurBone = &m_Skeleton.children[1]; +} + +void CMainFrame::OnUpdateControlLowerarm(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_OGLView.m_CurBone == &m_Skeleton.children[1]); +} + +void CMainFrame::OnControlHand() +{ + m_OGLView.m_CurBone = &m_Skeleton.children[2]; +} + +void CMainFrame::OnUpdateControlHand(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_OGLView.m_CurBone == &m_Skeleton.children[2]); +} diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.h index e17e986..380fdb9 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/MainFrm.h @@ -1,92 +1,92 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Slider.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - CSlider m_Slider; - -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - void LoadObjectFile(char *filename,t_Bone *bonePtr); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnHelpWhichopengl(); - afx_msg void OnEndkey(); - afx_msg void OnControlUpperarm(); - afx_msg void OnUpdateControlUpperarm(CCmdUI* pCmdUI); - afx_msg void OnControlLowerarm(); - afx_msg void OnUpdateControlLowerarm(CCmdUI* pCmdUI); - afx_msg void OnControlHand(); - afx_msg void OnUpdateControlHand(CCmdUI* pCmdUI); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Slider.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + CSlider m_Slider; + +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + void LoadObjectFile(char *filename,t_Bone *bonePtr); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnHelpWhichopengl(); + afx_msg void OnEndkey(); + afx_msg void OnControlUpperarm(); + afx_msg void OnUpdateControlUpperarm(CCmdUI* pCmdUI); + afx_msg void OnControlLowerarm(); + afx_msg void OnUpdateControlLowerarm(CCmdUI* pCmdUI); + afx_msg void OnControlHand(); + afx_msg void OnUpdateControlHand(CCmdUI* pCmdUI); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.cpp index 03a839d..6af4af7 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.cpp @@ -1,560 +1,560 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Slash.h" -#include "OGLView.h" -#include "SetRot.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_UseQuat = TRUE; - m_Skeleton = NULL; - m_AnimBlend = 0.0; -} - -COGLView::~COGLView() -{ -} - -void COGLView::UpdateStatus() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - - if (m_UseQuat) - m_ptrStatusBar->SetPaneText(1,"Quaternion Mode"); - else - m_ptrStatusBar->SetPaneText(1,"Euler Mode"); - - sprintf(message,"Rot (%.1f,%.1f,%.1f)", - m_CurBone->rot.x, - m_CurBone->rot.y, - m_CurBone->rot.z); - m_ptrStatusBar->SetPaneText(2,message); - - sprintf(message,"Q (%.2f,%.2f,%.2f) %.2f", - m_CurBone->quat.x, - m_CurBone->quat.y, - m_CurBone->quat.z, - m_CurBone->quat.w); - m_ptrStatusBar->SetPaneText(3,message); -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton,CSlider *slider, CCreateContext* pContext) -{ - m_Slider = slider; - m_Skeleton = skeleton; - // SET THE STARTING BONE TO BE THE UPPER ARM - m_CurBone = m_Skeleton->children; - - UpdateStatus(); // DRAW INITIAL STATUS BAR - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(40.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(40.0, aspect, 1.0f, 2000.0f); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -GLvoid COGLView::drawModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (curBone->desc != NULL) - { - // NOT HANDLING TEXTURE TYPES IN THIS DEMO - switch (curBone->desc->type) - { - case 0: - // JUST MESH NO VERTEX COLORS - glInterleavedArrays(GL_V3F,0,(GLvoid *)curBone->desc->frame[curBone->desc->cur_frame]->data); - break; - case 1: - // VERTEX COLORS - glInterleavedArrays(GL_C3F_V3F,0,(GLvoid *)curBone->desc->frame[curBone->desc->cur_frame]->data); - break; - } - - glDrawArrays(GL_TRIANGLES,0,curBone->desc->pointCnt); - glDisable(GL_TEXTURE_2D); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawSkeleton -// Purpose: Actually draws the Skeleton it is recursive -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawSkeleton(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; - tQuaternion primaryQuat,secondaryQuat,axisAngle; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - // Set base orientation and position - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - EulerToQuaternion(&curBone->p_rot,&primaryQuat); - EulerToQuaternion(&curBone->s_rot,&secondaryQuat); - SlerpQuat(&primaryQuat,&secondaryQuat,m_AnimBlend,&curBone->quat); - - if (m_UseQuat) - { - // QUATERNION HAS TO BE CONVERTED TO AN AXIS/ANGLE REPRESENTATION - QuatToAxisAngle(&curBone->quat,&axisAngle); - // DO THE ROTATION - glRotatef(axisAngle.w, axisAngle.x, axisAngle.y, axisAngle.z); - } - else - { - // Set observer's orientation and position - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - - } - - // THE SCALE IS LOCAL SO I PUSH AND POP - glPushMatrix(); - glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); - - // DRAW THE LITTLE AXIS - glCallList(OGL_AXIS_DLIST); - - // IF THERE IS A MODEL, DRAW IT - if (curBone->desc != NULL) - drawModel(curBone); - - glPopMatrix(); // THIS POP IS JUST FOR THE SCALE - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - drawSkeleton(curBone); - - glPopMatrix(); // THIS POPS THE WHOLE MATRIX - - // NEXT BONE - curBone++; - } -} -//// drawSkeleton ///////////////////////////////////////////////////////////// - -GLvoid COGLView::drawScene() -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - // GET THE INTERPOLATION VALUE FROM MY CUSTOM SLIDER CONTROL - m_AnimBlend = m_Slider->GetSetting(); - - if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; - if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; - if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); - - glRotatef(m_Skeleton->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton->rot.x, 1.0f, 0.0f, 0.0f); - - // DO THE REST OF THE SYSTEM - drawSkeleton(m_Skeleton); - - glPopMatrix(); - - glFinish(); - - SwapBuffers(m_hDC); - - // DRAW THE STATS AT THE BOTTOM OF THE SCREEN - UpdateStatus(); -} - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW - resize( cx,cy ); -} - -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_Slider->SetPos(0); // I HAVE ADJUSTED SO RESET INTERPOLATOR - m_mousepos = point; - // SAVE THE HIT SETTINGS SO I CAN PLAY WITH THEM - m_Grab_Rot_X = m_CurBone->rot.x; - m_Grab_Rot_Y = m_CurBone->rot.y; - m_Grab_Rot_Z = m_CurBone->rot.z; - m_Grab_Trans_X = m_Skeleton->trans.x; - m_Grab_Trans_Y = m_Skeleton->trans.y; - m_Grab_Trans_Z = m_Skeleton->trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Slider->SetPos(0); // I HAVE ADJUSTED SO RESET INTERPOLATOR - // SAVE THE HIT SETTINGS SO I CAN PLAY WITH THEM - m_Grab_Rot_X = m_CurBone->rot.x; - m_Grab_Rot_Y = m_CurBone->rot.y; - m_Grab_Rot_Z = m_CurBone->rot.z; - m_Grab_Trans_X = m_Skeleton->trans.x; - m_Grab_Trans_Y = m_Skeleton->trans.y; - m_Grab_Trans_Z = m_Skeleton->trans.z; - CWnd::OnRButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - switch (nChar) - { - case '1': - // SELECT THE UPPER ARM AS THE CURRENT BONE - m_CurBone = &m_Skeleton->children[0]; - break; - case '2': - // SELECT THE LOWER ARM AS THE CURRENT BONE - m_CurBone = &m_Skeleton->children[1]; - break; - case '3': - // SELECT THE HAND AS THE CURRENT BONE - m_CurBone = &m_Skeleton->children[2]; - break; - } - drawScene(); -} - -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton->trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(); - } - } - // ELSE ROTATE THE ROOT - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_CurBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_CurBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - // SET THE NEW START KEYFRAME POSITION - m_CurBone->p_rot.x = m_CurBone->rot.x; - m_CurBone->p_rot.y = m_CurBone->rot.y; - m_CurBone->p_rot.z = m_CurBone->rot.z; - m_AnimBlend = 0.0; - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_CurBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - // SET THE NEW START KEYFRAME POSITION - m_CurBone->p_rot.x = m_CurBone->rot.x; - m_CurBone->p_rot.y = m_CurBone->rot.y; - m_CurBone->p_rot.z = m_CurBone->rot.z; - m_AnimBlend = 0.0; - } - } - CWnd::OnMouseMove(nFlags, point); -} -// IF YOU DOUBLE CLICK, BRING UP A DIALOG TO EDIT THE CURRENT BONE ORIENTATION -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - CSetRot dialog; - dialog.m_XAxis = m_CurBone->rot.x; - dialog.m_YAxis = m_CurBone->rot.y; - dialog.m_ZAxis = m_CurBone->rot.z; - if (dialog.DoModal()) - { - m_CurBone->rot.x = dialog.m_XAxis; - m_CurBone->rot.y = dialog.m_YAxis; - m_CurBone->rot.z = dialog.m_ZAxis; - } - drawScene(); -} - -// LOCK IN THE CURRENT BONE ORIENTATION AS ITS SECONDARY TARGET -void COGLView::SetEndKey() -{ - m_CurBone->s_rot.x = m_CurBone->rot.x; - m_CurBone->s_rot.y = m_CurBone->rot.y; - m_CurBone->s_rot.z = m_CurBone->rot.z; - m_AnimBlend = 0.0; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Slash.h" +#include "OGLView.h" +#include "SetRot.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_UseQuat = TRUE; + m_Skeleton = NULL; + m_AnimBlend = 0.0; +} + +COGLView::~COGLView() +{ +} + +void COGLView::UpdateStatus() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + + if (m_UseQuat) + m_ptrStatusBar->SetPaneText(1,"Quaternion Mode"); + else + m_ptrStatusBar->SetPaneText(1,"Euler Mode"); + + sprintf(message,"Rot (%.1f,%.1f,%.1f)", + m_CurBone->rot.x, + m_CurBone->rot.y, + m_CurBone->rot.z); + m_ptrStatusBar->SetPaneText(2,message); + + sprintf(message,"Q (%.2f,%.2f,%.2f) %.2f", + m_CurBone->quat.x, + m_CurBone->quat.y, + m_CurBone->quat.z, + m_CurBone->quat.w); + m_ptrStatusBar->SetPaneText(3,message); +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton,CSlider *slider, CCreateContext* pContext) +{ + m_Slider = slider; + m_Skeleton = skeleton; + // SET THE STARTING BONE TO BE THE UPPER ARM + m_CurBone = m_Skeleton->children; + + UpdateStatus(); // DRAW INITIAL STATUS BAR + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(40.0, aspect, 1.0f, 2000.0f); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +GLvoid COGLView::drawModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (curBone->desc != NULL) + { + // NOT HANDLING TEXTURE TYPES IN THIS DEMO + switch (curBone->desc->type) + { + case 0: + // JUST MESH NO VERTEX COLORS + glInterleavedArrays(GL_V3F,0,(GLvoid *)curBone->desc->frame[curBone->desc->cur_frame]->data); + break; + case 1: + // VERTEX COLORS + glInterleavedArrays(GL_C3F_V3F,0,(GLvoid *)curBone->desc->frame[curBone->desc->cur_frame]->data); + break; + } + + glDrawArrays(GL_TRIANGLES,0,curBone->desc->pointCnt); + glDisable(GL_TEXTURE_2D); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawSkeleton +// Purpose: Actually draws the Skeleton it is recursive +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawSkeleton(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; + tQuaternion primaryQuat,secondaryQuat,axisAngle; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + // Set base orientation and position + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + EulerToQuaternion(&curBone->p_rot,&primaryQuat); + EulerToQuaternion(&curBone->s_rot,&secondaryQuat); + SlerpQuat(&primaryQuat,&secondaryQuat,m_AnimBlend,&curBone->quat); + + if (m_UseQuat) + { + // QUATERNION HAS TO BE CONVERTED TO AN AXIS/ANGLE REPRESENTATION + QuatToAxisAngle(&curBone->quat,&axisAngle); + // DO THE ROTATION + glRotatef(axisAngle.w, axisAngle.x, axisAngle.y, axisAngle.z); + } + else + { + // Set observer's orientation and position + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + + } + + // THE SCALE IS LOCAL SO I PUSH AND POP + glPushMatrix(); + glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); + + // DRAW THE LITTLE AXIS + glCallList(OGL_AXIS_DLIST); + + // IF THERE IS A MODEL, DRAW IT + if (curBone->desc != NULL) + drawModel(curBone); + + glPopMatrix(); // THIS POP IS JUST FOR THE SCALE + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + drawSkeleton(curBone); + + glPopMatrix(); // THIS POPS THE WHOLE MATRIX + + // NEXT BONE + curBone++; + } +} +//// drawSkeleton ///////////////////////////////////////////////////////////// + +GLvoid COGLView::drawScene() +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + // GET THE INTERPOLATION VALUE FROM MY CUSTOM SLIDER CONTROL + m_AnimBlend = m_Slider->GetSetting(); + + if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; + if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; + if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); + + glRotatef(m_Skeleton->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton->rot.x, 1.0f, 0.0f, 0.0f); + + // DO THE REST OF THE SYSTEM + drawSkeleton(m_Skeleton); + + glPopMatrix(); + + glFinish(); + + SwapBuffers(m_hDC); + + // DRAW THE STATS AT THE BOTTOM OF THE SCREEN + UpdateStatus(); +} + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW + resize( cx,cy ); +} + +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_Slider->SetPos(0); // I HAVE ADJUSTED SO RESET INTERPOLATOR + m_mousepos = point; + // SAVE THE HIT SETTINGS SO I CAN PLAY WITH THEM + m_Grab_Rot_X = m_CurBone->rot.x; + m_Grab_Rot_Y = m_CurBone->rot.y; + m_Grab_Rot_Z = m_CurBone->rot.z; + m_Grab_Trans_X = m_Skeleton->trans.x; + m_Grab_Trans_Y = m_Skeleton->trans.y; + m_Grab_Trans_Z = m_Skeleton->trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Slider->SetPos(0); // I HAVE ADJUSTED SO RESET INTERPOLATOR + // SAVE THE HIT SETTINGS SO I CAN PLAY WITH THEM + m_Grab_Rot_X = m_CurBone->rot.x; + m_Grab_Rot_Y = m_CurBone->rot.y; + m_Grab_Rot_Z = m_CurBone->rot.z; + m_Grab_Trans_X = m_Skeleton->trans.x; + m_Grab_Trans_Y = m_Skeleton->trans.y; + m_Grab_Trans_Z = m_Skeleton->trans.z; + CWnd::OnRButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + switch (nChar) + { + case '1': + // SELECT THE UPPER ARM AS THE CURRENT BONE + m_CurBone = &m_Skeleton->children[0]; + break; + case '2': + // SELECT THE LOWER ARM AS THE CURRENT BONE + m_CurBone = &m_Skeleton->children[1]; + break; + case '3': + // SELECT THE HAND AS THE CURRENT BONE + m_CurBone = &m_Skeleton->children[2]; + break; + } + drawScene(); +} + +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton->trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(); + } + } + // ELSE ROTATE THE ROOT + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_CurBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_CurBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + // SET THE NEW START KEYFRAME POSITION + m_CurBone->p_rot.x = m_CurBone->rot.x; + m_CurBone->p_rot.y = m_CurBone->rot.y; + m_CurBone->p_rot.z = m_CurBone->rot.z; + m_AnimBlend = 0.0; + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_CurBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + // SET THE NEW START KEYFRAME POSITION + m_CurBone->p_rot.x = m_CurBone->rot.x; + m_CurBone->p_rot.y = m_CurBone->rot.y; + m_CurBone->p_rot.z = m_CurBone->rot.z; + m_AnimBlend = 0.0; + } + } + CWnd::OnMouseMove(nFlags, point); +} +// IF YOU DOUBLE CLICK, BRING UP A DIALOG TO EDIT THE CURRENT BONE ORIENTATION +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + CSetRot dialog; + dialog.m_XAxis = m_CurBone->rot.x; + dialog.m_YAxis = m_CurBone->rot.y; + dialog.m_ZAxis = m_CurBone->rot.z; + if (dialog.DoModal()) + { + m_CurBone->rot.x = dialog.m_XAxis; + m_CurBone->rot.y = dialog.m_YAxis; + m_CurBone->rot.z = dialog.m_ZAxis; + } + drawScene(); +} + +// LOCK IN THE CURRENT BONE ORIENTATION AS ITS SECONDARY TARGET +void COGLView::SetEndKey() +{ + m_CurBone->s_rot.x = m_CurBone->rot.x; + m_CurBone->s_rot.y = m_CurBone->rot.y; + m_CurBone->s_rot.z = m_CurBone->rot.z; + m_AnimBlend = 0.0; +} + diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.h index 575507d..4618237 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/OGLView.h @@ -1,100 +1,100 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -#include "Slider.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - CSlider *m_Slider; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry; - BOOL m_UseQuat; - float m_AnimBlend; - t_Bone *m_Skeleton; - t_Bone *m_CurBone; // WHICH ONE IS UNDER UI CONTROL -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawSkeleton(t_Bone *rootBone); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void UpdateStatus(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - void SetEndKey(); // SET THE END KEYFRAME -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton,CSlider *slider, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +#include "Slider.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + CSlider *m_Slider; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry; + BOOL m_UseQuat; + float m_AnimBlend; + t_Bone *m_Skeleton; + t_Bone *m_CurBone; // WHICH ONE IS UNDER UI CONTROL +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawSkeleton(t_Bone *rootBone); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void UpdateStatus(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + void SetEndKey(); // SET THE END KEYFRAME +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton,CSlider *slider, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.cpp index 9093329..020da19 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.cpp @@ -1,413 +1,413 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.cpp : Quaternion System structure implementation file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY -// -// Created: -// JL 9/1/97 -// Modified: -// JL 3/15/97 Changed the SLERP comments once I understood it better -// -// Sources: -// Shoemake, Ken, "Animating Rotations with Quaternion Curves" -// Computer Graphics 85, pp. 245-254 -// Watt and Watt, Advanced Animation and Rendering Techniques -// Addison Wesley, pp. 360-368 -// Shoemake, Graphic Gems II. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include "skeleton.h" -#include "quatern.h" - -#define M_PI 3.14159265358979323846 -#define HALF_PI 1.57079632679489661923 - -/////////////////////////////////////////////////////////////////////////////// -// Function: CopyVector -// Purpose: Copy a vector -// Arguments: pointer to destination and source -/////////////////////////////////////////////////////////////////////////////// -void CopyVector(tVector *dest, tVector *src) -{ - dest->x = src->x; - dest->y = src->y; - dest->z = src->z; -} -//// CopyVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ScaleVector -// Purpose: Scale a vector -// Arguments: pointer to vector and scale factor -/////////////////////////////////////////////////////////////////////////////// -void ScaleVector(tVector *vect, float scale) -{ - vect->x *= scale; - vect->y *= scale; - vect->z *= scale; -} -//// ScaleVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: AddVectors -// Purpose: Add two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - dest->x = vect1->x + vect2->x; - dest->y = vect1->y + vect2->y; - dest->z = vect1->z + vect2->z; -} -//// AddVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DotVectors -// Purpose: Compute the dot product of two vectors -// Arguments: pointer to vectors -// Returns: Dot product -/////////////////////////////////////////////////////////////////////////////// -float DotVectors(tVector *vect1, tVector *vect2) -{ - return (vect1->x * vect2->x) + - (vect1->y * vect2->y) + - (vect1->z * vect2->z); -} -//// DotVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossVectors -// Purpose: Computes the cross product of two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - // COMPUTE THE CROSS PRODUCT - dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); - dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); - dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); -} -//// CrossVectors ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion v1,v2,v3,vf; -/////////////////////////////////////////////////////////////////////////////// - - CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); - - AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); - AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); - - vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); - - dest->x = vf.x; - dest->y = vf.y; - dest->z = vf.z; - dest->w = vf.w; -} -//// MultQuaternions ////////////////////////////////////////////////////////// - -/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR - I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY - THE MATH CHECKS OUT THOUGH */ -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions2 -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ - tQuaternion tmp; - tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + - quat2->y * quat1->z - quat2->z * quat1->y; - tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + - quat2->z * quat1->x - quat2->x * quat1->z; - tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + - quat2->x * quat1->y - quat2->y * quat1->x; - tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - - quat2->y * quat1->y - quat2->z * quat1->z; - dest->x = tmp.x; dest->y = tmp.y; - dest->z = tmp.z; dest->w = tmp.w; -} -//// MultQuaternions2 ////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeQuaternion -// Purpose: Normalize a Quaternion -// Arguments: a quaternion to set -// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 -// This function insures this -/////////////////////////////////////////////////////////////////////////////// -void NormalizeQuaternion(tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float magnitude; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, FIND THE MAGNITUDE - magnitude = (quat->x * quat->x) + - (quat->y * quat->y) + - (quat->z * quat->z) + - (quat->w * quat->w); - - // DIVIDE BY THE MAGNITUDE TO NORMALIZE - quat->x = quat->x / magnitude; - quat->y = quat->y / magnitude; - quat->z = quat->z / magnitude; - quat->w = quat->w / magnitude; -} -// NormalizeQuaternion /////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT -// A SERIES OF ROTATIONS TO QUATERNIONS. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted. It is more efficient this way though. -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - tx = rx * (float)0.5; - ty = ry * (float)0.5; - tz = rz * (float)0.5; - cx = (float)cos(tx); - cy = (float)cos(ty); - cz = (float)cos(tz); - sx = (float)sin(tx); - sy = (float)sin(ty); - sz = (float)sin(tz); - - cc = cx * cz; - cs = cx * sz; - sc = sx * cz; - ss = sx * sz; - - quat->x = (cy * sc) - (sy * cs); - quat->y = (cy * ss) + (sy * cc); - quat->z = (cy * cs) - (sy * sc); - quat->w = (cy * cc) + (sy * ss); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(quat); -} -// EulerToQuaternion ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: This is a second variation. It creates a -// Series of quaternions and multiplies them together -// It would be easier to extend this for other rotation orders -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,ti,tj,tk; - tQuaternion qx,qy,qz,qf; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - ti = rx * (float)0.5; - tj = ry * (float)0.5; - tk = rz * (float)0.5; - - qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); - qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); - qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); - - MultQuaternions(&qx,&qy,&qf); - MultQuaternions(&qf,&qz,&qf); -// ANOTHER TEST VARIATION -// MultQuaternions2(&qx,&qy,&qf); -// MultQuaternions2(&qf,&qz,&qf); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(&qf); - - quat->x = qf.x; - quat->y = qf.y; - quat->z = qf.z; - quat->w = qf.w; - -} -// EulerToQuaternion2 ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float scale,tw; -/////////////////////////////////////////////////////////////////////////////// - tw = (float)acos(quat->w) * 2; - scale = (float)sin(tw / 2.0); - axisAngle->x = quat->x / scale; - axisAngle->y = quat->y / scale; - axisAngle->z = quat->z / scale; - - // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES - axisAngle->w = (tw * (360 / 2)) / (float)M_PI; -} -// QuatToAxisAngle ///////////////////////////////////////////////////////// - -#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat2(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion quat1b; - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // MAKE SURE WE ARE TRAVELING ALONG THE SHORTER PATH - if (cosom < 0.0) - { - // IF WE ARE NOT, REVERSE ONE OF THE QUATERNIONS - cosom = -cosom; - quat1b.x = - quat1->x; - quat1b.y = - quat1->y; - quat1b.z = - quat1->z; - quat1b.w = - quat1->w; - } else { - quat1b.x = quat1->x; - quat1b.y = quat1->y; - quat1b.z = quat1->z; - quat1b.w = quat1->w; - } - - - if ((1.0 - cosom) > DELTA) { - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - scale0 = 1.0 - slerp; - scale1 = slerp; - } - - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; -} -// SlerpQuat ///////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -// Notes: The comments explain the handling of the special cases. -// The comments in the magazine were wrong. Adjust the -// DELTA constant to play with the LERP vs. SLERP level -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // CHECK A COUPLE OF SPECIAL CASES. - // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) - if ((1.0 + cosom) > DELTA) - { - // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT - if ((1.0 - cosom) > DELTA) { - // YES, DO A SLERP - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1.0 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - // NOT A VERY BIG DIFFERENCE, DO A LERP - scale0 = 1.0 - slerp; - scale1 = slerp; - } - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; - } else { - // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR - // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION - result->x = -quat2->y; - result->y = quat2->x; - result->z = -quat2->w; - result->w = quat2->z; - scale0 = sin((1.0 - slerp) * (float)HALF_PI); - scale1 = sin(slerp * (float)HALF_PI); - result->x = scale0 * quat1->x + scale1 * result->x; - result->y = scale0 * quat1->y + scale1 * result->y; - result->z = scale0 * quat1->z + scale1 * result->z; - result->w = scale0 * quat1->w + scale1 * result->w; - } - -} -// SlerpQuat ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.cpp : Quaternion System structure implementation file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY +// +// Created: +// JL 9/1/97 +// Modified: +// JL 3/15/97 Changed the SLERP comments once I understood it better +// +// Sources: +// Shoemake, Ken, "Animating Rotations with Quaternion Curves" +// Computer Graphics 85, pp. 245-254 +// Watt and Watt, Advanced Animation and Rendering Techniques +// Addison Wesley, pp. 360-368 +// Shoemake, Graphic Gems II. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include "skeleton.h" +#include "quatern.h" + +#define M_PI 3.14159265358979323846 +#define HALF_PI 1.57079632679489661923 + +/////////////////////////////////////////////////////////////////////////////// +// Function: CopyVector +// Purpose: Copy a vector +// Arguments: pointer to destination and source +/////////////////////////////////////////////////////////////////////////////// +void CopyVector(tVector *dest, tVector *src) +{ + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} +//// CopyVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ScaleVector +// Purpose: Scale a vector +// Arguments: pointer to vector and scale factor +/////////////////////////////////////////////////////////////////////////////// +void ScaleVector(tVector *vect, float scale) +{ + vect->x *= scale; + vect->y *= scale; + vect->z *= scale; +} +//// ScaleVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: AddVectors +// Purpose: Add two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + dest->x = vect1->x + vect2->x; + dest->y = vect1->y + vect2->y; + dest->z = vect1->z + vect2->z; +} +//// AddVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DotVectors +// Purpose: Compute the dot product of two vectors +// Arguments: pointer to vectors +// Returns: Dot product +/////////////////////////////////////////////////////////////////////////////// +float DotVectors(tVector *vect1, tVector *vect2) +{ + return (vect1->x * vect2->x) + + (vect1->y * vect2->y) + + (vect1->z * vect2->z); +} +//// DotVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossVectors +// Purpose: Computes the cross product of two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + // COMPUTE THE CROSS PRODUCT + dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); + dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); + dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); +} +//// CrossVectors ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion v1,v2,v3,vf; +/////////////////////////////////////////////////////////////////////////////// + + CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); + + AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); + AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); + + vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); + + dest->x = vf.x; + dest->y = vf.y; + dest->z = vf.z; + dest->w = vf.w; +} +//// MultQuaternions ////////////////////////////////////////////////////////// + +/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR + I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY + THE MATH CHECKS OUT THOUGH */ +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions2 +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ + tQuaternion tmp; + tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + + quat2->y * quat1->z - quat2->z * quat1->y; + tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + + quat2->z * quat1->x - quat2->x * quat1->z; + tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + + quat2->x * quat1->y - quat2->y * quat1->x; + tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - + quat2->y * quat1->y - quat2->z * quat1->z; + dest->x = tmp.x; dest->y = tmp.y; + dest->z = tmp.z; dest->w = tmp.w; +} +//// MultQuaternions2 ////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeQuaternion +// Purpose: Normalize a Quaternion +// Arguments: a quaternion to set +// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 +// This function insures this +/////////////////////////////////////////////////////////////////////////////// +void NormalizeQuaternion(tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float magnitude; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, FIND THE MAGNITUDE + magnitude = (quat->x * quat->x) + + (quat->y * quat->y) + + (quat->z * quat->z) + + (quat->w * quat->w); + + // DIVIDE BY THE MAGNITUDE TO NORMALIZE + quat->x = quat->x / magnitude; + quat->y = quat->y / magnitude; + quat->z = quat->z / magnitude; + quat->w = quat->w / magnitude; +} +// NormalizeQuaternion /////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT +// A SERIES OF ROTATIONS TO QUATERNIONS. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted. It is more efficient this way though. +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + tx = rx * (float)0.5; + ty = ry * (float)0.5; + tz = rz * (float)0.5; + cx = (float)cos(tx); + cy = (float)cos(ty); + cz = (float)cos(tz); + sx = (float)sin(tx); + sy = (float)sin(ty); + sz = (float)sin(tz); + + cc = cx * cz; + cs = cx * sz; + sc = sx * cz; + ss = sx * sz; + + quat->x = (cy * sc) - (sy * cs); + quat->y = (cy * ss) + (sy * cc); + quat->z = (cy * cs) - (sy * sc); + quat->w = (cy * cc) + (sy * ss); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(quat); +} +// EulerToQuaternion ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: This is a second variation. It creates a +// Series of quaternions and multiplies them together +// It would be easier to extend this for other rotation orders +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,ti,tj,tk; + tQuaternion qx,qy,qz,qf; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + ti = rx * (float)0.5; + tj = ry * (float)0.5; + tk = rz * (float)0.5; + + qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); + qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); + qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); + + MultQuaternions(&qx,&qy,&qf); + MultQuaternions(&qf,&qz,&qf); +// ANOTHER TEST VARIATION +// MultQuaternions2(&qx,&qy,&qf); +// MultQuaternions2(&qf,&qz,&qf); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(&qf); + + quat->x = qf.x; + quat->y = qf.y; + quat->z = qf.z; + quat->w = qf.w; + +} +// EulerToQuaternion2 ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float scale,tw; +/////////////////////////////////////////////////////////////////////////////// + tw = (float)acos(quat->w) * 2; + scale = (float)sin(tw / 2.0); + axisAngle->x = quat->x / scale; + axisAngle->y = quat->y / scale; + axisAngle->z = quat->z / scale; + + // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES + axisAngle->w = (tw * (360 / 2)) / (float)M_PI; +} +// QuatToAxisAngle ///////////////////////////////////////////////////////// + +#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat2(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion quat1b; + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // MAKE SURE WE ARE TRAVELING ALONG THE SHORTER PATH + if (cosom < 0.0) + { + // IF WE ARE NOT, REVERSE ONE OF THE QUATERNIONS + cosom = -cosom; + quat1b.x = - quat1->x; + quat1b.y = - quat1->y; + quat1b.z = - quat1->z; + quat1b.w = - quat1->w; + } else { + quat1b.x = quat1->x; + quat1b.y = quat1->y; + quat1b.z = quat1->z; + quat1b.w = quat1->w; + } + + + if ((1.0 - cosom) > DELTA) { + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + scale0 = 1.0 - slerp; + scale1 = slerp; + } + + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; +} +// SlerpQuat ///////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +// Notes: The comments explain the handling of the special cases. +// The comments in the magazine were wrong. Adjust the +// DELTA constant to play with the LERP vs. SLERP level +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // CHECK A COUPLE OF SPECIAL CASES. + // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) + if ((1.0 + cosom) > DELTA) + { + // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT + if ((1.0 - cosom) > DELTA) { + // YES, DO A SLERP + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1.0 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + // NOT A VERY BIG DIFFERENCE, DO A LERP + scale0 = 1.0 - slerp; + scale1 = slerp; + } + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; + } else { + // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR + // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION + result->x = -quat2->y; + result->y = quat2->x; + result->z = -quat2->w; + result->w = quat2->z; + scale0 = sin((1.0 - slerp) * (float)HALF_PI); + scale1 = sin(slerp * (float)HALF_PI); + result->x = scale0 * quat1->x + scale1 * result->x; + result->y = scale0 * quat1->y + scale1 * result->y; + result->z = scale0 * quat1->z + scale1 * result->z; + result->w = scale0 * quat1->w + scale1 * result->w; + } + +} +// SlerpQuat ///////////////////////////////////////////////////////////////// diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.h index e158e05..cf93d2d 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Quatern.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.h : Quaternion System structure definition file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(QUATERN_H__INCLUDED_) -#define QUATERN_H__INCLUDED_ - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; - -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); - -#endif // !defined(QUATERN_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.h : Quaternion System structure definition file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(QUATERN_H__INCLUDED_) +#define QUATERN_H__INCLUDED_ + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; + +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); + +#endif // !defined(QUATERN_H__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/ReadMe.txt b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/ReadMe.txt index b4fa566..8b6d276 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/ReadMe.txt +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/ReadMe.txt @@ -1,103 +1,103 @@ -Slash II - Slash Harder - -Quaternion Interpolation Demonstration Program March 15, 1998 -------------------------------------------------------------- - -v. 2.0 - -This is the sample application that accompanies the April 98 -Game Developer magazine. It is meant as a demonstration of -how use Quaternions in OpenGL. This is the second article -of the two part series. This one really deals with -interpolating between Quaternions. If you want more -explaination of the Euler angle to Quaternion code, see the -March 98 Game Developer magazine and sample code. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -There are instructions in the Help/About dialog. - -This program is to demonstrate the use of Quaternions for -animation control in OpenGL. - -The user interface for creating keyframe positions is a little -strange. What can I say, you want a good keyframing program, -buy a professional 3D animation package. - -Anyway, it works like this: - -The demo skeleton is an arm with three bones; Upper Arm, Lower Arm, -and Hand. Each bone has a primary rotation position and a secondary -one. The interpolator slider sets the relative position between these -keys. I created two keyframe positions for each bone and hard coded -them in as a sample "slash" move. But, you can create your own -interpolation. - -Select the bone you wish to position and then rotate it to the desired -orientation by dragging with the left mouse button for X and Y and -right button for the Z axis. When you have it set to the final -position, select "Keyframe/Set End Key" this locks it in. Do that -for all 3 bones. - -After all the keyframes are locked, move them all to the starting -orientation. Then you can use the slider to interpolate between -them. - -Other Functions: - -1,2,3 Select Upper Arm, Lower Arm, Hand as current bone. -Double Click Brings up edit box for orientation of current bone. -Ctrl+Mouse Drag Translate the base position of the system. - - ---------------------------------------- - -Other Info: - -The models were exported by a custom plugin and are Vertex Colored -openGL vertex arrays. The data is interleaved. I won't go into -the model format but it is real obvious if you look at the loader -in MainFrame and the skeleton format in the skeleton.h file. - -My explaination of the comparison in the SLERP code in the magazine -was wrong. Thanks to several people for pointing that out. The -comments in code here I believe is the correct one. Although, I haven't -created strange cases to test it all out. It seems very robust for all -the application I have used it for. - -This is a pretty big application. It seemed small when I started the -little demo but each feature added a bunch. Any questions, let me -know. I hope to scale back a bit on the demo apps but with -upcoming topics like skeletal deformation, IK, and dynamic LOD, -I doubt they will get much smaller. - -If you create cool tools or demos yourself and want me to check -them out. Send them. I would love to see what other people are -working on. Also, if you have things you are interested in -seeing cover, let me know. - -Have fun. - -Jeff - +Slash II - Slash Harder + +Quaternion Interpolation Demonstration Program March 15, 1998 +------------------------------------------------------------- + +v. 2.0 + +This is the sample application that accompanies the April 98 +Game Developer magazine. It is meant as a demonstration of +how use Quaternions in OpenGL. This is the second article +of the two part series. This one really deals with +interpolating between Quaternions. If you want more +explaination of the Euler angle to Quaternion code, see the +March 98 Game Developer magazine and sample code. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +There are instructions in the Help/About dialog. + +This program is to demonstrate the use of Quaternions for +animation control in OpenGL. + +The user interface for creating keyframe positions is a little +strange. What can I say, you want a good keyframing program, +buy a professional 3D animation package. + +Anyway, it works like this: + +The demo skeleton is an arm with three bones; Upper Arm, Lower Arm, +and Hand. Each bone has a primary rotation position and a secondary +one. The interpolator slider sets the relative position between these +keys. I created two keyframe positions for each bone and hard coded +them in as a sample "slash" move. But, you can create your own +interpolation. + +Select the bone you wish to position and then rotate it to the desired +orientation by dragging with the left mouse button for X and Y and +right button for the Z axis. When you have it set to the final +position, select "Keyframe/Set End Key" this locks it in. Do that +for all 3 bones. + +After all the keyframes are locked, move them all to the starting +orientation. Then you can use the slider to interpolate between +them. + +Other Functions: + +1,2,3 Select Upper Arm, Lower Arm, Hand as current bone. +Double Click Brings up edit box for orientation of current bone. +Ctrl+Mouse Drag Translate the base position of the system. + + +--------------------------------------- + +Other Info: + +The models were exported by a custom plugin and are Vertex Colored +openGL vertex arrays. The data is interleaved. I won't go into +the model format but it is real obvious if you look at the loader +in MainFrame and the skeleton format in the skeleton.h file. + +My explaination of the comparison in the SLERP code in the magazine +was wrong. Thanks to several people for pointing that out. The +comments in code here I believe is the correct one. Although, I haven't +created strange cases to test it all out. It seems very robust for all +the application I have used it for. + +This is a pretty big application. It seemed small when I started the +little demo but each feature added a bunch. Any questions, let me +know. I hope to scale back a bit on the demo apps but with +upcoming topics like skeletal deformation, IK, and dynamic LOD, +I doubt they will get much smaller. + +If you create cool tools or demos yourself and want me to check +them out. Send them. I would love to see what other people are +working on. Also, if you have things you are interested in +seeing cover, let me know. + +Have fun. + +Jeff + diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.cpp index 3621584..c4acf8f 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.cpp @@ -1,47 +1,47 @@ -// SetRot.cpp : implementation file -// - -#include "stdafx.h" -#include "Slash.h" -#include "SetRot.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSetRot dialog - - -CSetRot::CSetRot(CWnd* pParent /*=NULL*/) - : CDialog(CSetRot::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSetRot) - m_XAxis = 0.0f; - m_YAxis = 0.0f; - m_ZAxis = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSetRot::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSetRot) - DDX_Text(pDX, IDC_XAXIS, m_XAxis); - DDX_Text(pDX, IDC_YAXIS, m_YAxis); - DDX_Text(pDX, IDC_ZAXIS, m_ZAxis); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSetRot, CDialog) - //{{AFX_MSG_MAP(CSetRot) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSetRot message handlers +// SetRot.cpp : implementation file +// + +#include "stdafx.h" +#include "Slash.h" +#include "SetRot.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSetRot dialog + + +CSetRot::CSetRot(CWnd* pParent /*=NULL*/) + : CDialog(CSetRot::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSetRot) + m_XAxis = 0.0f; + m_YAxis = 0.0f; + m_ZAxis = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSetRot::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSetRot) + DDX_Text(pDX, IDC_XAXIS, m_XAxis); + DDX_Text(pDX, IDC_YAXIS, m_YAxis); + DDX_Text(pDX, IDC_ZAXIS, m_ZAxis); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSetRot, CDialog) + //{{AFX_MSG_MAP(CSetRot) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSetRot message handlers diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.h index bd7fd9f..2ec20f0 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/SetRot.h @@ -1,48 +1,48 @@ -#if !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// SetRot.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSetRot dialog - -class CSetRot : public CDialog -{ -// Construction -public: - CSetRot(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSetRot) - enum { IDD = IDD_SETROTATE }; - float m_XAxis; - float m_YAxis; - float m_ZAxis; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSetRot) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSetRot) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) +#if !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// SetRot.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSetRot dialog + +class CSetRot : public CDialog +{ +// Construction +public: + CSetRot(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSetRot) + enum { IDD = IDD_SETROTATE }; + float m_XAxis; + float m_YAxis; + float m_ZAxis; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSetRot) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSetRot) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.cpp index 8801f84..0f6f48f 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.cpp @@ -1,162 +1,162 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->p_scale.x = - bone->p_scale.y = - bone->p_scale.z = 1.0; - bone->s_scale.x = - bone->s_scale.y = - bone->s_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->p_rot.x = - bone->p_rot.y = - bone->p_rot.z = 0.0; - bone->s_rot.x = - bone->s_rot.y = - bone->s_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->p_trans.x = - bone->p_trans.y = - bone->p_trans.z = 0.0; - bone->s_trans.x = - bone->s_trans.y = - bone->s_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - bone->animBlend = 0.0; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->p_scale.x = + bone->p_scale.y = + bone->p_scale.z = 1.0; + bone->s_scale.x = + bone->s_scale.y = + bone->s_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->p_rot.x = + bone->p_rot.y = + bone->p_rot.z = 0.0; + bone->s_rot.x = + bone->s_rot.y = + bone->s_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->p_trans.x = + bone->p_trans.y = + bone->p_trans.z = 0.0; + bone->s_trans.x = + bone->s_trans.y = + bone->s_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + bone->animBlend = 0.0; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.h index f36f097..63bb769 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Skeleton.h @@ -1,173 +1,173 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define MAX_FRAMES 100 /* MAXIMUM FRAMES PER DESC */ -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -typedef struct -{ - float x,y,z; -} tVector; - -// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY -typedef struct -{ - float m[16]; -} tMatrix; - -#include "Quatern.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// -/* 3D OBJECT FRAME DEFINITION */ -typedef struct { - float *data; /* LIST OF DATA POINTS */ - tVector center; /* CALCED CENTER OF FRAME */ - long radius; /* MAX RADIUS FOR COLLISION */ -} tObjFrame; - -/* 3D OBJECT DESCRIPTION */ -typedef struct { - short cur_frame; /* WHAT FRAME AM I ON */ - short frameCnt; - long pointCnt; /* EACH DESCRIPTION MUST HAVE SAME POINT CNT */ - long polyCnt; - tObjFrame *frame[MAX_FRAMES]; /* LIST OF OBJECT FRAMES */ - long page_cnt; /* NUMBER OF TEXTURE PAGES */ - unsigned int glTex; /* TEXTURE ID */ - char textureName[80]; - long type; /* TYPE OF MODEL */ - long dataSize; /* SIZE OF A DATA ITEM */ -} tObjDesc; - - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector p_scale; // PRIMARY SCALE FACTORS - tVector p_rot; // PRIMARY ROTATION FACTORS - tVector p_trans; // PRIMARY TRANSLATION FACTORS - tVector s_scale; // SECONDARY SCALE FACTORS - tVector s_rot; // SECONDARY ROTATION FACTORS - tVector s_trans; // SECONDARY TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - tMatrix matrix; // PLACE TO STORE THE MATRIX - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - long desc_count; /* NUMBER OF MIP MODELS */ - tObjDesc *desc; /* POINTER TO DESCRIPTIONS */ - long cur_desc; /* NUMBER OF MIP MODELS */ - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - long *visuals; // POINTER TO VISUALS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define MAX_FRAMES 100 /* MAXIMUM FRAMES PER DESC */ +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +typedef struct +{ + float x,y,z; +} tVector; + +// NOT DECLARED AS float[4][4] BECAUSE OPENGL ACCESSES THIS STRANGLY +typedef struct +{ + float m[16]; +} tMatrix; + +#include "Quatern.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// +/* 3D OBJECT FRAME DEFINITION */ +typedef struct { + float *data; /* LIST OF DATA POINTS */ + tVector center; /* CALCED CENTER OF FRAME */ + long radius; /* MAX RADIUS FOR COLLISION */ +} tObjFrame; + +/* 3D OBJECT DESCRIPTION */ +typedef struct { + short cur_frame; /* WHAT FRAME AM I ON */ + short frameCnt; + long pointCnt; /* EACH DESCRIPTION MUST HAVE SAME POINT CNT */ + long polyCnt; + tObjFrame *frame[MAX_FRAMES]; /* LIST OF OBJECT FRAMES */ + long page_cnt; /* NUMBER OF TEXTURE PAGES */ + unsigned int glTex; /* TEXTURE ID */ + char textureName[80]; + long type; /* TYPE OF MODEL */ + long dataSize; /* SIZE OF A DATA ITEM */ +} tObjDesc; + + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector p_scale; // PRIMARY SCALE FACTORS + tVector p_rot; // PRIMARY ROTATION FACTORS + tVector p_trans; // PRIMARY TRANSLATION FACTORS + tVector s_scale; // SECONDARY SCALE FACTORS + tVector s_rot; // SECONDARY ROTATION FACTORS + tVector s_trans; // SECONDARY TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + tMatrix matrix; // PLACE TO STORE THE MATRIX + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + long desc_count; /* NUMBER OF MIP MODELS */ + tObjDesc *desc; /* POINTER TO DESCRIPTIONS */ + long cur_desc; /* NUMBER OF MIP MODELS */ + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + long *visuals; // POINTER TO VISUALS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.cpp index 3d36baf..694bded 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Slash.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Slash.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp - -BEGIN_MESSAGE_MAP(CSlashApp, CWinApp) - //{{AFX_MSG_MAP(CSlashApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp construction - -CSlashApp::CSlashApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSlashApp object - -CSlashApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp initialization - -BOOL CSlashApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - // SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSlashApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Slash.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Slash.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp + +BEGIN_MESSAGE_MAP(CSlashApp, CWinApp) + //{{AFX_MSG_MAP(CSlashApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp construction + +CSlashApp::CSlashApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSlashApp object + +CSlashApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp initialization + +BOOL CSlashApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + // SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSlashApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp commands diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.h index 9b108bb..dcdf2a9 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slash.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Slash.h : main header file for the SLASH application -// -// Purpose: header of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp: -// See Slash.cpp for the implementation of this class -// - -class CSlashApp : public CWinApp -{ -public: - CSlashApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSlashApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSlashApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Slash.h : main header file for the SLASH application +// +// Purpose: header of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp: +// See Slash.cpp for the implementation of this class +// + +class CSlashApp : public CWinApp +{ +public: + CSlashApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSlashApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSlashApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.cpp index 871d7c0..3aab8ed 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.cpp @@ -1,82 +1,82 @@ -// Slider.cpp : implementation file -// - -#include "stdafx.h" -#include "Slash.h" -#include "Slider.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSlider - -CSlider::CSlider() -{ - // FLAG WHETHER I AM DRAGGING THE SLIDER - m_pressed = FALSE; -} - -CSlider::~CSlider() -{ -} - - -BEGIN_MESSAGE_MAP(CSlider, CSliderCtrl) - //{{AFX_MSG_MAP(CSlider) - ON_WM_CREATE() - ON_WM_LBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONUP() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSlider message handlers - -int CSlider::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CSliderCtrl::OnCreate(lpCreateStruct) == -1) - return -1; - - // SET UP THE SLIDER SO IT GOES FROM 0 - 1024 - SetRange(0,1024,TRUE); - SetPos(0); - return 0; -} - -// GET A FLOAT REPRESENTING THE RELATIVE POSITION OF THE SLIDER -// Returns: float from 0-1 -float CSlider::GetSetting() -{ -/// Local Variables /////////////////////////////////////////////////////////// - int position; -/////////////////////////////////////////////////////////////////////////////// - position = GetPos(); - return position / 1024.0f; -} - -void CSlider::OnLButtonDown(UINT nFlags, CPoint point) -{ - // MARK THE DRAG - m_pressed = TRUE; - CSliderCtrl::OnLButtonDown(nFlags, point); -} - -void CSlider::OnMouseMove(UINT nFlags, CPoint point) -{ - // IF I AM DRAGGING, REDRAW MY MAIN WINDOW - if (m_pressed) - GetParent()->InvalidateRect(NULL); - CSliderCtrl::OnMouseMove(nFlags, point); -} - -void CSlider::OnLButtonUp(UINT nFlags, CPoint point) -{ - // NOT DRAGGING ANY MORE - m_pressed = FALSE; - CSliderCtrl::OnLButtonUp(nFlags, point); -} +// Slider.cpp : implementation file +// + +#include "stdafx.h" +#include "Slash.h" +#include "Slider.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSlider + +CSlider::CSlider() +{ + // FLAG WHETHER I AM DRAGGING THE SLIDER + m_pressed = FALSE; +} + +CSlider::~CSlider() +{ +} + + +BEGIN_MESSAGE_MAP(CSlider, CSliderCtrl) + //{{AFX_MSG_MAP(CSlider) + ON_WM_CREATE() + ON_WM_LBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSlider message handlers + +int CSlider::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CSliderCtrl::OnCreate(lpCreateStruct) == -1) + return -1; + + // SET UP THE SLIDER SO IT GOES FROM 0 - 1024 + SetRange(0,1024,TRUE); + SetPos(0); + return 0; +} + +// GET A FLOAT REPRESENTING THE RELATIVE POSITION OF THE SLIDER +// Returns: float from 0-1 +float CSlider::GetSetting() +{ +/// Local Variables /////////////////////////////////////////////////////////// + int position; +/////////////////////////////////////////////////////////////////////////////// + position = GetPos(); + return position / 1024.0f; +} + +void CSlider::OnLButtonDown(UINT nFlags, CPoint point) +{ + // MARK THE DRAG + m_pressed = TRUE; + CSliderCtrl::OnLButtonDown(nFlags, point); +} + +void CSlider::OnMouseMove(UINT nFlags, CPoint point) +{ + // IF I AM DRAGGING, REDRAW MY MAIN WINDOW + if (m_pressed) + GetParent()->InvalidateRect(NULL); + CSliderCtrl::OnMouseMove(nFlags, point); +} + +void CSlider::OnLButtonUp(UINT nFlags, CPoint point) +{ + // NOT DRAGGING ANY MORE + m_pressed = FALSE; + CSliderCtrl::OnLButtonUp(nFlags, point); +} diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.h index 06570a8..94451bb 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/Slider.h @@ -1,52 +1,52 @@ -#if !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// Slider.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSlider window - -class CSlider : public CSliderCtrl -{ -// Construction -public: - CSlider(); - float GetSetting(); - -// Attributes -private: - BOOL m_pressed; -// Operations -public: - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSlider) - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CSlider(); - - // Generated message map functions -protected: - //{{AFX_MSG(CSlider) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - //}}AFX_MSG - - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) +#if !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// Slider.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSlider window + +class CSlider : public CSliderCtrl +{ +// Construction +public: + CSlider(); + float GetSetting(); + +// Attributes +private: + BOOL m_pressed; +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSlider) + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CSlider(); + + // Generated message map functions +protected: + //{{AFX_MSG(CSlider) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SLIDER_H__708CA800_BE37_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.cpp b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.cpp index 3307002..228dea4 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.cpp +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Slash.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Slash.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.h index ddefdab..571c76c 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/resource.h b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/resource.h index 07aef8f..b8f4183 100644 --- a/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/resource.h +++ b/Using Quaterions for Animation in OpenGL Part 2, Interpolation/Code/OGL/SlashHarder/resource.h @@ -1,35 +1,35 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Slash.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SLASHTYPE 129 -#define IDD_SETROTATE 130 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_ZAXIS 1002 -#define IDC_SLIDER1 1002 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_ENDKEY 32776 -#define ID_CONTROL_UPPERARM 32777 -#define ID_CONTROL_LOWERARM 32778 -#define ID_CONTROL_HAND 32779 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 132 -#define _APS_NEXT_COMMAND_VALUE 32780 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Slash.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SLASHTYPE 129 +#define IDD_SETROTATE 130 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_ZAXIS 1002 +#define IDC_SLIDER1 1002 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_ENDKEY 32776 +#define ID_CONTROL_UPPERARM 32777 +#define ID_CONTROL_LOWERARM 32778 +#define ID_CONTROL_HAND 32779 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 132 +#define _APS_NEXT_COMMAND_VALUE 32780 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.cpp index 85acdaf..880329c 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.cpp @@ -1,246 +1,246 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Quaternion Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#include "stdafx.h" -#include "Slash.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_KEYDOWN() - ON_WM_KEYUP() - ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) - ON_COMMAND(ID_VIEW_USEQUATERNIONS, OnViewUsequaternions) - ON_UPDATE_COMMAND_UI(ID_VIEW_USEQUATERNIONS, OnUpdateViewUsequaternions) - ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) - ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_STATUS, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_ROT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_QUAT, // MY ADDITION FOR PUTTING SETTINGS - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - - InitializeSkeleton(); -} - -CMainFrame::~CMainFrame() -{ - free(m_Skeleton.children); -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - m_OGLView.m_ptrStatusBar = &m_wndStatusBar; - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Skeleton); // - 60 bottom - m_OGLView.ShowWindow(TRUE); - - m_OGLView.Invalidate(TRUE); - - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ -/// Local Variables /////////////////////////////////////////////////////////// - HICON hicon; -/////////////////////////////////////////////////////////////////////////////// - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnHelpWhichopengl -// Purpose: Create dialog to Show which version of OGL is running -// Notes: Pretty Handy info for debugging -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnHelpWhichopengl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -void CMainFrame::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - m_OGLView.drawScene(); -} - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom - CFrameWnd::OnSize(nType, cx, cy); -} - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - switch (nChar) - { - case 'Q': - break; - } - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *tempBones; -/////////////////////////////////////////////////////////////////////////////// - - // INITIALIZE SOME OF THE SKELETON VARIABLES - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.b_trans.y = -4.0f; // was -4 - m_Skeleton.b_trans.z = -100.0f; - m_Skeleton.trans.y = 0.0f; // -4 - m_Skeleton.trans.z = -100.0f; - - // ALLOC ROOM FOR BONES - tempBones = (t_Bone *)malloc(2 * sizeof(t_Bone)); - - m_Skeleton.childCnt = 1; - m_Skeleton.children = tempBones; - - ResetBone(&tempBones[0], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - ResetBone(&tempBones[1], &m_Skeleton); // SETUP INITIAL BONE SETTINGS - - tempBones[0].childCnt = 1; - tempBones[0].children = &tempBones[1]; - tempBones[0].trans.x = 0; - tempBones[0].rot.x = 0.0; - tempBones[0].rot.y = 0.0; - tempBones[0].rot.z = 0.0; - - tempBones[1].trans.y = 4; - -} - - -// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG -void CMainFrame::OnViewGeometry() -{ - m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS -void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); -} - -// TOGGLE THE STATUS OF THE USE QUATERNIONS FLAG -void CMainFrame::OnViewUsequaternions() -{ - m_OGLView.m_UseQuat = !m_OGLView.m_UseQuat; - m_OGLView.drawScene(); -} - -// SET THE CHECKED STATUS OF THE USE QUATERNIONS MENU BASED ON STATUS -void CMainFrame::OnUpdateViewUsequaternions(CCmdUI* pCmdUI) -{ - pCmdUI->SetCheck( m_OGLView.m_UseQuat ); -} - +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Quaternion Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "stdafx.h" +#include "Slash.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_GEOMETRY, OnViewGeometry) + ON_COMMAND(ID_VIEW_USEQUATERNIONS, OnViewUsequaternions) + ON_UPDATE_COMMAND_UI(ID_VIEW_USEQUATERNIONS, OnUpdateViewUsequaternions) + ON_UPDATE_COMMAND_UI(ID_VIEW_GEOMETRY, OnUpdateViewGeometry) + ON_COMMAND(ID_HELP_WHICHOPENGL, OnHelpWhichopengl) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_STATUS, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_ROT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_QUAT, // MY ADDITION FOR PUTTING SETTINGS + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + + InitializeSkeleton(); +} + +CMainFrame::~CMainFrame() +{ + free(m_Skeleton.children); +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + m_OGLView.m_ptrStatusBar = &m_wndStatusBar; + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, CRect(1, 1,rect.right - 3,rect.bottom),this,104,&m_Skeleton); // - 60 bottom + m_OGLView.ShowWindow(TRUE); + + m_OGLView.Invalidate(TRUE); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ +/// Local Variables /////////////////////////////////////////////////////////// + HICON hicon; +/////////////////////////////////////////////////////////////////////////////// + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnHelpWhichopengl +// Purpose: Create dialog to Show which version of OGL is running +// Notes: Pretty Handy info for debugging +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnHelpWhichopengl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +void CMainFrame::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + m_OGLView.drawScene(); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + m_OGLView.SetWindowPos( &wndTopMost, 1, 1, cx - 3, cy - 20 , SWP_NOZORDER ); // -60 bottom + CFrameWnd::OnSize(nType, cx, cy); +} + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + switch (nChar) + { + case 'Q': + break; + } + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *tempBones; +/////////////////////////////////////////////////////////////////////////////// + + // INITIALIZE SOME OF THE SKELETON VARIABLES + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.b_trans.y = -4.0f; // was -4 + m_Skeleton.b_trans.z = -100.0f; + m_Skeleton.trans.y = 0.0f; // -4 + m_Skeleton.trans.z = -100.0f; + + // ALLOC ROOM FOR BONES + tempBones = (t_Bone *)malloc(2 * sizeof(t_Bone)); + + m_Skeleton.childCnt = 1; + m_Skeleton.children = tempBones; + + ResetBone(&tempBones[0], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + ResetBone(&tempBones[1], &m_Skeleton); // SETUP INITIAL BONE SETTINGS + + tempBones[0].childCnt = 1; + tempBones[0].children = &tempBones[1]; + tempBones[0].trans.x = 0; + tempBones[0].rot.x = 0.0; + tempBones[0].rot.y = 0.0; + tempBones[0].rot.z = 0.0; + + tempBones[1].trans.y = 4; + +} + + +// TOGGLE THE STATUS OF THE VIEW GEOMETRY FLAG +void CMainFrame::OnViewGeometry() +{ + m_OGLView.m_DrawGeometry = !m_OGLView.m_DrawGeometry; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE VIEW GEOMETRY MENU BASED ON STATUS +void CMainFrame::OnUpdateViewGeometry(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_DrawGeometry ); +} + +// TOGGLE THE STATUS OF THE USE QUATERNIONS FLAG +void CMainFrame::OnViewUsequaternions() +{ + m_OGLView.m_UseQuat = !m_OGLView.m_UseQuat; + m_OGLView.drawScene(); +} + +// SET THE CHECKED STATUS OF THE USE QUATERNIONS MENU BASED ON STATUS +void CMainFrame::OnUpdateViewUsequaternions(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck( m_OGLView.m_UseQuat ); +} + diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.h index 1baef8d..808e599 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/MainFrm.h @@ -1,86 +1,86 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - COGLView m_OGLView; - -// Operations -public: - CMainFrame(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - CStatusBar m_wndStatusBar; - t_Bone m_Skeleton; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewGeometry(); - afx_msg void OnViewUsequaternions(); - afx_msg void OnUpdateViewUsequaternions(CCmdUI* pCmdUI); - afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); - afx_msg void OnHelpWhichopengl(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + COGLView m_OGLView; + +// Operations +public: + CMainFrame(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + t_Bone m_Skeleton; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewGeometry(); + afx_msg void OnViewUsequaternions(); + afx_msg void OnUpdateViewUsequaternions(CCmdUI* pCmdUI); + afx_msg void OnUpdateViewGeometry(CCmdUI* pCmdUI); + afx_msg void OnHelpWhichopengl(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__082DB1E8_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Model.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Model.h index a045176..46d734f 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Model.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Model.h @@ -1,71 +1,71 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// d:\outfile.h : Geometry Header File -// -// Purpose: Auto-Generated from Softimage -// -/////////////////////////////////////////////////////////////////////////////// - -#define SwordFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY -#define SwordPOLYCNT 26 // NUMBER OF POLYGONS IN THE MODEL -short gSword[SwordPOLYCNT][4] = -{ - { 0,1,3,2 }, - { 1,5,7,3 }, - { 5,4,6,7 }, - { 4,0,2,6 }, - { 4,5,1,0 }, - { 26,24,25,27 }, - { 6,2,8,9 }, - { 13,15,14,12 }, - { 3,7,10,11 }, - { 18,17,16,19 }, - { 10,7,13,12 }, - { 6,9,14,15 }, - { 9,10,12,14 }, - { 7,6,15,13 }, - { 3,11,16,17 }, - { 8,2,18,19 }, - { 11,8,19,16 }, - { 2,3,17,18 }, - { 11,10,21,20 }, - { 8,11,20,22 }, - { 9,8,22,23 }, - { 10,9,23,21 }, - { 20,21,25,24 }, - { 22,20,24,26 }, - { 23,22,26,27 }, - { 21,23,27,25 }, -}; - -GLfloat gSwordModel[] = -{ - 0.304688, 0.214844, 0.078125, -0.598001, -1.696002, -0.598001, - 0.304688, 0.214844, 0.078125, -0.598001, -1.696002, 0.598001, - 0.593750, 0.375000, 0.093750, -0.500000, 1.000000, -0.500000, - 0.593750, 0.375000, 0.093750, -0.500000, 1.000000, 0.500000, - 0.304688, 0.214844, 0.078125, 0.598001, -1.696002, -0.598001, - 0.304688, 0.214844, 0.078125, 0.598001, -1.696002, 0.598001, - 0.593750, 0.375000, 0.093750, 0.500000, 1.000000, -0.500000, - 0.593750, 0.375000, 0.093750, 0.500000, 1.000000, 0.500000, - 0.843750, 0.859375, 0.843750, -1.000000, 2.000000, -1.000000, - 0.843750, 0.859375, 0.843750, 1.000000, 2.000000, -1.000000, - 0.843750, 0.859375, 0.843750, 1.000000, 2.000000, 1.000000, - 0.843750, 0.859375, 0.843750, -1.000000, 2.000000, 1.000000, - 0.937500, 0.812500, 0.000000, 3.000000, 2.500000, 0.500000, - 0.937500, 0.812500, 0.000000, 3.000000, 2.000000, 0.500000, - 0.937500, 0.812500, 0.000000, 3.000000, 2.500000, -0.500000, - 0.937500, 0.812500, 0.000000, 3.000000, 2.000000, -0.500000, - 0.937500, 0.812500, 0.000000, -3.000000, 2.500000, 0.500000, - 0.937500, 0.812500, 0.000000, -3.000000, 2.000000, 0.500000, - 0.937500, 0.812500, 0.000000, -3.000000, 2.000000, -0.500000, - 0.937500, 0.812500, 0.000000, -3.000000, 2.500000, -0.500000, - 0.695313, 0.695313, 0.695313, -1.000000, 4.000000, 0.500000, - 0.695313, 0.695313, 0.695313, 1.000000, 4.000000, 0.500000, - 0.695313, 0.695313, 0.695313, -1.000000, 4.000000, -0.500000, - 0.695313, 0.695313, 0.695313, 1.000000, 4.000000, -0.500000, - 0.968750, 0.984375, 0.968750, -0.500000, 8.000000, 0.000000, - 0.968750, 0.984375, 0.968750, 0.500000, 8.000000, 0.000000, - 0.968750, 0.984375, 0.968750, -0.500000, 8.000000, 0.000000, - 0.968750, 0.984375, 0.968750, 0.500000, 8.000000, 0.000000, -}; +/////////////////////////////////////////////////////////////////////////////// +// +// d:\outfile.h : Geometry Header File +// +// Purpose: Auto-Generated from Softimage +// +/////////////////////////////////////////////////////////////////////////////// + +#define SwordFORMAT GL_C3F_V3F // MODEL HAS COLOR AND VERTEX ONLY +#define SwordPOLYCNT 26 // NUMBER OF POLYGONS IN THE MODEL +short gSword[SwordPOLYCNT][4] = +{ + { 0,1,3,2 }, + { 1,5,7,3 }, + { 5,4,6,7 }, + { 4,0,2,6 }, + { 4,5,1,0 }, + { 26,24,25,27 }, + { 6,2,8,9 }, + { 13,15,14,12 }, + { 3,7,10,11 }, + { 18,17,16,19 }, + { 10,7,13,12 }, + { 6,9,14,15 }, + { 9,10,12,14 }, + { 7,6,15,13 }, + { 3,11,16,17 }, + { 8,2,18,19 }, + { 11,8,19,16 }, + { 2,3,17,18 }, + { 11,10,21,20 }, + { 8,11,20,22 }, + { 9,8,22,23 }, + { 10,9,23,21 }, + { 20,21,25,24 }, + { 22,20,24,26 }, + { 23,22,26,27 }, + { 21,23,27,25 }, +}; + +GLfloat gSwordModel[] = +{ + 0.304688, 0.214844, 0.078125, -0.598001, -1.696002, -0.598001, + 0.304688, 0.214844, 0.078125, -0.598001, -1.696002, 0.598001, + 0.593750, 0.375000, 0.093750, -0.500000, 1.000000, -0.500000, + 0.593750, 0.375000, 0.093750, -0.500000, 1.000000, 0.500000, + 0.304688, 0.214844, 0.078125, 0.598001, -1.696002, -0.598001, + 0.304688, 0.214844, 0.078125, 0.598001, -1.696002, 0.598001, + 0.593750, 0.375000, 0.093750, 0.500000, 1.000000, -0.500000, + 0.593750, 0.375000, 0.093750, 0.500000, 1.000000, 0.500000, + 0.843750, 0.859375, 0.843750, -1.000000, 2.000000, -1.000000, + 0.843750, 0.859375, 0.843750, 1.000000, 2.000000, -1.000000, + 0.843750, 0.859375, 0.843750, 1.000000, 2.000000, 1.000000, + 0.843750, 0.859375, 0.843750, -1.000000, 2.000000, 1.000000, + 0.937500, 0.812500, 0.000000, 3.000000, 2.500000, 0.500000, + 0.937500, 0.812500, 0.000000, 3.000000, 2.000000, 0.500000, + 0.937500, 0.812500, 0.000000, 3.000000, 2.500000, -0.500000, + 0.937500, 0.812500, 0.000000, 3.000000, 2.000000, -0.500000, + 0.937500, 0.812500, 0.000000, -3.000000, 2.500000, 0.500000, + 0.937500, 0.812500, 0.000000, -3.000000, 2.000000, 0.500000, + 0.937500, 0.812500, 0.000000, -3.000000, 2.000000, -0.500000, + 0.937500, 0.812500, 0.000000, -3.000000, 2.500000, -0.500000, + 0.695313, 0.695313, 0.695313, -1.000000, 4.000000, 0.500000, + 0.695313, 0.695313, 0.695313, 1.000000, 4.000000, 0.500000, + 0.695313, 0.695313, 0.695313, -1.000000, 4.000000, -0.500000, + 0.695313, 0.695313, 0.695313, 1.000000, 4.000000, -0.500000, + 0.968750, 0.984375, 0.968750, -0.500000, 8.000000, 0.000000, + 0.968750, 0.984375, 0.968750, 0.500000, 8.000000, 0.000000, + 0.968750, 0.984375, 0.968750, -0.500000, 8.000000, 0.000000, + 0.968750, 0.984375, 0.968750, 0.500000, 8.000000, 0.000000, +}; diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.cpp index 557e943..46269ce 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.cpp @@ -1,530 +1,530 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Slash.h" -#include "OGLView.h" -#include "Model.h" // SOFTIMAGE MODEL DATA -#include "SetRot.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_DrawGeometry = TRUE; - m_UseQuat = TRUE; - m_Skeleton = NULL; -} - -COGLView::~COGLView() -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: UpdateStatus -// Purpose: Update the status bar with orientation info -/////////////////////////////////////////////////////////////////////////////// -void COGLView::UpdateStatus() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - - // PRINT IF I AM IN EULER OR QUATERNION MODE - if (m_UseQuat) - m_ptrStatusBar->SetPaneText(1,"Quaternion Mode"); - else - m_ptrStatusBar->SetPaneText(1,"Euler Mode"); - - // PRINT THE CURRENT EULER ANGLES - sprintf(message,"Rot (%.1f,%.1f,%.1f)", - m_Skeleton->children->rot.x, - m_Skeleton->children->rot.y, - m_Skeleton->children->rot.z); - m_ptrStatusBar->SetPaneText(2,message); - - // PRINT THE CURRENT QUATERNION - sprintf(message,"Q (%.2f,%.2f,%.2f) %.2f", - m_Skeleton->children->quat.x, - m_Skeleton->children->quat.y, - m_Skeleton->children->quat.z, - m_Skeleton->children->quat.w); - m_ptrStatusBar->SetPaneText(3,message); -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext) -{ - m_Skeleton = skeleton; - UpdateStatus(); // DRAW INITIAL STATUS BAR - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_SIZE() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glPushMatrix(); - glScalef(4.0,4.0,4.0); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glPopMatrix(); - glEndList(); - - - drawScene(); - return 0; -} - -/* OpenGL code */ -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect, 1.0, 2000.0); - glMatrixMode(GL_MODELVIEW); -} - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); -} - -// GET THE INFO ON THE VERSION OF OPENGL RUNNING -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawModel -// Purpose: Draws the model associated with a bone -// Notes: Currently uses a global model not associated with the bone -// The data uses Quads with shared vertices and vertex coloring -// so I chose to use indexed vertex arrays -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawModel(t_Bone *curBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop,pointloop; -/////////////////////////////////////////////////////////////////////////////// - // Declare the Array of Data - glInterleavedArrays(SwordFORMAT,0,(GLvoid *)&gSwordModel); - // Draw all the Quads at once - glDrawElements(GL_QUADS,SwordPOLYCNT * 4,GL_UNSIGNED_SHORT,gSword); - - // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER -/* glBegin(GL_QUADS); - for (loop = 0; loop < SwordPOLYCNT; loop++) - { - for (pointloop = 0; pointloop < 4; pointloop++) - { - glArrayElement(gSword[loop][pointloop]); - } - } - glEnd();*/ -} -// drawModel - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: drawScene -// Purpose: Draws the current OpenGL scene -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; - tQuaternion axisAngle,temp; -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; - if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; - if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); - - // ROTATE THE ROOT - glRotatef(m_Skeleton->rot.z, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton->rot.x, 0.0f, 0.0f, 1.0f); - - curBone = m_Skeleton->children; - for (loop = 0; loop < m_Skeleton->childCnt; loop++) - { - glPushMatrix(); - - // TRANSLATE OUT THE LOCAL BONE - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - // CONVERT THE EULER TO QUATERNION. STORE IT FOR DISPLAY AND USE - EulerToQuaternion(&curBone->rot,&curBone->quat); - // TEST OF DIFFERENT METHOD OF CONVERSION - // EulerToQuaternion2(&curBone->rot,&curBone->quat); - if (m_UseQuat) - { - // QUATERNION HAS TO BE CONVERTED TO AN AXIS/ANGLE REPRESENTATION - QuatToAxisAngle(&curBone->quat,&axisAngle); - AxisAngleToQuat((tVector *)&axisAngle, axisAngle.w, &temp); - // DO THE ROTATION - glRotatef(axisAngle.w, axisAngle.x, axisAngle.y, axisAngle.z); - } - else - { - // Rotate out the model via Euler angles - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - - } - - // IF I WANT TO, DRAW THE GEOMETRY - if (m_DrawGeometry) - drawModel(curBone); - - // DRAW THE AXIS - glCallList(OGL_AXIS_DLIST); - - glPopMatrix(); - - curBone++; - } - - glPopMatrix(); - glFinish(); - - SwapBuffers(m_hDC); - - // DRAW THE STATS AT THE BOTTOM OF THE SCREEN - UpdateStatus(); -} -// drawScene - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - drawScene(); - - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnSize(UINT nType, int cx, int cy) -{ - // RESIZE THE OPENGL WINDOW -// resize( cx,cy ); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDown -// Purpose: Left button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Grab_Rot_X = m_Skeleton->children->rot.x; - m_Grab_Rot_Y = m_Skeleton->children->rot.y; - m_Grab_Rot_Z = m_Skeleton->children->rot.z; - m_Grab_Trans_X = m_Skeleton->trans.x; - m_Grab_Trans_Y = m_Skeleton->trans.y; - m_Grab_Trans_Z = m_Skeleton->trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnRButtonDown -// Purpose: Right button down grabs the current point pos so I can use it -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - m_mousepos = point; - m_Grab_Rot_X = m_Skeleton->children->rot.x; - m_Grab_Rot_Y = m_Skeleton->children->rot.y; - m_Grab_Rot_Z = m_Skeleton->children->rot.z; - m_Grab_Trans_X = m_Skeleton->trans.x; - m_Grab_Trans_Y = m_Skeleton->trans.y; - m_Grab_Trans_Z = m_Skeleton->trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ - tVector euler; - switch (nChar) - { - case 'G': - m_DrawGeometry = !m_DrawGeometry; - break; - case 'E': - QuatToEuler(&m_Skeleton->children->quat, &euler); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnMouseMove -// Purpose: Handle mouse moves while pressed -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CONTROL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton->trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); - drawScene(); - } - } - // ELSE ROTATE THE BONE - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->children->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_Skeleton->children->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - } - else - { - if ((point.x - m_mousepos.x) != 0) - { - m_Skeleton->children->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - } - CWnd::OnMouseMove(nFlags, point); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnLButtonDblClk -// Purpose: Left Double click, get dialog for Orientation -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - CSetRot dialog; - dialog.m_XAxis = m_Skeleton->children->rot.x; - dialog.m_YAxis = m_Skeleton->children->rot.y; - dialog.m_ZAxis = m_Skeleton->children->rot.z; - if (dialog.DoModal()) - { - m_Skeleton->children->rot.x = dialog.m_XAxis; - m_Skeleton->children->rot.y = dialog.m_YAxis; - m_Skeleton->children->rot.z = dialog.m_ZAxis; - } - drawScene(); -} +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Slash.h" +#include "OGLView.h" +#include "Model.h" // SOFTIMAGE MODEL DATA +#include "SetRot.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_DrawGeometry = TRUE; + m_UseQuat = TRUE; + m_Skeleton = NULL; +} + +COGLView::~COGLView() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: UpdateStatus +// Purpose: Update the status bar with orientation info +/////////////////////////////////////////////////////////////////////////////// +void COGLView::UpdateStatus() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + + // PRINT IF I AM IN EULER OR QUATERNION MODE + if (m_UseQuat) + m_ptrStatusBar->SetPaneText(1,"Quaternion Mode"); + else + m_ptrStatusBar->SetPaneText(1,"Euler Mode"); + + // PRINT THE CURRENT EULER ANGLES + sprintf(message,"Rot (%.1f,%.1f,%.1f)", + m_Skeleton->children->rot.x, + m_Skeleton->children->rot.y, + m_Skeleton->children->rot.z); + m_ptrStatusBar->SetPaneText(2,message); + + // PRINT THE CURRENT QUATERNION + sprintf(message,"Q (%.2f,%.2f,%.2f) %.2f", + m_Skeleton->children->quat.x, + m_Skeleton->children->quat.y, + m_Skeleton->children->quat.z, + m_Skeleton->children->quat.w); + m_ptrStatusBar->SetPaneText(3,message); +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext) +{ + m_Skeleton = skeleton; + UpdateStatus(); // DRAW INITIAL STATUS BAR + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glPushMatrix(); + glScalef(4.0,4.0,4.0); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glPopMatrix(); + glEndList(); + + + drawScene(); + return 0; +} + +/* OpenGL code */ +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect, 1.0, 2000.0); + glMatrixMode(GL_MODELVIEW); +} + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); +} + +// GET THE INFO ON THE VERSION OF OPENGL RUNNING +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawModel +// Purpose: Draws the model associated with a bone +// Notes: Currently uses a global model not associated with the bone +// The data uses Quads with shared vertices and vertex coloring +// so I chose to use indexed vertex arrays +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawModel(t_Bone *curBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop,pointloop; +/////////////////////////////////////////////////////////////////////////////// + // Declare the Array of Data + glInterleavedArrays(SwordFORMAT,0,(GLvoid *)&gSwordModel); + // Draw all the Quads at once + glDrawElements(GL_QUADS,SwordPOLYCNT * 4,GL_UNSIGNED_SHORT,gSword); + + // THIS CODE WAS THE EQUIVALENT OF THE FOLLOWING, BUT FASTER +/* glBegin(GL_QUADS); + for (loop = 0; loop < SwordPOLYCNT; loop++) + { + for (pointloop = 0; pointloop < 4; pointloop++) + { + glArrayElement(gSword[loop][pointloop]); + } + } + glEnd();*/ +} +// drawModel + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: drawScene +// Purpose: Draws the current OpenGL scene +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; + tQuaternion axisAngle,temp; +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; + if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; + if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); + + // ROTATE THE ROOT + glRotatef(m_Skeleton->rot.z, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton->rot.x, 0.0f, 0.0f, 1.0f); + + curBone = m_Skeleton->children; + for (loop = 0; loop < m_Skeleton->childCnt; loop++) + { + glPushMatrix(); + + // TRANSLATE OUT THE LOCAL BONE + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + // CONVERT THE EULER TO QUATERNION. STORE IT FOR DISPLAY AND USE + EulerToQuaternion(&curBone->rot,&curBone->quat); + // TEST OF DIFFERENT METHOD OF CONVERSION + // EulerToQuaternion2(&curBone->rot,&curBone->quat); + if (m_UseQuat) + { + // QUATERNION HAS TO BE CONVERTED TO AN AXIS/ANGLE REPRESENTATION + QuatToAxisAngle(&curBone->quat,&axisAngle); + AxisAngleToQuat((tVector *)&axisAngle, axisAngle.w, &temp); + // DO THE ROTATION + glRotatef(axisAngle.w, axisAngle.x, axisAngle.y, axisAngle.z); + } + else + { + // Rotate out the model via Euler angles + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + + } + + // IF I WANT TO, DRAW THE GEOMETRY + if (m_DrawGeometry) + drawModel(curBone); + + // DRAW THE AXIS + glCallList(OGL_AXIS_DLIST); + + glPopMatrix(); + + curBone++; + } + + glPopMatrix(); + glFinish(); + + SwapBuffers(m_hDC); + + // DRAW THE STATS AT THE BOTTOM OF THE SCREEN + UpdateStatus(); +} +// drawScene + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + drawScene(); + + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnSize(UINT nType, int cx, int cy) +{ + // RESIZE THE OPENGL WINDOW +// resize( cx,cy ); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDown +// Purpose: Left button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Grab_Rot_X = m_Skeleton->children->rot.x; + m_Grab_Rot_Y = m_Skeleton->children->rot.y; + m_Grab_Rot_Z = m_Skeleton->children->rot.z; + m_Grab_Trans_X = m_Skeleton->trans.x; + m_Grab_Trans_Y = m_Skeleton->trans.y; + m_Grab_Trans_Z = m_Skeleton->trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnRButtonDown +// Purpose: Right button down grabs the current point pos so I can use it +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + m_mousepos = point; + m_Grab_Rot_X = m_Skeleton->children->rot.x; + m_Grab_Rot_Y = m_Skeleton->children->rot.y; + m_Grab_Rot_Z = m_Skeleton->children->rot.z; + m_Grab_Trans_X = m_Skeleton->trans.x; + m_Grab_Trans_Y = m_Skeleton->trans.y; + m_Grab_Trans_Z = m_Skeleton->trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ + tVector euler; + switch (nChar) + { + case 'G': + m_DrawGeometry = !m_DrawGeometry; + break; + case 'E': + QuatToEuler(&m_Skeleton->children->quat, &euler); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnMouseMove +// Purpose: Handle mouse moves while pressed +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CONTROL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton->trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); + drawScene(); + } + } + // ELSE ROTATE THE BONE + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->children->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_Skeleton->children->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + } + else + { + if ((point.x - m_mousepos.x) != 0) + { + m_Skeleton->children->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + } + CWnd::OnMouseMove(nFlags, point); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnLButtonDblClk +// Purpose: Left Double click, get dialog for Orientation +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + CSetRot dialog; + dialog.m_XAxis = m_Skeleton->children->rot.x; + dialog.m_YAxis = m_Skeleton->children->rot.y; + dialog.m_ZAxis = m_Skeleton->children->rot.z; + if (dialog.DoModal()) + { + m_Skeleton->children->rot.x = dialog.m_XAxis; + m_Skeleton->children->rot.y = dialog.m_YAxis; + m_Skeleton->children->rot.z = dialog.m_ZAxis; + } + drawScene(); +} diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.h index 288a213..df53f98 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/OGLView.h @@ -1,94 +1,94 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - CStatusBar *m_ptrStatusBar; - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - BOOL m_DrawGeometry; - BOOL m_UseQuat; -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawScene(GLvoid); - GLvoid drawModel(t_Bone *curBone); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void UpdateStatus(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone *m_Skeleton; - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + CStatusBar *m_ptrStatusBar; + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + BOOL m_DrawGeometry; + BOOL m_UseQuat; +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawScene(GLvoid); + GLvoid drawModel(t_Bone *curBone); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void UpdateStatus(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone *m_Skeleton; + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.cpp index 30633d7..2a10db6 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.cpp @@ -1,446 +1,446 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.cpp : Quaternion System structure implementation file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY -// -// Created: -// JL 9/1/97 -// -// Sources: -// Shoemake, Ken, "Animating Rotations with Quaternion Curves" -// Computer Graphics 85, pp. 245-254 -// Watt and Watt, Advanced Animation and Rendering Techniques -// Addison Wesley, pp. 360-368 -// Shoemake, Graphic Gems II. -// -// Notes: -// There are a couple of methods of conversion here so it -// can be played around with a bit. One is more clear and the other -// is a bit faster. -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include -#include "skeleton.h" -#include "quatern.h" - -#define M_PI 3.14159265358979323846 -#define HALF_PI 1.57079632679489661923 - -/////////////////////////////////////////////////////////////////////////////// -// Function: CopyVector -// Purpose: Copy a vector -// Arguments: pointer to destination and source -/////////////////////////////////////////////////////////////////////////////// -void CopyVector(tVector *dest, tVector *src) -{ - dest->x = src->x; - dest->y = src->y; - dest->z = src->z; -} -//// CopyVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ScaleVector -// Purpose: Scale a vector -// Arguments: pointer to vector and scale factor -/////////////////////////////////////////////////////////////////////////////// -void ScaleVector(tVector *vect, float scale) -{ - vect->x *= scale; - vect->y *= scale; - vect->z *= scale; -} -//// ScaleVector /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: AddVectors -// Purpose: Add two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - dest->x = vect1->x + vect2->x; - dest->y = vect1->y + vect2->y; - dest->z = vect1->z + vect2->z; -} -//// AddVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: DotVectors -// Purpose: Compute the dot product of two vectors -// Arguments: pointer to vectors -// Returns: Dot product -/////////////////////////////////////////////////////////////////////////////// -float DotVectors(tVector *vect1, tVector *vect2) -{ - return (vect1->x * vect2->x) + - (vect1->y * vect2->y) + - (vect1->z * vect2->z); -} -//// DotVectors /////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: CrossVectors -// Purpose: Computes the cross product of two vectors -// Arguments: pointer to vectors and dest -/////////////////////////////////////////////////////////////////////////////// -void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) -{ - // COMPUTE THE CROSS PRODUCT - dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); - dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); - dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); -} -//// CrossVectors ///////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ -/// Local Variables /////////////////////////////////////////////////////////// - tQuaternion v1,v2,v3,vf; -/////////////////////////////////////////////////////////////////////////////// - - CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 - ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 - - CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); - - AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); - AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); - - vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); - - dest->x = vf.x; - dest->y = vf.y; - dest->z = vf.z; - dest->w = vf.w; -} -//// MultQuaternions ////////////////////////////////////////////////////////// - -/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR - I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY - THE MATH CHECKS OUT THOUGH */ -/////////////////////////////////////////////////////////////////////////////// -// Function: MultQuaternions2 -// Purpose: Computes the product of two quaternions -// Arguments: pointer to quaternions and dest -/////////////////////////////////////////////////////////////////////////////// -void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) -{ - tQuaternion tmp; - tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + - quat2->y * quat1->z - quat2->z * quat1->y; - tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + - quat2->z * quat1->x - quat2->x * quat1->z; - tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + - quat2->x * quat1->y - quat2->y * quat1->x; - tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - - quat2->y * quat1->y - quat2->z * quat1->z; - dest->x = tmp.x; dest->y = tmp.y; - dest->z = tmp.z; dest->w = tmp.w; -} -//// MultQuaternions2 ////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: NormalizeQuaternion -// Purpose: Normalize a Quaternion -// Arguments: a quaternion to set -// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 -// This function insures this -/////////////////////////////////////////////////////////////////////////////// -void NormalizeQuaternion(tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float magnitude; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, FIND THE MAGNITUDE - magnitude = (quat->x * quat->x) + - (quat->y * quat->y) + - (quat->z * quat->z) + - (quat->w * quat->w); - - // DIVIDE BY THE MAGNITUDE TO NORMALIZE - quat->x = quat->x / magnitude; - quat->y = quat->y / magnitude; - quat->z = quat->z / magnitude; - quat->w = quat->w / magnitude; -} -// NormalizeQuaternion /////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT -// A SERIES OF ROTATIONS TO QUATERNIONS. -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted. It is more efficient this way though. -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - tx = rx * (float)0.5; - ty = ry * (float)0.5; - tz = rz * (float)0.5; - cx = (float)cos(tx); - cy = (float)cos(ty); - cz = (float)cos(tz); - sx = (float)sin(tx); - sy = (float)sin(ty); - sz = (float)sin(tz); - - cc = cx * cz; - cs = cx * sz; - sc = sx * cz; - ss = sx * sz; - - quat->x = (cy * sc) - (sy * cs); - quat->y = (cy * ss) + (sy * cc); - quat->z = (cy * cs) - (sy * sc); - quat->w = (cy * cc) + (sy * ss); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(quat); -} -// EulerToQuaternion ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -// Discussion: This is a second variation. It creates a -// Series of quaternions and multiplies them together -// It would be easier to extend this for other rotation orders -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float rx,ry,rz,ti,tj,tk; - tQuaternion qx,qy,qz,qf; -/////////////////////////////////////////////////////////////////////////////// - // FIRST STEP, CONVERT ANGLES TO RADIANS - rx = (rot->x * (float)M_PI) / (360 / 2); - ry = (rot->y * (float)M_PI) / (360 / 2); - rz = (rot->z * (float)M_PI) / (360 / 2); - // GET THE HALF ANGLES - ti = rx * (float)0.5; - tj = ry * (float)0.5; - tk = rz * (float)0.5; - - qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); - qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); - qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); - - MultQuaternions(&qx,&qy,&qf); - MultQuaternions(&qf,&qz,&qf); - -// ANOTHER TEST VARIATION -// MultQuaternions2(&qx,&qy,&qf); -// MultQuaternions2(&qf,&qz,&qf); - - // INSURE THE QUATERNION IS NORMALIZED - // PROBABLY NOT NECESSARY IN MOST CASES - NormalizeQuaternion(&qf); - - quat->x = qf.x; - quat->y = qf.y; - quat->z = qf.z; - quat->w = qf.w; - -} -// EulerToQuaternion2 ///////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float scale,tw; -/////////////////////////////////////////////////////////////////////////////// - tw = (float)acos(quat->w) * 2; - scale = (float)sin(tw / 2.0); - axisAngle->x = quat->x / scale; - axisAngle->y = quat->y / scale; - axisAngle->z = quat->z / scale; - - // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES - axisAngle->w = (tw * (360 / 2)) / (float)M_PI; -} -// QuatToAxisAngle ///////////////////////////////////////////////////////// - -void AxisAngleToQuat(const tVector *axis, const float angle, tQuaternion *quat) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float scale,tw; -/////////////////////////////////////////////////////////////////////////////// - tw = (angle * (float)M_PI)/(180.0f); // TO RADIANS - quat->w = cos(tw / 2.0f); - scale = (float)sin(tw / 2.0); - quat->x = axis->x * scale; - quat->y = axis->y * scale; - quat->z = axis->z * scale; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToEuler -// Purpose: Convert a Quaternion back to Euler Angles -// Arguments: Quaternions and target Euler vector -// Notes: The method is to convert Quaternion to a 3x3 matrix and -// decompose the matrix. This is subject to the -// ambiguities of square roots and problems with inverse trig. -// Matrix to Euler conversion is really very ill-defined but works -// for my purposes. -/////////////////////////////////////////////////////////////////////////////// -void QuatToEuler(const tQuaternion *quat, tVector *euler) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float matrix[3][3]; - float cx,sx,x; - float cy,sy,y,yr; - float cz,sz,z; -/////////////////////////////////////////////////////////////////////////////// - // CONVERT QUATERNION TO MATRIX - I DON'T REALLY NEED ALL OF IT - matrix[0][0] = 1.0f - (2.0f * quat->y * quat->y) - (2.0f * quat->z * quat->z); -// matrix[0][1] = (2.0f * quat->x * quat->y) - (2.0f * quat->w * quat->z); -// matrix[0][2] = (2.0f * quat->x * quat->z) + (2.0f * quat->w * quat->y); - matrix[1][0] = (2.0f * quat->x * quat->y) + (2.0f * quat->w * quat->z); -// matrix[1][1] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->z * quat->z); -// matrix[1][2] = (2.0f * quat->y * quat->z) - (2.0f * quat->w * quat->x); - matrix[2][0] = (2.0f * quat->x * quat->z) - (2.0f * quat->w * quat->y); - matrix[2][1] = (2.0f * quat->y * quat->z) + (2.0f * quat->w * quat->x); - matrix[2][2] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->y * quat->y); - - sy = -matrix[2][0]; - cy = sqrt(1 - (sy * sy)); - yr = (float)atan2(sy,cy); - euler->y = (yr * 180.0f) / (float)M_PI; - - // AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270 - // NOT CHECKING cy BECAUSE OF PRECISION ERRORS - if (sy != 1.0f && sy != -1.0f) - { - cx = matrix[2][2] / cy; - sx = matrix[2][1] / cy; - euler->x = ((float)atan2(sx,cx) * 180.0f) / (float)M_PI; // RAD TO DEG - - cz = matrix[0][0] / cy; - sz = matrix[1][0] / cy; - euler->z = ((float)atan2(sz,cz) * 180.0f) / (float)M_PI; // RAD TO DEG - } - else - { - // SINCE Cos(Y) IS 0, I AM SCREWED. ADOPT THE STANDARD Z = 0 - // I THINK THERE IS A WAY TO FIX THIS BUT I AM NOT SURE. EULERS SUCK - // NEED SOME MORE OF THE MATRIX TERMS NOW - matrix[1][1] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->z * quat->z); - matrix[1][2] = (2.0f * quat->y * quat->z) - (2.0f * quat->w * quat->x); - cx = matrix[1][1]; - sx = -matrix[1][2]; - euler->x = ((float)atan2(sx,cx) * 180.0f) / (float)M_PI; // RAD TO DEG - - cz = 1.0f; - sz = 0.0f; - euler->z = ((float)atan2(sz,cz) * 180.0f) / (float)M_PI; // RAD TO DEG - } -} -// QuatToEuler /////////////////////////////////////////////////////////////// - -// THIS ROUTINE IS REALLY FOR THE APRIL ARTICLE BUT IF YOU WANT TO PLAY -// AROUND WITH IT, HERE IT IS. - -#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -// Notes: The comments explain the handling of the special cases. -// The comments in the magazine were wrong. Adjust the -// DELTA constant to play with the LERP vs. SLERP level -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) -{ -/// Local Variables /////////////////////////////////////////////////////////// - double omega,cosom,sinom,scale0,scale1; -/////////////////////////////////////////////////////////////////////////////// - // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE - // QUATERNIONS - cosom = quat1->x * quat2->x + - quat1->y * quat2->y + - quat1->z * quat2->z + - quat1->w * quat2->w; - - // CHECK A COUPLE OF SPECIAL CASES. - // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) - if ((1.0 + cosom) > DELTA) - { - // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT - if ((1.0 - cosom) > DELTA) { - // YES, DO A SLERP - omega = acos(cosom); - sinom = sin(omega); - scale0 = sin((1.0 - slerp) * omega) / sinom; - scale1 = sin(slerp * omega) / sinom; - } else { - // NOT A VERY BIG DIFFERENCE, DO A LERP - scale0 = 1.0 - slerp; - scale1 = slerp; - } - result->x = scale0 * quat1->x + scale1 * quat2->x; - result->y = scale0 * quat1->y + scale1 * quat2->y; - result->z = scale0 * quat1->z + scale1 * quat2->z; - result->w = scale0 * quat1->w + scale1 * quat2->w; - } else { - // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR - // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION - result->x = -quat2->y; - result->y = quat2->x; - result->z = -quat2->w; - result->w = quat2->z; - scale0 = sin((1.0 - slerp) * (float)HALF_PI); - scale1 = sin(slerp * (float)HALF_PI); - result->x = scale0 * quat1->x + scale1 * result->x; - result->y = scale0 * quat1->y + scale1 * result->y; - result->z = scale0 * quat1->z + scale1 * result->z; - result->w = scale0 * quat1->w + scale1 * result->w; - } - -} -// SlerpQuat ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.cpp : Quaternion System structure implementation file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// ALSO NOT TOTALLY OPTIMIZED AND TRICKED OUT FOR CLARITY +// +// Created: +// JL 9/1/97 +// +// Sources: +// Shoemake, Ken, "Animating Rotations with Quaternion Curves" +// Computer Graphics 85, pp. 245-254 +// Watt and Watt, Advanced Animation and Rendering Techniques +// Addison Wesley, pp. 360-368 +// Shoemake, Graphic Gems II. +// +// Notes: +// There are a couple of methods of conversion here so it +// can be played around with a bit. One is more clear and the other +// is a bit faster. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include +#include "skeleton.h" +#include "quatern.h" + +#define M_PI 3.14159265358979323846 +#define HALF_PI 1.57079632679489661923 + +/////////////////////////////////////////////////////////////////////////////// +// Function: CopyVector +// Purpose: Copy a vector +// Arguments: pointer to destination and source +/////////////////////////////////////////////////////////////////////////////// +void CopyVector(tVector *dest, tVector *src) +{ + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} +//// CopyVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ScaleVector +// Purpose: Scale a vector +// Arguments: pointer to vector and scale factor +/////////////////////////////////////////////////////////////////////////////// +void ScaleVector(tVector *vect, float scale) +{ + vect->x *= scale; + vect->y *= scale; + vect->z *= scale; +} +//// ScaleVector /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: AddVectors +// Purpose: Add two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void AddVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + dest->x = vect1->x + vect2->x; + dest->y = vect1->y + vect2->y; + dest->z = vect1->z + vect2->z; +} +//// AddVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: DotVectors +// Purpose: Compute the dot product of two vectors +// Arguments: pointer to vectors +// Returns: Dot product +/////////////////////////////////////////////////////////////////////////////// +float DotVectors(tVector *vect1, tVector *vect2) +{ + return (vect1->x * vect2->x) + + (vect1->y * vect2->y) + + (vect1->z * vect2->z); +} +//// DotVectors /////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: CrossVectors +// Purpose: Computes the cross product of two vectors +// Arguments: pointer to vectors and dest +/////////////////////////////////////////////////////////////////////////////// +void CrossVectors(tVector *vect1, tVector *vect2, tVector *dest) +{ + // COMPUTE THE CROSS PRODUCT + dest->x = (vect1->y * vect2->z) - (vect1->z * vect2->y); + dest->y = (vect1->z * vect2->x) - (vect1->x * vect2->z); + dest->z = (vect1->x * vect2->y) - (vect1->y * vect2->x); +} +//// CrossVectors ///////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ +/// Local Variables /////////////////////////////////////////////////////////// + tQuaternion v1,v2,v3,vf; +/////////////////////////////////////////////////////////////////////////////// + + CopyVector((tVector *)&v1, (tVector *)quat1); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v1,quat2->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CopyVector((tVector *)&v2, (tVector *)quat2); // COPY OFF THE VECTOR PART OF THE QUAT1 + ScaleVector((tVector *)&v2,quat1->w); // MULTIPLY IT BY THE SCALAR PART OF QUAT2 + + CrossVectors((tVector *)quat2,(tVector *)quat1,(tVector *)&v3); + + AddVectors((tVector *)&v1, (tVector *)&v2, (tVector *)&vf); + AddVectors((tVector *)&v3, (tVector *)&vf, (tVector *)&vf); + + vf.w = (quat1->w * quat2->w) - DotVectors((tVector *)quat1,(tVector *)quat2); + + dest->x = vf.x; + dest->y = vf.y; + dest->z = vf.z; + dest->w = vf.w; +} +//// MultQuaternions ////////////////////////////////////////////////////////// + +/* AN OPTIMIZATION/REORGANIZATION OF ABOVE CODE - NOT AS CLEAR + I THINK THIS IS SIMILAR TO GRAPHIC GEMS THOUGH I DON'T HAVE THE REF HANDY + THE MATH CHECKS OUT THOUGH */ +/////////////////////////////////////////////////////////////////////////////// +// Function: MultQuaternions2 +// Purpose: Computes the product of two quaternions +// Arguments: pointer to quaternions and dest +/////////////////////////////////////////////////////////////////////////////// +void MultQuaternions2(tQuaternion *quat1, tQuaternion *quat2, tQuaternion *dest) +{ + tQuaternion tmp; + tmp.x = quat2->w * quat1->x + quat2->x * quat1->w + + quat2->y * quat1->z - quat2->z * quat1->y; + tmp.y = quat2->w * quat1->y + quat2->y * quat1->w + + quat2->z * quat1->x - quat2->x * quat1->z; + tmp.z = quat2->w * quat1->z + quat2->z * quat1->w + + quat2->x * quat1->y - quat2->y * quat1->x; + tmp.w = quat2->w * quat1->w - quat2->x * quat1->x - + quat2->y * quat1->y - quat2->z * quat1->z; + dest->x = tmp.x; dest->y = tmp.y; + dest->z = tmp.z; dest->w = tmp.w; +} +//// MultQuaternions2 ////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: NormalizeQuaternion +// Purpose: Normalize a Quaternion +// Arguments: a quaternion to set +// Discussion: Quaternions must follow the rules of x^2 + y^2 + z^2 + w^2 = 1 +// This function insures this +/////////////////////////////////////////////////////////////////////////////// +void NormalizeQuaternion(tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float magnitude; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, FIND THE MAGNITUDE + magnitude = (quat->x * quat->x) + + (quat->y * quat->y) + + (quat->z * quat->z) + + (quat->w * quat->w); + + // DIVIDE BY THE MAGNITUDE TO NORMALIZE + quat->x = quat->x / magnitude; + quat->y = quat->y / magnitude; + quat->z = quat->z / magnitude; + quat->w = quat->w / magnitude; +} +// NormalizeQuaternion /////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// THESE TWO PROCEDURES ARE FUNCTIONALLY EQUIVALENT. TWO METHODS TO CONVERT +// A SERIES OF ROTATIONS TO QUATERNIONS. +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted. It is more efficient this way though. +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,tx,ty,tz,cx,cy,cz,sx,sy,sz,cc,cs,sc,ss; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + tx = rx * (float)0.5; + ty = ry * (float)0.5; + tz = rz * (float)0.5; + cx = (float)cos(tx); + cy = (float)cos(ty); + cz = (float)cos(tz); + sx = (float)sin(tx); + sy = (float)sin(ty); + sz = (float)sin(tz); + + cc = cx * cz; + cs = cx * sz; + sc = sx * cz; + ss = sx * sz; + + quat->x = (cy * sc) - (sy * cs); + quat->y = (cy * ss) + (sy * cc); + quat->z = (cy * cs) - (sy * sc); + quat->w = (cy * cc) + (sy * ss); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(quat); +} +// EulerToQuaternion ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +// Discussion: This is a second variation. It creates a +// Series of quaternions and multiplies them together +// It would be easier to extend this for other rotation orders +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float rx,ry,rz,ti,tj,tk; + tQuaternion qx,qy,qz,qf; +/////////////////////////////////////////////////////////////////////////////// + // FIRST STEP, CONVERT ANGLES TO RADIANS + rx = (rot->x * (float)M_PI) / (360 / 2); + ry = (rot->y * (float)M_PI) / (360 / 2); + rz = (rot->z * (float)M_PI) / (360 / 2); + // GET THE HALF ANGLES + ti = rx * (float)0.5; + tj = ry * (float)0.5; + tk = rz * (float)0.5; + + qx.x = (float)sin(ti); qx.y = 0.0; qx.z = 0.0; qx.w = (float)cos(ti); + qy.x = 0.0; qy.y = (float)sin(tj); qy.z = 0.0; qy.w = (float)cos(tj); + qz.x = 0.0; qz.y = 0.0; qz.z = (float)sin(tk); qz.w = (float)cos(tk); + + MultQuaternions(&qx,&qy,&qf); + MultQuaternions(&qf,&qz,&qf); + +// ANOTHER TEST VARIATION +// MultQuaternions2(&qx,&qy,&qf); +// MultQuaternions2(&qf,&qz,&qf); + + // INSURE THE QUATERNION IS NORMALIZED + // PROBABLY NOT NECESSARY IN MOST CASES + NormalizeQuaternion(&qf); + + quat->x = qf.x; + quat->y = qf.y; + quat->z = qf.z; + quat->w = qf.w; + +} +// EulerToQuaternion2 ///////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float scale,tw; +/////////////////////////////////////////////////////////////////////////////// + tw = (float)acos(quat->w) * 2; + scale = (float)sin(tw / 2.0); + axisAngle->x = quat->x / scale; + axisAngle->y = quat->y / scale; + axisAngle->z = quat->z / scale; + + // NOW CONVERT THE ANGLE OF ROTATION BACK TO DEGREES + axisAngle->w = (tw * (360 / 2)) / (float)M_PI; +} +// QuatToAxisAngle ///////////////////////////////////////////////////////// + +void AxisAngleToQuat(const tVector *axis, const float angle, tQuaternion *quat) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float scale,tw; +/////////////////////////////////////////////////////////////////////////////// + tw = (angle * (float)M_PI)/(180.0f); // TO RADIANS + quat->w = cos(tw / 2.0f); + scale = (float)sin(tw / 2.0); + quat->x = axis->x * scale; + quat->y = axis->y * scale; + quat->z = axis->z * scale; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToEuler +// Purpose: Convert a Quaternion back to Euler Angles +// Arguments: Quaternions and target Euler vector +// Notes: The method is to convert Quaternion to a 3x3 matrix and +// decompose the matrix. This is subject to the +// ambiguities of square roots and problems with inverse trig. +// Matrix to Euler conversion is really very ill-defined but works +// for my purposes. +/////////////////////////////////////////////////////////////////////////////// +void QuatToEuler(const tQuaternion *quat, tVector *euler) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float matrix[3][3]; + float cx,sx,x; + float cy,sy,y,yr; + float cz,sz,z; +/////////////////////////////////////////////////////////////////////////////// + // CONVERT QUATERNION TO MATRIX - I DON'T REALLY NEED ALL OF IT + matrix[0][0] = 1.0f - (2.0f * quat->y * quat->y) - (2.0f * quat->z * quat->z); +// matrix[0][1] = (2.0f * quat->x * quat->y) - (2.0f * quat->w * quat->z); +// matrix[0][2] = (2.0f * quat->x * quat->z) + (2.0f * quat->w * quat->y); + matrix[1][0] = (2.0f * quat->x * quat->y) + (2.0f * quat->w * quat->z); +// matrix[1][1] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->z * quat->z); +// matrix[1][2] = (2.0f * quat->y * quat->z) - (2.0f * quat->w * quat->x); + matrix[2][0] = (2.0f * quat->x * quat->z) - (2.0f * quat->w * quat->y); + matrix[2][1] = (2.0f * quat->y * quat->z) + (2.0f * quat->w * quat->x); + matrix[2][2] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->y * quat->y); + + sy = -matrix[2][0]; + cy = sqrt(1 - (sy * sy)); + yr = (float)atan2(sy,cy); + euler->y = (yr * 180.0f) / (float)M_PI; + + // AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270 + // NOT CHECKING cy BECAUSE OF PRECISION ERRORS + if (sy != 1.0f && sy != -1.0f) + { + cx = matrix[2][2] / cy; + sx = matrix[2][1] / cy; + euler->x = ((float)atan2(sx,cx) * 180.0f) / (float)M_PI; // RAD TO DEG + + cz = matrix[0][0] / cy; + sz = matrix[1][0] / cy; + euler->z = ((float)atan2(sz,cz) * 180.0f) / (float)M_PI; // RAD TO DEG + } + else + { + // SINCE Cos(Y) IS 0, I AM SCREWED. ADOPT THE STANDARD Z = 0 + // I THINK THERE IS A WAY TO FIX THIS BUT I AM NOT SURE. EULERS SUCK + // NEED SOME MORE OF THE MATRIX TERMS NOW + matrix[1][1] = 1.0f - (2.0f * quat->x * quat->x) - (2.0f * quat->z * quat->z); + matrix[1][2] = (2.0f * quat->y * quat->z) - (2.0f * quat->w * quat->x); + cx = matrix[1][1]; + sx = -matrix[1][2]; + euler->x = ((float)atan2(sx,cx) * 180.0f) / (float)M_PI; // RAD TO DEG + + cz = 1.0f; + sz = 0.0f; + euler->z = ((float)atan2(sz,cz) * 180.0f) / (float)M_PI; // RAD TO DEG + } +} +// QuatToEuler /////////////////////////////////////////////////////////////// + +// THIS ROUTINE IS REALLY FOR THE APRIL ARTICLE BUT IF YOU WANT TO PLAY +// AROUND WITH IT, HERE IT IS. + +#define DELTA 0.0001 // DIFFERENCE AT WHICH TO LERP INSTEAD OF SLERP +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +// Notes: The comments explain the handling of the special cases. +// The comments in the magazine were wrong. Adjust the +// DELTA constant to play with the LERP vs. SLERP level +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result) +{ +/// Local Variables /////////////////////////////////////////////////////////// + double omega,cosom,sinom,scale0,scale1; +/////////////////////////////////////////////////////////////////////////////// + // USE THE DOT PRODUCT TO GET THE COSINE OF THE ANGLE BETWEEN THE + // QUATERNIONS + cosom = quat1->x * quat2->x + + quat1->y * quat2->y + + quat1->z * quat2->z + + quat1->w * quat2->w; + + // CHECK A COUPLE OF SPECIAL CASES. + // MAKE SURE THE TWO QUATERNIONS ARE NOT EXACTLY OPPOSITE? (WITHIN A LITTLE SLOP) + if ((1.0 + cosom) > DELTA) + { + // ARE THEY MORE THAN A LITTLE BIT DIFFERENT? AVOID A DIVIDED BY ZERO AND LERP IF NOT + if ((1.0 - cosom) > DELTA) { + // YES, DO A SLERP + omega = acos(cosom); + sinom = sin(omega); + scale0 = sin((1.0 - slerp) * omega) / sinom; + scale1 = sin(slerp * omega) / sinom; + } else { + // NOT A VERY BIG DIFFERENCE, DO A LERP + scale0 = 1.0 - slerp; + scale1 = slerp; + } + result->x = scale0 * quat1->x + scale1 * quat2->x; + result->y = scale0 * quat1->y + scale1 * quat2->y; + result->z = scale0 * quat1->z + scale1 * quat2->z; + result->w = scale0 * quat1->w + scale1 * quat2->w; + } else { + // THE QUATERNIONS ARE NEARLY OPPOSITE SO TO AVOID A DIVIDED BY ZERO ERROR + // CALCULATE A PERPENDICULAR QUATERNION AND SLERP THAT DIRECTION + result->x = -quat2->y; + result->y = quat2->x; + result->z = -quat2->w; + result->w = quat2->z; + scale0 = sin((1.0 - slerp) * (float)HALF_PI); + scale1 = sin(slerp * (float)HALF_PI); + result->x = scale0 * quat1->x + scale1 * result->x; + result->y = scale0 * quat1->y + scale1 * result->y; + result->z = scale0 * quat1->z + scale1 * result->z; + result->w = scale0 * quat1->w + scale1 * result->w; + } + +} +// SlerpQuat ///////////////////////////////////////////////////////////////// diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.h index 84631d8..2d97971 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Quatern.h @@ -1,68 +1,68 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Quaternion.h : Quaternion System structure definition file -// -// Purpose: Quaternion Conversion and Evaluation Functions -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(QUATERN_H__INCLUDED_) -#define QUATERN_H__INCLUDED_ - -/// Quaternion Definitions //////////////////////////////////////////////////// -typedef struct -{ - float x,y,z,w; -} tQuaternion; - -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: EulerToQuaternion2 -// Purpose: Convert a set of Euler angles to a Quaternion -// Arguments: A rotation set of 3 angles, a quaternion to set -/////////////////////////////////////////////////////////////////////////////// -void EulerToQuaternion2(tVector *rot, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: QuatToAxisAngle -// Purpose: Convert a Quaternion to Axis Angle representation -// Arguments: A quaternion to convert, a axisAngle to set -// Discussion: As the order of rotations is important I am -// using the Quantum Mechanics convention of (X,Y,Z) -// a Yaw-Pitch-Roll (Y,X,Z) system would have to be -// adjusted -/////////////////////////////////////////////////////////////////////////////// -void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); -void AxisAngleToQuat(const tVector *axis, const float angle, tQuaternion *quat); - -/////////////////////////////////////////////////////////////////////////////// -// Function: SlerpQuat -// Purpose: Spherical Linear Interpolation Between two Quaternions -// Arguments: Two Quaternions, blend factor, result quaternion -/////////////////////////////////////////////////////////////////////////////// -void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); - -void QuatToEuler(const tQuaternion *quat, tVector *euler); - -#endif // !defined(QUATERN_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Quaternion.h : Quaternion System structure definition file +// +// Purpose: Quaternion Conversion and Evaluation Functions +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(QUATERN_H__INCLUDED_) +#define QUATERN_H__INCLUDED_ + +/// Quaternion Definitions //////////////////////////////////////////////////// +typedef struct +{ + float x,y,z,w; +} tQuaternion; + +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: EulerToQuaternion2 +// Purpose: Convert a set of Euler angles to a Quaternion +// Arguments: A rotation set of 3 angles, a quaternion to set +/////////////////////////////////////////////////////////////////////////////// +void EulerToQuaternion2(tVector *rot, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: QuatToAxisAngle +// Purpose: Convert a Quaternion to Axis Angle representation +// Arguments: A quaternion to convert, a axisAngle to set +// Discussion: As the order of rotations is important I am +// using the Quantum Mechanics convention of (X,Y,Z) +// a Yaw-Pitch-Roll (Y,X,Z) system would have to be +// adjusted +/////////////////////////////////////////////////////////////////////////////// +void QuatToAxisAngle(tQuaternion *quat,tQuaternion *axisAngle); +void AxisAngleToQuat(const tVector *axis, const float angle, tQuaternion *quat); + +/////////////////////////////////////////////////////////////////////////////// +// Function: SlerpQuat +// Purpose: Spherical Linear Interpolation Between two Quaternions +// Arguments: Two Quaternions, blend factor, result quaternion +/////////////////////////////////////////////////////////////////////////////// +void SlerpQuat(tQuaternion *quat1,tQuaternion *quat2,float slerp, tQuaternion *result); + +void QuatToEuler(const tQuaternion *quat, tVector *euler); + +#endif // !defined(QUATERN_H__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/ReadMe.txt b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/ReadMe.txt index e057e59..29ef1c8 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/ReadMe.txt +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/ReadMe.txt @@ -1,55 +1,55 @@ -Quaternion in OpenGL Demonstration Program Feb 5, 1998 --------------------------------------------------------- -v. 1.0 - -This is the sample application that accompanies the March 98 -Game Developer magazine. It is meant as a demonstration of -how use Quaternions in OpenGL. This is the first article -of the two part series. I really only prints out the values -in the status bar and allows you to toggle between Quaternions -and Euler angles. The second part will deal more -with interpolating between Quaternions. The Quaternion -SLERP code is in here if you want to play around with it. - -Write to me if you have problems or questions and check -the web site or Game Developer's web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm Feb 5, 1998 ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, Riva 128 (New Beta OGL Drivers), and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -There are instructions in the Help/About dialog. - -By default it is in "Use Quaternions" mode. In this mode, -The current Euler angles of a bone are converted to Quaternions -then to Axis/Angle for use in OpenGL. All the Quaternion code -is in Quaternion.cpp/.h. - -So, for now it really doesn't do much, just shows that there is -no difference between using Quaternions and Euler angles in -OpenGL. It also prints out the values at the bottom status -bar. - -It also has an example of working with Vertex Arrays as well as -Display Lists. I have been playing around with different variations -of interleaved arrays and found this a pretty good way to do things. - -Have some fun. - +Quaternion in OpenGL Demonstration Program Feb 5, 1998 +-------------------------------------------------------- +v. 1.0 + +This is the sample application that accompanies the March 98 +Game Developer magazine. It is meant as a demonstration of +how use Quaternions in OpenGL. This is the first article +of the two part series. I really only prints out the values +in the status bar and allows you to toggle between Quaternions +and Euler angles. The second part will deal more +with interpolating between Quaternions. The Quaternion +SLERP code is in here if you want to play around with it. + +Write to me if you have problems or questions and check +the web site or Game Developer's web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm Feb 5, 1998 +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, Riva 128 (New Beta OGL Drivers), and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +There are instructions in the Help/About dialog. + +By default it is in "Use Quaternions" mode. In this mode, +The current Euler angles of a bone are converted to Quaternions +then to Axis/Angle for use in OpenGL. All the Quaternion code +is in Quaternion.cpp/.h. + +So, for now it really doesn't do much, just shows that there is +no difference between using Quaternions and Euler angles in +OpenGL. It also prints out the values at the bottom status +bar. + +It also has an example of working with Vertex Arrays as well as +Display Lists. I have been playing around with different variations +of interleaved arrays and found this a pretty good way to do things. + +Have some fun. + Jeff \ No newline at end of file diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.cpp index 3621584..c4acf8f 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.cpp @@ -1,47 +1,47 @@ -// SetRot.cpp : implementation file -// - -#include "stdafx.h" -#include "Slash.h" -#include "SetRot.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSetRot dialog - - -CSetRot::CSetRot(CWnd* pParent /*=NULL*/) - : CDialog(CSetRot::IDD, pParent) -{ - //{{AFX_DATA_INIT(CSetRot) - m_XAxis = 0.0f; - m_YAxis = 0.0f; - m_ZAxis = 0.0f; - //}}AFX_DATA_INIT -} - - -void CSetRot::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CSetRot) - DDX_Text(pDX, IDC_XAXIS, m_XAxis); - DDX_Text(pDX, IDC_YAXIS, m_YAxis); - DDX_Text(pDX, IDC_ZAXIS, m_ZAxis); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CSetRot, CDialog) - //{{AFX_MSG_MAP(CSetRot) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSetRot message handlers +// SetRot.cpp : implementation file +// + +#include "stdafx.h" +#include "Slash.h" +#include "SetRot.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSetRot dialog + + +CSetRot::CSetRot(CWnd* pParent /*=NULL*/) + : CDialog(CSetRot::IDD, pParent) +{ + //{{AFX_DATA_INIT(CSetRot) + m_XAxis = 0.0f; + m_YAxis = 0.0f; + m_ZAxis = 0.0f; + //}}AFX_DATA_INIT +} + + +void CSetRot::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CSetRot) + DDX_Text(pDX, IDC_XAXIS, m_XAxis); + DDX_Text(pDX, IDC_YAXIS, m_YAxis); + DDX_Text(pDX, IDC_ZAXIS, m_ZAxis); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CSetRot, CDialog) + //{{AFX_MSG_MAP(CSetRot) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSetRot message handlers diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.h index bd7fd9f..2ec20f0 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/SetRot.h @@ -1,48 +1,48 @@ -#if !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// SetRot.h : header file -// - -///////////////////////////////////////////////////////////////////////////// -// CSetRot dialog - -class CSetRot : public CDialog -{ -// Construction -public: - CSetRot(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CSetRot) - enum { IDD = IDD_SETROTATE }; - float m_XAxis; - float m_YAxis; - float m_ZAxis; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSetRot) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CSetRot) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) +#if !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// SetRot.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CSetRot dialog + +class CSetRot : public CDialog +{ +// Construction +public: + CSetRot(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CSetRot) + enum { IDD = IDD_SETROTATE }; + float m_XAxis; + float m_YAxis; + float m_ZAxis; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSetRot) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CSetRot) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SETROT_H__56A308A2_70E2_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.cpp index 562f27a..a75a9c7 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.cpp @@ -1,152 +1,152 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} - -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} - -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - - bone->scale.x = offset[6]; - bone->scale.y = offset[7]; - bone->scale.z = offset[8]; - break; - - } - } -} - -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} + +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} + +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + + bone->scale.x = offset[6]; + bone->scale.y = offset[7]; + bone->scale.z = offset[8]; + break; + + } + } +} + +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } } \ No newline at end of file diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.h index 1a687b3..3cc2f8c 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Skeleton.h @@ -1,138 +1,138 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -typedef struct -{ - float x,y,z; -} tVector; - -#include "Quatern.h" // GET THE TYPE FOR QUATERNION - -/// Structure Definitions /////////////////////////////////////////////////////// - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - long *visuals; // POINTER TO VISUALS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +typedef struct +{ + float x,y,z; +} tVector; + +#include "Quatern.h" // GET THE TYPE FOR QUATERNION + +/// Structure Definitions /////////////////////////////////////////////////////// + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + long *visuals; // POINTER TO VISUALS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.cpp index 4025a10..b08c0bb 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.cpp @@ -1,154 +1,154 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Slash.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Slash.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp - -BEGIN_MESSAGE_MAP(CSlashApp, CWinApp) - //{{AFX_MSG_MAP(CSlashApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp construction - -CSlashApp::CSlashApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CSlashApp object - -CSlashApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp initialization - -BOOL CSlashApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Local AppWizard-Generated Applications")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CSlashApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Slash.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Slash.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp + +BEGIN_MESSAGE_MAP(CSlashApp, CWinApp) + //{{AFX_MSG_MAP(CSlashApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp construction + +CSlashApp::CSlashApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CSlashApp object + +CSlashApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp initialization + +BOOL CSlashApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CSlashApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp commands diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.h index 9b108bb..dcdf2a9 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Slash.h : main header file for the SLASH application -// -// Purpose: header of Main Application of Quaternion Animation System -// -// Created: -// JL 11/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CSlashApp: -// See Slash.cpp for the implementation of this class -// - -class CSlashApp : public CWinApp -{ -public: - CSlashApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CSlashApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CSlashApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Slash.h : main header file for the SLASH application +// +// Purpose: header of Main Application of Quaternion Animation System +// +// Created: +// JL 11/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CSlashApp: +// See Slash.cpp for the implementation of this class +// + +class CSlashApp : public CWinApp +{ +public: + CSlashApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CSlashApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CSlashApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SLASH_H__082DB1E4_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.mak b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.mak index 8f69741..f4bc821 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.mak +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/Slash.mak @@ -1,431 +1,431 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on Slash.dsp -!IF "$(CFG)" == "" -CFG=Slash - Win32 Debug -!MESSAGE No configuration specified. Defaulting to Slash - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Slash - Win32 Release" && "$(CFG)" != "Slash - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Slash.mak" CFG="Slash - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Slash - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Slash - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Slash - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\Slash.exe" - -!ELSE - -ALL : "$(OUTDIR)\Slash.exe" - -!ENDIF - -CLEAN : - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Quatern.obj" - -@erase "$(INTDIR)\SetRot.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Slash.obj" - -@erase "$(INTDIR)\Slash.pch" - -@erase "$(INTDIR)\Slash.res" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc50.idb" - -@erase "$(OUTDIR)\Slash.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\Slash.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ - -CPP_OBJS=.\Release/ -CPP_SBRS=. -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Slash.res" /d "NDEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Slash.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:no /pdb:"$(OUTDIR)\Slash.pdb" /machine:I386\ - /out:"$(OUTDIR)\Slash.exe" -LINK32_OBJS= \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Quatern.obj" \ - "$(INTDIR)\SetRot.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\Slash.obj" \ - "$(INTDIR)\Slash.res" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\Slash.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\Slash.exe" - -!ELSE - -ALL : "$(OUTDIR)\Slash.exe" - -!ENDIF - -CLEAN : - -@erase "$(INTDIR)\MainFrm.obj" - -@erase "$(INTDIR)\OGLView.obj" - -@erase "$(INTDIR)\Quatern.obj" - -@erase "$(INTDIR)\SetRot.obj" - -@erase "$(INTDIR)\Skeleton.obj" - -@erase "$(INTDIR)\Slash.obj" - -@erase "$(INTDIR)\Slash.pch" - -@erase "$(INTDIR)\Slash.res" - -@erase "$(INTDIR)\StdAfx.obj" - -@erase "$(INTDIR)\vc50.idb" - -@erase "$(INTDIR)\vc50.pdb" - -@erase "$(OUTDIR)\Slash.exe" - -@erase "$(OUTDIR)\Slash.ilk" - -@erase "$(OUTDIR)\Slash.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\Slash.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ - -CPP_OBJS=.\Debug/ -CPP_SBRS=. -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Slash.res" /d "_DEBUG" -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Slash.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ - /incremental:yes /pdb:"$(OUTDIR)\Slash.pdb" /debug /machine:I386\ - /out:"$(OUTDIR)\Slash.exe" /pdbtype:sept -LINK32_OBJS= \ - "$(INTDIR)\MainFrm.obj" \ - "$(INTDIR)\OGLView.obj" \ - "$(INTDIR)\Quatern.obj" \ - "$(INTDIR)\SetRot.obj" \ - "$(INTDIR)\Skeleton.obj" \ - "$(INTDIR)\Slash.obj" \ - "$(INTDIR)\Slash.res" \ - "$(INTDIR)\StdAfx.obj" - -"$(OUTDIR)\Slash.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - - -!IF "$(CFG)" == "Slash - Win32 Release" || "$(CFG)" == "Slash - Win32 Debug" -SOURCE=.\MainFrm.cpp - -!IF "$(CFG)" == "Slash - Win32 Release" - -DEP_CPP_MAINF=\ - ".\MainFrm.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\Slash.h"\ - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -DEP_CPP_MAINF=\ - ".\MainFrm.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\Slash.h"\ - ".\StdAfx.h"\ - {$(INCLUDE)}"GL\gl.h"\ - {$(INCLUDE)}"GL\glu.h"\ - - -"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ENDIF - -SOURCE=.\OGLView.cpp - -!IF "$(CFG)" == "Slash - Win32 Release" - -DEP_CPP_OGLVI=\ - ".\Model.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\SetRot.h"\ - ".\Skeleton.h"\ - ".\Slash.h"\ - - -"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -DEP_CPP_OGLVI=\ - ".\Model.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\SetRot.h"\ - ".\Skeleton.h"\ - ".\Slash.h"\ - ".\StdAfx.h"\ - {$(INCLUDE)}"GL\gl.h"\ - {$(INCLUDE)}"GL\glu.h"\ - - -"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ENDIF - -SOURCE=.\Quatern.cpp - -!IF "$(CFG)" == "Slash - Win32 Release" - -DEP_CPP_QUATE=\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -DEP_CPP_QUATE=\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ENDIF - -SOURCE=.\SetRot.cpp - -!IF "$(CFG)" == "Slash - Win32 Release" - -DEP_CPP_SETRO=\ - ".\SetRot.h"\ - ".\Slash.h"\ - - -"$(INTDIR)\SetRot.obj" : $(SOURCE) $(DEP_CPP_SETRO) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -DEP_CPP_SETRO=\ - ".\SetRot.h"\ - ".\Slash.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\SetRot.obj" : $(SOURCE) $(DEP_CPP_SETRO) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ENDIF - -SOURCE=.\Skeleton.cpp - -!IF "$(CFG)" == "Slash - Win32 Release" - -DEP_CPP_SKELE=\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - - -"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -DEP_CPP_SKELE=\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\StdAfx.h"\ - - -"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ENDIF - -SOURCE=.\Slash.cpp - -!IF "$(CFG)" == "Slash - Win32 Release" - -DEP_CPP_SLASH=\ - ".\MainFrm.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\Slash.h"\ - - -"$(INTDIR)\Slash.obj" : $(SOURCE) $(DEP_CPP_SLASH) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -DEP_CPP_SLASH=\ - ".\MainFrm.h"\ - ".\OGLView.h"\ - ".\Quatern.h"\ - ".\Skeleton.h"\ - ".\Slash.h"\ - ".\StdAfx.h"\ - {$(INCLUDE)}"GL\gl.h"\ - {$(INCLUDE)}"GL\glu.h"\ - - -"$(INTDIR)\Slash.obj" : $(SOURCE) $(DEP_CPP_SLASH) "$(INTDIR)"\ - "$(INTDIR)\Slash.pch" - - -!ENDIF - -SOURCE=.\Slash.rc -DEP_RSC_SLASH_=\ - ".\res\Slash.ico"\ - ".\res\Slash.rc2"\ - ".\res\SlashDoc.ico"\ - - -"$(INTDIR)\Slash.res" : $(SOURCE) $(DEP_RSC_SLASH_) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - - -SOURCE=.\StdAfx.cpp -DEP_CPP_STDAF=\ - ".\StdAfx.h"\ - - -!IF "$(CFG)" == "Slash - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\Slash.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ - - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Slash.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ - "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "Slash - Win32 Debug" - -CPP_SWITCHES=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D\ - "_WINDOWS" /Fp"$(INTDIR)\Slash.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\"\ - /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Slash.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ - "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - - -!ENDIF - +# Microsoft Developer Studio Generated NMAKE File, Based on Slash.dsp +!IF "$(CFG)" == "" +CFG=Slash - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Slash - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Slash - Win32 Release" && "$(CFG)" != "Slash - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Slash.mak" CFG="Slash - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Slash - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Slash - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Slash - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Slash.exe" + +!ELSE + +ALL : "$(OUTDIR)\Slash.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Quatern.obj" + -@erase "$(INTDIR)\SetRot.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Slash.obj" + -@erase "$(INTDIR)\Slash.pch" + -@erase "$(INTDIR)\Slash.res" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(OUTDIR)\Slash.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\Slash.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ + +CPP_OBJS=.\Release/ +CPP_SBRS=. +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Slash.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Slash.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:no /pdb:"$(OUTDIR)\Slash.pdb" /machine:I386\ + /out:"$(OUTDIR)\Slash.exe" +LINK32_OBJS= \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Quatern.obj" \ + "$(INTDIR)\SetRot.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\Slash.obj" \ + "$(INTDIR)\Slash.res" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\Slash.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\Slash.exe" + +!ELSE + +ALL : "$(OUTDIR)\Slash.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\MainFrm.obj" + -@erase "$(INTDIR)\OGLView.obj" + -@erase "$(INTDIR)\Quatern.obj" + -@erase "$(INTDIR)\SetRot.obj" + -@erase "$(INTDIR)\Skeleton.obj" + -@erase "$(INTDIR)\Slash.obj" + -@erase "$(INTDIR)\Slash.pch" + -@erase "$(INTDIR)\Slash.res" + -@erase "$(INTDIR)\StdAfx.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(OUTDIR)\Slash.exe" + -@erase "$(OUTDIR)\Slash.ilk" + -@erase "$(OUTDIR)\Slash.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\Slash.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ + +CPP_OBJS=.\Debug/ +CPP_SBRS=. +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\Slash.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Slash.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=opengl32.lib glu32.lib glaux.lib /nologo /subsystem:windows\ + /incremental:yes /pdb:"$(OUTDIR)\Slash.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)\Slash.exe" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\MainFrm.obj" \ + "$(INTDIR)\OGLView.obj" \ + "$(INTDIR)\Quatern.obj" \ + "$(INTDIR)\SetRot.obj" \ + "$(INTDIR)\Skeleton.obj" \ + "$(INTDIR)\Slash.obj" \ + "$(INTDIR)\Slash.res" \ + "$(INTDIR)\StdAfx.obj" + +"$(OUTDIR)\Slash.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + + +!IF "$(CFG)" == "Slash - Win32 Release" || "$(CFG)" == "Slash - Win32 Debug" +SOURCE=.\MainFrm.cpp + +!IF "$(CFG)" == "Slash - Win32 Release" + +DEP_CPP_MAINF=\ + ".\MainFrm.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\Slash.h"\ + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +DEP_CPP_MAINF=\ + ".\MainFrm.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\Slash.h"\ + ".\StdAfx.h"\ + {$(INCLUDE)}"GL\gl.h"\ + {$(INCLUDE)}"GL\glu.h"\ + + +"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ENDIF + +SOURCE=.\OGLView.cpp + +!IF "$(CFG)" == "Slash - Win32 Release" + +DEP_CPP_OGLVI=\ + ".\Model.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\SetRot.h"\ + ".\Skeleton.h"\ + ".\Slash.h"\ + + +"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +DEP_CPP_OGLVI=\ + ".\Model.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\SetRot.h"\ + ".\Skeleton.h"\ + ".\Slash.h"\ + ".\StdAfx.h"\ + {$(INCLUDE)}"GL\gl.h"\ + {$(INCLUDE)}"GL\glu.h"\ + + +"$(INTDIR)\OGLView.obj" : $(SOURCE) $(DEP_CPP_OGLVI) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ENDIF + +SOURCE=.\Quatern.cpp + +!IF "$(CFG)" == "Slash - Win32 Release" + +DEP_CPP_QUATE=\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +DEP_CPP_QUATE=\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\Quatern.obj" : $(SOURCE) $(DEP_CPP_QUATE) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ENDIF + +SOURCE=.\SetRot.cpp + +!IF "$(CFG)" == "Slash - Win32 Release" + +DEP_CPP_SETRO=\ + ".\SetRot.h"\ + ".\Slash.h"\ + + +"$(INTDIR)\SetRot.obj" : $(SOURCE) $(DEP_CPP_SETRO) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +DEP_CPP_SETRO=\ + ".\SetRot.h"\ + ".\Slash.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\SetRot.obj" : $(SOURCE) $(DEP_CPP_SETRO) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ENDIF + +SOURCE=.\Skeleton.cpp + +!IF "$(CFG)" == "Slash - Win32 Release" + +DEP_CPP_SKELE=\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + + +"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +DEP_CPP_SKELE=\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\StdAfx.h"\ + + +"$(INTDIR)\Skeleton.obj" : $(SOURCE) $(DEP_CPP_SKELE) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ENDIF + +SOURCE=.\Slash.cpp + +!IF "$(CFG)" == "Slash - Win32 Release" + +DEP_CPP_SLASH=\ + ".\MainFrm.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\Slash.h"\ + + +"$(INTDIR)\Slash.obj" : $(SOURCE) $(DEP_CPP_SLASH) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +DEP_CPP_SLASH=\ + ".\MainFrm.h"\ + ".\OGLView.h"\ + ".\Quatern.h"\ + ".\Skeleton.h"\ + ".\Slash.h"\ + ".\StdAfx.h"\ + {$(INCLUDE)}"GL\gl.h"\ + {$(INCLUDE)}"GL\glu.h"\ + + +"$(INTDIR)\Slash.obj" : $(SOURCE) $(DEP_CPP_SLASH) "$(INTDIR)"\ + "$(INTDIR)\Slash.pch" + + +!ENDIF + +SOURCE=.\Slash.rc +DEP_RSC_SLASH_=\ + ".\res\Slash.ico"\ + ".\res\Slash.rc2"\ + ".\res\SlashDoc.ico"\ + + +"$(INTDIR)\Slash.res" : $(SOURCE) $(DEP_RSC_SLASH_) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +SOURCE=.\StdAfx.cpp +DEP_CPP_STDAF=\ + ".\StdAfx.h"\ + + +!IF "$(CFG)" == "Slash - Win32 Release" + +CPP_SWITCHES=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)\Slash.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c\ + + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Slash.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ + "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "Slash - Win32 Debug" + +CPP_SWITCHES=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /Fp"$(INTDIR)\Slash.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\StdAfx.obj" "$(INTDIR)\Slash.pch" : $(SOURCE) $(DEP_CPP_STDAF)\ + "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + + +!ENDIF + diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.cpp b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.cpp index 3307002..228dea4 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.cpp +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Slash.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Slash.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.h index ddefdab..571c76c 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__082DB1E6_6069_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/resource.h b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/resource.h index 483a858..8b0f8db 100644 --- a/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/resource.h +++ b/Using Quaterions for Animation in OpenGL/Code/OGL/Slash/resource.h @@ -1,30 +1,30 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Slash.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_SLASHTYPE 129 -#define IDD_SETROTATE 130 -#define IDC_XAXIS 1000 -#define IDC_YAXIS 1001 -#define IDC_ZAXIS 1002 -#define ID_VIEW_GEOMETRY 32771 -#define ID_VIEW_USEQUATERNIONS 32772 -#define ID_HELP_WHICHOPENGL 32774 -#define ID_INDICATOR_ROT2 59142 -#define ID_INDICATOR_QUAT 59143 -#define ID_INDICATOR_ROT 59144 -#define ID_INDICATOR_STATUS 59145 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32775 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Slash.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_SLASHTYPE 129 +#define IDD_SETROTATE 130 +#define IDC_XAXIS 1000 +#define IDC_YAXIS 1001 +#define IDC_ZAXIS 1002 +#define ID_VIEW_GEOMETRY 32771 +#define ID_VIEW_USEQUATERNIONS 32772 +#define ID_HELP_WHICHOPENGL 32774 +#define ID_INDICATOR_ROT2 59142 +#define ID_INDICATOR_QUAT 59143 +#define ID_INDICATOR_ROT 59144 +#define ID_INDICATOR_STATUS 59145 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 131 +#define _APS_NEXT_COMMAND_VALUE 32775 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.cpp index 3ff5f27..ec6a10e 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.cpp @@ -1,158 +1,158 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Dagger.cpp : Defines the class behaviors for the application. -// -// Purpose: Implementation of Main Application of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Dagger.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CDaggerApp - -BEGIN_MESSAGE_MAP(CDaggerApp, CWinApp) - //{{AFX_MSG_MAP(CDaggerApp) - ON_COMMAND(ID_APP_ABOUT, OnAppAbout) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP - // Standard file based document commands -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CDaggerApp construction - -CDaggerApp::CDaggerApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - -///////////////////////////////////////////////////////////////////////////// -// The one and only CDaggerApp object - -CDaggerApp theApp; - -///////////////////////////////////////////////////////////////////////////// -// CDaggerApp initialization - -BOOL CDaggerApp::InitInstance() -{ - AfxEnableControlContainer(); - - // Standard initialization - // If you are not using these features and wish to reduce the size - // of your final executable, you should remove from the following - // the specific initialization routines you do not need. - -#ifdef _AFXDLL - Enable3dControls(); // Call this when using MFC in a shared DLL -#else - Enable3dControlsStatic(); // Call this when linking to MFC statically -#endif - - // Change the registry key under which our settings are stored. - // You should modify this string to be something appropriate - // such as the name of your company or organization. - SetRegistryKey(_T("Dagger")); - - LoadStdProfileSettings(); // Load standard INI file options (including MRU) - - // Register the application's document templates. Document templates - // serve as the connection between documents, frame windows and views. - - CMainFrame* pFrame = new CMainFrame; - - if (!pFrame->LoadFrame(IDR_MAINFRAME, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { - return FALSE; - } - - m_pMainWnd = pFrame; - - // The one and only window has been initialized, so show and update it. -// m_pMainWnd->ShowWindow(SW_SHOW); -// m_pMainWnd->UpdateWindow(); - - - // Enable drag/drop open - m_pMainWnd->DragAcceptFiles(); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -// CAboutDlg dialog used for App About - -class CAboutDlg : public CDialog -{ -public: - CAboutDlg(); - -// Dialog Data - //{{AFX_DATA(CAboutDlg) - enum { IDD = IDD_ABOUTBOX }; - //}}AFX_DATA - - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CAboutDlg) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - //{{AFX_MSG(CAboutDlg) - // No message handlers - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) -{ - //{{AFX_DATA_INIT(CAboutDlg) - //}}AFX_DATA_INIT -} - -void CAboutDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CAboutDlg) - //}}AFX_DATA_MAP -} - -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) - //{{AFX_MSG_MAP(CAboutDlg) - // No message handlers - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -// App command to run the dialog -void CDaggerApp::OnAppAbout() -{ - CAboutDlg aboutDlg; - aboutDlg.DoModal(); -} - -///////////////////////////////////////////////////////////////////////////// -// CDaggerApp commands +/////////////////////////////////////////////////////////////////////////////// +// +// Dagger.cpp : Defines the class behaviors for the application. +// +// Purpose: Implementation of Main Application of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Dagger.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDaggerApp + +BEGIN_MESSAGE_MAP(CDaggerApp, CWinApp) + //{{AFX_MSG_MAP(CDaggerApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP + // Standard file based document commands +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDaggerApp construction + +CDaggerApp::CDaggerApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CDaggerApp object + +CDaggerApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CDaggerApp initialization + +BOOL CDaggerApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Dagger")); + + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + // Register the application's document templates. Document templates + // serve as the connection between documents, frame windows and views. + + CMainFrame* pFrame = new CMainFrame; + + if (!pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE)) { + return FALSE; + } + + m_pMainWnd = pFrame; + + // The one and only window has been initialized, so show and update it. +// m_pMainWnd->ShowWindow(SW_SHOW); +// m_pMainWnd->UpdateWindow(); + + + // Enable drag/drop open + m_pMainWnd->DragAcceptFiles(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CDaggerApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CDaggerApp commands diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.h index 64bdbb5..439a2a4 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Dagger.h @@ -1,65 +1,65 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Dagger.h : main header file for the DAGGER application -// -// Purpose: header of Main Application of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_DAGGER_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_DAGGER_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - -///////////////////////////////////////////////////////////////////////////// -// CDaggerApp: -// See Dagger.cpp for the implementation of this class -// - -class CDaggerApp : public CWinApp -{ -public: - CDaggerApp(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CDaggerApp) - public: - virtual BOOL InitInstance(); - //}}AFX_VIRTUAL - -// Implementation - - //{{AFX_MSG(CDaggerApp) - afx_msg void OnAppAbout(); - // NOTE - the ClassWizard will add and remove member functions here. - // DO NOT EDIT what you see in these blocks of generated code ! - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_DAGGER_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Dagger.h : main header file for the DAGGER application +// +// Purpose: header of Main Application of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_DAGGER_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_DAGGER_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CDaggerApp: +// See Dagger.cpp for the implementation of this class +// + +class CDaggerApp : public CWinApp +{ +public: + CDaggerApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDaggerApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CDaggerApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DAGGER_H__4B0629B9_2696_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/HierWin.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/HierWin.cpp index e04a454..f2ff743 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/HierWin.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/HierWin.cpp @@ -1,268 +1,268 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// HierWin.cpp : implementation file -// -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Dagger.h" -#include "HierWin.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -///////////////////////////////////////////////////////////////////////////// -// CHierWin - -CHierWin::CHierWin() -{ - m_Skeleton = NULL; -} - -CHierWin::~CHierWin() -{ -} - - -BOOL CHierWin::PreCreateWindow(CREATESTRUCT& cs) -{ - CString className; - HCURSOR arrow; - - arrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - -// className = AfxRegisterWndClass(NULL, -// (HCURSOR)arrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), 0); //m_HArrow -// cs.lpszClass = className; - - return CTreeCtrl::PreCreateWindow(cs); -} - -int CHierWin::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) - return -1; - - ResetSkeleton(); - return 0; -} - -void CHierWin::ResetSkeleton() -{ - DeleteAllItems(); // CLEAR THE CONTROL - m_TreeRoot = InsertItem( "Skeleton", TVI_ROOT, TVI_LAST ); - // SET THE ROOT DATA TO NULL - SetItemData( m_TreeRoot, NULL ); -} - -void CHierWin::SetSkeleton(t_Bone *skeleton, HTREEITEM item) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; - HTREEITEM curItem; -/////////////////////////////////////////////////////////////////////////////// - - if (item == NULL) - { - item = m_TreeRoot; - m_Skeleton = skeleton; - SetItemData( item, (DWORD)m_Skeleton ); - } - - if (skeleton->childCnt > 0) - { - child = skeleton->children; - for (loop = 0; loop < skeleton->childCnt; loop++,child++) - { - curItem = InsertItem( child->name, item, TVI_LAST ); - SetItemData( curItem, (DWORD)child ); - EnsureVisible( curItem ); - if (child->childCnt > 0) - SetSkeleton(child,curItem); - } - } -} - -void CHierWin::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - // RESET FOCUS TO MAINFRAME - // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS - GetParent()->SetFocus( ); - //CTreeCtrl::OnKeyUp(nChar, nRepCnt, nFlags); -} - -void CHierWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - // RESET FOCUS TO MAINFRAME - // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS - GetParent()->SetFocus( ); - //CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags); -} - -BEGIN_MESSAGE_MAP(CHierWin, CTreeCtrl) - //{{AFX_MSG_MAP(CHierWin) - ON_WM_CREATE() - ON_WM_KEYUP() - ON_WM_KEYDOWN() - ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) - ON_WM_LBUTTONUP() - ON_WM_LBUTTONDBLCLK() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CHierWin message handlers - -void CHierWin::OnLButtonUp(UINT nFlags, CPoint point) -{ - // RESET FOCUS TO MAINFRAME - // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS - GetParent()->SetFocus( ); - - CTreeCtrl::OnLButtonUp(nFlags, point); -} - -void CHierWin::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - EditBone(); - CTreeCtrl::OnLButtonDblClk(nFlags, point); -} - -void CHierWin::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) -{ - NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; - if (m_Skeleton > NULL) - m_Skeleton->id = GetItemData(GetSelectedItem()); - GetParent()->Invalidate(TRUE ); - *pResult = 0; -} - -void CHierWin::AddBone() -{ -/// Local Variables /////////////////////////////////////////////////////////// - HTREEITEM item,curItem; - CBoneInfo dialog; - t_Bone *bonePtr; -/////////////////////////////////////////////////////////////////////////////// - item = GetSelectedItem(); - if (item == NULL) - { - dialog.m_Trans_X = m_Skeleton->trans.x; - dialog.m_Trans_Y = m_Skeleton->trans.y; - dialog.m_Trans_Z = m_Skeleton->trans.z; - dialog.m_Rot_X = m_Skeleton->rot.x; - dialog.m_Rot_Y = m_Skeleton->rot.y; - dialog.m_Rot_Z = m_Skeleton->rot.z; - } - else - { - bonePtr = (t_Bone *)GetItemData( item); - dialog.m_Rot_X = 0.0f; - dialog.m_Rot_Y = 0.0f; - dialog.m_Rot_Z = 0.0f; - dialog.m_Trans_X = 0.0f; - dialog.m_Trans_Y = 0.0f; - dialog.m_Trans_Z = 0.0f; - } - if (dialog.DoModal()) - { - if (item == NULL) - InsertItem( dialog.m_BoneName, TVI_ROOT, TVI_LAST ); - else - curItem = InsertItem( dialog.m_BoneName, item, TVI_LAST ); - EnsureVisible( curItem ); - } -} - -void CHierWin::EditBone() -{ -/// Local Variables /////////////////////////////////////////////////////////// - HTREEITEM item; - CBoneInfo dialog; - t_Bone *bonePtr; -/////////////////////////////////////////////////////////////////////////////// - item = GetSelectedItem(); - if (item != NULL) - { - bonePtr = (t_Bone *)GetItemData( item); - dialog.m_BoneName = bonePtr->name; - dialog.m_Trans_X = bonePtr->trans.x; - dialog.m_Trans_Y = bonePtr->trans.y; - dialog.m_Trans_Z = bonePtr->trans.z; - dialog.m_Rot_X = bonePtr->rot.x; - dialog.m_Rot_Y = bonePtr->rot.y; - dialog.m_Rot_Z = bonePtr->rot.z; - if (dialog.DoModal()) - { - strcpy(bonePtr->name,(LPCTSTR)(dialog.m_BoneName)); - bonePtr->trans.x = dialog.m_Trans_X; - bonePtr->trans.y = dialog.m_Trans_Y; - bonePtr->trans.z = dialog.m_Trans_Z; - bonePtr->rot.x = dialog.m_Rot_X; - bonePtr->rot.y = dialog.m_Rot_Y; - bonePtr->rot.z = dialog.m_Rot_Z; - ResetSkeleton(); - SetSkeleton(m_Skeleton, NULL); - } - } -} - -///////////////////////////////////////////////////////////////////////////// -// CBoneInfo dialog - - -CBoneInfo::CBoneInfo(CWnd* pParent /*=NULL*/) - : CDialog(CBoneInfo::IDD, pParent) -{ - //{{AFX_DATA_INIT(CBoneInfo) - m_BoneName = _T(""); - m_Rot_X = 0.0f; - m_Rot_Y = 0.0f; - m_Rot_Z = 0.0f; - m_Trans_X = 0.0f; - m_Trans_Y = 0.0f; - m_Trans_Z = 0.0f; - //}}AFX_DATA_INIT -} - - -void CBoneInfo::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CBoneInfo) - DDX_Text(pDX, IDC_BONE_NAME, m_BoneName); - DDX_Text(pDX, IDC_ROT_X, m_Rot_X); - DDX_Text(pDX, IDC_ROT_Y, m_Rot_Y); - DDX_Text(pDX, IDC_ROT_Z, m_Rot_Z); - DDX_Text(pDX, IDC_TRANS_X, m_Trans_X); - DDX_Text(pDX, IDC_TRANS_Y, m_Trans_Y); - DDX_Text(pDX, IDC_TRANS_Z, m_Trans_Z); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CBoneInfo, CDialog) - //{{AFX_MSG_MAP(CBoneInfo) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CBoneInfo message handlers -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. +/////////////////////////////////////////////////////////////////////////////// +// +// HierWin.cpp : implementation file +// +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Dagger.h" +#include "HierWin.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CHierWin + +CHierWin::CHierWin() +{ + m_Skeleton = NULL; +} + +CHierWin::~CHierWin() +{ +} + + +BOOL CHierWin::PreCreateWindow(CREATESTRUCT& cs) +{ + CString className; + HCURSOR arrow; + + arrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + +// className = AfxRegisterWndClass(NULL, +// (HCURSOR)arrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), 0); //m_HArrow +// cs.lpszClass = className; + + return CTreeCtrl::PreCreateWindow(cs); +} + +int CHierWin::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) + return -1; + + ResetSkeleton(); + return 0; +} + +void CHierWin::ResetSkeleton() +{ + DeleteAllItems(); // CLEAR THE CONTROL + m_TreeRoot = InsertItem( "Skeleton", TVI_ROOT, TVI_LAST ); + // SET THE ROOT DATA TO NULL + SetItemData( m_TreeRoot, NULL ); +} + +void CHierWin::SetSkeleton(t_Bone *skeleton, HTREEITEM item) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; + HTREEITEM curItem; +/////////////////////////////////////////////////////////////////////////////// + + if (item == NULL) + { + item = m_TreeRoot; + m_Skeleton = skeleton; + SetItemData( item, (DWORD)m_Skeleton ); + } + + if (skeleton->childCnt > 0) + { + child = skeleton->children; + for (loop = 0; loop < skeleton->childCnt; loop++,child++) + { + curItem = InsertItem( child->name, item, TVI_LAST ); + SetItemData( curItem, (DWORD)child ); + EnsureVisible( curItem ); + if (child->childCnt > 0) + SetSkeleton(child,curItem); + } + } +} + +void CHierWin::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + // RESET FOCUS TO MAINFRAME + // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS + GetParent()->SetFocus( ); + //CTreeCtrl::OnKeyUp(nChar, nRepCnt, nFlags); +} + +void CHierWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + // RESET FOCUS TO MAINFRAME + // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS + GetParent()->SetFocus( ); + //CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags); +} + +BEGIN_MESSAGE_MAP(CHierWin, CTreeCtrl) + //{{AFX_MSG_MAP(CHierWin) + ON_WM_CREATE() + ON_WM_KEYUP() + ON_WM_KEYDOWN() + ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged) + ON_WM_LBUTTONUP() + ON_WM_LBUTTONDBLCLK() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CHierWin message handlers + +void CHierWin::OnLButtonUp(UINT nFlags, CPoint point) +{ + // RESET FOCUS TO MAINFRAME + // NEEDED TO ADD THIS SINCE THE TREECTRL WILL HOLD FOCUS + GetParent()->SetFocus( ); + + CTreeCtrl::OnLButtonUp(nFlags, point); +} + +void CHierWin::OnLButtonDblClk(UINT nFlags, CPoint point) +{ + EditBone(); + CTreeCtrl::OnLButtonDblClk(nFlags, point); +} + +void CHierWin::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; + if (m_Skeleton > NULL) + m_Skeleton->id = GetItemData(GetSelectedItem()); + GetParent()->Invalidate(TRUE ); + *pResult = 0; +} + +void CHierWin::AddBone() +{ +/// Local Variables /////////////////////////////////////////////////////////// + HTREEITEM item,curItem; + CBoneInfo dialog; + t_Bone *bonePtr; +/////////////////////////////////////////////////////////////////////////////// + item = GetSelectedItem(); + if (item == NULL) + { + dialog.m_Trans_X = m_Skeleton->trans.x; + dialog.m_Trans_Y = m_Skeleton->trans.y; + dialog.m_Trans_Z = m_Skeleton->trans.z; + dialog.m_Rot_X = m_Skeleton->rot.x; + dialog.m_Rot_Y = m_Skeleton->rot.y; + dialog.m_Rot_Z = m_Skeleton->rot.z; + } + else + { + bonePtr = (t_Bone *)GetItemData( item); + dialog.m_Rot_X = 0.0f; + dialog.m_Rot_Y = 0.0f; + dialog.m_Rot_Z = 0.0f; + dialog.m_Trans_X = 0.0f; + dialog.m_Trans_Y = 0.0f; + dialog.m_Trans_Z = 0.0f; + } + if (dialog.DoModal()) + { + if (item == NULL) + InsertItem( dialog.m_BoneName, TVI_ROOT, TVI_LAST ); + else + curItem = InsertItem( dialog.m_BoneName, item, TVI_LAST ); + EnsureVisible( curItem ); + } +} + +void CHierWin::EditBone() +{ +/// Local Variables /////////////////////////////////////////////////////////// + HTREEITEM item; + CBoneInfo dialog; + t_Bone *bonePtr; +/////////////////////////////////////////////////////////////////////////////// + item = GetSelectedItem(); + if (item != NULL) + { + bonePtr = (t_Bone *)GetItemData( item); + dialog.m_BoneName = bonePtr->name; + dialog.m_Trans_X = bonePtr->trans.x; + dialog.m_Trans_Y = bonePtr->trans.y; + dialog.m_Trans_Z = bonePtr->trans.z; + dialog.m_Rot_X = bonePtr->rot.x; + dialog.m_Rot_Y = bonePtr->rot.y; + dialog.m_Rot_Z = bonePtr->rot.z; + if (dialog.DoModal()) + { + strcpy(bonePtr->name,(LPCTSTR)(dialog.m_BoneName)); + bonePtr->trans.x = dialog.m_Trans_X; + bonePtr->trans.y = dialog.m_Trans_Y; + bonePtr->trans.z = dialog.m_Trans_Z; + bonePtr->rot.x = dialog.m_Rot_X; + bonePtr->rot.y = dialog.m_Rot_Y; + bonePtr->rot.z = dialog.m_Rot_Z; + ResetSkeleton(); + SetSkeleton(m_Skeleton, NULL); + } + } +} + +///////////////////////////////////////////////////////////////////////////// +// CBoneInfo dialog + + +CBoneInfo::CBoneInfo(CWnd* pParent /*=NULL*/) + : CDialog(CBoneInfo::IDD, pParent) +{ + //{{AFX_DATA_INIT(CBoneInfo) + m_BoneName = _T(""); + m_Rot_X = 0.0f; + m_Rot_Y = 0.0f; + m_Rot_Z = 0.0f; + m_Trans_X = 0.0f; + m_Trans_Y = 0.0f; + m_Trans_Z = 0.0f; + //}}AFX_DATA_INIT +} + + +void CBoneInfo::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CBoneInfo) + DDX_Text(pDX, IDC_BONE_NAME, m_BoneName); + DDX_Text(pDX, IDC_ROT_X, m_Rot_X); + DDX_Text(pDX, IDC_ROT_Y, m_Rot_Y); + DDX_Text(pDX, IDC_ROT_Z, m_Rot_Z); + DDX_Text(pDX, IDC_TRANS_X, m_Trans_X); + DDX_Text(pDX, IDC_TRANS_Y, m_Trans_Y); + DDX_Text(pDX, IDC_TRANS_Z, m_Trans_Z); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CBoneInfo, CDialog) + //{{AFX_MSG_MAP(CBoneInfo) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CBoneInfo message handlers +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.cpp index d7d4545..c839f8c 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.cpp @@ -1,710 +1,710 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadAnim.cpp -// -// Purpose: implementation of the Motion Capture file Loader -// -// Created: -// JL 9/5/97 -// Versions: -// 1.0 12/2/97 Initial Merge of the BVA Code -// 1.02 1/10/97 Merge in of ASF Hierarchy read code -// -// Todo: -// Still trying to catch up from the holidays -// Need to merge AMC portion of Acclaim loader for animation -// Merge of BVH reader code -// -// I WILL PROBABLY PULL OUT THE CHANNELS INTO A NEW STRUCT -// ADD SPEED OF PLAYBACK VARIABLE TO CHANNEL STRUCT -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "LoadAnim.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: ParseString -// Purpose: Actually breaks a string of words into individual pieces -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -void ParseString(char *buffer,CStringArray *words,int *cnt) -{ -/// Local Variables /////////////////////////////////////////////////////////// - CString in = buffer, temp; -/////////////////////////////////////////////////////////////////////////////// - - in.TrimLeft(); - in.TrimRight(); - *cnt = 0; - do - { - temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB - words->Add(temp); - if (temp == in) break; - in = in.Right(in.GetLength() - temp.GetLength()); - in.TrimLeft(); - *cnt = *cnt + 1; - } while (1); - *cnt = *cnt + 1; -} -//// ParseString ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: FindBoneParent -// Purpose: Find the pointer to a bone with a given name -// Arguments: Source string in, array to put the words and the count -/////////////////////////////////////////////////////////////////////////////// -t_Bone *FindBoneParent(t_Bone *bone, char *name) -{ -/// Local Variables /////////////////////////////////////////////////////////// - t_Bone *retbone; - int loop; -/////////////////////////////////////////////////////////////////////////////// - // IF I HAVE THE RIGHT ONE, RETURN IT - if (strcmp(bone->name,name) == 0) - return bone; - if (bone->childCnt > 0) - { - for (loop = 0; loop < bone->childCnt; loop++) - { - // IF ONE OF THE CHILDREN IS THE ONE, RETURN IT - if (strcmp(bone->children[loop].name,name) == 0) - return &bone->children[loop]; - if (bone->children[loop].childCnt > 0) - { - retbone = FindBoneParent(&bone->children[loop],name); - if (retbone != NULL) - return retbone; - } - } - - } - // ALL HAS FAILED, RETURN NULL - return NULL; -} -//// FindBoneParent /////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadBVA -// Purpose: Actually load a BVA file into the system -// Arguments: Name of the file to open and root skeleton to put it in -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadBVA(CString name,t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS - int loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - int frameCnt; - float frameTime; - t_Bone *tempBones,*curBone; - float *tempChannel,*fptr; -/////////////////////////////////////////////////////////////////////////////// - // OPEN THE BVA FILE - if (fp = fopen((LPCTSTR)name,"r")) { - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - // SEE IF WE CAN FIND THE SEGMENT KEYWORD - if (words.GetAt(0) == "Segment:") - { - // IF SO, WE FOUND A BONE SO ALLOC ROOM FOR IT - tempBones = (t_Bone *)malloc((root->childCnt + 1) * sizeof(t_Bone)); - if (root->childCnt > 0 && root->children != NULL) - { - // COPY OVER THE ONES THAT WERE ALREADY THERE - memcpy(tempBones,root->children,root->childCnt * sizeof(t_Bone)); - free(root->children); - } - curBone = &tempBones[root->childCnt++]; - root->children = tempBones; - // COPY THE NAME INTO THE BONE - strcpy(curBone->name,words.GetAt(1)); - // SET THE ID TO THE BONE NUMBER - curBone->id = root->childCnt; - ResetBone(curBone, root); // SETUP INITIAL BONE SETTINGS - words.RemoveAll(); // CLEAR WORD BUFFER - // NEXT GET THE FRAMECOUNT - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - // NEXT LINE SHOULD BE FRAMES THEN A COUNT - if (words.GetAt(0) == "Frames:" && cnt == 2) - { - frameCnt = atoi(words.GetAt(1)); - words.RemoveAll(); // CLEAR WORD BUFFER - // NEXT GET THE FRAMETIME - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (words.GetAt(0) == "Frame" && - words.GetAt(1) == "Time:" && - cnt == 3) - { - frameTime = (float)atof(words.GetAt(2)); - words.RemoveAll(); // CLEAR WORD BUFFER - // TWO JUNK LINES FOR THE UNITS. I DON'T CARE - fgets(buffer,MAX_STRINGLENGTH,fp); - fgets(buffer,MAX_STRINGLENGTH,fp); - // NOW READY TO LOAD ALL THE ANIMATION - // ALLOC 9 FLOATS PER FRAME SINCE BVA HAS 9 ELEMENTS TO THE CHANNEL - tempChannel = (float *)malloc(sizeof(float) * frameCnt * - s_Channel_Type_Size[CHANNEL_TYPE_SRT]); - fptr = tempChannel; - // LOOP THROUGH THE FRAMES OF ANIMATION DATA - for (loop = 0; loop < frameCnt; loop++) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (cnt == s_Channel_Type_Size[CHANNEL_TYPE_SRT]) - { - for (loop2 = 0; loop2 < s_Channel_Type_Size[CHANNEL_TYPE_SRT]; loop2++) - { - *fptr = (float)atof(words.GetAt(loop2)); - // CONVERT INCHES TO FEET - if (loop2 < 3) *fptr = *fptr / 12; - fptr++; - } - } - else - { - sprintf(buffer,"Not Enough Entries in channel %s frame %d\nExpected %d Got %d",curBone->name,loop,s_Channel_Type_Size[CHANNEL_TYPE_SRT],cnt); - ::MessageBox(NULL,buffer,"BVA Load ERROR!!",MB_OK); - free(tempChannel); - return FALSE; - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - - // SET THE CHANNEL INFO INTO BONE - curBone->primChannel = tempChannel; - curBone->primChanType = CHANNEL_TYPE_SRT; - curBone->primFrameCount = (float)frameCnt; - curBone->primSpeed = (float)(30.0 * frameTime); // CONVERT TO FRAME STEP SIZE AT 30FPS - BoneSetFrame(curBone,0); - } - - } - else - { - sprintf(buffer,"Couldn't Find FrameCnt Area for Bone %s",curBone->name); - ::MessageBox(NULL,buffer,"BVA Load ERROR!!",MB_OK); - free(tempBones); - root->childCnt = 0; - root->children = NULL; - return FALSE; - } - } - } - fclose(fp); - return TRUE; - } - return FALSE; -} -//// LoadBVA ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadBVH -// Purpose: Actually load a BVH file into the system -// Arguments: Name of the file to open and root skeleton to put it in -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadBVH(CString name,t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS - int cnt; - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - CString temp; - t_Bone *tempBones,*curBone,*parent; - int boneNum = 0; - float **dataptr,*animData = NULL; - int channelCnt = 0,frameCnt = 0; -/////////////////////////////////////////////////////////////////////////////// - dataptr = (float **)malloc(sizeof(float *) * 255); - curBone = root; - // OPEN THE BVH FILE - if (fp = fopen((LPCTSTR)name,"r")) { - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - // SEE IF WE CAN FIND THE BONE SEGMENT KEYWORD - if (words.GetAt(0) == "ROOT" || words.GetAt(0) == "JOINT" || words.GetAt(0) == "End") - { - // IF SO, WE FOUND A BONE SO ALLOC ROOM FOR IT - tempBones = (t_Bone *)malloc((curBone->childCnt + 1) * sizeof(t_Bone)); - if (curBone->childCnt > 0 && curBone->children != NULL) - { - // COPY OVER THE ONES THAT WERE ALREADY THERE - memcpy(tempBones,curBone->children,curBone->childCnt * sizeof(t_Bone)); - // fix up the data pointers for any copied ones - for (int i = 0; i < curBone->childCnt; i++) - { - t_Bone *b1,*b2; - b1 = &curBone->children[i]; - b2 = &tempBones[i]; - for (int j = 0; j < channelCnt; j++) - { - if (dataptr[j] == &b1->rot.x) dataptr[j] = &b2->rot.x; - if (dataptr[j] == &b1->rot.y) dataptr[j] = &b2->rot.y; - if (dataptr[j] == &b1->rot.z) dataptr[j] = &b2->rot.z; - if (dataptr[j] == &b1->trans.x) dataptr[j] = &b2->trans.x; - if (dataptr[j] == &b1->trans.y) dataptr[j] = &b2->trans.y; - if (dataptr[j] == &b1->trans.z) dataptr[j] = &b2->trans.z; - } - } - free(curBone->children); - } - parent = curBone; - curBone->childCnt++; - boneNum++; - curBone->children = tempBones; - curBone = &tempBones[curBone->childCnt - 1]; - // COPY THE NAME INTO THE BONE - if (words.GetSize() > 2) - sprintf(curBone->name,"%s %s",words.GetAt(1),words.GetAt(2)); - else - sprintf(curBone->name,"%s",words.GetAt(1)); - // SET THE ID TO THE BONE NUMBER - curBone->id = boneNum; - ResetBone(curBone, parent); // SETUP INITIAL BONE SETTINGS -// curBone->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); - - words.RemoveAll(); // CLEAR WORD BUFFER - // NEXT GET THE FRAMECOUNT - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (words.GetAt(0) != "{") - { - ::MessageBox(NULL,"Error parsing BVH File: No opening Braces","ERROR",MB_OK); - } - } - else if (words.GetAt(0) == "CHANNELS") // Channel Pointers - { - for (int loop = 0; loop < atoi(words.GetAt(1)); loop++) - { - if (words.GetAt(2 + loop) == "Xposition") - { - dataptr[channelCnt++] = &curBone->trans.x; - } - else if (words.GetAt(2 + loop) == "Yposition") - { - dataptr[channelCnt++] = &curBone->trans.y; - } - else if (words.GetAt(2 + loop) == "Zposition") - { - dataptr[channelCnt++] = &curBone->trans.z; - } - else if (words.GetAt(2 + loop) == "Xrotation") - { - dataptr[channelCnt++] = &curBone->rot.x; - } - else if (words.GetAt(2 + loop) == "Yrotation") - { - dataptr[channelCnt++] = &curBone->rot.y; - } - else if (words.GetAt(2 + loop) == "Zrotation") - { - dataptr[channelCnt++] = &curBone->rot.z; - } - } - } - else if (words.GetAt(0) == "OFFSET") - { - curBone->trans.x = curBone->b_trans.x = atof(words.GetAt(1)) / 10.0f; - curBone->trans.y = curBone->b_trans.y = atof(words.GetAt(2)) / 10.0f; - curBone->trans.z = curBone->b_trans.z = atof(words.GetAt(3)) / 10.0f; - } - else if (words.GetAt(0) == "}") - { - curBone = curBone->parent; - } - else if (words.GetAt(0) == "MOTION") - { - words.RemoveAll(); // CLEAR WORD BUFFER - break; - } - words.RemoveAll(); // CLEAR WORD BUFFER - } - // Now we should be in motion area - while (!feof(fp)) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (words.GetAt(0) == "Frames:") - { - frameCnt = atoi(words.GetAt(1)); - animData = (float *)malloc(sizeof(float) * channelCnt * frameCnt); - if (animData != NULL) - { - words.RemoveAll(); // CLEAR WORD BUFFER - // NEXT GET THE FRAME TIME - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - words.RemoveAll(); // CLEAR WORD BUFFER - for (int loop = 0; loop < frameCnt; loop++) - { - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - for (int loop2 = 0; loop2 < channelCnt; loop2++) - { - animData[loop * channelCnt + loop2] = atof(words.GetAt(loop2)); - if (loop2 < 3) - animData[loop * channelCnt + loop2] = animData[loop * channelCnt + loop2] / 10.0f; - } - - words.RemoveAll(); // CLEAR WORD BUFFER - } - - } - } - - words.RemoveAll(); // CLEAR WORD BUFFER - } - // Set the First Frame - for (int loop = 0; loop < channelCnt; loop++) - *dataptr[loop] = animData[loop]; - - - // SET THE CHANNEL INFO INTO BONE - root->primChannel = animData; - root->primChanType = CHANNEL_TYPE_BVH; - root->primFrameCount = (float)frameCnt; - root->primCurFrame = 0; - root->primSpeed = (float)(1); // CONVERT TO FRAME STEP SIZE AT 30FPS - root->secChannel = (float *)dataptr; - root->secFrameCount = (float)channelCnt; - - fclose(fp); - return TRUE; - } - return FALSE; -} -//// LoadBVH ////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: HandleAcclaimBone -// Purpose: Parse the Bone block in an Acclaim ASF file -// Arguments: Pointer to file handle and bone root -/////////////////////////////////////////////////////////////////////////////// -void HandleAcclaimBone(FILE *fp,t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - char buffer[MAX_STRINGLENGTH]; - char mess[MAX_STRINGLENGTH]; // FOR ERROR MESSAGE - CStringArray words; - t_Bone *tempBones,*curBone; - float dirx = 0.0,diry = 0.0,dirz = 0.0; // TEMP STORAGE FOR BONE DIRECTION - float length = 0.0; // BONE LENGTH STORAGE -/////////////////////////////////////////////////////////////////////////////// - // IF SO, WE FOUND A BONE SO ALLOC ROOM FOR IT - tempBones = (t_Bone *)malloc((root->childCnt + 1) * sizeof(t_Bone)); - if (root->childCnt > 0 && root->children != NULL) - { - // COPY OVER THE ONES THAT WERE ALREADY THERE - memcpy(tempBones,root->children,root->childCnt * sizeof(t_Bone)); - free(root->children); - } - // GRAB A HANDLE TO THE CURRENT BONE - curBone = &tempBones[root->childCnt++]; - ResetBone(curBone,NULL); - // SINCE THE ACCLAIM SCALE IS SO MUCH LARGE, I AM SCALING UP THE BONES - // SO YOU CAN ACTUALLY SEE THEM - curBone->scale.x = - curBone->scale.y = - curBone->scale.z = 10.0; - - // I AM ASSUMING A ROTATION ONLY CHANNEL SETTING - // SINCE NOT ALL BLOCKS HAVE DOF IN MY DATA - curBone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER - root->children = tempBones; - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - // HANDLE THE ID KEYWORD - if (words.GetAt(0) == "id") - { - curBone->id = atoi(words.GetAt(1)); - } - // HANDLE THE NAME KEYWORD - else if (words.GetAt(0) == "name") - { - strcpy(curBone->name, words.GetAt(1)); - } - // HANDLE THE DIRECTION KEYWORD - else if (words.GetAt(0) == "direction") - { - // THIS CONTROLS THE VECTOR AT WHICH THE BONE IS DEFINED - // SO I WANT TO STORE IT - dirx = atof(words.GetAt(1)); - diry = atof(words.GetAt(2)); - dirz = atof(words.GetAt(3)); - } - // HANDLE THE LENGTH KEYWORD - else if (words.GetAt(0) == "length") - { - length = atof(words.GetAt(1)); - // STORE OFF THE LENGTH VECTOR TO CALC THE TRANSFORMS LATER - curBone->length.x = length * dirx; - curBone->length.y = length * diry; - curBone->length.z = length * dirz; - } - // HANDLE THE BODYMASS KEYWORD - else if (words.GetAt(0) == "bodymass") - { - curBone->mass = atof(words.GetAt(1)); - } - // HANDLE THE COFMASS KEYWORD - else if (words.GetAt(0) == "cofmass") - { - // CENTER IS A PERCENTAGE ALONG THE BONE SO I MULT BY THE LENGTH VECTOR - curBone->center.x = atof(words.GetAt(1)) * curBone->b_trans.x; - curBone->center.y = atof(words.GetAt(1)) * curBone->b_trans.y; - curBone->center.z = atof(words.GetAt(1)) * curBone->b_trans.z; - } - // HANDLE THE DOF KEYWORD - else if (words.GetAt(0) == "dof") - { - // HERE WE NEED TO DETERMINE THE NUMBER OF CHANNELS AND ORDER - if (words.GetAt(1) == "rx" && words.GetAt(2) == "ry" && - words.GetAt(3) == "rz") - { - curBone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER - } - // I AM ONLY SUPPORTING THAT DOF SO REPORT OTHERS - // NONE OF MY DATA IS IN ANOTHER FORMAT - else - { - sprintf(mess,"Unsupported DOF for Bone '%s': %s",curBone->name,buffer); - ::MessageBox(NULL,buffer,"ASSF Load ERROR!!",MB_OK); - } - } - } - // I AM NOT HANDLING THE "LIMITS" OR "AXIS" BLOCKS - // KEEP PARSING UNTIL WE HIT AN END BLOCK - while ((words.GetAt(0) != "end") && !feof(fp)); -} -//// HandleAcclaimBone //////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: HandleAcclaimHierarchy -// Purpose: Parse the Hierarchy block in an Acclaim ASF file -// Arguments: Pointer to file handle and bone root -// Discussion: Tricky point is that since the position of the bone is -// Based on the length of the parent's bone, I need to fix -// this up at this point once I know the parent. -/////////////////////////////////////////////////////////////////////////////// -void HandleAcclaimHierarchy(FILE *fp,t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int bonecnt,loop,loop2,cnt; - char buffer[MAX_STRINGLENGTH]; - char name[80]; // BONE NAME - CStringArray words; - t_Bone *tempBone,*bonelist; -/////////////////////////////////////////////////////////////////////////////// - // ALLOC ROOM FOR THE BONE LIST - bonelist = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); - if (root->childCnt > 0 && root->children != NULL) - { - // COPY OVER THE ONES THAT WERE ALREADY THERE - memcpy(bonelist,root->children,root->childCnt * sizeof(t_Bone)); - bonecnt = root->childCnt; - free(root->children); - } - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - // HANDLE ANY VALID HIERARCHY NODES - if (words.GetAt(0) != "end" && words.GetAt(0).GetAt(0) != '#') - { - // HANDLE THE ROOT BIT - if (words.GetAt(0) == "root") - { - root->childCnt = words.GetSize() - 1; - root->children = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); - // GO THROUGH THE LIST OF CHILDREN - for (loop = 0; loop < root->childCnt; loop++) - { - // FIND A MATCH IN MY BONELIST - for (loop2 = 0; loop2 < bonecnt; loop2++) - { - if (words.GetAt(loop + 1) == bonelist[loop2].name) - { - // FOUND THE MATCH SO COPY IT OVER - memcpy(&root->children[loop],&bonelist[loop2],sizeof(t_Bone)); - } - } - } - } - // ANYTHING BUT THE "ROOT" ONE - else - { - strcpy(name,words.GetAt(0)); // NAME OF PARENT - tempBone = FindBoneParent(root,name); // GET THE POINTER TO THE PARENT - if (tempBone != NULL) - { - tempBone->childCnt = words.GetSize() - 1; - tempBone->children = (t_Bone *)malloc((tempBone->childCnt) * sizeof(t_Bone)); - // GO THROUGH THE LIST OF CHILDREN - for (loop = 0; loop < tempBone->childCnt; loop++) - { - // FIND A MATCH IN MY BONELIST - for (loop2 = 0; loop2 < bonecnt; loop2++) - { - if (words.GetAt(loop + 1) == bonelist[loop2].name) - { - // FOUND THE MATCH SO COPY IT OVER - memcpy(&tempBone->children[loop],&bonelist[loop2],sizeof(t_Bone)); - // SET THE TRANSLATION FOR THIS BONE NOW BASED ON THE PARENT LENGTH - tempBone->children[loop].b_trans.x = tempBone->length.x; - tempBone->children[loop].b_trans.y = tempBone->length.y; - tempBone->children[loop].b_trans.z = tempBone->length.z; - memcpy(&tempBone->children[loop].trans,&tempBone->children[loop].b_trans,sizeof(tVector)); - } - } - } - } - } - } - } - // I AM NOT HANDLING THE "LIMITS" OR "AXIS" BLOCKS - // KEEP PARSING UNTIL WE HIT AN END BLOCK - while ((words.GetAt(0) != "end") && !feof(fp)); - // FREE THE BONELIST - free(bonelist); -} -//// HandleAcclaimHierarchy /////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: LoadAcclaim -// Purpose: Actually load a Acclaim file into the system -// Arguments: Name of the file to open and root skeleton to put it in -/////////////////////////////////////////////////////////////////////////////// -BOOL LoadAcclaim(CString name,t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int cnt; - FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS - char buffer[MAX_STRINGLENGTH]; - CStringArray words; - BOOL grabNew = TRUE; // DO I NEED A NEW LINE? -/////////////////////////////////////////////////////////////////////////////// - // OPEN THE ACCLAIM ASF PORTION OF THE FILE - // THIS PART HOLDS THE DEFINITIONS FOR ALL THE BONES AS WELL AS THE - // HIERARCHY INFO - if (fp = fopen((LPCTSTR)name,"r")) { - while (!feof(fp)) - { - if (grabNew) - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - } - grabNew = TRUE; // MAKE SURE I DO THIS TIME - // SEE IF WE CAN FIND THE NAME KEYWORD - if (words.GetAt(0) == ":name") - { - // STORE OFF THE NAME - strcpy(root->name,words.GetAt(1)); - } - // I AM IGNORING UNITS KEYWORD - else if (words.GetAt(0) == ":units") - { - // GO THROUGH THE UNITS ITEMS - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - } - while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); - grabNew = FALSE; // DON'T REGRAB A MESSAGE - } - // I AM IGNORING DOCUMENTATION BLOCK - else if (words.GetAt(0) == ":documentation") - { - // GO THROUGH THE DOCUMENTATION ITEMS - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - } - while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); - grabNew = FALSE; // DON'T REGRAB A MESSAGE - } - // HANDLE THE ROOT BLOCK - // SINCE I WANT IT IN THE MIDDLE OF THE DISPLAY AND - // INITIALIZED LIKE I HAVE IT, I WILL IGNORE - else if (words.GetAt(0) == ":root") - { - // SHOULD JUST BE TWO LINES BUT... - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - } - while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); - grabNew = FALSE; // DON'T REGRAB A MESSAGE - } - // HANDLE THE BONEDATA BLOCK - // THIS IS THE MEAT OF THE SKELETAL LOAD - else if (words.GetAt(0) == ":bonedata") - { - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (words.GetAt(0) == "begin") - { - // FOUND A BONE BLOCK, GO OFF AND HANDLE IT - HandleAcclaimBone(fp,root); - } - } - while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); - grabNew = FALSE; // DON'T REGRAB A MESSAGE - } - // HANDLE THE HIERARCHY BLOCK - // CONTROLS THE PARENT STRUCTURE OF THE SKELETON - else if (words.GetAt(0) == ":hierarchy") - { - do - { - words.RemoveAll(); // CLEAR WORD BUFFER - fgets(buffer,MAX_STRINGLENGTH,fp); - ParseString(buffer,&words,&cnt); - if (words.GetAt(0) == "begin" && !feof(fp)) - { - // FOUND A BONE BLOCK, GO OFF AND HANDLE IT - HandleAcclaimHierarchy(fp,root); - } - } - while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); - grabNew = FALSE; // DON'T REGRAB A MESSAGE - } - } - fclose(fp); - return TRUE; - } - return FALSE; -} -//// LoadAcclaim ////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// LoadAnim.cpp +// +// Purpose: implementation of the Motion Capture file Loader +// +// Created: +// JL 9/5/97 +// Versions: +// 1.0 12/2/97 Initial Merge of the BVA Code +// 1.02 1/10/97 Merge in of ASF Hierarchy read code +// +// Todo: +// Still trying to catch up from the holidays +// Need to merge AMC portion of Acclaim loader for animation +// Merge of BVH reader code +// +// I WILL PROBABLY PULL OUT THE CHANNELS INTO A NEW STRUCT +// ADD SPEED OF PLAYBACK VARIABLE TO CHANNEL STRUCT +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "LoadAnim.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: ParseString +// Purpose: Actually breaks a string of words into individual pieces +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +void ParseString(char *buffer,CStringArray *words,int *cnt) +{ +/// Local Variables /////////////////////////////////////////////////////////// + CString in = buffer, temp; +/////////////////////////////////////////////////////////////////////////////// + + in.TrimLeft(); + in.TrimRight(); + *cnt = 0; + do + { + temp = in.SpanExcluding(" \t"); // GET UP TO THE NEXT SPACE OR TAB + words->Add(temp); + if (temp == in) break; + in = in.Right(in.GetLength() - temp.GetLength()); + in.TrimLeft(); + *cnt = *cnt + 1; + } while (1); + *cnt = *cnt + 1; +} +//// ParseString ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: FindBoneParent +// Purpose: Find the pointer to a bone with a given name +// Arguments: Source string in, array to put the words and the count +/////////////////////////////////////////////////////////////////////////////// +t_Bone *FindBoneParent(t_Bone *bone, char *name) +{ +/// Local Variables /////////////////////////////////////////////////////////// + t_Bone *retbone; + int loop; +/////////////////////////////////////////////////////////////////////////////// + // IF I HAVE THE RIGHT ONE, RETURN IT + if (strcmp(bone->name,name) == 0) + return bone; + if (bone->childCnt > 0) + { + for (loop = 0; loop < bone->childCnt; loop++) + { + // IF ONE OF THE CHILDREN IS THE ONE, RETURN IT + if (strcmp(bone->children[loop].name,name) == 0) + return &bone->children[loop]; + if (bone->children[loop].childCnt > 0) + { + retbone = FindBoneParent(&bone->children[loop],name); + if (retbone != NULL) + return retbone; + } + } + + } + // ALL HAS FAILED, RETURN NULL + return NULL; +} +//// FindBoneParent /////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadBVA +// Purpose: Actually load a BVA file into the system +// Arguments: Name of the file to open and root skeleton to put it in +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadBVA(CString name,t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS + int loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + int frameCnt; + float frameTime; + t_Bone *tempBones,*curBone; + float *tempChannel,*fptr; +/////////////////////////////////////////////////////////////////////////////// + // OPEN THE BVA FILE + if (fp = fopen((LPCTSTR)name,"r")) { + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + // SEE IF WE CAN FIND THE SEGMENT KEYWORD + if (words.GetAt(0) == "Segment:") + { + // IF SO, WE FOUND A BONE SO ALLOC ROOM FOR IT + tempBones = (t_Bone *)malloc((root->childCnt + 1) * sizeof(t_Bone)); + if (root->childCnt > 0 && root->children != NULL) + { + // COPY OVER THE ONES THAT WERE ALREADY THERE + memcpy(tempBones,root->children,root->childCnt * sizeof(t_Bone)); + free(root->children); + } + curBone = &tempBones[root->childCnt++]; + root->children = tempBones; + // COPY THE NAME INTO THE BONE + strcpy(curBone->name,words.GetAt(1)); + // SET THE ID TO THE BONE NUMBER + curBone->id = root->childCnt; + ResetBone(curBone, root); // SETUP INITIAL BONE SETTINGS + words.RemoveAll(); // CLEAR WORD BUFFER + // NEXT GET THE FRAMECOUNT + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + // NEXT LINE SHOULD BE FRAMES THEN A COUNT + if (words.GetAt(0) == "Frames:" && cnt == 2) + { + frameCnt = atoi(words.GetAt(1)); + words.RemoveAll(); // CLEAR WORD BUFFER + // NEXT GET THE FRAMETIME + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (words.GetAt(0) == "Frame" && + words.GetAt(1) == "Time:" && + cnt == 3) + { + frameTime = (float)atof(words.GetAt(2)); + words.RemoveAll(); // CLEAR WORD BUFFER + // TWO JUNK LINES FOR THE UNITS. I DON'T CARE + fgets(buffer,MAX_STRINGLENGTH,fp); + fgets(buffer,MAX_STRINGLENGTH,fp); + // NOW READY TO LOAD ALL THE ANIMATION + // ALLOC 9 FLOATS PER FRAME SINCE BVA HAS 9 ELEMENTS TO THE CHANNEL + tempChannel = (float *)malloc(sizeof(float) * frameCnt * + s_Channel_Type_Size[CHANNEL_TYPE_SRT]); + fptr = tempChannel; + // LOOP THROUGH THE FRAMES OF ANIMATION DATA + for (loop = 0; loop < frameCnt; loop++) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (cnt == s_Channel_Type_Size[CHANNEL_TYPE_SRT]) + { + for (loop2 = 0; loop2 < s_Channel_Type_Size[CHANNEL_TYPE_SRT]; loop2++) + { + *fptr = (float)atof(words.GetAt(loop2)); + // CONVERT INCHES TO FEET + if (loop2 < 3) *fptr = *fptr / 12; + fptr++; + } + } + else + { + sprintf(buffer,"Not Enough Entries in channel %s frame %d\nExpected %d Got %d",curBone->name,loop,s_Channel_Type_Size[CHANNEL_TYPE_SRT],cnt); + ::MessageBox(NULL,buffer,"BVA Load ERROR!!",MB_OK); + free(tempChannel); + return FALSE; + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + + // SET THE CHANNEL INFO INTO BONE + curBone->primChannel = tempChannel; + curBone->primChanType = CHANNEL_TYPE_SRT; + curBone->primFrameCount = (float)frameCnt; + curBone->primSpeed = (float)(30.0 * frameTime); // CONVERT TO FRAME STEP SIZE AT 30FPS + BoneSetFrame(curBone,0); + } + + } + else + { + sprintf(buffer,"Couldn't Find FrameCnt Area for Bone %s",curBone->name); + ::MessageBox(NULL,buffer,"BVA Load ERROR!!",MB_OK); + free(tempBones); + root->childCnt = 0; + root->children = NULL; + return FALSE; + } + } + } + fclose(fp); + return TRUE; + } + return FALSE; +} +//// LoadBVA ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadBVH +// Purpose: Actually load a BVH file into the system +// Arguments: Name of the file to open and root skeleton to put it in +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadBVH(CString name,t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS + int cnt; + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + CString temp; + t_Bone *tempBones,*curBone,*parent; + int boneNum = 0; + float **dataptr,*animData = NULL; + int channelCnt = 0,frameCnt = 0; +/////////////////////////////////////////////////////////////////////////////// + dataptr = (float **)malloc(sizeof(float *) * 255); + curBone = root; + // OPEN THE BVH FILE + if (fp = fopen((LPCTSTR)name,"r")) { + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + // SEE IF WE CAN FIND THE BONE SEGMENT KEYWORD + if (words.GetAt(0) == "ROOT" || words.GetAt(0) == "JOINT" || words.GetAt(0) == "End") + { + // IF SO, WE FOUND A BONE SO ALLOC ROOM FOR IT + tempBones = (t_Bone *)malloc((curBone->childCnt + 1) * sizeof(t_Bone)); + if (curBone->childCnt > 0 && curBone->children != NULL) + { + // COPY OVER THE ONES THAT WERE ALREADY THERE + memcpy(tempBones,curBone->children,curBone->childCnt * sizeof(t_Bone)); + // fix up the data pointers for any copied ones + for (int i = 0; i < curBone->childCnt; i++) + { + t_Bone *b1,*b2; + b1 = &curBone->children[i]; + b2 = &tempBones[i]; + for (int j = 0; j < channelCnt; j++) + { + if (dataptr[j] == &b1->rot.x) dataptr[j] = &b2->rot.x; + if (dataptr[j] == &b1->rot.y) dataptr[j] = &b2->rot.y; + if (dataptr[j] == &b1->rot.z) dataptr[j] = &b2->rot.z; + if (dataptr[j] == &b1->trans.x) dataptr[j] = &b2->trans.x; + if (dataptr[j] == &b1->trans.y) dataptr[j] = &b2->trans.y; + if (dataptr[j] == &b1->trans.z) dataptr[j] = &b2->trans.z; + } + } + free(curBone->children); + } + parent = curBone; + curBone->childCnt++; + boneNum++; + curBone->children = tempBones; + curBone = &tempBones[curBone->childCnt - 1]; + // COPY THE NAME INTO THE BONE + if (words.GetSize() > 2) + sprintf(curBone->name,"%s %s",words.GetAt(1),words.GetAt(2)); + else + sprintf(curBone->name,"%s",words.GetAt(1)); + // SET THE ID TO THE BONE NUMBER + curBone->id = boneNum; + ResetBone(curBone, parent); // SETUP INITIAL BONE SETTINGS +// curBone->curMatrix = (tMatrix *)malloc(sizeof(tMatrix)); + + words.RemoveAll(); // CLEAR WORD BUFFER + // NEXT GET THE FRAMECOUNT + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (words.GetAt(0) != "{") + { + ::MessageBox(NULL,"Error parsing BVH File: No opening Braces","ERROR",MB_OK); + } + } + else if (words.GetAt(0) == "CHANNELS") // Channel Pointers + { + for (int loop = 0; loop < atoi(words.GetAt(1)); loop++) + { + if (words.GetAt(2 + loop) == "Xposition") + { + dataptr[channelCnt++] = &curBone->trans.x; + } + else if (words.GetAt(2 + loop) == "Yposition") + { + dataptr[channelCnt++] = &curBone->trans.y; + } + else if (words.GetAt(2 + loop) == "Zposition") + { + dataptr[channelCnt++] = &curBone->trans.z; + } + else if (words.GetAt(2 + loop) == "Xrotation") + { + dataptr[channelCnt++] = &curBone->rot.x; + } + else if (words.GetAt(2 + loop) == "Yrotation") + { + dataptr[channelCnt++] = &curBone->rot.y; + } + else if (words.GetAt(2 + loop) == "Zrotation") + { + dataptr[channelCnt++] = &curBone->rot.z; + } + } + } + else if (words.GetAt(0) == "OFFSET") + { + curBone->trans.x = curBone->b_trans.x = atof(words.GetAt(1)) / 10.0f; + curBone->trans.y = curBone->b_trans.y = atof(words.GetAt(2)) / 10.0f; + curBone->trans.z = curBone->b_trans.z = atof(words.GetAt(3)) / 10.0f; + } + else if (words.GetAt(0) == "}") + { + curBone = curBone->parent; + } + else if (words.GetAt(0) == "MOTION") + { + words.RemoveAll(); // CLEAR WORD BUFFER + break; + } + words.RemoveAll(); // CLEAR WORD BUFFER + } + // Now we should be in motion area + while (!feof(fp)) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (words.GetAt(0) == "Frames:") + { + frameCnt = atoi(words.GetAt(1)); + animData = (float *)malloc(sizeof(float) * channelCnt * frameCnt); + if (animData != NULL) + { + words.RemoveAll(); // CLEAR WORD BUFFER + // NEXT GET THE FRAME TIME + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + words.RemoveAll(); // CLEAR WORD BUFFER + for (int loop = 0; loop < frameCnt; loop++) + { + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + for (int loop2 = 0; loop2 < channelCnt; loop2++) + { + animData[loop * channelCnt + loop2] = atof(words.GetAt(loop2)); + if (loop2 < 3) + animData[loop * channelCnt + loop2] = animData[loop * channelCnt + loop2] / 10.0f; + } + + words.RemoveAll(); // CLEAR WORD BUFFER + } + + } + } + + words.RemoveAll(); // CLEAR WORD BUFFER + } + // Set the First Frame + for (int loop = 0; loop < channelCnt; loop++) + *dataptr[loop] = animData[loop]; + + + // SET THE CHANNEL INFO INTO BONE + root->primChannel = animData; + root->primChanType = CHANNEL_TYPE_BVH; + root->primFrameCount = (float)frameCnt; + root->primCurFrame = 0; + root->primSpeed = (float)(1); // CONVERT TO FRAME STEP SIZE AT 30FPS + root->secChannel = (float *)dataptr; + root->secFrameCount = (float)channelCnt; + + fclose(fp); + return TRUE; + } + return FALSE; +} +//// LoadBVH ////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: HandleAcclaimBone +// Purpose: Parse the Bone block in an Acclaim ASF file +// Arguments: Pointer to file handle and bone root +/////////////////////////////////////////////////////////////////////////////// +void HandleAcclaimBone(FILE *fp,t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + char buffer[MAX_STRINGLENGTH]; + char mess[MAX_STRINGLENGTH]; // FOR ERROR MESSAGE + CStringArray words; + t_Bone *tempBones,*curBone; + float dirx = 0.0,diry = 0.0,dirz = 0.0; // TEMP STORAGE FOR BONE DIRECTION + float length = 0.0; // BONE LENGTH STORAGE +/////////////////////////////////////////////////////////////////////////////// + // IF SO, WE FOUND A BONE SO ALLOC ROOM FOR IT + tempBones = (t_Bone *)malloc((root->childCnt + 1) * sizeof(t_Bone)); + if (root->childCnt > 0 && root->children != NULL) + { + // COPY OVER THE ONES THAT WERE ALREADY THERE + memcpy(tempBones,root->children,root->childCnt * sizeof(t_Bone)); + free(root->children); + } + // GRAB A HANDLE TO THE CURRENT BONE + curBone = &tempBones[root->childCnt++]; + ResetBone(curBone,NULL); + // SINCE THE ACCLAIM SCALE IS SO MUCH LARGE, I AM SCALING UP THE BONES + // SO YOU CAN ACTUALLY SEE THEM + curBone->scale.x = + curBone->scale.y = + curBone->scale.z = 10.0; + + // I AM ASSUMING A ROTATION ONLY CHANNEL SETTING + // SINCE NOT ALL BLOCKS HAVE DOF IN MY DATA + curBone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER + root->children = tempBones; + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + // HANDLE THE ID KEYWORD + if (words.GetAt(0) == "id") + { + curBone->id = atoi(words.GetAt(1)); + } + // HANDLE THE NAME KEYWORD + else if (words.GetAt(0) == "name") + { + strcpy(curBone->name, words.GetAt(1)); + } + // HANDLE THE DIRECTION KEYWORD + else if (words.GetAt(0) == "direction") + { + // THIS CONTROLS THE VECTOR AT WHICH THE BONE IS DEFINED + // SO I WANT TO STORE IT + dirx = atof(words.GetAt(1)); + diry = atof(words.GetAt(2)); + dirz = atof(words.GetAt(3)); + } + // HANDLE THE LENGTH KEYWORD + else if (words.GetAt(0) == "length") + { + length = atof(words.GetAt(1)); + // STORE OFF THE LENGTH VECTOR TO CALC THE TRANSFORMS LATER + curBone->length.x = length * dirx; + curBone->length.y = length * diry; + curBone->length.z = length * dirz; + } + // HANDLE THE BODYMASS KEYWORD + else if (words.GetAt(0) == "bodymass") + { + curBone->mass = atof(words.GetAt(1)); + } + // HANDLE THE COFMASS KEYWORD + else if (words.GetAt(0) == "cofmass") + { + // CENTER IS A PERCENTAGE ALONG THE BONE SO I MULT BY THE LENGTH VECTOR + curBone->center.x = atof(words.GetAt(1)) * curBone->b_trans.x; + curBone->center.y = atof(words.GetAt(1)) * curBone->b_trans.y; + curBone->center.z = atof(words.GetAt(1)) * curBone->b_trans.z; + } + // HANDLE THE DOF KEYWORD + else if (words.GetAt(0) == "dof") + { + // HERE WE NEED TO DETERMINE THE NUMBER OF CHANNELS AND ORDER + if (words.GetAt(1) == "rx" && words.GetAt(2) == "ry" && + words.GetAt(3) == "rz") + { + curBone->flags = CHANNEL_TYPE_RXYZ; // ROTATION (RX RY RZ) ORDER + } + // I AM ONLY SUPPORTING THAT DOF SO REPORT OTHERS + // NONE OF MY DATA IS IN ANOTHER FORMAT + else + { + sprintf(mess,"Unsupported DOF for Bone '%s': %s",curBone->name,buffer); + ::MessageBox(NULL,buffer,"ASSF Load ERROR!!",MB_OK); + } + } + } + // I AM NOT HANDLING THE "LIMITS" OR "AXIS" BLOCKS + // KEEP PARSING UNTIL WE HIT AN END BLOCK + while ((words.GetAt(0) != "end") && !feof(fp)); +} +//// HandleAcclaimBone //////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: HandleAcclaimHierarchy +// Purpose: Parse the Hierarchy block in an Acclaim ASF file +// Arguments: Pointer to file handle and bone root +// Discussion: Tricky point is that since the position of the bone is +// Based on the length of the parent's bone, I need to fix +// this up at this point once I know the parent. +/////////////////////////////////////////////////////////////////////////////// +void HandleAcclaimHierarchy(FILE *fp,t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int bonecnt,loop,loop2,cnt; + char buffer[MAX_STRINGLENGTH]; + char name[80]; // BONE NAME + CStringArray words; + t_Bone *tempBone,*bonelist; +/////////////////////////////////////////////////////////////////////////////// + // ALLOC ROOM FOR THE BONE LIST + bonelist = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); + if (root->childCnt > 0 && root->children != NULL) + { + // COPY OVER THE ONES THAT WERE ALREADY THERE + memcpy(bonelist,root->children,root->childCnt * sizeof(t_Bone)); + bonecnt = root->childCnt; + free(root->children); + } + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + // HANDLE ANY VALID HIERARCHY NODES + if (words.GetAt(0) != "end" && words.GetAt(0).GetAt(0) != '#') + { + // HANDLE THE ROOT BIT + if (words.GetAt(0) == "root") + { + root->childCnt = words.GetSize() - 1; + root->children = (t_Bone *)malloc((root->childCnt) * sizeof(t_Bone)); + // GO THROUGH THE LIST OF CHILDREN + for (loop = 0; loop < root->childCnt; loop++) + { + // FIND A MATCH IN MY BONELIST + for (loop2 = 0; loop2 < bonecnt; loop2++) + { + if (words.GetAt(loop + 1) == bonelist[loop2].name) + { + // FOUND THE MATCH SO COPY IT OVER + memcpy(&root->children[loop],&bonelist[loop2],sizeof(t_Bone)); + } + } + } + } + // ANYTHING BUT THE "ROOT" ONE + else + { + strcpy(name,words.GetAt(0)); // NAME OF PARENT + tempBone = FindBoneParent(root,name); // GET THE POINTER TO THE PARENT + if (tempBone != NULL) + { + tempBone->childCnt = words.GetSize() - 1; + tempBone->children = (t_Bone *)malloc((tempBone->childCnt) * sizeof(t_Bone)); + // GO THROUGH THE LIST OF CHILDREN + for (loop = 0; loop < tempBone->childCnt; loop++) + { + // FIND A MATCH IN MY BONELIST + for (loop2 = 0; loop2 < bonecnt; loop2++) + { + if (words.GetAt(loop + 1) == bonelist[loop2].name) + { + // FOUND THE MATCH SO COPY IT OVER + memcpy(&tempBone->children[loop],&bonelist[loop2],sizeof(t_Bone)); + // SET THE TRANSLATION FOR THIS BONE NOW BASED ON THE PARENT LENGTH + tempBone->children[loop].b_trans.x = tempBone->length.x; + tempBone->children[loop].b_trans.y = tempBone->length.y; + tempBone->children[loop].b_trans.z = tempBone->length.z; + memcpy(&tempBone->children[loop].trans,&tempBone->children[loop].b_trans,sizeof(tVector)); + } + } + } + } + } + } + } + // I AM NOT HANDLING THE "LIMITS" OR "AXIS" BLOCKS + // KEEP PARSING UNTIL WE HIT AN END BLOCK + while ((words.GetAt(0) != "end") && !feof(fp)); + // FREE THE BONELIST + free(bonelist); +} +//// HandleAcclaimHierarchy /////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: LoadAcclaim +// Purpose: Actually load a Acclaim file into the system +// Arguments: Name of the file to open and root skeleton to put it in +/////////////////////////////////////////////////////////////////////////////// +BOOL LoadAcclaim(CString name,t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int cnt; + FILE *fp; // I PREFER THIS STYLE OF FILE ACCESS + char buffer[MAX_STRINGLENGTH]; + CStringArray words; + BOOL grabNew = TRUE; // DO I NEED A NEW LINE? +/////////////////////////////////////////////////////////////////////////////// + // OPEN THE ACCLAIM ASF PORTION OF THE FILE + // THIS PART HOLDS THE DEFINITIONS FOR ALL THE BONES AS WELL AS THE + // HIERARCHY INFO + if (fp = fopen((LPCTSTR)name,"r")) { + while (!feof(fp)) + { + if (grabNew) + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + } + grabNew = TRUE; // MAKE SURE I DO THIS TIME + // SEE IF WE CAN FIND THE NAME KEYWORD + if (words.GetAt(0) == ":name") + { + // STORE OFF THE NAME + strcpy(root->name,words.GetAt(1)); + } + // I AM IGNORING UNITS KEYWORD + else if (words.GetAt(0) == ":units") + { + // GO THROUGH THE UNITS ITEMS + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + } + while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); + grabNew = FALSE; // DON'T REGRAB A MESSAGE + } + // I AM IGNORING DOCUMENTATION BLOCK + else if (words.GetAt(0) == ":documentation") + { + // GO THROUGH THE DOCUMENTATION ITEMS + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + } + while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); + grabNew = FALSE; // DON'T REGRAB A MESSAGE + } + // HANDLE THE ROOT BLOCK + // SINCE I WANT IT IN THE MIDDLE OF THE DISPLAY AND + // INITIALIZED LIKE I HAVE IT, I WILL IGNORE + else if (words.GetAt(0) == ":root") + { + // SHOULD JUST BE TWO LINES BUT... + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + } + while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); + grabNew = FALSE; // DON'T REGRAB A MESSAGE + } + // HANDLE THE BONEDATA BLOCK + // THIS IS THE MEAT OF THE SKELETAL LOAD + else if (words.GetAt(0) == ":bonedata") + { + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (words.GetAt(0) == "begin") + { + // FOUND A BONE BLOCK, GO OFF AND HANDLE IT + HandleAcclaimBone(fp,root); + } + } + while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); + grabNew = FALSE; // DON'T REGRAB A MESSAGE + } + // HANDLE THE HIERARCHY BLOCK + // CONTROLS THE PARENT STRUCTURE OF THE SKELETON + else if (words.GetAt(0) == ":hierarchy") + { + do + { + words.RemoveAll(); // CLEAR WORD BUFFER + fgets(buffer,MAX_STRINGLENGTH,fp); + ParseString(buffer,&words,&cnt); + if (words.GetAt(0) == "begin" && !feof(fp)) + { + // FOUND A BONE BLOCK, GO OFF AND HANDLE IT + HandleAcclaimHierarchy(fp,root); + } + } + while ((words.GetAt(0).GetAt(0) != ':') && !feof(fp)); + grabNew = FALSE; // DON'T REGRAB A MESSAGE + } + } + fclose(fp); + return TRUE; + } + return FALSE; +} +//// LoadAcclaim ////////////////////////////////////////////////////////////// diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.h index dc76ccf..42a89a4 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/LoadAnim.h @@ -1,30 +1,30 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// LoadAnim.h -// -// Purpose: implementation of the Motion Capture file Loader -// -// Created: -// JL 9/5/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(LoadAnim_H__INCLUDED_) -#define LoadAnim_H__INCLUDED_ - -#define MAX_STRINGLENGTH 8192 - -#include "Skeleton.h" - -BOOL LoadBVA(CString name,t_Bone *root); -BOOL LoadBVH(CString name,t_Bone *root); -BOOL LoadAcclaim(CString name,t_Bone *root); - -#endif // !defined(LoadAnim_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// LoadAnim.h +// +// Purpose: implementation of the Motion Capture file Loader +// +// Created: +// JL 9/5/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(LoadAnim_H__INCLUDED_) +#define LoadAnim_H__INCLUDED_ + +#define MAX_STRINGLENGTH 8192 + +#include "Skeleton.h" + +BOOL LoadBVA(CString name,t_Bone *root); +BOOL LoadBVH(CString name,t_Bone *root); +BOOL LoadAcclaim(CString name,t_Bone *root); + +#endif // !defined(LoadAnim_H__INCLUDED_) diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.cpp index 6e96f3e..d558e6d 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.cpp @@ -1,482 +1,482 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.cpp : implementation of the CMainFrame class -// -// Purpose: Implementation of Main Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// Versions: -// 1.01 12/20/97 Added OpenGL Resize Code, Moved window size to defines -// 1.02 1/10/97 Merge in of ASF Hierarchy read code -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "mmsystem.h" // NEED THIS FOR THE TIMEGETTIME -#include "Dagger.h" -#include "HierWin.h" -#include "LoadAnim.h" - -#include "MainFrm.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -/// Local Defines ///////////////////////////////////////////////////////////// -#define HIERWIN_START_X 0 // STARTING X POSITION OF HIERARCHY WINDOW -#define HIERWIN_START_Y 32 // STARTING Y POSITION OF HIERARCHY WINDOW -#define HIERWIN_WIDTH 160 // WIDTH OF HIERARCHY WINDOW -#define HIERWIN_BOTTOM 52 // BOTTOM BORDER OF HIERARCHY WINDOW -#define OGLWIN_START_X 162 // STARTING X POSITION OF OPENGL WINDOW -#define OGLWIN_START_Y 32 // STARTING Y POSITION OF OPENGL WINDOW -#define OGLWIN_WIDTH 164 // WIDTH OF OPENGL WINDOW SUBTRACTED FROM MAX -#define OGLWIN_BOTTOM 52 // BOTTOM BORDER OF OPENGL WINDOW -/////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame - -IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) - -BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) - //{{AFX_MSG_MAP(CMainFrame) - ON_WM_CREATE() - ON_WM_SIZE() -// FOR NOW I DON'T HANDLE THE ADD BONE -// ON_COMMAND(ID_ADD_BONE, OnAddBone) - ON_WM_KEYUP() - ON_WM_KEYDOWN() - ON_COMMAND(ID_VIEW_RESETSKELETON, OnViewResetskeleton) - ON_COMMAND(ID_BACK_FRAME, OnBackFrame) - ON_COMMAND(ID_PLAY_BACK, OnPlayBack) - ON_COMMAND(ID_STOP, OnStop) - ON_COMMAND(ID_PLAY_FORWARD, OnPlayForward) - ON_COMMAND(ID_FORWARD_FRAME, OnForwardFrame) - ON_COMMAND(ID_FILE_LOADANIM, OnFileLoadanim) - ON_WM_PAINT() - ON_COMMAND(ID_ANIMATION_PLAYBACKSPEED, OnAnimationPlaybackspeed) - ON_COMMAND(ID_WHICHOGL, OnWhichogl) - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -static UINT indicators[] = -{ - ID_SEPARATOR, // status line indicator - ID_INDICATOR_FRAME2, // FOR DISPLAY OF FRAMECOUNT AND CURRENT FRAME - ID_INDICATOR_CAPS, - ID_INDICATOR_NUM, - ID_INDICATOR_SCRL, -}; - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame construction/destruction - -CMainFrame::CMainFrame() -{ - m_Animating = FALSE; - m_ElapsedTime = ~(DWORD)0; // initialize to a big number - m_Animation_Direction = 1; - m_AnimSpeed = 30; // DEFAULT PLAYBACK SPEED AS FRAME DELAY - m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - - InitializeSkeleton(); -} - -CMainFrame::~CMainFrame() -{ - m_HierWin.DestroyWindow(); -} - -int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - GetClientRect(&rect); - - if (CFrameWnd::OnCreate(lpCreateStruct) == -1) - return -1; - - if (!m_wndToolBar.Create(this) || - !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) - { - TRACE0("Failed to create toolbar\n"); - return -1; // fail to create - } - - if (!m_wndStatusBar.Create(this) || - !m_wndStatusBar.SetIndicators(indicators, - sizeof(indicators)/sizeof(UINT))) - { - TRACE0("Failed to create status bar\n"); - return -1; // fail to create - } - - // TODO: Remove this if you don't want tool tips or a resizeable toolbar - m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | - CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); - - // TODO: Delete these three lines if you don't want the toolbar to - // be dockable -/* m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); - EnableDocking(CBRS_ALIGN_ANY); - DockControlBar(&m_wndToolBar); -*/ - m_HierWin.Create( TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS, - CRect(HIERWIN_START_X, HIERWIN_START_Y,HIERWIN_WIDTH,rect.bottom - HIERWIN_BOTTOM), this, 1001); - m_HierWin.ShowWindow(TRUE); - - m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, - CRect(OGLWIN_START_X, OGLWIN_START_Y,rect.right - OGLWIN_WIDTH,rect.bottom - OGLWIN_BOTTOM),this,104,&m_Skeleton); - m_OGLView.ShowWindow(TRUE); - - m_OGLView.m_StatusBar = &m_wndStatusBar; - - m_OGLView.Invalidate(TRUE); - - - // Now we initialize the animation code - - m_StartTime = ::timeGetTime(); // get time in ms - - // need a previous time if we start off animated - if ( m_Animating ) - { - m_previousElapsedTime = m_StartTime; - } - return 0; -} - -BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) -{ - HICON hicon; - - hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - - m_ClassName = AfxRegisterWndClass(NULL, - (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow - cs.lpszClass = m_ClassName; - - return CFrameWnd::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame implementation - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame diagnostics - -#ifdef _DEBUG -void CMainFrame::AssertValid() const -{ - CFrameWnd::AssertValid(); -} - -void CMainFrame::Dump(CDumpContext& dc) const -{ - CFrameWnd::Dump(dc); -} - -#endif //_DEBUG - -///////////////////////////////////////////////////////////////////////////// -// CMainFrame message handlers - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnWhichogl -// Purpose: Create dialog to Show which version of OGL is running -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnWhichogl() -{ - m_OGLView.GetGLInfo(); -} -// OnWhichogl - -BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) -{ - - return CFrameWnd::OnCreateClient(lpcs, pContext); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnPaint -// Purpose: This routine grabs the message loop if I am animating and -// handles the messages. This way I can play back as fast -// as possible -// Reference: OpenGL Programming for Windows 95 by Ron Fosner -// Sort of a variation on that code -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnPaint() -{ - MSG msg; - CPaintDC dc(this); // device context for painting - - // IF I AM IN ANIMATING MODE - while ( m_Animating == TRUE) - { - while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - m_Animating = FALSE; - ::PostQuitMessage(0); - } - - // Dispatch any messages as needed - if (!AfxGetApp()->PreTranslateMessage(&msg)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - // Give the Idle system some time - AfxGetApp()->OnIdle(0); - AfxGetApp()->OnIdle(1); - - } - m_ElapsedTime = ::timeGetTime(); // get current time - - // CHECK IF ENOUGH TIME HAS GONE BY TO DRAW THE NEXT FRAME - if (ElapsedTimeRender() > (unsigned int)(1000/m_AnimSpeed) ) - { - // ADVANCE THE ANIMATION - BoneAdvanceFrame(&m_Skeleton,m_Animation_Direction,TRUE); - // REDRAW THE OGL WINDOW - m_OGLView.drawScene(); - // RESET THE TIME COUNTER - m_previousElapsedTime = m_ElapsedTime; - } - } - - m_OGLView.drawScene(); -} -/// OnPaint //////////////////////////////////////////////////////////// - -void CMainFrame::OnSize(UINT nType, int cx, int cy) -{ - // RESET THE HierWin WINDOW SIZE - m_HierWin.SetWindowPos( &wndTopMost, HIERWIN_START_X, HIERWIN_START_Y, HIERWIN_WIDTH, cy - HIERWIN_BOTTOM, SWP_NOZORDER ); - // RESET THE m_OGLView WINDOW SIZE - m_OGLView.SetWindowPos( &wndTopMost, OGLWIN_START_X, OGLWIN_START_Y, cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM, SWP_NOZORDER ); - // RESET THE ACTUAL OPENGL WINDOW SIZE - m_OGLView.resize( cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM); - CFrameWnd::OnSize(nType, cx, cy); -} - -// HAVEN'T IMPLEMENTED ADDING A BONE -#if 0 -void CMainFrame::OnAddBone() -{ - m_HierWin.AddBone(); -} -#endif - -void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyDown(nChar); - CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); -} - -void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -{ - m_OGLView.HandleKeyUp(nChar); - CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); -} - -///////////////////////////////////////////////////////////////////////////// -// Hierarchy Manipulation Functions - -void CMainFrame::InitializeSkeleton() -{ - // INITIALIZE SOME OF THE SKELETON VARIABLES - ResetBone(&m_Skeleton, NULL); - m_Skeleton.id = -1; - strcpy(m_Skeleton.name,"Skeleton"); - m_Skeleton.rot.x = 0.0f; - m_Skeleton.rot.y = 0.0f; - m_Skeleton.rot.z = 0.0f; - m_Skeleton.b_trans.y = -3.0f; - m_Skeleton.b_trans.z = -40.0f; - m_Skeleton.trans.y = -3.0f; - m_Skeleton.trans.z = -40.0f; -} - -///////////////////////////////////////////////////////////////////////////// -// View Manipulation Functions - -void CMainFrame::OnViewResetskeleton() -{ - // PASS THIS MESSAGE OFF TO THE OGL CLASS - m_OGLView.OnViewResetskeleton(); -} - -///////////////////////////////////////////////////////////////////////////// -// Animation Control Functions - -void CMainFrame::OnPlayBack() -{ - m_Animating = TRUE; - m_Animation_Direction = -1; - Invalidate(TRUE); -} - -void CMainFrame::OnBackFrame() -{ - m_Animating = FALSE; - BoneAdvanceFrame(&m_Skeleton,-1,TRUE); - m_OGLView.drawScene(); -} - -void CMainFrame::OnStop() -{ - m_Animating = FALSE; -} - -void CMainFrame::OnForwardFrame() -{ - m_Animating = FALSE; - BoneAdvanceFrame(&m_Skeleton,1,TRUE); - m_OGLView.drawScene(); -} - -void CMainFrame::OnPlayForward() -{ - m_Animation_Direction = 1; - m_Animating = TRUE; - Invalidate(TRUE); -} - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnAnimationPlaybackspeed -// Purpose: Create dialog to change speed of playback -// Response to Menu Message -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnAnimationPlaybackspeed() -{ -/// Local Variables /////////////////////////////////////////////////////////// - CPlaySpeed dialog; // Class of Dialog box -/////////////////////////////////////////////////////////////////////////////// - dialog.m_Playback_Speed = m_AnimSpeed; - if (dialog.DoModal()) - { - m_AnimSpeed = dialog.m_Playback_Speed; - Invalidate(TRUE); - } -} -/// OnAnimationPlaybackspeed /////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// Animation File Functions - -/////////////////////////////////////////////////////////////////////////////// -// Procedure: OnFileLoadanim -// Purpose: Create dialog to load an animation file of various formats -// Response to Menu Message -/////////////////////////////////////////////////////////////////////////////// -void CMainFrame::OnFileLoadanim() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char BASED_CODE szFilter[] = "Biovision BVA (*.bva)|*.bva|Biovision Heirarchy BVH (*.bvh)|*.bvh|Acclaim File (*.asf)|*.asf||"; - CFileDialog *dialog; - CString exten; -/////////////////////////////////////////////////////////////////////////////// - - dialog = new CFileDialog(TRUE,"bva",NULL, NULL,szFilter); - if (dialog->DoModal() == IDOK) - { - exten = dialog->GetFileExt(); - exten.MakeUpper(); - if (exten == "BVA") - { - DestroySkeleton(&m_Skeleton); - InitializeSkeleton(); - LoadBVA(dialog->GetPathName(),&m_Skeleton); - m_HierWin.ResetSkeleton(); - m_HierWin.SetSkeleton(&m_Skeleton, NULL); - m_OGLView.drawScene(); - m_OGLView.OnViewResetskeleton(); - } - // HANDLE THE ACCLAIM FORMAT - else if (exten == "ASF") - { - DestroySkeleton(&m_Skeleton); - InitializeSkeleton(); - LoadAcclaim(dialog->GetPathName(),&m_Skeleton); - m_HierWin.ResetSkeleton(); - m_HierWin.SetSkeleton(&m_Skeleton, NULL); - m_OGLView.drawScene(); - m_OGLView.OnViewResetskeleton(); - // ACCLAIM IS MUCH LARGER SO I AM OFFSETTING THE CAMERA A BIT - m_Skeleton.b_trans.y = 5.0f; - m_Skeleton.b_trans.z = -400.0f; - m_Skeleton.trans.y = 5.0f; - m_Skeleton.trans.z = -400.0f; - } - // HANDLE THE BIOVISION HEIRARCHY - else if (exten == "BVH") - { - DestroySkeleton(&m_Skeleton); - InitializeSkeleton(); - LoadBVH(dialog->GetPathName(),&m_Skeleton); - m_HierWin.ResetSkeleton(); - m_HierWin.SetSkeleton(&m_Skeleton, NULL); - m_OGLView.drawScene(); - m_OGLView.OnViewResetskeleton(); - } - } - delete dialog; -} -/// OnFileLoadanim //////////////////////////////////////////////////////////// - - -/// Local Dialog Code ///////////////////////////////////////////////////////// -// -// MFC LIKES TO PUT THESE IN A SEPARATE FILE, BUT IT LIKE THEM IN CODE THAT -// USES THEM -// -/////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CPlaySpeed dialog - - -CPlaySpeed::CPlaySpeed(CWnd* pParent /*=NULL*/) - : CDialog(CPlaySpeed::IDD, pParent) -{ - //{{AFX_DATA_INIT(CPlaySpeed) - m_Playback_Speed = 0; - //}}AFX_DATA_INIT -} - - -void CPlaySpeed::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CPlaySpeed) - DDX_Text(pDX, IDC_PLAYBACK_SPEED, m_Playback_Speed); - DDV_MinMaxUInt(pDX, m_Playback_Speed, 1, 99999); - //}}AFX_DATA_MAP -} - - -BEGIN_MESSAGE_MAP(CPlaySpeed, CDialog) - //{{AFX_MSG_MAP(CPlaySpeed) - // NOTE: the ClassWizard will add message map macros here - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CPlaySpeed message handlers - - +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.cpp : implementation of the CMainFrame class +// +// Purpose: Implementation of Main Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// Versions: +// 1.01 12/20/97 Added OpenGL Resize Code, Moved window size to defines +// 1.02 1/10/97 Merge in of ASF Hierarchy read code +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "mmsystem.h" // NEED THIS FOR THE TIMEGETTIME +#include "Dagger.h" +#include "HierWin.h" +#include "LoadAnim.h" + +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +/// Local Defines ///////////////////////////////////////////////////////////// +#define HIERWIN_START_X 0 // STARTING X POSITION OF HIERARCHY WINDOW +#define HIERWIN_START_Y 32 // STARTING Y POSITION OF HIERARCHY WINDOW +#define HIERWIN_WIDTH 160 // WIDTH OF HIERARCHY WINDOW +#define HIERWIN_BOTTOM 52 // BOTTOM BORDER OF HIERARCHY WINDOW +#define OGLWIN_START_X 162 // STARTING X POSITION OF OPENGL WINDOW +#define OGLWIN_START_Y 32 // STARTING Y POSITION OF OPENGL WINDOW +#define OGLWIN_WIDTH 164 // WIDTH OF OPENGL WINDOW SUBTRACTED FROM MAX +#define OGLWIN_BOTTOM 52 // BOTTOM BORDER OF OPENGL WINDOW +/////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_SIZE() +// FOR NOW I DON'T HANDLE THE ADD BONE +// ON_COMMAND(ID_ADD_BONE, OnAddBone) + ON_WM_KEYUP() + ON_WM_KEYDOWN() + ON_COMMAND(ID_VIEW_RESETSKELETON, OnViewResetskeleton) + ON_COMMAND(ID_BACK_FRAME, OnBackFrame) + ON_COMMAND(ID_PLAY_BACK, OnPlayBack) + ON_COMMAND(ID_STOP, OnStop) + ON_COMMAND(ID_PLAY_FORWARD, OnPlayForward) + ON_COMMAND(ID_FORWARD_FRAME, OnForwardFrame) + ON_COMMAND(ID_FILE_LOADANIM, OnFileLoadanim) + ON_WM_PAINT() + ON_COMMAND(ID_ANIMATION_PLAYBACKSPEED, OnAnimationPlaybackspeed) + ON_COMMAND(ID_WHICHOGL, OnWhichogl) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_FRAME2, // FOR DISPLAY OF FRAMECOUNT AND CURRENT FRAME + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_Animating = FALSE; + m_ElapsedTime = ~(DWORD)0; // initialize to a big number + m_Animation_Direction = 1; + m_AnimSpeed = 30; // DEFAULT PLAYBACK SPEED AS FRAME DELAY + m_HArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + + InitializeSkeleton(); +} + +CMainFrame::~CMainFrame() +{ + m_HierWin.DestroyWindow(); +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + GetClientRect(&rect); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + if (!m_wndToolBar.Create(this) || + !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + // TODO: Remove this if you don't want tool tips or a resizeable toolbar + m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | + CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); + + // TODO: Delete these three lines if you don't want the toolbar to + // be dockable +/* m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); + EnableDocking(CBRS_ALIGN_ANY); + DockControlBar(&m_wndToolBar); +*/ + m_HierWin.Create( TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS, + CRect(HIERWIN_START_X, HIERWIN_START_Y,HIERWIN_WIDTH,rect.bottom - HIERWIN_BOTTOM), this, 1001); + m_HierWin.ShowWindow(TRUE); + + m_OGLView.Create(NULL,"Render Window",WS_CHILD | WS_VISIBLE, + CRect(OGLWIN_START_X, OGLWIN_START_Y,rect.right - OGLWIN_WIDTH,rect.bottom - OGLWIN_BOTTOM),this,104,&m_Skeleton); + m_OGLView.ShowWindow(TRUE); + + m_OGLView.m_StatusBar = &m_wndStatusBar; + + m_OGLView.Invalidate(TRUE); + + + // Now we initialize the animation code + + m_StartTime = ::timeGetTime(); // get time in ms + + // need a previous time if we start off animated + if ( m_Animating ) + { + m_previousElapsedTime = m_StartTime; + } + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + HICON hicon; + + hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + + m_ClassName = AfxRegisterWndClass(NULL, + (HCURSOR)m_HArrow, (HBRUSH)::GetStockObject(DKGRAY_BRUSH), hicon); //m_HArrow + cs.lpszClass = m_ClassName; + + return CFrameWnd::PreCreateWindow(cs); +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame implementation + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnWhichogl +// Purpose: Create dialog to Show which version of OGL is running +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnWhichogl() +{ + m_OGLView.GetGLInfo(); +} +// OnWhichogl + +BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) +{ + + return CFrameWnd::OnCreateClient(lpcs, pContext); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnPaint +// Purpose: This routine grabs the message loop if I am animating and +// handles the messages. This way I can play back as fast +// as possible +// Reference: OpenGL Programming for Windows 95 by Ron Fosner +// Sort of a variation on that code +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnPaint() +{ + MSG msg; + CPaintDC dc(this); // device context for painting + + // IF I AM IN ANIMATING MODE + while ( m_Animating == TRUE) + { + while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + m_Animating = FALSE; + ::PostQuitMessage(0); + } + + // Dispatch any messages as needed + if (!AfxGetApp()->PreTranslateMessage(&msg)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + // Give the Idle system some time + AfxGetApp()->OnIdle(0); + AfxGetApp()->OnIdle(1); + + } + m_ElapsedTime = ::timeGetTime(); // get current time + + // CHECK IF ENOUGH TIME HAS GONE BY TO DRAW THE NEXT FRAME + if (ElapsedTimeRender() > (unsigned int)(1000/m_AnimSpeed) ) + { + // ADVANCE THE ANIMATION + BoneAdvanceFrame(&m_Skeleton,m_Animation_Direction,TRUE); + // REDRAW THE OGL WINDOW + m_OGLView.drawScene(); + // RESET THE TIME COUNTER + m_previousElapsedTime = m_ElapsedTime; + } + } + + m_OGLView.drawScene(); +} +/// OnPaint //////////////////////////////////////////////////////////// + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + // RESET THE HierWin WINDOW SIZE + m_HierWin.SetWindowPos( &wndTopMost, HIERWIN_START_X, HIERWIN_START_Y, HIERWIN_WIDTH, cy - HIERWIN_BOTTOM, SWP_NOZORDER ); + // RESET THE m_OGLView WINDOW SIZE + m_OGLView.SetWindowPos( &wndTopMost, OGLWIN_START_X, OGLWIN_START_Y, cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM, SWP_NOZORDER ); + // RESET THE ACTUAL OPENGL WINDOW SIZE + m_OGLView.resize( cx - OGLWIN_WIDTH, cy - OGLWIN_BOTTOM); + CFrameWnd::OnSize(nType, cx, cy); +} + +// HAVEN'T IMPLEMENTED ADDING A BONE +#if 0 +void CMainFrame::OnAddBone() +{ + m_HierWin.AddBone(); +} +#endif + +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyDown(nChar); + CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + m_OGLView.HandleKeyUp(nChar); + CFrameWnd::OnKeyUp(nChar, nRepCnt, nFlags); +} + +///////////////////////////////////////////////////////////////////////////// +// Hierarchy Manipulation Functions + +void CMainFrame::InitializeSkeleton() +{ + // INITIALIZE SOME OF THE SKELETON VARIABLES + ResetBone(&m_Skeleton, NULL); + m_Skeleton.id = -1; + strcpy(m_Skeleton.name,"Skeleton"); + m_Skeleton.rot.x = 0.0f; + m_Skeleton.rot.y = 0.0f; + m_Skeleton.rot.z = 0.0f; + m_Skeleton.b_trans.y = -3.0f; + m_Skeleton.b_trans.z = -40.0f; + m_Skeleton.trans.y = -3.0f; + m_Skeleton.trans.z = -40.0f; +} + +///////////////////////////////////////////////////////////////////////////// +// View Manipulation Functions + +void CMainFrame::OnViewResetskeleton() +{ + // PASS THIS MESSAGE OFF TO THE OGL CLASS + m_OGLView.OnViewResetskeleton(); +} + +///////////////////////////////////////////////////////////////////////////// +// Animation Control Functions + +void CMainFrame::OnPlayBack() +{ + m_Animating = TRUE; + m_Animation_Direction = -1; + Invalidate(TRUE); +} + +void CMainFrame::OnBackFrame() +{ + m_Animating = FALSE; + BoneAdvanceFrame(&m_Skeleton,-1,TRUE); + m_OGLView.drawScene(); +} + +void CMainFrame::OnStop() +{ + m_Animating = FALSE; +} + +void CMainFrame::OnForwardFrame() +{ + m_Animating = FALSE; + BoneAdvanceFrame(&m_Skeleton,1,TRUE); + m_OGLView.drawScene(); +} + +void CMainFrame::OnPlayForward() +{ + m_Animation_Direction = 1; + m_Animating = TRUE; + Invalidate(TRUE); +} + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnAnimationPlaybackspeed +// Purpose: Create dialog to change speed of playback +// Response to Menu Message +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnAnimationPlaybackspeed() +{ +/// Local Variables /////////////////////////////////////////////////////////// + CPlaySpeed dialog; // Class of Dialog box +/////////////////////////////////////////////////////////////////////////////// + dialog.m_Playback_Speed = m_AnimSpeed; + if (dialog.DoModal()) + { + m_AnimSpeed = dialog.m_Playback_Speed; + Invalidate(TRUE); + } +} +/// OnAnimationPlaybackspeed /////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Animation File Functions + +/////////////////////////////////////////////////////////////////////////////// +// Procedure: OnFileLoadanim +// Purpose: Create dialog to load an animation file of various formats +// Response to Menu Message +/////////////////////////////////////////////////////////////////////////////// +void CMainFrame::OnFileLoadanim() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char BASED_CODE szFilter[] = "Biovision BVA (*.bva)|*.bva|Biovision Heirarchy BVH (*.bvh)|*.bvh|Acclaim File (*.asf)|*.asf||"; + CFileDialog *dialog; + CString exten; +/////////////////////////////////////////////////////////////////////////////// + + dialog = new CFileDialog(TRUE,"bva",NULL, NULL,szFilter); + if (dialog->DoModal() == IDOK) + { + exten = dialog->GetFileExt(); + exten.MakeUpper(); + if (exten == "BVA") + { + DestroySkeleton(&m_Skeleton); + InitializeSkeleton(); + LoadBVA(dialog->GetPathName(),&m_Skeleton); + m_HierWin.ResetSkeleton(); + m_HierWin.SetSkeleton(&m_Skeleton, NULL); + m_OGLView.drawScene(); + m_OGLView.OnViewResetskeleton(); + } + // HANDLE THE ACCLAIM FORMAT + else if (exten == "ASF") + { + DestroySkeleton(&m_Skeleton); + InitializeSkeleton(); + LoadAcclaim(dialog->GetPathName(),&m_Skeleton); + m_HierWin.ResetSkeleton(); + m_HierWin.SetSkeleton(&m_Skeleton, NULL); + m_OGLView.drawScene(); + m_OGLView.OnViewResetskeleton(); + // ACCLAIM IS MUCH LARGER SO I AM OFFSETTING THE CAMERA A BIT + m_Skeleton.b_trans.y = 5.0f; + m_Skeleton.b_trans.z = -400.0f; + m_Skeleton.trans.y = 5.0f; + m_Skeleton.trans.z = -400.0f; + } + // HANDLE THE BIOVISION HEIRARCHY + else if (exten == "BVH") + { + DestroySkeleton(&m_Skeleton); + InitializeSkeleton(); + LoadBVH(dialog->GetPathName(),&m_Skeleton); + m_HierWin.ResetSkeleton(); + m_HierWin.SetSkeleton(&m_Skeleton, NULL); + m_OGLView.drawScene(); + m_OGLView.OnViewResetskeleton(); + } + } + delete dialog; +} +/// OnFileLoadanim //////////////////////////////////////////////////////////// + + +/// Local Dialog Code ///////////////////////////////////////////////////////// +// +// MFC LIKES TO PUT THESE IN A SEPARATE FILE, BUT IT LIKE THEM IN CODE THAT +// USES THEM +// +/////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CPlaySpeed dialog + + +CPlaySpeed::CPlaySpeed(CWnd* pParent /*=NULL*/) + : CDialog(CPlaySpeed::IDD, pParent) +{ + //{{AFX_DATA_INIT(CPlaySpeed) + m_Playback_Speed = 0; + //}}AFX_DATA_INIT +} + + +void CPlaySpeed::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CPlaySpeed) + DDX_Text(pDX, IDC_PLAYBACK_SPEED, m_Playback_Speed); + DDV_MinMaxUInt(pDX, m_Playback_Speed, 1, 99999); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CPlaySpeed, CDialog) + //{{AFX_MSG_MAP(CPlaySpeed) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPlaySpeed message handlers + + diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.h index d70d485..cd38f1a 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/MainFrm.h @@ -1,153 +1,153 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// MainFrm.h : interface of the CMainFrame class -// -// Purpose: Implementation of Main Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#include "HierWin.h" -#include "OGLView.h" -#include "Skeleton.h" - -class CMainFrame : public CFrameWnd -{ -protected: // create from serialization only - DECLARE_DYNCREATE(CMainFrame) - -// Attributes -public: - CString m_ClassName; - HCURSOR m_HArrow; - CHierWin m_HierWin; - COGLView m_OGLView; - int m_Animation_Direction; // USED FOR FORWARD/BACK PLAYBACK - int m_AnimSpeed; // SPEED OF PLAYBACK IN FPS - BOOL m_Animating; - // for elapsed timing calculations - DWORD m_StartTime,m_ElapsedTime,m_previousElapsedTime; - -// Operations -public: - CMainFrame(); - - // The Timing Member Functions - // The following are used in timing calulations - DWORD ElapsedTime( void ) - { return( m_ElapsedTime - m_StartTime );} - DWORD ElapsedTimeRender( void ) - { return( m_ElapsedTime-m_previousElapsedTime);} - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CMainFrame) - public: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - protected: - virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CMainFrame(); -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: // control bar embedded members - t_Bone m_Skeleton; - CStatusBar m_wndStatusBar; - CToolBar m_wndToolBar; - - void InitializeSkeleton(); - -// Generated message map functions -protected: - //{{AFX_MSG(CMainFrame) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnSize(UINT nType, int cx, int cy); - afx_msg void OnAddBone(); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnViewResetskeleton(); - afx_msg void OnBackFrame(); - afx_msg void OnPlayBack(); - afx_msg void OnStop(); - afx_msg void OnPlayForward(); - afx_msg void OnForwardFrame(); - afx_msg void OnFileLoadanim(); - afx_msg void OnPaint(); - afx_msg void OnAnimationPlaybackspeed(); - afx_msg void OnWhichogl(); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -/// Local Dialog Headers /////////////////////////////////////////////////////// -// -// MFC LIKES TO PUT THESE IN A SEPARATE FILE, BUT IT LIKE THEM IN CODE THAT -// USES THEM -// -/////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CPlaySpeed dialog - -class CPlaySpeed : public CDialog -{ -// Construction -public: - CPlaySpeed(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CPlaySpeed) - enum { IDD = IDD_SPEED }; - UINT m_Playback_Speed; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CPlaySpeed) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CPlaySpeed) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) - +/////////////////////////////////////////////////////////////////////////////// +// +// MainFrm.h : interface of the CMainFrame class +// +// Purpose: Implementation of Main Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "HierWin.h" +#include "OGLView.h" +#include "Skeleton.h" + +class CMainFrame : public CFrameWnd +{ +protected: // create from serialization only + DECLARE_DYNCREATE(CMainFrame) + +// Attributes +public: + CString m_ClassName; + HCURSOR m_HArrow; + CHierWin m_HierWin; + COGLView m_OGLView; + int m_Animation_Direction; // USED FOR FORWARD/BACK PLAYBACK + int m_AnimSpeed; // SPEED OF PLAYBACK IN FPS + BOOL m_Animating; + // for elapsed timing calculations + DWORD m_StartTime,m_ElapsedTime,m_previousElapsedTime; + +// Operations +public: + CMainFrame(); + + // The Timing Member Functions + // The following are used in timing calulations + DWORD ElapsedTime( void ) + { return( m_ElapsedTime - m_StartTime );} + DWORD ElapsedTimeRender( void ) + { return( m_ElapsedTime-m_previousElapsedTime);} + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + protected: + virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + t_Bone m_Skeleton; + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + + void InitializeSkeleton(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnAddBone(); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewResetskeleton(); + afx_msg void OnBackFrame(); + afx_msg void OnPlayBack(); + afx_msg void OnStop(); + afx_msg void OnPlayForward(); + afx_msg void OnForwardFrame(); + afx_msg void OnFileLoadanim(); + afx_msg void OnPaint(); + afx_msg void OnAnimationPlaybackspeed(); + afx_msg void OnWhichogl(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +/// Local Dialog Headers /////////////////////////////////////////////////////// +// +// MFC LIKES TO PUT THESE IN A SEPARATE FILE, BUT IT LIKE THEM IN CODE THAT +// USES THEM +// +/////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CPlaySpeed dialog + +class CPlaySpeed : public CDialog +{ +// Construction +public: + CPlaySpeed(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CPlaySpeed) + enum { IDD = IDD_SPEED }; + UINT m_Playback_Speed; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPlaySpeed) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CPlaySpeed) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__4B0629BD_2696_11D1_83A0_004005308EB5__INCLUDED_) + diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.cpp index e983347..dc7cdbc 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.cpp @@ -1,589 +1,589 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.cpp : implementation file -// -// Purpose: Implementation of OpenGL Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// Versions: -// 1.01 12/20/97 Fix perspective in OpenGL Resize Code -// 1.02 1/10/97 Change to display code to handle skeletal hierarchy -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "Dagger.h" -#include "OGLView.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -// ENABLE THE USE OF DISPLAY LISTS... -// FOR TESTING I CAN COMMENT THEM OUT -#define USE_DRAWLISTS 1 - -/// Application Definitions /////////////////////////////////////////////////// -#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID -#define OGL_SELECTED_DLIST 2 // SELECTED BONE OPENGL DISPLAY LIST -#define ROTATE_SPEED 1.0 // SPEED OF ROTATION -/////////////////////////////////////////////////////////////////////////////// - -/// Global Variables ////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// COGLView - -COGLView::COGLView() -{ - // INITIALIZE THE MODE KEYS - m_Skeleton = NULL; - m_StatusBar = NULL; // CLEAR THIS. IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT -} - -COGLView::~COGLView() -{ -} - -BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext) -{ - m_Skeleton = skeleton; - m_SelectedBone = skeleton; - return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); -} - -BEGIN_MESSAGE_MAP(COGLView, CWnd) - //{{AFX_MSG_MAP(COGLView) - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_PAINT() - ON_WM_LBUTTONDOWN() - ON_WM_RBUTTONDOWN() - ON_WM_MOUSEMOVE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - - -///////////////////////////////////////////////////////////////////////////// -// COGLView message handlers - -BOOL COGLView::SetupPixelFormat(HDC hdc) -{ -/// Local Variables /////////////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd, *ppfd; - int pixelformat; -/////////////////////////////////////////////////////////////////////////////// - ppfd = &pfd; - - ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ppfd->dwLayerMask = PFD_MAIN_PLANE; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = 16; - ppfd->cDepthBits = 16; - ppfd->cAccumBits = 0; - ppfd->cStencilBits = 0; - - pixelformat = ChoosePixelFormat(hdc, ppfd); - - if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { - MessageBox("ChoosePixelFormat failed", "Error", MB_OK); - return FALSE; - } - - if (pfd.dwFlags & PFD_NEED_PALETTE) { - MessageBox("Needs palette", "Error", MB_OK); - return FALSE; - } - - if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { - MessageBox("SetPixelFormat failed", "Error", MB_OK); - return FALSE; - } - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: DrawAxis -// Purpose: Draws the Axis model using GL Lines -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -void COGLView::DrawAxis(void) -{ - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); -} -//// DrawAxis ///////////////////////////////////////////////////////////////// - -int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ -/// Local Variables /////////////////////////////////////////////////////////// - RECT rect; -/////////////////////////////////////////////////////////////////////////////// - if (CWnd::OnCreate(lpCreateStruct) == -1) - return -1; - m_hDC = ::GetDC(m_hWnd); - if (!SetupPixelFormat(m_hDC)) - PostQuitMessage (0); - - m_hRC = wglCreateContext(m_hDC); - wglMakeCurrent(m_hDC, m_hRC); - GetClientRect(&rect); - initializeGL(rect.right, rect.bottom); - -#if USE_DRAWLISTS - - // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN - // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z - glNewList(OGL_AXIS_DLIST,GL_COMPILE); - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED - glVertex3f(-0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.15f, 0.04f, 0.0f); - glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.15f, -0.04f, 0.0f); - glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN - glVertex3f( 0.0f, 0.2f, 0.0f); - glVertex3f( 0.0f, -0.2f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.04f, 0.15f, 0.0f); - glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( -0.04f, 0.15f, 0.0f); - glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE - glVertex3f( 0.0f, 0.0f, 0.2f); - glVertex3f( 0.0f, 0.0f, -0.2f); - glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD - glVertex3f( 0.0f, 0.04f, 0.15f); - glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD - glVertex3f( 0.0f, -0.04f, 0.15f); - glEnd(); - glEndList(); - - // CREATE THE DISPLAY LIST THE SELECTED BONE JUST A CUBE - glNewList(OGL_SELECTED_DLIST,GL_COMPILE); - glBegin(GL_QUADS); - glColor3f(1.0f, 1.0f, 0.0f); // YELLOW - // BOTTOM - glVertex3f(-0.05f, -0.05f, -0.05f); - glVertex3f( 0.05f, -0.05f, -0.05f); - glVertex3f( 0.05f, -0.05f, 0.05f); - glVertex3f(-0.05f, -0.05f, 0.05f); - // BACK - glVertex3f(-0.05f, 0.05f, -0.05f); - glVertex3f( 0.05f, 0.05f, -0.05f); - glVertex3f( 0.05f, -0.05f, -0.05f); - glVertex3f(-0.05f, -0.05f, -0.05f); - // FRONT - glVertex3f(-0.05f, -0.05f, 0.05f); - glVertex3f( 0.05f, -0.05f, 0.05f); - glVertex3f( 0.05f, 0.05f, 0.05f); - glVertex3f(-0.05f, 0.05f, 0.05f); - // RIGHT - glVertex3f(-0.05f, -0.05f, -0.05f); - glVertex3f(-0.05f, -0.05f, 0.05f); - glVertex3f(-0.05f, 0.05f, 0.05f); - glVertex3f(-0.05f, 0.05f, -0.05f); - // LEFT - glVertex3f( 0.05f, 0.05f, -0.05f); - glVertex3f( 0.05f, 0.05f, 0.05f); - glVertex3f( 0.05f, -0.05f, 0.05f); - glVertex3f( 0.05f, -0.05f, -0.05f); - // TOP - glVertex3f(-0.05f, 0.05f, 0.05f); - glVertex3f( 0.05f, 0.05f, 0.05f); - glVertex3f( 0.05f, 0.05f, -0.05f); - glVertex3f(-0.05f, 0.05f, -0.05f); - glEnd(); - glEndList(); -#endif - drawScene(); - return 0; -} - -/* OpenGL code */ - -/////////////////////////////////////////////////////////////////////////////// -// Function: resize -// Purpose: This code handles the windows resize for OpenGL -// Arguments: Width and heights of the view window -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::resize( GLsizei width, GLsizei height ) -{ -// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glViewport(0, 0, width, height); - - aspect = (GLfloat)width/(GLfloat)height; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); -} -//// resize ///////////////////////////////////////////////////////////////// - -GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) -{ -/// Local Variables /////////////////////////////////////////////////////////// - GLfloat aspect; -/////////////////////////////////////////////////////////////////////////////// - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClearDepth(1.0); - glDepthFunc(GL_LESS); - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - aspect = (GLfloat)width/(GLfloat)height; - // Establish viewing volume - gluPerspective(10.0, aspect,1, 2000); - glMatrixMode(GL_MODELVIEW); - - // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP - glPolygonMode(GL_FRONT,GL_FILL); - glDepthFunc(GL_LESS); - glEnable(GL_CULL_FACE); - glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST); -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawSkeleton -// Purpose: Actually draws the Skeleton it is recursive -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawSkeleton(t_Bone *rootBone) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *curBone; -/////////////////////////////////////////////////////////////////////////////// - curBone = rootBone->children; - for (loop = 0; loop < rootBone->childCnt; loop++) - { - glPushMatrix(); - - glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); - - // Set observer's orientation and position - glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); - glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); - - // THE SCALE IS LOCAL SO I PUSH AND POP - glPushMatrix(); - glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); - -#if USE_DRAWLISTS - // DRAW THE AXIS OGL OBJECT - glCallList(OGL_AXIS_DLIST); - // IF SOMETHING IS SELECTED, DRAW TAG BOX - if (m_Skeleton->id == (long)curBone) - { - m_SelectedBone = curBone; - glCallList(OGL_SELECTED_DLIST); - } -#else - // DRAW THE AXIS OGL OBJECT USING DRAW ROUTINE - DrawAxis(); -#endif - glPopMatrix(); - - // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL - if (curBone->childCnt > 0) - drawSkeleton(curBone); - - glPopMatrix(); - - curBone++; - } -} -//// drawSkeleton ///////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// Function: drawScene -// Purpose: Actually draw the OpenGL Scene -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -GLvoid COGLView::drawScene(GLvoid) -{ -/// Local Variables /////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; - if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; - if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; - - glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING - - glPushMatrix(); - - // Set root skeleton's orientation and position - glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); - - glRotatef(m_Skeleton->rot.x, 1.0f, 0.0f, 0.0f); - glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); - glRotatef(m_Skeleton->rot.z, 0.0f, 0.0f, 1.0f); - - m_SelectedBone = m_Skeleton; - - drawSkeleton(m_Skeleton); - - glPopMatrix(); - glFinish(); - - SwapBuffers(m_hDC); - - UpdateStatusBarFrameInfo(); -} -//// drawScene ////////////////////////////////////////////////////// - - -void COGLView::OnDestroy() -{ - CWnd::OnDestroy(); - if (m_hRC) - wglDeleteContext(m_hRC); - if (m_hDC) - ::ReleaseDC(m_hWnd,m_hDC); - m_hRC = 0; - m_hDC = 0; - - -} - -void COGLView::OnPaint() -{ - CPaintDC dc(this); // device context for painting - - drawScene(); - // Do not call CWnd::OnPaint() for painting messages -} - -void COGLView::OnLButtonDown(UINT nFlags, CPoint point) -{ - // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER - m_mousepos = point; - m_Grab_Rot_X = m_SelectedBone->rot.x; - m_Grab_Rot_Y = m_SelectedBone->rot.y; - m_Grab_Rot_Z = m_SelectedBone->rot.z; - m_Grab_Trans_X = m_SelectedBone->trans.x; - m_Grab_Trans_Y = m_SelectedBone->trans.y; - m_Grab_Trans_Z = m_SelectedBone->trans.z; - CWnd::OnLButtonDown(nFlags, point); -} - -void COGLView::OnRButtonDown(UINT nFlags, CPoint point) -{ - // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER - m_mousepos = point; - m_Grab_Rot_X = m_SelectedBone->rot.x; - m_Grab_Rot_Y = m_SelectedBone->rot.y; - m_Grab_Rot_Z = m_SelectedBone->rot.z; - m_Grab_Trans_X = m_SelectedBone->trans.x; - m_Grab_Trans_Y = m_SelectedBone->trans.y; - m_Grab_Trans_Z = m_SelectedBone->trans.z; - CWnd::OnRButtonDown(nFlags, point); -} - - -// 0 = READY -// 1 = ROTATE -// 2 = TRANSLATE -void COGLView::UpdateStatusBar(int mode) -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - if (mode == 1) - { - strcpy(message,"Rotate"); - } - else if (mode == 2) - { - strcpy(message,"Translate"); - } - else - { - strcpy(message,"Ready"); - } - m_StatusBar->SetPaneText(0,message); -} - -void COGLView::UpdateStatusBarFrameInfo() -{ -/// Local Variables /////////////////////////////////////////////////////////// - char message[80]; -/////////////////////////////////////////////////////////////////////////////// - if (m_StatusBar != NULL && m_Skeleton->children != NULL) - { - sprintf(message,"Frame %3d/%3d",(int)m_Skeleton->children->primCurFrame,(int)m_Skeleton->children->primFrameCount); - //m_StatusBar->SetPaneStyle(1,SBPS_POPOUT); - m_StatusBar->SetPaneText(1,message); - } -} - -void COGLView::HandleKeyDown(UINT nChar) -{ -} - -void COGLView::HandleKeyUp(UINT nChar) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnMouseMove -// Purpose: Handler for the mouse. Handles movement when pressed -// Arguments: Flags for key masks and point -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnMouseMove(UINT nFlags, CPoint point) -{ - UpdateStatusBar(0); - if (nFlags & MK_LBUTTON > 0) - { - // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE - if ((nFlags & MK_CONTROL) > 0) - { - UpdateStatusBar(2); - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->trans.x = m_Grab_Trans_X + (.05f * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_SelectedBone->trans.y = m_Grab_Trans_Y - (.05f * (point.y - m_mousepos.y)); - drawScene(); - } - } - // ELSE "SHIFT" ROTATE THE ROOT - else if ((nFlags & MK_SHIFT) > 0) - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - if ((point.y - m_mousepos.y) != 0) - { - m_SelectedBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); - drawScene(); - } - } - } - else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) - { - if ((nFlags & MK_CONTROL) > 0) - { - UpdateStatusBar(2); - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); - drawScene(); - } - } - else if ((nFlags & MK_SHIFT) > 0) - { - UpdateStatusBar(1); - if ((point.x - m_mousepos.x) != 0) - { - m_SelectedBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); - drawScene(); - } - } - } - - CWnd::OnMouseMove(nFlags, point); -} -//// OnMouseMove ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: OnViewResetskeleton -// Purpose: Reset the view settings for the skeleton -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -void COGLView::OnViewResetskeleton() -{ - m_Skeleton->trans.x = 0.0f; - m_Skeleton->trans.y = -3.0f; - m_Skeleton->trans.z = -40.0f; - m_Skeleton->rot.x = 0.0f; - m_Skeleton->rot.y = 0.0f; - m_Skeleton->rot.z = 0.0f; - drawScene(); -} -//// OnViewResetskeleton ////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: GetGLInfo -// Purpose: Get the OpenGL Vendor and Rederer info as strings -// Arguments: None -/////////////////////////////////////////////////////////////////////////////// -void COGLView::GetGLInfo() -{ -//// Local Variables //////////////////////////////////////////////////////////////// - char *who, *which, *ver, *ext, *message; - int len; -///////////////////////////////////////////////////////////////////////////////////// - who = (char *)::glGetString( GL_VENDOR ); - which = (char *)::glGetString( GL_RENDERER ); - ver = (char *)::glGetString( GL_VERSION ); - ext = (char *)::glGetString( GL_EXTENSIONS ); - - len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); - - message = (char *)malloc(len); - sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", - who, which, ver, ext); - - ::MessageBox(NULL,message,"GL Info",MB_OK); - - free(message); -} - -//// GetGLInfo ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.cpp : implementation file +// +// Purpose: Implementation of OpenGL Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// Versions: +// 1.01 12/20/97 Fix perspective in OpenGL Resize Code +// 1.02 1/10/97 Change to display code to handle skeletal hierarchy +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "Dagger.h" +#include "OGLView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// ENABLE THE USE OF DISPLAY LISTS... +// FOR TESTING I CAN COMMENT THEM OUT +#define USE_DRAWLISTS 1 + +/// Application Definitions /////////////////////////////////////////////////// +#define OGL_AXIS_DLIST 1 // OPENGL DISPLAY LIST ID +#define OGL_SELECTED_DLIST 2 // SELECTED BONE OPENGL DISPLAY LIST +#define ROTATE_SPEED 1.0 // SPEED OF ROTATION +/////////////////////////////////////////////////////////////////////////////// + +/// Global Variables ////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// COGLView + +COGLView::COGLView() +{ + // INITIALIZE THE MODE KEYS + m_Skeleton = NULL; + m_StatusBar = NULL; // CLEAR THIS. IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT +} + +COGLView::~COGLView() +{ +} + +BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext) +{ + m_Skeleton = skeleton; + m_SelectedBone = skeleton; + return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); +} + +BEGIN_MESSAGE_MAP(COGLView, CWnd) + //{{AFX_MSG_MAP(COGLView) + ON_WM_CREATE() + ON_WM_DESTROY() + ON_WM_PAINT() + ON_WM_LBUTTONDOWN() + ON_WM_RBUTTONDOWN() + ON_WM_MOUSEMOVE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// COGLView message handlers + +BOOL COGLView::SetupPixelFormat(HDC hdc) +{ +/// Local Variables /////////////////////////////////////////////////////////// + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; +/////////////////////////////////////////////////////////////////////////////// + ppfd = &pfd; + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ppfd->dwLayerMask = PFD_MAIN_PLANE; + ppfd->iPixelType = PFD_TYPE_RGBA; + ppfd->cColorBits = 16; + ppfd->cDepthBits = 16; + ppfd->cAccumBits = 0; + ppfd->cStencilBits = 0; + + pixelformat = ChoosePixelFormat(hdc, ppfd); + + if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { + MessageBox("ChoosePixelFormat failed", "Error", MB_OK); + return FALSE; + } + + if (pfd.dwFlags & PFD_NEED_PALETTE) { + MessageBox("Needs palette", "Error", MB_OK); + return FALSE; + } + + if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { + MessageBox("SetPixelFormat failed", "Error", MB_OK); + return FALSE; + } + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: DrawAxis +// Purpose: Draws the Axis model using GL Lines +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +void COGLView::DrawAxis(void) +{ + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); +} +//// DrawAxis ///////////////////////////////////////////////////////////////// + +int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ +/// Local Variables /////////////////////////////////////////////////////////// + RECT rect; +/////////////////////////////////////////////////////////////////////////////// + if (CWnd::OnCreate(lpCreateStruct) == -1) + return -1; + m_hDC = ::GetDC(m_hWnd); + if (!SetupPixelFormat(m_hDC)) + PostQuitMessage (0); + + m_hRC = wglCreateContext(m_hDC); + wglMakeCurrent(m_hDC, m_hRC); + GetClientRect(&rect); + initializeGL(rect.right, rect.bottom); + +#if USE_DRAWLISTS + + // CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN + // THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z + glNewList(OGL_AXIS_DLIST,GL_COMPILE); + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // X AXIS STARTS - COLOR RED + glVertex3f(-0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.15f, 0.04f, 0.0f); + glVertex3f( 0.2f, 0.0f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.15f, -0.04f, 0.0f); + glColor3f(0.0f, 1.0f, 0.0f); // Y AXIS STARTS - COLOR GREEN + glVertex3f( 0.0f, 0.2f, 0.0f); + glVertex3f( 0.0f, -0.2f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.04f, 0.15f, 0.0f); + glVertex3f( 0.0f, 0.2f, 0.0f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( -0.04f, 0.15f, 0.0f); + glColor3f(0.0f, 0.0f, 1.0f); // Z AXIS STARTS - COLOR BLUE + glVertex3f( 0.0f, 0.0f, 0.2f); + glVertex3f( 0.0f, 0.0f, -0.2f); + glVertex3f( 0.0f, 0.0f, 0.2f); // TOP PIECE OF ARROWHEAD + glVertex3f( 0.0f, 0.04f, 0.15f); + glVertex3f( 0.0f, 0.0f, 0.2f); // BOTTOM PIECE OF ARROWHEAD + glVertex3f( 0.0f, -0.04f, 0.15f); + glEnd(); + glEndList(); + + // CREATE THE DISPLAY LIST THE SELECTED BONE JUST A CUBE + glNewList(OGL_SELECTED_DLIST,GL_COMPILE); + glBegin(GL_QUADS); + glColor3f(1.0f, 1.0f, 0.0f); // YELLOW + // BOTTOM + glVertex3f(-0.05f, -0.05f, -0.05f); + glVertex3f( 0.05f, -0.05f, -0.05f); + glVertex3f( 0.05f, -0.05f, 0.05f); + glVertex3f(-0.05f, -0.05f, 0.05f); + // BACK + glVertex3f(-0.05f, 0.05f, -0.05f); + glVertex3f( 0.05f, 0.05f, -0.05f); + glVertex3f( 0.05f, -0.05f, -0.05f); + glVertex3f(-0.05f, -0.05f, -0.05f); + // FRONT + glVertex3f(-0.05f, -0.05f, 0.05f); + glVertex3f( 0.05f, -0.05f, 0.05f); + glVertex3f( 0.05f, 0.05f, 0.05f); + glVertex3f(-0.05f, 0.05f, 0.05f); + // RIGHT + glVertex3f(-0.05f, -0.05f, -0.05f); + glVertex3f(-0.05f, -0.05f, 0.05f); + glVertex3f(-0.05f, 0.05f, 0.05f); + glVertex3f(-0.05f, 0.05f, -0.05f); + // LEFT + glVertex3f( 0.05f, 0.05f, -0.05f); + glVertex3f( 0.05f, 0.05f, 0.05f); + glVertex3f( 0.05f, -0.05f, 0.05f); + glVertex3f( 0.05f, -0.05f, -0.05f); + // TOP + glVertex3f(-0.05f, 0.05f, 0.05f); + glVertex3f( 0.05f, 0.05f, 0.05f); + glVertex3f( 0.05f, 0.05f, -0.05f); + glVertex3f(-0.05f, 0.05f, -0.05f); + glEnd(); + glEndList(); +#endif + drawScene(); + return 0; +} + +/* OpenGL code */ + +/////////////////////////////////////////////////////////////////////////////// +// Function: resize +// Purpose: This code handles the windows resize for OpenGL +// Arguments: Width and heights of the view window +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::resize( GLsizei width, GLsizei height ) +{ +// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glViewport(0, 0, width, height); + + aspect = (GLfloat)width/(GLfloat)height; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); +} +//// resize ///////////////////////////////////////////////////////////////// + +GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) +{ +/// Local Variables /////////////////////////////////////////////////////////// + GLfloat aspect; +/////////////////////////////////////////////////////////////////////////////// + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glDepthFunc(GL_LESS); + glShadeModel(GL_SMOOTH); + + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + aspect = (GLfloat)width/(GLfloat)height; + // Establish viewing volume + gluPerspective(10.0, aspect,1, 2000); + glMatrixMode(GL_MODELVIEW); + + // SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP + glPolygonMode(GL_FRONT,GL_FILL); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST); +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawSkeleton +// Purpose: Actually draws the Skeleton it is recursive +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawSkeleton(t_Bone *rootBone) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *curBone; +/////////////////////////////////////////////////////////////////////////////// + curBone = rootBone->children; + for (loop = 0; loop < rootBone->childCnt; loop++) + { + glPushMatrix(); + + glTranslatef(curBone->trans.x, curBone->trans.y, curBone->trans.z); + + // Set observer's orientation and position + glRotatef(curBone->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(curBone->rot.x, 1.0f, 0.0f, 0.0f); + glRotatef(curBone->rot.z, 0.0f, 0.0f, 1.0f); + + // THE SCALE IS LOCAL SO I PUSH AND POP + glPushMatrix(); + glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z); + +#if USE_DRAWLISTS + // DRAW THE AXIS OGL OBJECT + glCallList(OGL_AXIS_DLIST); + // IF SOMETHING IS SELECTED, DRAW TAG BOX + if (m_Skeleton->id == (long)curBone) + { + m_SelectedBone = curBone; + glCallList(OGL_SELECTED_DLIST); + } +#else + // DRAW THE AXIS OGL OBJECT USING DRAW ROUTINE + DrawAxis(); +#endif + glPopMatrix(); + + // CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL + if (curBone->childCnt > 0) + drawSkeleton(curBone); + + glPopMatrix(); + + curBone++; + } +} +//// drawSkeleton ///////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// Function: drawScene +// Purpose: Actually draw the OpenGL Scene +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +GLvoid COGLView::drawScene(GLvoid) +{ +/// Local Variables /////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + + if (m_Skeleton->rot.y > 360.0f) m_Skeleton->rot.y -= 360.0f; + if (m_Skeleton->rot.x > 360.0f) m_Skeleton->rot.x -= 360.0f; + if (m_Skeleton->rot.z > 360.0f) m_Skeleton->rot.z -= 360.0f; + + glDisable(GL_DEPTH_TEST); // TURN OFF DEPTH TEST FOR CLEAR + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); // ENABLE DEPTH TESTING + + glPushMatrix(); + + // Set root skeleton's orientation and position + glTranslatef(m_Skeleton->trans.x, m_Skeleton->trans.y, m_Skeleton->trans.z); + + glRotatef(m_Skeleton->rot.x, 1.0f, 0.0f, 0.0f); + glRotatef(m_Skeleton->rot.y, 0.0f, 1.0f, 0.0f); + glRotatef(m_Skeleton->rot.z, 0.0f, 0.0f, 1.0f); + + m_SelectedBone = m_Skeleton; + + drawSkeleton(m_Skeleton); + + glPopMatrix(); + glFinish(); + + SwapBuffers(m_hDC); + + UpdateStatusBarFrameInfo(); +} +//// drawScene ////////////////////////////////////////////////////// + + +void COGLView::OnDestroy() +{ + CWnd::OnDestroy(); + if (m_hRC) + wglDeleteContext(m_hRC); + if (m_hDC) + ::ReleaseDC(m_hWnd,m_hDC); + m_hRC = 0; + m_hDC = 0; + + +} + +void COGLView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + drawScene(); + // Do not call CWnd::OnPaint() for painting messages +} + +void COGLView::OnLButtonDown(UINT nFlags, CPoint point) +{ + // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER + m_mousepos = point; + m_Grab_Rot_X = m_SelectedBone->rot.x; + m_Grab_Rot_Y = m_SelectedBone->rot.y; + m_Grab_Rot_Z = m_SelectedBone->rot.z; + m_Grab_Trans_X = m_SelectedBone->trans.x; + m_Grab_Trans_Y = m_SelectedBone->trans.y; + m_Grab_Trans_Z = m_SelectedBone->trans.z; + CWnd::OnLButtonDown(nFlags, point); +} + +void COGLView::OnRButtonDown(UINT nFlags, CPoint point) +{ + // STORE OFF THE KIT POINT AND SETTINGS FOR THE MOVEMENT LATER + m_mousepos = point; + m_Grab_Rot_X = m_SelectedBone->rot.x; + m_Grab_Rot_Y = m_SelectedBone->rot.y; + m_Grab_Rot_Z = m_SelectedBone->rot.z; + m_Grab_Trans_X = m_SelectedBone->trans.x; + m_Grab_Trans_Y = m_SelectedBone->trans.y; + m_Grab_Trans_Z = m_SelectedBone->trans.z; + CWnd::OnRButtonDown(nFlags, point); +} + + +// 0 = READY +// 1 = ROTATE +// 2 = TRANSLATE +void COGLView::UpdateStatusBar(int mode) +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + if (mode == 1) + { + strcpy(message,"Rotate"); + } + else if (mode == 2) + { + strcpy(message,"Translate"); + } + else + { + strcpy(message,"Ready"); + } + m_StatusBar->SetPaneText(0,message); +} + +void COGLView::UpdateStatusBarFrameInfo() +{ +/// Local Variables /////////////////////////////////////////////////////////// + char message[80]; +/////////////////////////////////////////////////////////////////////////////// + if (m_StatusBar != NULL && m_Skeleton->children != NULL) + { + sprintf(message,"Frame %3d/%3d",(int)m_Skeleton->children->primCurFrame,(int)m_Skeleton->children->primFrameCount); + //m_StatusBar->SetPaneStyle(1,SBPS_POPOUT); + m_StatusBar->SetPaneText(1,message); + } +} + +void COGLView::HandleKeyDown(UINT nChar) +{ +} + +void COGLView::HandleKeyUp(UINT nChar) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnMouseMove +// Purpose: Handler for the mouse. Handles movement when pressed +// Arguments: Flags for key masks and point +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnMouseMove(UINT nFlags, CPoint point) +{ + UpdateStatusBar(0); + if (nFlags & MK_LBUTTON > 0) + { + // IF I AM HOLDING THE 'CTRL' BUTTON TRANSLATE + if ((nFlags & MK_CONTROL) > 0) + { + UpdateStatusBar(2); + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->trans.x = m_Grab_Trans_X + (.05f * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_SelectedBone->trans.y = m_Grab_Trans_Y - (.05f * (point.y - m_mousepos.y)); + drawScene(); + } + } + // ELSE "SHIFT" ROTATE THE ROOT + else if ((nFlags & MK_SHIFT) > 0) + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + if ((point.y - m_mousepos.y) != 0) + { + m_SelectedBone->rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); + drawScene(); + } + } + } + else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) + { + if ((nFlags & MK_CONTROL) > 0) + { + UpdateStatusBar(2); + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->trans.z = m_Grab_Trans_Z + (.1f * (point.x - m_mousepos.x)); + drawScene(); + } + } + else if ((nFlags & MK_SHIFT) > 0) + { + UpdateStatusBar(1); + if ((point.x - m_mousepos.x) != 0) + { + m_SelectedBone->rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); + drawScene(); + } + } + } + + CWnd::OnMouseMove(nFlags, point); +} +//// OnMouseMove ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: OnViewResetskeleton +// Purpose: Reset the view settings for the skeleton +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +void COGLView::OnViewResetskeleton() +{ + m_Skeleton->trans.x = 0.0f; + m_Skeleton->trans.y = -3.0f; + m_Skeleton->trans.z = -40.0f; + m_Skeleton->rot.x = 0.0f; + m_Skeleton->rot.y = 0.0f; + m_Skeleton->rot.z = 0.0f; + drawScene(); +} +//// OnViewResetskeleton ////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: GetGLInfo +// Purpose: Get the OpenGL Vendor and Rederer info as strings +// Arguments: None +/////////////////////////////////////////////////////////////////////////////// +void COGLView::GetGLInfo() +{ +//// Local Variables //////////////////////////////////////////////////////////////// + char *who, *which, *ver, *ext, *message; + int len; +///////////////////////////////////////////////////////////////////////////////////// + who = (char *)::glGetString( GL_VENDOR ); + which = (char *)::glGetString( GL_RENDERER ); + ver = (char *)::glGetString( GL_VERSION ); + ext = (char *)::glGetString( GL_EXTENSIONS ); + + len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); + + message = (char *)malloc(len); + sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", + who, which, ver, ext); + + ::MessageBox(NULL,message,"GL Info",MB_OK); + + free(message); +} + +//// GetGLInfo ///////////////////////////////////////////////////////////////// diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.h index 7ce7dab..0a7b037 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/OGLView.h @@ -1,94 +1,94 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// OGLView.h : class definition file -// -// Purpose: Implementation of OpenGL Window of Hierarchical Animation System -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// OGLView.h : header file -// - -#include -#include - -#include "Skeleton.h" -///////////////////////////////////////////////////////////////////////////// -// COGLView window - -class COGLView : public CWnd -{ -// Construction -public: - COGLView(); - -// Attributes -public: - HDC m_hDC; - HGLRC m_hRC; - CPoint m_mousepos; - float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; - float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; - CStatusBar *m_StatusBar; - -// Operations -public: - BOOL SetupPixelFormat(HDC hdc); - GLvoid drawSkeleton(t_Bone *rootBone); - GLvoid drawScene(GLvoid); - GLvoid initializeGL(GLsizei width, GLsizei height); - GLvoid resize( GLsizei width, GLsizei height ); - void GetGLInfo(); - void HandleKeyUp(UINT nChar); - void HandleKeyDown(UINT nChar); - void OnViewResetskeleton(); -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(COGLView) - public: - virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext = NULL); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~COGLView(); - - // Generated message map functions -protected: - t_Bone *m_Skeleton,*m_SelectedBone; - void UpdateStatusBar(int mode); - void UpdateStatusBarFrameInfo(); - void DrawAxis(); - //{{AFX_MSG(COGLView) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - afx_msg void OnPaint(); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnRButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMouseMove(UINT nFlags, CPoint point); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// OGLView.h : class definition file +// +// Purpose: Implementation of OpenGL Window of Hierarchical Animation System +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OGLView.h : header file +// + +#include +#include + +#include "Skeleton.h" +///////////////////////////////////////////////////////////////////////////// +// COGLView window + +class COGLView : public CWnd +{ +// Construction +public: + COGLView(); + +// Attributes +public: + HDC m_hDC; + HGLRC m_hRC; + CPoint m_mousepos; + float m_Grab_Rot_X,m_Grab_Rot_Y,m_Grab_Rot_Z; + float m_Grab_Trans_X,m_Grab_Trans_Y,m_Grab_Trans_Z; + CStatusBar *m_StatusBar; + +// Operations +public: + BOOL SetupPixelFormat(HDC hdc); + GLvoid drawSkeleton(t_Bone *rootBone); + GLvoid drawScene(GLvoid); + GLvoid initializeGL(GLsizei width, GLsizei height); + GLvoid resize( GLsizei width, GLsizei height ); + void GetGLInfo(); + void HandleKeyUp(UINT nChar); + void HandleKeyDown(UINT nChar); + void OnViewResetskeleton(); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COGLView) + public: + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, t_Bone *skeleton, CCreateContext* pContext = NULL); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~COGLView(); + + // Generated message map functions +protected: + t_Bone *m_Skeleton,*m_SelectedBone; + void UpdateStatusBar(int mode); + void UpdateStatusBarFrameInfo(); + void DrawAxis(); + //{{AFX_MSG(COGLView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg void OnPaint(); + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnRButtonDown(UINT nFlags, CPoint point); + afx_msg void OnMouseMove(UINT nFlags, CPoint point); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OGLVIEW_H__2AB46761_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/ReadMe.txt b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/ReadMe.txt index 542ab89..b5f7160 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/ReadMe.txt +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/ReadMe.txt @@ -1,98 +1,98 @@ -Dagger Motion Capture File Viewer Jan 10, 1997 ----------------------------------------------------- -v. 1.02 - -Well, I got some time to work on this today so I merged in -my code that loaded the ASF Acclaim skeletal file. I still need -to bring in the AMC motion file but that is pretty easy. I hope -to do one evening this week so check the site later in the week. - -Still need to merge in the BVH loader to the sample app. That -is real easy, though and should only take a few hours when I -find the time. - -The ASF code needed to have the OGL draw routine re-arranged a -bit to handle the hierarchy. Pretty simple though. See the -drawSkeleton routine in OGLView.cpp to see what I did. - -Vast difference in scale of the BVA vs. Acclaim sample files made -it necessary to change the default camera positions and axis scales -for the two files. I used the scale channel in the bone structure -for this since I wasn't using it for anything else. - -That's it for today. Someone ambitious may want to add a -Curve plotter for the animation channels. It would be cool -to see all the animated channels plotted in an editable window. -That would be the basis for a motion smoother/editor. Not -far from a real F-curve editor then. - -Let me know if you want to do this but don't quite get it. - - -Dagger Motion Capture File Viewer Dec 16, 1997 ------------------------------------------------------ - -Well the issue release snuck up on me fast. - -This is the sample application that accompanies the Jan 98 -Game Developer magazine. It is meant as a demonstration of -how to load and display Motion Capture data via standard -file formats. - -First off, I am pulling out this code from my existing tools -and converting them to a nice clean OpenGL application. I am -a little behind in finishing this. I have only converted the -BVA loader code. I will convert my BVH and AMC loaders as -soon as I can and upload them to my website as well as -Game Developer. In any case, this should be a great start to -working with motion data. - -Thanks again to House of Moves and Biovision for providing -sample motion files to work with. Write to me if you have -problems or questions and check the web site for updates. - -Jeff Lander -jeffl@darwin3d.com -www.darwin3d.com/gamedev.htm Dec. 18, 1997 ------------------------------------------------------------ - -I know this code could be optimized for maximum performance -but it was written to be a clean example without a lot of -tricks. It should be easy to learn and build from. - -Here are the details. - -I compiled the code with Visual C++ 5.0. It has been tested -with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL -Drivers, and Symetra Ultra FX Pro. - -It should run on any OpenGL fully complient driver. This -DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX -OpenGL does not support OpenGL in a window so will not work -with this application. - -There are instructions in the Help/About dialog. - -Use Frame/Load Animation to bring in a BVA file. You can -use the VCR style controls to play it back. Hold the SHIFT -with the mouse buttons to rotate the view or CTRL to -translate the view around. - -The Hierarchy window (HierWin.CPP/H) can be used to select a Bone. -Double click on it to bring up the edit window. This allows you -to change the bone transformation settings. Playing the animation -loses those changes. - -I started implementing an Add bone command but it is not complete -and commented out. - -In the article I described using Windows Timers to play the animation. -When I finished my production tool, I found that it could not play -back as fast as I thought it should. It turned out the WinTimer was -a real slowdown to the system. So, I yanked it out and grabbed the -message handler and run the animation from there. That improved -things greatly. I know I could even get it a bit faster but it -wouldn't be as windows friendly. - -Have some fun. - +Dagger Motion Capture File Viewer Jan 10, 1997 +---------------------------------------------------- +v. 1.02 + +Well, I got some time to work on this today so I merged in +my code that loaded the ASF Acclaim skeletal file. I still need +to bring in the AMC motion file but that is pretty easy. I hope +to do one evening this week so check the site later in the week. + +Still need to merge in the BVH loader to the sample app. That +is real easy, though and should only take a few hours when I +find the time. + +The ASF code needed to have the OGL draw routine re-arranged a +bit to handle the hierarchy. Pretty simple though. See the +drawSkeleton routine in OGLView.cpp to see what I did. + +Vast difference in scale of the BVA vs. Acclaim sample files made +it necessary to change the default camera positions and axis scales +for the two files. I used the scale channel in the bone structure +for this since I wasn't using it for anything else. + +That's it for today. Someone ambitious may want to add a +Curve plotter for the animation channels. It would be cool +to see all the animated channels plotted in an editable window. +That would be the basis for a motion smoother/editor. Not +far from a real F-curve editor then. + +Let me know if you want to do this but don't quite get it. + + +Dagger Motion Capture File Viewer Dec 16, 1997 +----------------------------------------------------- + +Well the issue release snuck up on me fast. + +This is the sample application that accompanies the Jan 98 +Game Developer magazine. It is meant as a demonstration of +how to load and display Motion Capture data via standard +file formats. + +First off, I am pulling out this code from my existing tools +and converting them to a nice clean OpenGL application. I am +a little behind in finishing this. I have only converted the +BVA loader code. I will convert my BVH and AMC loaders as +soon as I can and upload them to my website as well as +Game Developer. In any case, this should be a great start to +working with motion data. + +Thanks again to House of Moves and Biovision for providing +sample motion files to work with. Write to me if you have +problems or questions and check the web site for updates. + +Jeff Lander +jeffl@darwin3d.com +www.darwin3d.com/gamedev.htm Dec. 18, 1997 +----------------------------------------------------------- + +I know this code could be optimized for maximum performance +but it was written to be a clean example without a lot of +tricks. It should be easy to learn and build from. + +Here are the details. + +I compiled the code with Visual C++ 5.0. It has been tested +with Microsoft OpenGL, SGI OpenGL, Permidia 1 and 2 OpenGL +Drivers, and Symetra Ultra FX Pro. + +It should run on any OpenGL fully complient driver. This +DOES NOT include the mini-QuakeGL driver for 3DFX. 3DFX +OpenGL does not support OpenGL in a window so will not work +with this application. + +There are instructions in the Help/About dialog. + +Use Frame/Load Animation to bring in a BVA file. You can +use the VCR style controls to play it back. Hold the SHIFT +with the mouse buttons to rotate the view or CTRL to +translate the view around. + +The Hierarchy window (HierWin.CPP/H) can be used to select a Bone. +Double click on it to bring up the edit window. This allows you +to change the bone transformation settings. Playing the animation +loses those changes. + +I started implementing an Add bone command but it is not complete +and commented out. + +In the article I described using Windows Timers to play the animation. +When I finished my production tool, I found that it could not play +back as fast as I thought it should. It turned out the WinTimer was +a real slowdown to the system. So, I yanked it out and grabbed the +message handler and run the animation from there. That improved +things greatly. I know I could even get it a bit faster but it +wouldn't be as windows friendly. + +Have some fun. + diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.cpp index dcc2c41..67a2c4a 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.cpp @@ -1,200 +1,200 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.cpp : Animation System Skeleton supprt file -// -// Purpose: Structure Supprt routines for Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "skeleton.h" - -/////////////////////////////////////////////////////////////////////////////// -// Function: DestroySkeleton -// Purpose: Clear memory for a skeletal system -// Arguments: Pointer to bone system -/////////////////////////////////////////////////////////////////////////////// -void DestroySkeleton(t_Bone *root) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; -/////////////////////////////////////////////////////////////////////////////// - // NEED TO RECURSIVELY GO THROUGH THE CHILDREN - if (root->childCnt > 0) - { - child = root->children; - for (loop = 0; loop < root->childCnt; loop++,child++) - { - if (child->childCnt > 0) - DestroySkeleton(child); - if (child->primChannel > NULL) - { - free(child->primChannel); - child->primChannel = NULL; - } - } - free(root->children); - } - - root->primChanType = CHANNEL_TYPE_NONE; - root->secChanType = CHANNEL_TYPE_NONE; - root->primFrameCount = 0; - root->secFrameCount = 0; - root->primCurFrame = 0; - root->secCurFrame = 0; - root->primChannel = NULL; - root->secChannel = NULL; - - root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - root->visuals = NULL; // POINTER TO VISUALS - root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - root->children = NULL; // POINTER TO CHILDREN -} -//// DestroySkeleton ////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: ResetBone -// Purpose: Reset the bone system and set the parent bone -// Arguments: Pointer to bone system, and parent bone (could be null) -/////////////////////////////////////////////////////////////////////////////// -void ResetBone(t_Bone *bone,t_Bone *parent) -{ - bone->b_scale.x = - bone->b_scale.y = - bone->b_scale.z = 1.0; - bone->scale.x = - bone->scale.y = - bone->scale.z = 1.0; - - bone->b_rot.x = - bone->b_rot.y = - bone->b_rot.z = 0.0; - bone->rot.x = - bone->rot.y = - bone->rot.z = 0.0; - - bone->b_trans.x = - bone->b_trans.y = - bone->b_trans.z = 0.0; - bone->trans.x = - bone->trans.y = - bone->trans.z = 0.0; - - bone->primChanType = CHANNEL_TYPE_NONE; - bone->secChanType = CHANNEL_TYPE_NONE; - bone->primFrameCount = 0; - bone->secFrameCount = 0; - bone->primCurFrame = 0; - bone->secCurFrame = 0; - bone->primChannel = NULL; - bone->secChannel = NULL; - - bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS - bone->visuals = NULL; // POINTER TO VISUALS - bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS - bone->children = NULL; // POINTER TO CHILDREN - bone->parent = parent; -} -//// ResetBone //////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: BoneSetFrame -// Purpose: Set the animation stream for a bone -// Arguments: Pointer to bone system, frame to set to -/////////////////////////////////////////////////////////////////////////////// -void BoneSetFrame(t_Bone *bone,int frame) -{ -/// Local Variables /////////////////////////////////////////////////////////// - float *offset; -/////////////////////////////////////////////////////////////////////////////// - - if (bone->primChannel != NULL) - { - offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); - - // THIS HANDLES THE INDIVIDUAL STREAM TYPES. ONLY ONE NOW. - switch (bone->primChanType) - { - // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER - case CHANNEL_TYPE_SRT: - bone->trans.x = offset[0]; - bone->trans.y = offset[1]; - bone->trans.z = offset[2]; - - bone->rot.x = offset[3]; - bone->rot.y = offset[4]; - bone->rot.z = offset[5]; - -// I DON'T REALLY WANT MY ANIMATION TO DEAL WITH SCALE RIGHT NOW -// EVEN THOUGH IT IS IN THE BVA FILE -// bone->scale.x = offset[6]; -// bone->scale.y = offset[7]; -// bone->scale.z = offset[8]; - break; - - } - } -} -//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Function: BoneAdvanceFrame -// Purpose: Increment the animation stream for a bone and possible the -// children attached to that bone1 -// Arguments: Pointer to bone system, Delta frame value to move, if it is recursive -/////////////////////////////////////////////////////////////////////////////// -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) -{ -/// Local Variables /////////////////////////////////////////////////////////// - int loop; - t_Bone *child; - float **dataptr,*animData = NULL; -/////////////////////////////////////////////////////////////////////////////// - if (bone->primChanType != CHANNEL_TYPE_BVH) - { - // THERE MUST BE SOME THINGS TO ADVANCE - if (bone->childCnt > 0) - { - child = bone->children; - for (loop = 0; loop < bone->childCnt; loop++,child++) - { - // ADVANCE THE STREAM - child->primCurFrame += direction; - if (child->primCurFrame >= child->primFrameCount) - child->primCurFrame = 0; - if (child->primCurFrame < 0) - child->primCurFrame += child->primFrameCount; - BoneSetFrame(child,(int)child->primCurFrame); - if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN - BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER - } - } - } - else // Handle BVH - { - bone->primCurFrame += direction; - if (bone->primCurFrame >= bone->primFrameCount) - bone->primCurFrame = 0; - if (bone->primCurFrame < 0) - bone->primCurFrame += bone->primFrameCount; - dataptr = (float **)bone->secChannel; - animData = (float *)bone->primChannel; - animData = &animData[(int)(bone->primCurFrame * bone->secFrameCount)]; - for (loop = 0; loop < bone->secFrameCount; loop++) - *dataptr[loop] = animData[loop]; - } -} -//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.cpp : Animation System Skeleton supprt file +// +// Purpose: Structure Supprt routines for Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#include "skeleton.h" + +/////////////////////////////////////////////////////////////////////////////// +// Function: DestroySkeleton +// Purpose: Clear memory for a skeletal system +// Arguments: Pointer to bone system +/////////////////////////////////////////////////////////////////////////////// +void DestroySkeleton(t_Bone *root) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; +/////////////////////////////////////////////////////////////////////////////// + // NEED TO RECURSIVELY GO THROUGH THE CHILDREN + if (root->childCnt > 0) + { + child = root->children; + for (loop = 0; loop < root->childCnt; loop++,child++) + { + if (child->childCnt > 0) + DestroySkeleton(child); + if (child->primChannel > NULL) + { + free(child->primChannel); + child->primChannel = NULL; + } + } + free(root->children); + } + + root->primChanType = CHANNEL_TYPE_NONE; + root->secChanType = CHANNEL_TYPE_NONE; + root->primFrameCount = 0; + root->secFrameCount = 0; + root->primCurFrame = 0; + root->secCurFrame = 0; + root->primChannel = NULL; + root->secChannel = NULL; + + root->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + root->visuals = NULL; // POINTER TO VISUALS + root->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + root->children = NULL; // POINTER TO CHILDREN +} +//// DestroySkeleton ////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: ResetBone +// Purpose: Reset the bone system and set the parent bone +// Arguments: Pointer to bone system, and parent bone (could be null) +/////////////////////////////////////////////////////////////////////////////// +void ResetBone(t_Bone *bone,t_Bone *parent) +{ + bone->b_scale.x = + bone->b_scale.y = + bone->b_scale.z = 1.0; + bone->scale.x = + bone->scale.y = + bone->scale.z = 1.0; + + bone->b_rot.x = + bone->b_rot.y = + bone->b_rot.z = 0.0; + bone->rot.x = + bone->rot.y = + bone->rot.z = 0.0; + + bone->b_trans.x = + bone->b_trans.y = + bone->b_trans.z = 0.0; + bone->trans.x = + bone->trans.y = + bone->trans.z = 0.0; + + bone->primChanType = CHANNEL_TYPE_NONE; + bone->secChanType = CHANNEL_TYPE_NONE; + bone->primFrameCount = 0; + bone->secFrameCount = 0; + bone->primCurFrame = 0; + bone->secCurFrame = 0; + bone->primChannel = NULL; + bone->secChannel = NULL; + + bone->visualCnt = 0; // COUNT OF ATTACHED VISUAL ELEMENTS + bone->visuals = NULL; // POINTER TO VISUALS + bone->childCnt = 0; // COUNT OF ATTACHED BONE ELEMENTS + bone->children = NULL; // POINTER TO CHILDREN + bone->parent = parent; +} +//// ResetBone //////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: BoneSetFrame +// Purpose: Set the animation stream for a bone +// Arguments: Pointer to bone system, frame to set to +/////////////////////////////////////////////////////////////////////////////// +void BoneSetFrame(t_Bone *bone,int frame) +{ +/// Local Variables /////////////////////////////////////////////////////////// + float *offset; +/////////////////////////////////////////////////////////////////////////////// + + if (bone->primChannel != NULL) + { + offset = (float *)(bone->primChannel + (s_Channel_Type_Size[bone->primChanType] * frame)); + + // THIS HANDLES THE INDIVIDUAL STREAM TYPES. ONLY ONE NOW. + switch (bone->primChanType) + { + // TYPE_SRT HAS 9 FLOATS IN TXYZ,RXYZ,SXYZ ORDER + case CHANNEL_TYPE_SRT: + bone->trans.x = offset[0]; + bone->trans.y = offset[1]; + bone->trans.z = offset[2]; + + bone->rot.x = offset[3]; + bone->rot.y = offset[4]; + bone->rot.z = offset[5]; + +// I DON'T REALLY WANT MY ANIMATION TO DEAL WITH SCALE RIGHT NOW +// EVEN THOUGH IT IS IN THE BVA FILE +// bone->scale.x = offset[6]; +// bone->scale.y = offset[7]; +// bone->scale.z = offset[8]; + break; + + } + } +} +//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Function: BoneAdvanceFrame +// Purpose: Increment the animation stream for a bone and possible the +// children attached to that bone1 +// Arguments: Pointer to bone system, Delta frame value to move, if it is recursive +/////////////////////////////////////////////////////////////////////////////// +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren) +{ +/// Local Variables /////////////////////////////////////////////////////////// + int loop; + t_Bone *child; + float **dataptr,*animData = NULL; +/////////////////////////////////////////////////////////////////////////////// + if (bone->primChanType != CHANNEL_TYPE_BVH) + { + // THERE MUST BE SOME THINGS TO ADVANCE + if (bone->childCnt > 0) + { + child = bone->children; + for (loop = 0; loop < bone->childCnt; loop++,child++) + { + // ADVANCE THE STREAM + child->primCurFrame += direction; + if (child->primCurFrame >= child->primFrameCount) + child->primCurFrame = 0; + if (child->primCurFrame < 0) + child->primCurFrame += child->primFrameCount; + BoneSetFrame(child,(int)child->primCurFrame); + if (doChildren && child->childCnt > 0) // IF THIS CHILD HAS CHILDREN + BoneAdvanceFrame(child,direction,doChildren); // RECURSE DOWN HIER + } + } + } + else // Handle BVH + { + bone->primCurFrame += direction; + if (bone->primCurFrame >= bone->primFrameCount) + bone->primCurFrame = 0; + if (bone->primCurFrame < 0) + bone->primCurFrame += bone->primFrameCount; + dataptr = (float **)bone->secChannel; + animData = (float *)bone->primChannel; + animData = &animData[(int)(bone->primCurFrame * bone->secFrameCount)]; + for (loop = 0; loop < bone->secFrameCount; loop++) + *dataptr[loop] = animData[loop]; + } +} +//// BoneAdvanceFrame ///////////////////////////////////////////////////////////////// diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.h index aada5a9..d506f52 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/Skeleton.h @@ -1,143 +1,143 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Skeleton.h : Animation System structure definition file -// -// Purpose: Structure Definition of Hierarchical Animation System -// -// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY -// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(SKELETON_H__INCLUDED_) -#define SKELETON_H__INCLUDED_ - -/// Bone Definitions ///////////////////////////////////////////////////////// -#define BONE_ID_ROOT 1 // ROOT BONE -/////////////////////////////////////////////////////////////////////////////// - -/// Channel Definitions /////////////////////////////////////////////////////// -#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED -#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION -#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER -#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER -#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER -#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER -#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER -#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER -#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER -#define CHANNEL_TYPE_S 256 // SCALE ONLY -#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER -#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS -#define CHANNEL_TYPE_BVH 2048 // SPECIAL FORMAT FOR BVH - -/////////////////////////////////////////////////////////////////////////////// - -// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE -static int s_Channel_Type_Size[] = -{ - 0, - 9, - 6, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 3 -}; - -typedef struct -{ - float x,y,z; -} tVector; - -typedef struct -{ - float x,y,z,a; -} tQuaternion; - -/// Structure Definitions /////////////////////////////////////////////////////// - -// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM -// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT -// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE -// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD -// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS -// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE -struct t_Bone -{ - long id; // BONE ID - char name[80]; // BONE NAME - long flags; // BONE FLAGS - // HIERARCHY INFO - t_Bone *parent; // POINTER TO PARENT BONE - int childCnt; // COUNT OF CHILD BONES - t_Bone *children; // POINTER TO CHILDREN - // TRANSFORMATION INFO - tVector b_scale; // BASE SCALE FACTORS - tVector b_rot; // BASE ROTATION FACTORS - tVector b_trans; // BASE TRANSLATION FACTORS - tVector scale; // CURRENT SCALE FACTORS - tVector rot; // CURRENT ROTATION FACTORS - tVector trans; // CURRENT TRANSLATION FACTORS - tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION - - // ANIMATION INFO - DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED - float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION - float primFrameCount; // FRAMES IN PRIMARY CHANNEL - float primSpeed; // CURRENT PLAYBACK SPEED - float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED - float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION - float secFrameCount; // FRAMES IN SECONDARY CHANNEL - float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL - float secSpeed; // CURRENT PLAYBACK SPEED - float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) - // DOF CONSTRAINTS - int min_rx, max_rx; // ROTATION X LIMITS - int min_ry, max_ry; // ROTATION Y LIMITS - int min_rz, max_rz; // ROTATION Z LIMITS - float damp_width, damp_strength; // DAMPENING SETTINGS - // VISUAL ELEMENTS - int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS - long *visuals; // POINTER TO VISUALS - int *CV_ptr; // POINTER TO CONTROL VERTICES - float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES - // COLLISION ELEMENTS - float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) - tVector center; // CENTER OF OBJECT (MASS) - float bsphere; // BOUNDING SPHERE (RADIUS) - // PHYSICS - tVector length; // BONE LENGTH VECTOR - float mass; // MASS - float friction; // STATIC FRICTION - float kfriction; // KINETIC FRICTION - float elast; // ELASTICITY -}; - -/////////////////////////////////////////////////////////////////////////////// - -/// Support Function Definitions ////////////////////////////////////////////// - -void DestroySkeleton(t_Bone *root); -void ResetBone(t_Bone *bone,t_Bone *parent); -void BoneSetFrame(t_Bone *bone,int frame); -void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); - -/////////////////////////////////////////////////////////////////////////////// - -#endif // !defined(SKELETON_H__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// Skeleton.h : Animation System structure definition file +// +// Purpose: Structure Definition of Hierarchical Animation System +// +// I DIDN'T PUT THESE IN A C++ CLASS FOR CROSS PLATFORM COMPATIBILITY +// SINCE THE ENGINE MAY BE IMPLEMENTED ON CONSOLES AND OTHER SYSTEMS +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(SKELETON_H__INCLUDED_) +#define SKELETON_H__INCLUDED_ + +/// Bone Definitions ///////////////////////////////////////////////////////// +#define BONE_ID_ROOT 1 // ROOT BONE +/////////////////////////////////////////////////////////////////////////////// + +/// Channel Definitions /////////////////////////////////////////////////////// +#define CHANNEL_TYPE_NONE 0 // NO CHANNEL APPLIED +#define CHANNEL_TYPE_SRT 1 // SCALE ROTATION AND TRANSLATION +#define CHANNEL_TYPE_TRANS 2 // CHANNEL HAS TRANSLATION (X Y Z) ORDER +#define CHANNEL_TYPE_RXYZ 4 // ROTATION (RX RY RZ) ORDER +#define CHANNEL_TYPE_RZXY 8 // ROTATION (RZ RX RY) ORDER +#define CHANNEL_TYPE_RYZX 16 // ROTATION (RY RZ RX) ORDER +#define CHANNEL_TYPE_RZYX 32 // ROTATION (RZ RY RX) ORDER +#define CHANNEL_TYPE_RXZY 64 // ROTATION (RX RZ RY) ORDER +#define CHANNEL_TYPE_RYXZ 128 // ROTATION (RY RX RZ) ORDER +#define CHANNEL_TYPE_S 256 // SCALE ONLY +#define CHANNEL_TYPE_T 512 // TRANSLATION ONLY (X Y Z) ORDER +#define CHANNEL_TYPE_INTERLEAVED 1024 // THIS DATA STREAM HAS MULTIPLE CHANNELS +#define CHANNEL_TYPE_BVH 2048 // SPECIAL FORMAT FOR BVH + +/////////////////////////////////////////////////////////////////////////////// + +// COUNT OF NUMBER OF FLOATS FOR EACH CHANNEL TYPE +static int s_Channel_Type_Size[] = +{ + 0, + 9, + 6, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 +}; + +typedef struct +{ + float x,y,z; +} tVector; + +typedef struct +{ + float x,y,z,a; +} tQuaternion; + +/// Structure Definitions /////////////////////////////////////////////////////// + +// THIS STRUCTURE DEFINES A BONE IN THE ANIMATION SYSTEM +// A BONE IS ACTUALLY AN ABSTRACT REPRESENTATION OF A OBJECT +// IN THE 3D WORLD. A CHARACTER COULD BE MADE OF ONE BONE +// WITH MULTIPLE VISUALS OF ANIMATION ATTACHED. THIS WOULD +// BE SIMILAR TO A QUAKE CHARACTER. BY MAKING IT HAVE LEVELS +// OF HIERARCHY AND CHANNELS OF ANIMATION IT IS JUST MORE FLEXIBLE +struct t_Bone +{ + long id; // BONE ID + char name[80]; // BONE NAME + long flags; // BONE FLAGS + // HIERARCHY INFO + t_Bone *parent; // POINTER TO PARENT BONE + int childCnt; // COUNT OF CHILD BONES + t_Bone *children; // POINTER TO CHILDREN + // TRANSFORMATION INFO + tVector b_scale; // BASE SCALE FACTORS + tVector b_rot; // BASE ROTATION FACTORS + tVector b_trans; // BASE TRANSLATION FACTORS + tVector scale; // CURRENT SCALE FACTORS + tVector rot; // CURRENT ROTATION FACTORS + tVector trans; // CURRENT TRANSLATION FACTORS + tQuaternion quat; // QUATERNION USEFUL FOR ANIMATION + + // ANIMATION INFO + DWORD primChanType; // WHAT TYPE OF PREIMARY CHAN IS ATTACHED + float *primChannel; // POINTER TO PRIMARY CHANNEL OF ANIMATION + float primFrameCount; // FRAMES IN PRIMARY CHANNEL + float primSpeed; // CURRENT PLAYBACK SPEED + float primCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + DWORD secChanType; // WHAT TYPE OF SECONDARY CHAN IS ATTACHED + float *secChannel; // POINTER TO SECONDARY CHANNEL OF ANIMATION + float secFrameCount; // FRAMES IN SECONDARY CHANNEL + float secCurFrame; // CURRENT FRAME NUMBER IN CHANNEL + float secSpeed; // CURRENT PLAYBACK SPEED + float animBlend; // BLENDING FACTOR (ANIM WEIGHTING) + // DOF CONSTRAINTS + int min_rx, max_rx; // ROTATION X LIMITS + int min_ry, max_ry; // ROTATION Y LIMITS + int min_rz, max_rz; // ROTATION Z LIMITS + float damp_width, damp_strength; // DAMPENING SETTINGS + // VISUAL ELEMENTS + int visualCnt; // COUNT OF ATTACHED VISUAL ELEMENTS + long *visuals; // POINTER TO VISUALS + int *CV_ptr; // POINTER TO CONTROL VERTICES + float *CV_weight; // POINTER TO ARRAY OF WEIGHTING VALUES + // COLLISION ELEMENTS + float bbox[6]; // BOUNDING BOX (UL XYZ, LR XYZ) + tVector center; // CENTER OF OBJECT (MASS) + float bsphere; // BOUNDING SPHERE (RADIUS) + // PHYSICS + tVector length; // BONE LENGTH VECTOR + float mass; // MASS + float friction; // STATIC FRICTION + float kfriction; // KINETIC FRICTION + float elast; // ELASTICITY +}; + +/////////////////////////////////////////////////////////////////////////////// + +/// Support Function Definitions ////////////////////////////////////////////// + +void DestroySkeleton(t_Bone *root); +void ResetBone(t_Bone *bone,t_Bone *parent); +void BoneSetFrame(t_Bone *bone,int frame); +void BoneAdvanceFrame(t_Bone *bone,int direction,BOOL doChildren); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // !defined(SKELETON_H__INCLUDED_) diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.cpp b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.cpp index 2a5544b..ff4b52b 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.cpp +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.cpp @@ -1,6 +1,6 @@ -// stdafx.cpp : source file that includes just the standard includes -// Dagger.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - +// stdafx.cpp : source file that includes just the standard includes +// Dagger.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.h index ed96a91..f78606a 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/StdAfx.h @@ -1,26 +1,26 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 - -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers - -#include // MFC core and standard components -#include // MFC extensions -#include // MFC OLE automation classes -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - - -//{{AFX_INSERT_LOCATION}} -// Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC OLE automation classes +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__4B0629BB_2696_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/hierwin.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/hierwin.h index 015eebd..2ae5371 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/hierwin.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/hierwin.h @@ -1,116 +1,116 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// HierWin.h : class definition file -// -// -// Created: -// JL 9/1/97 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright 1997 Jeff Lander, All Rights Reserved. -// For educational purposes only. -// Please do not republish in electronic or print form without permission -// Thanks - jeffl@darwin3d.com -// -/////////////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) -#define AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_ - -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -// HierWin.h : header file -// -#include "Skeleton.h" - -///////////////////////////////////////////////////////////////////////////// -// CHierWin window - -class CHierWin : public CTreeCtrl -{ -// Construction -public: - CHierWin(); - -// Attributes -protected: - HTREEITEM m_TreeRoot; - t_Bone *m_Skeleton; -// Operations -public: - void ResetSkeleton(); - void SetSkeleton(t_Bone *skeleton, HTREEITEM item); - void AddBone(); - -protected: - void EditBone(); - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CHierWin) - protected: - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CHierWin(); - - // Generated message map functions -protected: - //{{AFX_MSG(CHierWin) - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); - afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - //}}AFX_MSG - - DECLARE_MESSAGE_MAP() -}; - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// CBoneInfo dialog - -class CBoneInfo : public CDialog -{ -// Construction -public: - CBoneInfo(CWnd* pParent = NULL); // standard constructor - -// Dialog Data - //{{AFX_DATA(CBoneInfo) - enum { IDD = IDD_BONE_INFO }; - CString m_BoneName; - float m_Rot_X; - float m_Rot_Y; - float m_Rot_Z; - float m_Trans_X; - float m_Trans_Y; - float m_Trans_Z; - //}}AFX_DATA - - -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CBoneInfo) - protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - //}}AFX_VIRTUAL - -// Implementation -protected: - - // Generated message map functions - //{{AFX_MSG(CBoneInfo) - // NOTE: the ClassWizard will add member functions here - //}}AFX_MSG - DECLARE_MESSAGE_MAP() -}; - -#endif // !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) +/////////////////////////////////////////////////////////////////////////////// +// +// HierWin.h : class definition file +// +// +// Created: +// JL 9/1/97 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright 1997 Jeff Lander, All Rights Reserved. +// For educational purposes only. +// Please do not republish in electronic or print form without permission +// Thanks - jeffl@darwin3d.com +// +/////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) +#define AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// HierWin.h : header file +// +#include "Skeleton.h" + +///////////////////////////////////////////////////////////////////////////// +// CHierWin window + +class CHierWin : public CTreeCtrl +{ +// Construction +public: + CHierWin(); + +// Attributes +protected: + HTREEITEM m_TreeRoot; + t_Bone *m_Skeleton; +// Operations +public: + void ResetSkeleton(); + void SetSkeleton(t_Bone *skeleton, HTREEITEM item); + void AddBone(); + +protected: + void EditBone(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CHierWin) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CHierWin(); + + // Generated message map functions +protected: + //{{AFX_MSG(CHierWin) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CBoneInfo dialog + +class CBoneInfo : public CDialog +{ +// Construction +public: + CBoneInfo(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CBoneInfo) + enum { IDD = IDD_BONE_INFO }; + CString m_BoneName; + float m_Rot_X; + float m_Rot_Y; + float m_Rot_Z; + float m_Trans_X; + float m_Trans_Y; + float m_Trans_Z; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CBoneInfo) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CBoneInfo) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +#endif // !defined(AFX_HierWin_H__2AB46760_27CD_11D1_83A0_004005308EB5__INCLUDED_) diff --git a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/resource.h b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/resource.h index 6f47181..3b6feb1 100644 --- a/Working with Motion Capture in OpenGL/Code/OGL/Dagger/resource.h +++ b/Working with Motion Capture in OpenGL/Code/OGL/Dagger/resource.h @@ -1,42 +1,42 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Dagger.rc -// -#define IDD_ABOUTBOX 100 -#define IDR_MAINFRAME 128 -#define IDR_DAGGERTYPE 129 -#define IDD_BONE_INFO 132 -#define IDD_SPEED 133 -#define IDC_BONE_NAME 1001 -#define IDC_TRANS_X 1002 -#define IDC_TRANS_Y 1003 -#define IDC_PLAYBACK_SPEED 1003 -#define IDC_TRANS_Z 1004 -#define IDC_ROT_X 1005 -#define IDC_ROT_Y 1006 -#define IDC_ROT_Z 1007 -#define ID_PLAY_FORWARD 32777 -#define ID_FORWARD_FRAME 32778 -#define ID_STOP 32779 -#define ID_BACK_FRAME 32780 -#define ID_PLAY_BACK 32781 -#define ID_ADD_BONE 32782 -#define ID_DELETE_BONE 32783 -#define ID_VIEW_RESETSKELETON 32784 -#define ID_FILE_LOADANIM 32785 -#define ID_ANIMATION_PLAYBACKSPEED 32788 -#define ID_WHICHOGL 32789 -#define ID_INDICATOR_FRAME 59142 -#define ID_INDICATOR_FRAME2 59143 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 134 -#define _APS_NEXT_COMMAND_VALUE 32790 -#define _APS_NEXT_CONTROL_VALUE 1004 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Dagger.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_DAGGERTYPE 129 +#define IDD_BONE_INFO 132 +#define IDD_SPEED 133 +#define IDC_BONE_NAME 1001 +#define IDC_TRANS_X 1002 +#define IDC_TRANS_Y 1003 +#define IDC_PLAYBACK_SPEED 1003 +#define IDC_TRANS_Z 1004 +#define IDC_ROT_X 1005 +#define IDC_ROT_Y 1006 +#define IDC_ROT_Z 1007 +#define ID_PLAY_FORWARD 32777 +#define ID_FORWARD_FRAME 32778 +#define ID_STOP 32779 +#define ID_BACK_FRAME 32780 +#define ID_PLAY_BACK 32781 +#define ID_ADD_BONE 32782 +#define ID_DELETE_BONE 32783 +#define ID_VIEW_RESETSKELETON 32784 +#define ID_FILE_LOADANIM 32785 +#define ID_ANIMATION_PLAYBACKSPEED 32788 +#define ID_WHICHOGL 32789 +#define ID_INDICATOR_FRAME 59142 +#define ID_INDICATOR_FRAME2 59143 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 134 +#define _APS_NEXT_COMMAND_VALUE 32790 +#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/quat2eul.cpp b/quat2eul.cpp index 53c951f..f83a0c2 100644 --- a/quat2eul.cpp +++ b/quat2eul.cpp @@ -32,9 +32,9 @@ void QuatToEuler(const tQuaternion *quat, tVector *euler) yr = (float)atan2(sy,cy); euler->y = (yr * 180.0f) / (float)M_PI; - // AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270 + // AVOID DIVIDE BY ZERO ERROR ONLY WHERE Y= +-90 or +-270 // NOT CHECKING cy BECAUSE OF PRECISION ERRORS - if (sy != 1.0f && sy != -1.0f) + if (sy != 1.0f && sy != -1.0f) { cx = matrix[2][2] / cy; sx = matrix[2][1] / cy;