From b72804294a6fb7cdde8a6333bf2cb0ca9b78c036 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Fri, 25 Apr 2003 21:05:40 +0000 Subject: [PATCH] working on Mesh support - loads only Milkshape ASCII - doesn't yet load textures or render with materials --- stepmania/bend.txt | 338 +++++++++++ stepmania/src/GameConstantsAndTypes.cpp | 6 - stepmania/src/GameConstantsAndTypes.h | 11 +- stepmania/src/Milkshape.h | 165 ++++++ stepmania/src/Model.cpp | 752 ++++++++++++++++++++++++ stepmania/src/Model.h | 55 ++ stepmania/src/RageDisplay.cpp | 9 + stepmania/src/RageDisplay.h | 1 + stepmania/src/ScreenSandbox.cpp | 7 +- stepmania/src/ScreenSandbox.h | 4 +- stepmania/src/StepMania.dsp | 30 +- stepmania/src/StepMania.vcproj | 15 + stepmania/src/mathlib.c | 404 +++++++++++++ stepmania/src/mathlib.h | 92 +++ 14 files changed, 1868 insertions(+), 21 deletions(-) create mode 100644 stepmania/bend.txt create mode 100644 stepmania/src/Milkshape.h create mode 100644 stepmania/src/Model.cpp create mode 100644 stepmania/src/Model.h create mode 100644 stepmania/src/mathlib.c create mode 100644 stepmania/src/mathlib.h diff --git a/stepmania/bend.txt b/stepmania/bend.txt new file mode 100644 index 0000000000..4d2dbe6654 --- /dev/null +++ b/stepmania/bend.txt @@ -0,0 +1,338 @@ +// MilkShape 3D ASCII + +Frames: 30 +Frame: 1 + +Meshes: 1 +"Cylinder01" 0 -1 +91 +0 4.500000 -33.250000 0.000000 0.000000 1.000000 6 +0 4.500000 -23.666668 0.000000 0.000000 0.833333 5 +0 3.897114 -23.666668 2.250000 0.083333 0.833333 5 +0 3.897114 -33.250000 2.250000 0.083333 1.000000 6 +0 4.500000 -14.083334 0.000000 0.000000 0.666667 4 +0 3.897114 -14.083334 2.250000 0.083333 0.666667 4 +0 4.500000 -4.500000 0.000000 0.000000 0.500000 3 +0 3.897114 -4.500000 2.250000 0.083333 0.500000 3 +0 4.500000 5.083332 0.000000 0.000000 0.333333 2 +0 3.897114 5.083332 2.250000 0.083333 0.333333 2 +0 4.500000 14.666668 0.000000 0.000000 0.166667 1 +0 3.897114 14.666668 2.250000 0.083333 0.166667 1 +0 4.500000 24.250000 0.000000 0.000000 0.000000 0 +0 3.897114 24.250000 2.250000 0.083333 0.000000 0 +0 2.250000 -33.250000 3.897114 0.166667 1.000000 6 +0 2.250000 -23.666668 3.897114 0.166667 0.833333 5 +0 2.250000 -14.083334 3.897114 0.166667 0.666667 4 +0 2.250000 -4.500000 3.897114 0.166667 0.500000 3 +0 2.250000 5.083332 3.897114 0.166667 0.333333 2 +0 2.250000 14.666668 3.897114 0.166667 0.166667 1 +0 2.250000 24.250000 3.897114 0.166667 0.000000 0 +0 0.000000 -23.666668 4.500000 0.250000 0.833333 5 +0 0.000000 -33.250000 4.500000 0.250000 1.000000 6 +0 0.000000 -14.083334 4.500000 0.250000 0.666667 4 +0 0.000000 -4.500000 4.500000 0.250000 0.500000 3 +0 0.000000 5.083332 4.500000 0.250000 0.333333 2 +0 0.000000 14.666668 4.500000 0.250000 0.166667 1 +0 0.000000 24.250000 4.500000 0.250000 0.000000 0 +0 -2.250000 -33.250000 3.897114 0.333333 1.000000 6 +0 -2.250000 -23.666668 3.897114 0.333333 0.833333 5 +0 -2.250000 -14.083334 3.897114 0.333333 0.666667 4 +0 -2.250000 -4.500000 3.897114 0.333333 0.500000 3 +0 -2.250000 5.083332 3.897114 0.333333 0.333333 2 +0 -2.250000 14.666668 3.897114 0.333333 0.166667 1 +0 -2.250000 24.250000 3.897114 0.333333 0.000000 0 +0 -3.897114 -23.666668 2.250000 0.416667 0.833333 5 +0 -3.897114 -33.250000 2.250000 0.416667 1.000000 6 +0 -3.897114 -14.083334 2.250000 0.416667 0.666667 4 +0 -3.897114 -4.500000 2.250000 0.416667 0.500000 3 +0 -3.897114 5.083332 2.250000 0.416667 0.333333 2 +0 -3.897114 14.666668 2.250000 0.416667 0.166667 1 +0 -3.897114 24.250000 2.250000 0.416667 0.000000 0 +0 -4.500000 -33.250000 0.000000 0.500000 1.000000 6 +0 -4.500000 -23.666668 0.000000 0.500000 0.833333 5 +0 -4.500000 -14.083334 0.000000 0.500000 0.666667 4 +0 -4.500000 -4.500000 0.000000 0.500000 0.500000 3 +0 -4.500000 5.083332 0.000000 0.500000 0.333333 2 +0 -4.500000 14.666668 0.000000 0.500000 0.166667 1 +0 -4.500000 24.250000 0.000000 0.500000 0.000000 0 +0 -3.897114 -23.666668 -2.250000 0.583333 0.833333 5 +0 -3.897114 -33.250000 -2.250000 0.583333 1.000000 6 +0 -3.897114 -14.083334 -2.250000 0.583333 0.666667 4 +0 -3.897114 -4.500000 -2.250000 0.583333 0.500000 3 +0 -3.897114 5.083332 -2.250000 0.583333 0.333333 2 +0 -3.897114 14.666668 -2.250000 0.583333 0.166667 1 +0 -3.897114 24.250000 -2.250000 0.583333 0.000000 0 +0 -2.250000 -33.250000 -3.897114 0.666667 1.000000 6 +0 -2.250000 -23.666668 -3.897114 0.666667 0.833333 5 +0 -2.250000 -14.083334 -3.897114 0.666667 0.666667 4 +0 -2.250000 -4.500000 -3.897114 0.666667 0.500000 3 +0 -2.250000 5.083332 -3.897114 0.666667 0.333333 2 +0 -2.250000 14.666668 -3.897114 0.666667 0.166667 1 +0 -2.250000 24.250000 -3.897114 0.666667 0.000000 0 +0 -0.000000 -23.666668 -4.500000 0.750000 0.833333 5 +0 -0.000000 -33.250000 -4.500000 0.750000 1.000000 6 +0 -0.000000 -14.083334 -4.500000 0.750000 0.666667 4 +0 -0.000000 -4.500000 -4.500000 0.750000 0.500000 3 +0 -0.000000 5.083332 -4.500000 0.750000 0.333333 2 +0 -0.000000 14.666668 -4.500000 0.750000 0.166667 1 +0 -0.000000 24.250000 -4.500000 0.750000 0.000000 0 +0 2.250000 -33.250000 -3.897114 0.833333 1.000000 6 +0 2.250000 -23.666668 -3.897114 0.833333 0.833333 5 +0 2.250000 -14.083334 -3.897114 0.833333 0.666667 4 +0 2.250000 -4.500000 -3.897114 0.833333 0.500000 3 +0 2.250000 5.083332 -3.897114 0.833333 0.333333 2 +0 2.250000 14.666668 -3.897114 0.833333 0.166667 1 +0 2.250000 24.250000 -3.897114 0.833333 0.000000 0 +0 3.897114 -23.666668 -2.250000 0.916667 0.833333 5 +0 3.897114 -33.250000 -2.250000 0.916667 1.000000 6 +0 3.897114 -14.083334 -2.250000 0.916667 0.666667 4 +0 3.897114 -4.500000 -2.250000 0.916667 0.500000 3 +0 3.897114 5.083332 -2.250000 0.916667 0.333333 2 +0 3.897114 14.666668 -2.250000 0.916667 0.166667 1 +0 3.897114 24.250000 -2.250000 0.916667 0.000000 0 +0 4.500000 -33.250000 0.000000 1.000000 1.000000 6 +0 4.500000 -23.666668 0.000000 1.000000 0.833333 5 +0 4.500000 -14.083334 0.000000 1.000000 0.666667 4 +0 4.500000 -4.500000 0.000000 1.000000 0.500000 3 +0 4.500000 5.083332 0.000000 1.000000 0.333333 2 +0 4.500000 14.666668 0.000000 1.000000 0.166667 1 +0 4.500000 24.250000 0.000000 1.000000 0.000000 0 +12 +1.000000 0.000000 0.000000 +0.866025 0.000000 0.500000 +0.500000 0.000000 0.866025 +0.000000 0.000000 1.000000 +-0.500000 0.000000 0.866025 +-0.866025 0.000000 0.500000 +-1.000000 0.000000 0.000000 +-0.866025 0.000000 -0.500000 +-0.500000 0.000000 -0.866025 +0.000000 0.000000 -1.000000 +0.500000 0.000000 -0.866025 +0.866025 0.000000 -0.500000 +144 +0 0 1 2 0 0 1 1 +0 0 2 3 0 1 1 1 +0 1 4 2 0 0 1 1 +0 4 5 2 0 1 1 1 +0 4 6 7 0 0 1 1 +0 4 7 5 0 1 1 1 +0 6 8 7 0 0 1 1 +0 8 9 7 0 1 1 1 +0 8 10 11 0 0 1 1 +0 8 11 9 0 1 1 1 +0 10 12 11 0 0 1 1 +0 12 13 11 0 1 1 1 +0 3 2 14 1 1 2 1 +0 2 15 14 1 2 2 1 +0 2 5 16 1 1 2 1 +0 2 16 15 1 2 2 1 +0 5 7 16 1 1 2 1 +0 7 17 16 1 2 2 1 +0 7 9 18 1 1 2 1 +0 7 18 17 1 2 2 1 +0 9 11 18 1 1 2 1 +0 11 19 18 1 2 2 1 +0 11 13 20 1 1 2 1 +0 11 20 19 1 2 2 1 +0 14 15 21 2 2 3 1 +0 14 21 22 2 3 3 1 +0 15 16 21 2 2 3 1 +0 16 23 21 2 3 3 1 +0 16 17 24 2 2 3 1 +0 16 24 23 2 3 3 1 +0 17 18 24 2 2 3 1 +0 18 25 24 2 3 3 1 +0 18 19 26 2 2 3 1 +0 18 26 25 2 3 3 1 +0 19 20 26 2 2 3 1 +0 20 27 26 2 3 3 1 +0 22 21 28 3 3 4 1 +0 21 29 28 3 4 4 1 +0 21 23 30 3 3 4 1 +0 21 30 29 3 4 4 1 +0 23 24 30 3 3 4 1 +0 24 31 30 3 4 4 1 +0 24 25 32 3 3 4 1 +0 24 32 31 3 4 4 1 +0 25 26 32 3 3 4 1 +0 26 33 32 3 4 4 1 +0 26 27 34 3 3 4 1 +0 26 34 33 3 4 4 1 +0 28 29 35 4 4 5 1 +0 28 35 36 4 5 5 1 +0 29 30 35 4 4 5 1 +0 30 37 35 4 5 5 1 +0 30 31 38 4 4 5 1 +0 30 38 37 4 5 5 1 +0 31 32 38 4 4 5 1 +0 32 39 38 4 5 5 1 +0 32 33 40 4 4 5 1 +0 32 40 39 4 5 5 1 +0 33 34 40 4 4 5 1 +0 34 41 40 4 5 5 1 +0 36 35 42 5 5 6 1 +0 35 43 42 5 6 6 1 +0 35 37 44 5 5 6 1 +0 35 44 43 5 6 6 1 +0 37 38 44 5 5 6 1 +0 38 45 44 5 6 6 1 +0 38 39 46 5 5 6 1 +0 38 46 45 5 6 6 1 +0 39 40 46 5 5 6 1 +0 40 47 46 5 6 6 1 +0 40 41 48 5 5 6 1 +0 40 48 47 5 6 6 1 +0 42 43 49 6 6 7 1 +0 42 49 50 6 7 7 1 +0 43 44 49 6 6 7 1 +0 44 51 49 6 7 7 1 +0 44 45 52 6 6 7 1 +0 44 52 51 6 7 7 1 +0 45 46 52 6 6 7 1 +0 46 53 52 6 7 7 1 +0 46 47 54 6 6 7 1 +0 46 54 53 6 7 7 1 +0 47 48 54 6 6 7 1 +0 48 55 54 6 7 7 1 +0 50 49 56 7 7 8 1 +0 49 57 56 7 8 8 1 +0 49 51 58 7 7 8 1 +0 49 58 57 7 8 8 1 +0 51 52 58 7 7 8 1 +0 52 59 58 7 8 8 1 +0 52 53 60 7 7 8 1 +0 52 60 59 7 8 8 1 +0 53 54 60 7 7 8 1 +0 54 61 60 7 8 8 1 +0 54 55 62 7 7 8 1 +0 54 62 61 7 8 8 1 +0 56 57 63 8 8 9 1 +0 56 63 64 8 9 9 1 +0 57 58 63 8 8 9 1 +0 58 65 63 8 9 9 1 +0 58 59 66 8 8 9 1 +0 58 66 65 8 9 9 1 +0 59 60 66 8 8 9 1 +0 60 67 66 8 9 9 1 +0 60 61 68 8 8 9 1 +0 60 68 67 8 9 9 1 +0 61 62 68 8 8 9 1 +0 62 69 68 8 9 9 1 +0 64 63 70 9 9 10 1 +0 63 71 70 9 10 10 1 +0 63 65 72 9 9 10 1 +0 63 72 71 9 10 10 1 +0 65 66 72 9 9 10 1 +0 66 73 72 9 10 10 1 +0 66 67 74 9 9 10 1 +0 66 74 73 9 10 10 1 +0 67 68 74 9 9 10 1 +0 68 75 74 9 10 10 1 +0 68 69 76 9 9 10 1 +0 68 76 75 9 10 10 1 +0 70 71 77 10 10 11 1 +0 70 77 78 10 11 11 1 +0 71 72 77 10 10 11 1 +0 72 79 77 10 11 11 1 +0 72 73 80 10 10 11 1 +0 72 80 79 10 11 11 1 +0 73 74 80 10 10 11 1 +0 74 81 80 10 11 11 1 +0 74 75 82 10 10 11 1 +0 74 82 81 10 11 11 1 +0 75 76 82 10 10 11 1 +0 76 83 82 10 11 11 1 +0 78 77 84 11 11 0 1 +0 77 85 84 11 0 0 1 +0 77 79 86 11 11 0 1 +0 77 86 85 11 0 0 1 +0 79 80 86 11 11 0 1 +0 80 87 86 11 0 0 1 +0 80 81 88 11 11 0 1 +0 80 88 87 11 0 0 1 +0 81 82 88 11 11 0 1 +0 82 89 88 11 0 0 1 +0 82 83 90 11 11 0 1 +0 82 90 89 11 0 0 1 + +Materials: 0 + +Bones: 7 +"joint1" +"" +0 0.000000 24.250000 0.000000 1.545162 1.570796 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.000000 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.000000 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +"joint2" +"joint1" +0 0.000000 0.000000 9.753204 0.106538 0.000000 0.000000 +3 +1.000000 0.000000 -0.000000 -0.000000 +15.000000 0.000000 0.000000 -0.000000 +30.000000 0.000000 0.000000 -0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 -0.401426 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +"joint3" +"joint2" +0 0.000000 0.000000 9.280355 0.134906 -0.000000 3.141593 +3 +1.000000 -0.000000 -0.000000 0.000000 +15.000000 -0.000000 -0.000000 0.000000 +30.000000 -0.000000 -0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.366519 0.000000 -0.000000 +30.000000 0.000000 0.000000 0.000000 +"joint4" +"joint3" +0 0.000000 0.000000 9.263503 -0.054002 0.000000 0.000000 +3 +1.000000 0.000000 -0.000000 0.000000 +15.000000 0.000000 -0.000000 0.000000 +30.000000 0.000000 -0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.523599 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +"joint5" +"joint4" +0 0.000000 0.000000 10.000000 0.000000 0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.000000 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.401426 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +"joint6" +"joint5" +0 0.000000 0.000000 10.000000 0.026310 0.000259 0.000000 +3 +1.000000 0.000000 -0.000000 -0.000000 +15.000000 0.000000 0.000000 -0.000000 +30.000000 0.000000 0.000000 -0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.383972 -0.000016 0.000097 +30.000000 0.000000 0.000000 0.000000 +"joint7" +"joint6" +5 0.000000 0.000000 9.503289 0.000000 0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.000000 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 +3 +1.000000 0.000000 0.000000 0.000000 +15.000000 0.174533 0.000000 0.000000 +30.000000 0.000000 0.000000 0.000000 diff --git a/stepmania/src/GameConstantsAndTypes.cpp b/stepmania/src/GameConstantsAndTypes.cpp index b4174e1836..f2fad0204f 100644 --- a/stepmania/src/GameConstantsAndTypes.cpp +++ b/stepmania/src/GameConstantsAndTypes.cpp @@ -13,12 +13,6 @@ #include "GameConstantsAndTypes.h" #include "GameState.h" -const CString BG_ANIMS_DIR = "BGAnimations/"; -const CString VISUALIZATIONS_DIR = "Visualizations/"; -const CString RANDOMMOVIES_DIR = "RandomMovies/"; - -const CString DEFAULT_RANKING_NAME = "STEP"; -const CString GROUP_ALL_MUSIC = ""; CString CategoryToString( RadarCategory cat ) { diff --git a/stepmania/src/GameConstantsAndTypes.h b/stepmania/src/GameConstantsAndTypes.h index 11bb78ecf8..e2f6564f78 100644 --- a/stepmania/src/GameConstantsAndTypes.h +++ b/stepmania/src/GameConstantsAndTypes.h @@ -168,7 +168,7 @@ enum RankingCategory NUM_RANKING_CATEGORIES }; -extern const CString DEFAULT_RANKING_NAME; +#define DEFAULT_RANKING_NAME CString("STEP") RankingCategory AverageMeterToRankingCategory( float fAverageMeter ); @@ -179,7 +179,7 @@ const int MAX_RANKING_NAME_LENGTH = 4; // // Group stuff // -extern const CString GROUP_ALL_MUSIC; +#define GROUP_ALL_MUSIC CString("") // @@ -221,9 +221,10 @@ enum BattleResult -extern const CString BG_ANIMS_DIR; -extern const CString VISUALIZATIONS_DIR; -extern const CString RANDOMMOVIES_DIR; +#define BG_ANIMS_DIR CString("BGAnimations/") +#define VISUALIZATIONS_DIR CString("Visualizations/") +#define RANDOMMOVIES_DIR CString("RandomMovies/") + diff --git a/stepmania/src/Milkshape.h b/stepmania/src/Milkshape.h new file mode 100644 index 0000000000..28c92d3188 --- /dev/null +++ b/stepmania/src/Milkshape.h @@ -0,0 +1,165 @@ +#ifndef Milkshape_H +#define Milkshape_H +/* +----------------------------------------------------------------------------- + Class: Milkshape + + Desc: Types defined in msLib.h. C arrays converted to use std::vector + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +/********************************************************************** + * + * Constants + * + **********************************************************************/ + +#define MS_MAX_NAME 32 +#define MS_MAX_PATH 256 + + + +/********************************************************************** + * + * Types + * + **********************************************************************/ + +#ifndef byte +typedef unsigned char byte; +#endif /* byte */ + +#ifndef word +typedef unsigned short word; +#endif /* word */ + + +typedef struct msVec2 { + float v[2]; + operator float* () { return v; }; + operator const float* () const { return v; }; +} msVec2; +typedef struct msVec3 { + float v[3]; + operator float* () { return v; }; + operator const float* () const { return v; }; +} msVec3; +typedef struct msVec4 { + float v[4]; + operator float* () { return v; }; + operator const float* () const { return v; }; +} msVec4; + + +/* msFlag */ +typedef enum { + eSelected = 1, eSelected2 = 2, eHidden = 4, eDirty = 8, eAveraged = 16, eUnused = 32 +} msFlag; + +/* msVertex */ +typedef struct msVertex +{ + byte nFlags; + msVec3 Vertex; + msVec2 uv; + char nBoneIndex; +} msVertex; + +/* msTriangle */ +typedef struct +{ + word nFlags; + word nVertexIndices[3]; + word nNormalIndices[3]; + msVec3 Normal; + byte nSmoothingGroup; +} msTriangle; + +/* msMesh */ +typedef struct msMesh +{ + byte nFlags; + char szName[MS_MAX_NAME]; + char nMaterialIndex; + + vector Vertices; + + vector Normals; + + vector Triangles; +} msMesh; + +/* msMaterial */ +typedef struct msMaterial +{ + int nFlags; + char szName[MS_MAX_NAME]; + msVec4 Ambient; + msVec4 Diffuse; + msVec4 Specular; + msVec4 Emissive; + float fShininess; + float fTransparency; + char szDiffuseTexture[MS_MAX_PATH]; + char szAlphaTexture[MS_MAX_PATH]; + int nName; +} msMaterial; + +/* msPositionKey */ +typedef struct msPositionKey +{ + float fTime; + msVec3 Position; +} msPositionKey; + +/* msRotationKey */ +typedef struct msRotationKey +{ + float fTime; + msVec3 Rotation; +} msRotationKey; + +/* msBone */ +typedef struct msBone +{ + int nFlags; + char szName[MS_MAX_NAME]; + char szParentName[MS_MAX_NAME]; + msVec3 Position; + msVec3 Rotation; + + vector PositionKeys; + + int nNumRotationKeys; + int nNumAllocedRotationKeys; + vector RotationKeys; +} msBone; + +/* msModel */ +typedef struct msModel +{ + vector Meshes; + + vector Materials; + + vector Bones; + + int FindBoneByName( const char* szName ) + { + for( unsigned i=0; inTotalFrames = nFrame; + } + if (sscanf (szLine, "Frame: %d", &nFrame) == 1) + { + m_pModel->nFrame = nFrame; + } + + int nNumMeshes = 0; + if (sscanf (szLine, "Meshes: %d", &nNumMeshes) == 1) + { + for (i = 0; i < nNumMeshes && !bError; i++) + { + m_pModel->Meshes.resize( m_pModel->Meshes.size()+1 ); + msMesh& mesh = m_pModel->Meshes.back(); + + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + // mesh: name, flags, material index + if (sscanf (szLine, "\"%[^\"]\" %d %d",szName, &nFlags, &nIndex) != 3) + { + bError = true; + break; + } + + strcpy( mesh.szName, szName ); + mesh.nFlags = nFlags; + mesh.nMaterialIndex = nIndex; + + // + // vertices + // + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + int nNumVertices = 0; + if (sscanf (szLine, "%d", &nNumVertices) != 1) + { + bError = true; + break; + } + + for (j = 0; j < nNumVertices; j++) + { + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + msVec3 Vertex; + msVec2 uv; + if (sscanf (szLine, "%d %f %f %f %f %f %d", + &nFlags, + &Vertex[0], &Vertex[1], &Vertex[2], + &uv[0], &uv[1], + &nIndex + ) != 7) + { + bError = true; + break; + } + + mesh.Vertices.resize( mesh.Vertices.size()+1 ); + msVertex& vertex = mesh.Vertices.back(); + vertex.nFlags = nFlags; + memcpy( vertex.Vertex, Vertex, sizeof(vertex.Vertex) ); + memcpy( vertex.uv, uv, sizeof(vertex.uv) ); + vertex.nBoneIndex = nIndex; + AddPointToBounds (Vertex, m_vMins, m_vMaxs); + } + + // + // normals + // + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + int nNumNormals = 0; + if (sscanf (szLine, "%d", &nNumNormals) != 1) + { + bError = true; + break; + } + + for (j = 0; j < nNumNormals; j++) + { + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + msVec3 Normal; + if (sscanf (szLine, "%f %f %f", &Normal[0], &Normal[1], &Normal[2]) != 3) + { + bError = true; + break; + } + + VectorNormalize (Normal); + mesh.Normals.push_back( Normal ); + } + // + // triangles + // + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + int nNumTriangles = 0; + if (sscanf (szLine, "%d", &nNumTriangles) != 1) + { + bError = true; + break; + } + + for (j = 0; j < nNumTriangles; j++) + { + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + + word nIndices[3]; + word nNormalIndices[3]; + if (sscanf (szLine, "%d %d %d %d %d %d %d %d", + &nFlags, + &nIndices[0], &nIndices[1], &nIndices[2], + &nNormalIndices[0], &nNormalIndices[1], &nNormalIndices[2], + &nIndex + ) != 8) + { + bError = true; + break; + } + + mesh.Triangles.resize( mesh.Triangles.size()+1 ); + msTriangle& Triangle = mesh.Triangles.back(); + Triangle.nFlags = nFlags; + memcpy( &Triangle.nVertexIndices, nIndices, sizeof(Triangle.nVertexIndices) ); + memcpy( &Triangle.nNormalIndices, nNormalIndices, sizeof(Triangle.nNormalIndices) ); + Triangle.nSmoothingGroup = nIndex; + + // + // calculate triangle normals + // + vec3_t v1, v2; + msVertex *pVertices[3]; + pVertices[0] = &mesh.Vertices[ nIndices[0] ]; + pVertices[1] = &mesh.Vertices[ nIndices[1] ]; + pVertices[2] = &mesh.Vertices[ nIndices[2] ]; + VectorSubtract (pVertices[0]->Vertex, pVertices[1]->Vertex, v1); + VectorSubtract (pVertices[2]->Vertex, pVertices[1]->Vertex, v2); + CrossProduct (v1, v2, Triangle.Normal); + VectorNormalize (Triangle.Normal); + VectorScale (Triangle.Normal, -1, Triangle.Normal); + } + } + } + + // + // materials + // + int nNumMaterials = 0; + if (sscanf (szLine, "Materials: %d", &nNumMaterials) == 1) + { + int i; + char szName[MS_MAX_NAME]; + + for (i = 0; i < nNumMaterials && !bError; i++) + { + m_pModel->Materials.resize( m_pModel->Materials.size() ); + msMaterial& Material = m_pModel->Materials.back(); + + // name + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + if (sscanf (szLine, "\"%[^\"]\"", szName) != 1) + { + bError = true; + break; + } + strcpy( Material.szName, szName ); + + // ambient + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + msVec4 Ambient; + if (sscanf (szLine, "%f %f %f %f", &Ambient.v[0], &Ambient.v[1], &Ambient.v[2], &Ambient.v[3]) != 4) + { + bError = true; + break; + } + memcpy( &Material.Ambient, &Ambient, sizeof(Material.Ambient) ); + + // diffuse + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + msVec4 Diffuse; + if (sscanf (szLine, "%f %f %f %f", &Diffuse.v[0], &Diffuse.v[1], &Diffuse.v[2], &Diffuse.v[3]) != 4) + { + bError = true; + break; + } + memcpy( &Material.Diffuse, &Diffuse, sizeof(Material.Diffuse) ); + + // specular + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + msVec4 Specular; + if (sscanf (szLine, "%f %f %f %f", &Specular.v[0], &Specular.v[1], &Specular.v[2], &Specular.v[3]) != 4) + { + bError = true; + break; + } + memcpy( &Material.Specular, &Specular, sizeof(Material.Specular) ); + + // emissive + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + msVec4 Emissive; + if (sscanf (szLine, "%f %f %f %f", &Emissive.v[0], &Emissive.v[1], &Emissive.v[2], &Emissive.v[3]) != 4) + { + bError = true; + break; + } + memcpy( &Material.Emissive, &Emissive, sizeof(Material.Emissive) ); + + // shininess + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + float fShininess; + if (sscanf (szLine, "%f", &fShininess) != 1) + { + bError = true; + break; + } + Material.fShininess = fShininess; + + // transparency + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + float fTransparency; + if (sscanf (szLine, "%f", &fTransparency) != 1) + { + bError = true; + break; + } + Material.fTransparency = 1.0f; + + // diffuse texture + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + if (sscanf (szLine, "\"%[^\"]\"", szName) != 1) + { + bError = true; + break; + } + strcpy( Material.szDiffuseTexture, szName ); + + // alpha texture + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + strcpy (szName, ""); + sscanf (szLine, "\"%[^\"]\"", szName); + + strcpy( Material.szAlphaTexture, szName ); + } + } + + // + // bones + // + int nNumBones = 0; + if (sscanf (szLine, "Bones: %d", &nNumBones) == 1) + { + int i; + char szName[MS_MAX_NAME]; + + for (i = 0; i < nNumBones && !bError; i++) + { + m_pModel->Bones.resize( m_pModel->Bones.size()+1 ); + msBone& Bone = m_pModel->Bones.back(); + + // name + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + if (sscanf (szLine, "\"%[^\"]\"", szName) != 1) + { + bError = true; + break; + } + strcpy( Bone.szName, szName ); + + // alpha texture + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + strcpy (szName, ""); + sscanf (szLine, "\"%[^\"]\"", szName); + + strcpy( Bone.szParentName, szName ); + + // flags, position, rotation + msVec3 Position, Rotation; + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + if (sscanf (szLine, "%d %f %f %f %f %f %f", + &nFlags, + &Position.v[0], &Position.v[1], &Position.v[2], + &Rotation.v[0], &Rotation.v[1], &Rotation.v[2]) != 7) + { + bError = true; + break; + } + Bone.nFlags = nFlags; + memcpy( &Bone.Position, &Position, sizeof(Bone.Position) ); + memcpy( &Bone.Rotation, &Rotation, sizeof(Bone.Rotation) ); + + float fTime; + + // position key count + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + int nNumPositionKeys = 0; + if (sscanf (szLine, "%d", &nNumPositionKeys) != 1) + { + bError = true; + break; + } + + for (j = 0; j < nNumPositionKeys; j++) + { + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + if (sscanf (szLine, "%f %f %f %f", &fTime, &Position[0], &Position[1], &Position[2]) != 4) + { + bError = true; + break; + } + + msPositionKey key = { fTime, { Position[0], Position[1], Position[2] } }; + Bone.PositionKeys.push_back( key ); + } + + // rotation key count + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + int nNumRotationKeys = 0; + if (sscanf (szLine, "%d", &nNumRotationKeys) != 1) + { + bError = true; + break; + } + + for (j = 0; j < nNumRotationKeys; j++) + { + if (!fgets (szLine, 256, file)) + { + bError = true; + break; + } + if (sscanf (szLine, "%f %f %f %f", &fTime, &Rotation[0], &Rotation[1], &Rotation[2]) != 4) + { + bError = true; + break; + } + + msRotationKey key = { fTime, { Rotation[0], Rotation[1], Rotation[2] } }; + Bone.RotationKeys.push_back( key ); + } + } + } + } + + fclose (file); + + SetupBones (); + + return true; +} + +void Model::DrawPrimitives() +{ + if (!m_pModel) + return; + + DISPLAY->SetTexture( NULL ); + DISPLAY->SetBlendModeNormal(); + + for (int i = 0; i < (int)m_pModel->Meshes.size(); i++) + { + msMesh *pMesh = &m_pModel->Meshes[i]; + for (int j = 0; j < (int)pMesh->Triangles.size(); j++) + { + RageVertex verts[3]; + + msTriangle *pTriangle = &pMesh->Triangles[j]; + word nIndices[3], nNormalIndices[3]; + memcpy( nIndices, pTriangle->nVertexIndices, sizeof(nIndices) ); + memcpy( nNormalIndices, pTriangle->nNormalIndices, sizeof(nNormalIndices) ); + for (int k = 0; k < 3; k++) + { + msVertex *pVertex = &pMesh->Vertices[ nIndices[k] ]; + RageVertex& v = verts[k]; + v.c = RageColor(1,1,1,1); + if (pVertex->nBoneIndex == -1) + { + v.p.x = pVertex->Vertex[0]; + v.p.y = pVertex->Vertex[1]; + v.p.z = pVertex->Vertex[2]; + } + else + { + msVec3 Vertex; + VectorRotate (pVertex->Vertex, m_pBones[pVertex->nBoneIndex].mFinal, Vertex); + Vertex[0] += m_pBones[pVertex->nBoneIndex].mFinal[0][3]; + Vertex[1] += m_pBones[pVertex->nBoneIndex].mFinal[1][3]; + Vertex[2] += m_pBones[pVertex->nBoneIndex].mFinal[2][3]; + v.p.x = Vertex[0]; + v.p.y = Vertex[1]; + v.p.z = Vertex[2]; + } + } + DISPLAY->DrawTriangles( verts, 3 ); + } + } +} + +float +Model::CalcDistance () const +{ + float dx = m_vMaxs[0] - m_vMins[0]; + float dy = m_vMaxs[1] - m_vMins[1]; + float dz = m_vMaxs[2] - m_vMins[2]; + float d = dx; + if (dy > d) + d = dy; + if (dz > d) + d = dz; + + return d; +} + +void +Model::SetupBones () +{ + int nBoneCount = (int)m_pModel->Bones.size(); + if (!m_pBones) + { + m_pBones = new myBone_t[nBoneCount]; + } + + int i, j; + for (i = 0; i < nBoneCount; i++) + { + msBone *pBone = &m_pModel->Bones[i]; + msVec3 vRot; + vRot[0] = pBone->Rotation[0] * 180 / (float) Q_PI; + vRot[1] = pBone->Rotation[1] * 180 / (float) Q_PI; + vRot[2] = pBone->Rotation[2] * 180 / (float) Q_PI; + AngleMatrix (vRot, m_pBones[i].mRelative); + m_pBones[i].mRelative[0][3] = pBone->Position[0]; + m_pBones[i].mRelative[1][3] = pBone->Position[1]; + m_pBones[i].mRelative[2][3] = pBone->Position[2]; + + int nParentBone = m_pModel->FindBoneByName( pBone->szParentName ); + if (nParentBone != -1) + { + R_ConcatTransforms (m_pBones[nParentBone].mAbsolute, m_pBones[i].mRelative, m_pBones[i].mAbsolute); + memcpy (m_pBones[i].mFinal, m_pBones[i].mAbsolute, sizeof (matrix_t)); + } + else + { + memcpy (m_pBones[i].mAbsolute, m_pBones[i].mRelative, sizeof (matrix_t)); + memcpy (m_pBones[i].mFinal, m_pBones[i].mRelative, sizeof (matrix_t)); + } + } + + for (i = 0; i < m_pModel->Meshes.size(); i++) + { + msMesh *pMesh = &m_pModel->Meshes[i]; + for (j = 0; j < (int)pMesh->Vertices.size(); j++) + { + msVertex *pVertex = &pMesh->Vertices[j]; + if (pVertex->nBoneIndex != -1) + { + pVertex->Vertex[0] -= m_pBones[pVertex->nBoneIndex].mAbsolute[0][3]; + pVertex->Vertex[1] -= m_pBones[pVertex->nBoneIndex].mAbsolute[1][3]; + pVertex->Vertex[2] -= m_pBones[pVertex->nBoneIndex].mAbsolute[2][3]; + msVec3 vTmp; + VectorIRotate (pVertex->Vertex, m_pBones[pVertex->nBoneIndex].mAbsolute, vTmp); + VectorCopy (vTmp, pVertex->Vertex); + } + } + } + + m_fCurrFrame = (float) m_pModel->nFrame; +} + +void +Model::AdvanceFrame (float dt) +{ + if (!m_pModel) + return; + + m_fCurrFrame += dt; + if (m_fCurrFrame > (float) m_pModel->nTotalFrames) + m_fCurrFrame = 0.0f; + + int nBoneCount = (int)m_pModel->Bones.size(); + int i, j; + for (i = 0; i < nBoneCount; i++) + { + msBone *pBone = &m_pModel->Bones[i]; + int nPositionKeyCount = pBone->PositionKeys.size(); + int nRotationKeyCount = pBone->RotationKeys.size(); + if (nPositionKeyCount == 0 && nRotationKeyCount == 0) + { + memcpy (m_pBones[i].mFinal, m_pBones[i].mAbsolute, sizeof (matrix_t)); + } + else + { + msVec3 vPos; + msVec4 vRot; + // + // search for the adjaced position keys + // + msPositionKey *pLastPositionKey = 0, *pThisPositionKey = 0; + for (j = 0; j < nPositionKeyCount; j++) + { + msPositionKey *pPositionKey = &pBone->PositionKeys[j]; + if (pPositionKey->fTime >= m_fCurrFrame) + { + pThisPositionKey = pPositionKey; + break; + } + pLastPositionKey = pPositionKey; + } + if (pLastPositionKey != 0 && pThisPositionKey != 0) + { + float d = pThisPositionKey->fTime - pLastPositionKey->fTime; + float s = (m_fCurrFrame - pLastPositionKey->fTime) / d; + vPos[0] = pLastPositionKey->Position[0] + (pThisPositionKey->Position[0] - pLastPositionKey->Position[0]) * s; + vPos[1] = pLastPositionKey->Position[1] + (pThisPositionKey->Position[1] - pLastPositionKey->Position[1]) * s; + vPos[2] = pLastPositionKey->Position[2] + (pThisPositionKey->Position[2] - pLastPositionKey->Position[2]) * s; + } + else if (pLastPositionKey == 0) + { + VectorCopy (pThisPositionKey->Position, vPos); + } + else if (pThisPositionKey == 0) + { + VectorCopy (pLastPositionKey->Position, vPos); + } + // + // search for the adjaced rotation keys + // + matrix_t m; + msRotationKey *pLastRotationKey = 0, *pThisRotationKey = 0; + for (j = 0; j < nRotationKeyCount; j++) + { + msRotationKey *pRotationKey = &pBone->RotationKeys[j]; + if (pRotationKey->fTime >= m_fCurrFrame) + { + pThisRotationKey = pRotationKey; + break; + } + pLastRotationKey = pRotationKey; + } + if (pLastRotationKey != 0 && pThisRotationKey != 0) + { + float d = pThisRotationKey->fTime - pLastRotationKey->fTime; + float s = (m_fCurrFrame - pLastRotationKey->fTime) / d; +#if 1 + msVec4 q1, q2, q; + AngleQuaternion (pLastRotationKey->Rotation, q1); + AngleQuaternion (pThisRotationKey->Rotation, q2); + QuaternionSlerp (q1, q2, s, q); + QuaternionMatrix (q, m); +#else + vRot[0] = pLastRotationKey->Rotation[0] + (pThisRotationKey->Rotation[0] - pLastRotationKey->Rotation[0]) * s; + vRot[1] = pLastRotationKey->Rotation[1] + (pThisRotationKey->Rotation[1] - pLastRotationKey->Rotation[1]) * s; + vRot[2] = pLastRotationKey->Rotation[2] + (pThisRotationKey->Rotation[2] - pLastRotationKey->Rotation[2]) * s; + vRot[0] *= 180 / (float) Q_PI; + vRot[1] *= 180 / (float) Q_PI; + vRot[2] *= 180 / (float) Q_PI; + AngleMatrix (vRot, m); +#endif + } + else if (pLastRotationKey == 0) + { + vRot[0] = pThisRotationKey->Rotation[0] * 180 / (float) Q_PI; + vRot[1] = pThisRotationKey->Rotation[1] * 180 / (float) Q_PI; + vRot[2] = pThisRotationKey->Rotation[2] * 180 / (float) Q_PI; + AngleMatrix (vRot, m); + } + else if (pThisRotationKey == 0) + { + vRot[0] = pLastRotationKey->Rotation[0] * 180 / (float) Q_PI; + vRot[1] = pLastRotationKey->Rotation[1] * 180 / (float) Q_PI; + vRot[2] = pLastRotationKey->Rotation[2] * 180 / (float) Q_PI; + AngleMatrix (vRot, m); + } + m[0][3] = vPos[0]; + m[1][3] = vPos[1]; + m[2][3] = vPos[2]; + R_ConcatTransforms (m_pBones[i].mRelative, m, m_pBones[i].mRelativeFinal); + int nParentBone = m_pModel->FindBoneByName( pBone->szParentName ); + if (nParentBone == -1) + { + memcpy (m_pBones[i].mFinal, m_pBones[i].mRelativeFinal, sizeof (matrix_t)); + } + else + { + R_ConcatTransforms (m_pBones[nParentBone].mFinal, m_pBones[i].mRelativeFinal, m_pBones[i].mFinal); + } + } + } +} + +void Model::Update( float fDelta ) +{ + AdvanceFrame( fDelta ); +} \ No newline at end of file diff --git a/stepmania/src/Model.h b/stepmania/src/Model.h new file mode 100644 index 0000000000..841524600c --- /dev/null +++ b/stepmania/src/Model.h @@ -0,0 +1,55 @@ +#ifndef Model_H +#define Model_H +/* +----------------------------------------------------------------------------- + Class: Model + + Desc: A 3D model. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Actor.h" +#include "RageTypes.h" + +struct msModel; + +typedef float matrix_t[3][4]; +typedef struct +{ + matrix_t mRelative; + matrix_t mAbsolute; + matrix_t mRelativeFinal; + matrix_t mFinal; +} myBone_t; + + +class Model : public Actor +{ +public: + Model (); + virtual ~Model (); + +public: + void Clear (); + bool Load(const char *szFilename); + + virtual void Update( float fDelta ); + virtual void DrawPrimitives(); + + float CalcDistance () const; + void SetupBones (); + void AdvanceFrame (float dt); + +private: + msModel *m_pModel; + RageVector3 m_vMins, m_vMaxs; + myBone_t *m_pBones; + float m_fCurrFrame; +}; + + + +#endif diff --git a/stepmania/src/RageDisplay.cpp b/stepmania/src/RageDisplay.cpp index 575e06d868..be5e5bbb4d 100644 --- a/stepmania/src/RageDisplay.cpp +++ b/stepmania/src/RageDisplay.cpp @@ -7,6 +7,7 @@ Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. Chris Danford + Glenn Maynard ----------------------------------------------------------------------------- */ @@ -469,6 +470,14 @@ void RageDisplay::DrawStrip( const RageVertex v[], int iNumVerts ) g_iVertsRenderedSinceLastCheck += iNumVerts; } +void RageDisplay::DrawTriangles( const RageVertex v[], int iNumVerts ) +{ + ASSERT( iNumVerts >= 3 ); + glInterleavedArrays( RageVertexFormat, sizeof(RageVertex), v ); + glDrawArrays( GL_TRIANGLES, 0, iNumVerts ); + g_iVertsRenderedSinceLastCheck += iNumVerts; +} + /* Draw a line as a quad. GL_LINES with antialiasing off can draw line * ends at odd angles--they're forced to axis-alignment regardless of the * angle of the line. */ diff --git a/stepmania/src/RageDisplay.h b/stepmania/src/RageDisplay.h index 40364c1ae5..2e1360175f 100644 --- a/stepmania/src/RageDisplay.h +++ b/stepmania/src/RageDisplay.h @@ -72,6 +72,7 @@ public: void DrawQuads( const RageVertex v[], int iNumVerts ); void DrawFan( const RageVertex v[], int iNumVerts ); void DrawStrip( const RageVertex v[], int iNumVerts ); + void DrawTriangles( const RageVertex v[], int iNumVerts ); void DrawLoop( const RageVertex v[], int iNumVerts, float LineWidth ); void DrawLoop_LinesAndPoints( const RageVertex v[], int iNumVerts, float LineWidth ); void DrawLoop_Polys( const RageVertex v[], int iNumVerts, float LineWidth ); diff --git a/stepmania/src/ScreenSandbox.cpp b/stepmania/src/ScreenSandbox.cpp index e146af1b46..e4b2e49f70 100644 --- a/stepmania/src/ScreenSandbox.cpp +++ b/stepmania/src/ScreenSandbox.cpp @@ -30,9 +30,10 @@ ScreenSandbox::ScreenSandbox() : Screen("ScreenSandbox") // m_sprite.SetXY( CENTER_X, CENTER_Y ); // this->AddChild( &m_sprite ); - obj.SetXY(CENTER_X, CENTER_Y); -// obj.SetZoom(50); - this->AddChild(&obj); + m_model.SetXY(CENTER_X, CENTER_Y); + m_model.SetZoom(10); + m_model.Load( "bend.txt" ); + this->AddChild(&m_model); this->AddChild( &m_In ); diff --git a/stepmania/src/ScreenSandbox.h b/stepmania/src/ScreenSandbox.h index 176af958f2..b8f9b916f1 100644 --- a/stepmania/src/ScreenSandbox.h +++ b/stepmania/src/ScreenSandbox.h @@ -12,7 +12,7 @@ */ #include "Screen.h" -#include "Sample3dObject.h" +#include "Model.h" #include "Quad.h" #include "Transition.h" @@ -28,7 +28,7 @@ public: void MenuRight( PlayerNumber pn ); void Update(float f); - Sample3dObject obj; + Model m_model; Quad m_quad; Transition m_In; Transition m_Out; diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index df2eba339c..1a59b34512 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="StepMania" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 60000 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 @@ -57,10 +57,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /pdb:none # Begin Special Build Tool IntDir=.\../Release6 -TargetDir=\temp\stepmania +TargetDir=\stepmania\stepmania TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -92,10 +92,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # Begin Special Build Tool IntDir=.\../Debug6 -TargetDir=\temp\stepmania +TargetDir=\stepmania\stepmania TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -1000,6 +1000,26 @@ SOURCE=.\BitmapText.h # End Source File # Begin Source File +SOURCE=.\mathlib.c +# End Source File +# Begin Source File + +SOURCE=.\mathlib.h +# End Source File +# Begin Source File + +SOURCE=.\Milkshape.h +# End Source File +# Begin Source File + +SOURCE=.\Model.cpp +# End Source File +# Begin Source File + +SOURCE=.\Model.h +# End Source File +# Begin Source File + SOURCE=.\Quad.h # End Source File # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 16f5004d85..0106ccfc63 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -1596,6 +1596,15 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ + + + + + + @@ -1605,6 +1614,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ + + + + EQUAL_EPSILON) + return false; + } + + return true; +} + +vec_t Q_rint (vec_t in) +{ + return floor (in + 0.5); +} + +void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc) +{ + vc[0] = va[0] + scale*vb[0]; + vc[1] = va[1] + scale*vb[1]; + vc[2] = va[2] + scale*vb[2]; +} + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +{ + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +vec_t _DotProduct (vec3_t v1, vec3_t v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out) +{ + out[0] = va[0]-vb[0]; + out[1] = va[1]-vb[1]; + out[2] = va[2]-vb[2]; +} + +void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out) +{ + out[0] = va[0]+vb[0]; + out[1] = va[1]+vb[1]; + out[2] = va[2]+vb[2]; +} + +void _VectorCopy (vec3_t in, vec3_t out) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +void _VectorScale (vec3_t v, vec_t scale, vec3_t out) +{ + out[0] = v[0] * scale; + out[1] = v[1] * scale; + out[2] = v[2] * scale; +} + +vec_t VectorNormalize (vec3_t v) +{ + int i; + double length; + +if ( fabs(v[1] - 0.000215956) < 0.0001) +i=1; + + length = 0; + for (i=0 ; i< 3 ; i++) + length += v[i]*v[i]; + length = sqrt (length); + if (length == 0) + return 0; + + for (i=0 ; i< 3 ; i++) + v[i] /= length; + + return length; +} + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void ClearBounds (vec3_t mins, vec3_t maxs) +{ + mins[0] = mins[1] = mins[2] = 99999; + maxs[0] = maxs[1] = maxs[2] = -99999; +} + +void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs) +{ + int i; + vec_t val; + + for (i=0 ; i<3 ; i++) + { + val = v[i]; + if (val < mins[i]) + mins[i] = val; + if (val > maxs[i]) + maxs[i] = val; + } +} + +void AngleMatrix (const vec3_t angles, float (*matrix)[4] ) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + + angle = angles[2] * (Q_PI*2 / 360); + sy = sin(angle); + cy = cos(angle); + angle = angles[1] * (Q_PI*2 / 360); + sp = sin(angle); + cp = cos(angle); + angle = angles[0] * (Q_PI*2 / 360); + sr = sin(angle); + cr = cos(angle); + + // matrix = (Z * Y) * X + matrix[0][0] = cp*cy; + matrix[1][0] = cp*sy; + matrix[2][0] = -sp; + matrix[0][1] = sr*sp*cy+cr*-sy; + matrix[1][1] = sr*sp*sy+cr*cy; + matrix[2][1] = sr*cp; + matrix[0][2] = (cr*sp*cy+-sr*-sy); + matrix[1][2] = (cr*sp*sy+-sr*cy); + matrix[2][2] = cr*cp; + matrix[0][3] = 0.0; + matrix[1][3] = 0.0; + matrix[2][3] = 0.0; +} + +void AngleIMatrix (const vec3_t angles, float matrix[3][4] ) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + + angle = angles[2] * (Q_PI*2 / 360); + sy = sin(angle); + cy = cos(angle); + angle = angles[1] * (Q_PI*2 / 360); + sp = sin(angle); + cp = cos(angle); + angle = angles[0] * (Q_PI*2 / 360); + sr = sin(angle); + cr = cos(angle); + + // matrix = (Z * Y) * X + matrix[0][0] = cp*cy; + matrix[0][1] = cp*sy; + matrix[0][2] = -sp; + matrix[1][0] = sr*sp*cy+cr*-sy; + matrix[1][1] = sr*sp*sy+cr*cy; + matrix[1][2] = sr*cp; + matrix[2][0] = (cr*sp*cy+-sr*-sy); + matrix[2][1] = (cr*sp*sy+-sr*cy); + matrix[2][2] = cr*cp; + matrix[0][3] = 0.0; + matrix[1][3] = 0.0; + matrix[2][3] = 0.0; +} + +void R_ConcatTransforms (const float in1[3][4], const float in2[3][4], float out[3][4]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + + in1[0][2] * in2[2][3] + in1[0][3]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + + in1[1][2] * in2[2][3] + in1[1][3]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; + out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + + in1[2][2] * in2[2][3] + in1[2][3]; +} + + + +void VectorRotate (const vec3_t in1, const float in2[3][4], vec3_t out) +{ + out[0] = DotProduct(in1, in2[0]); + out[1] = DotProduct(in1, in2[1]); + out[2] = DotProduct(in1, in2[2]); +} + + +// rotate by the inverse of the matrix +void VectorIRotate (const vec3_t in1, const float in2[3][4], vec3_t out) +{ + out[0] = in1[0]*in2[0][0] + in1[1]*in2[1][0] + in1[2]*in2[2][0]; + out[1] = in1[0]*in2[0][1] + in1[1]*in2[1][1] + in1[2]*in2[2][1]; + out[2] = in1[0]*in2[0][2] + in1[1]*in2[1][2] + in1[2]*in2[2][2]; +} + + +void VectorTransform (const vec3_t in1, const float in2[3][4], vec3_t out) +{ + out[0] = DotProduct(in1, in2[0]) + in2[0][3]; + out[1] = DotProduct(in1, in2[1]) + in2[1][3]; + out[2] = DotProduct(in1, in2[2]) + in2[2][3]; +} + + + +void AngleQuaternion( const vec3_t angles, vec4_t quaternion ) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + + // FIXME: rescale the inputs to 1/2 angle + angle = angles[2] * 0.5; + sy = sin(angle); + cy = cos(angle); + angle = angles[1] * 0.5; + sp = sin(angle); + cp = cos(angle); + angle = angles[0] * 0.5; + sr = sin(angle); + cr = cos(angle); + + quaternion[0] = sr*cp*cy-cr*sp*sy; // X + quaternion[1] = cr*sp*cy+sr*cp*sy; // Y + quaternion[2] = cr*cp*sy-sr*sp*cy; // Z + quaternion[3] = cr*cp*cy+sr*sp*sy; // W +} + +void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] ) +{ + + matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2]; + matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2]; + matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1]; + + matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2]; + matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2]; + matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0]; + + matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1]; + matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0]; + matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1]; +} + +void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt ) +{ + int i; + float omega, cosom, sinom, sclp, sclq; + + // decide if one of the quaternions is backwards + float a = 0; + float b = 0; + for (i = 0; i < 4; i++) { + a += (p[i]-q[i])*(p[i]-q[i]); + b += (p[i]+q[i])*(p[i]+q[i]); + } + if (a > b) { + for (i = 0; i < 4; i++) { + q[i] = -q[i]; + } + } + + cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; + + if ((1.0 + cosom) > 0.00000001) { + if ((1.0 - cosom) > 0.00000001) { + omega = acos( cosom ); + sinom = sin( omega ); + sclp = sin( (1.0 - t)*omega) / sinom; + sclq = sin( t*omega ) / sinom; + } + else { + sclp = 1.0 - t; + sclq = t; + } + for (i = 0; i < 4; i++) { + qt[i] = sclp * p[i] + sclq * q[i]; + } + } + else { + qt[0] = -p[1]; + qt[1] = p[0]; + qt[2] = -p[3]; + qt[3] = p[2]; + sclp = sin( (1.0 - t) * 0.5 * Q_PI); + sclq = sin( t * 0.5 * Q_PI); + for (i = 0; i < 3; i++) { + qt[i] = sclp * p[i] + sclq * qt[i]; + } + } +} + +void VecToAngles( const vec3_t value1, vec3_t angles ) +{ + float forward; + float yaw, pitch; + + if ( value1[1] == 0 && value1[0] == 0 ) { + yaw = 0; + if ( value1[2] > 0 ) { + pitch = 90; + } + else { + pitch = 270; + } + } + else { + if ( value1[0] ) { + yaw = ( atan2 ( value1[1], value1[0] ) * 180 / Q_PI ); + } + else if ( value1[1] > 0 ) { + yaw = 90; + } + else { + yaw = 270; + } + if ( yaw < 0 ) { + yaw += 360; + } + + forward = sqrt ( value1[0]*value1[0] + value1[1]*value1[1] ); + pitch = ( atan2(value1[2], forward) * 180 / Q_PI ); + if ( pitch < 0 ) { + pitch += 360; + } + } + + angles[0] = -pitch; + angles[1] = yaw; + angles[2] = 0; +} + +float AngleNormalize360 ( float angle ) +{ + return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535); +} diff --git a/stepmania/src/mathlib.h b/stepmania/src/mathlib.h new file mode 100644 index 0000000000..d5863ca7fe --- /dev/null +++ b/stepmania/src/mathlib.h @@ -0,0 +1,92 @@ +/*** +* +* Copyright (c) 1998, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +****/ + +#ifndef __MATHLIB__ +#define __MATHLIB__ + +// mathlib.h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DOUBLEVEC_T +typedef double vec_t; +#else +typedef float vec_t; +#endif +typedef vec_t vec3_t[3]; // x,y,z +typedef vec_t vec4_t[4]; // x,y,z,w + +#define SIDE_FRONT 0 +#define SIDE_ON 2 +#define SIDE_BACK 1 +#define SIDE_CROSS -2 + +#define Q_PI 3.14159265358979323846 + +//extern vec3_t vec3_origin; + +// Use this definition globally +#define ON_EPSILON 0.01 +#define EQUAL_EPSILON 0.001 + +int VectorCompare (vec3_t v1, vec3_t v2); + +#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) +#define VectorFill(a,b) { (a)[0]=(b); (a)[1]=(b); (a)[2]=(b);} +#define VectorAvg(a) ( ( (a)[0] + (a)[1] + (a)[2] ) / 3 ) +#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} +#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} +#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} +#define VectorScale(a,b,c) {(c)[0]=(b)*(a)[0];(c)[1]=(b)*(a)[1];(c)[2]=(b)*(a)[2];} + +vec_t Q_rint (vec_t in); +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out); +void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out); +void _VectorCopy (vec3_t in, vec3_t out); +void _VectorScale (vec3_t v, vec_t scale, vec3_t out); + +double VectorLength(vec3_t v); + +void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc); + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +vec_t VectorNormalize (vec3_t v); +void VectorInverse (vec3_t v); + +void ClearBounds (vec3_t mins, vec3_t maxs); +void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); + +void AngleMatrix (const vec3_t angles, float matrix[3][4] ); +void AngleIMatrix (const vec3_t angles, float matrix[3][4] ); +void R_ConcatTransforms (const float in1[3][4], const float in2[3][4], float out[3][4]); + +void VectorIRotate (const vec3_t in1, const float in2[3][4], vec3_t out); +void VectorRotate (const vec3_t in1, const float in2[3][4], vec3_t out); + +void VectorTransform (const vec3_t in1, const float in2[3][4], vec3_t out); + +void AngleQuaternion( const vec3_t angles, vec4_t quaternion ); +void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] ); +void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt ); + +void VecToAngles( const vec3_t value1, vec3_t angles ); +float AngleNormalize360 ( float angle ); + + +#ifdef __cplusplus +} +#endif + +#endif