├── .gitignore ├── README.md ├── example_Butterfly ├── Makefile ├── Project.xcconfig ├── addons.make ├── bin │ └── data │ │ └── .gitkeep ├── config.make ├── example_Butterfly.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ ├── example_Butterfly Debug.xcscheme │ │ │ └── example_Butterfly Release.xcscheme │ └── xcuserdata │ │ └── Abhi.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── openFrameworks-Info.plist └── src │ ├── main.cpp │ ├── ofApp.cpp │ ├── ofApp.h │ ├── ofxAnimatable.cpp │ ├── ofxAnimatable.h │ ├── ofxAnimatableFloat.cpp │ ├── ofxAnimatableFloat.h │ ├── ofxAnimatableOfColor.cpp │ ├── ofxAnimatableOfColor.h │ ├── ofxAnimatableOfPoint.cpp │ └── ofxAnimatableOfPoint.h ├── example_SineWaves ├── Makefile ├── Project.xcconfig ├── addons.make ├── bin │ └── data │ │ └── .gitkeep ├── config.make ├── example_SineWaves.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ ├── example_SineWaves Debug.xcscheme │ │ │ └── example_SineWaves Release.xcscheme │ └── xcuserdata │ │ └── Abhi.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── openFrameworks-Info.plist └── src │ ├── MyEquations.h │ ├── main.cpp │ ├── ofApp.cpp │ ├── ofApp.h │ ├── ofxAnimatable.cpp │ ├── ofxAnimatable.h │ ├── ofxAnimatableFloat.cpp │ ├── ofxAnimatableFloat.h │ ├── ofxAnimatableOfColor.cpp │ ├── ofxAnimatableOfColor.h │ ├── ofxAnimatableOfPoint.cpp │ └── ofxAnimatableOfPoint.h ├── example_simple ├── Makefile ├── Project.xcconfig ├── addons.make ├── bin │ └── data │ │ ├── .gitkeep │ │ ├── flower.jpg │ │ └── verdana.ttf ├── config.make ├── example_simple.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ ├── example_simple Debug.xcscheme │ │ │ └── example_simple Release.xcscheme │ └── xcuserdata │ │ └── Abhi.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── openFrameworks-Info.plist └── src │ ├── MyEquations.h │ ├── main.cpp │ ├── ofApp.cpp │ ├── ofApp.h │ ├── ofxAnimatable.cpp │ ├── ofxAnimatable.h │ ├── ofxAnimatableFloat.cpp │ ├── ofxAnimatableFloat.h │ ├── ofxAnimatableOfColor.cpp │ ├── ofxAnimatableOfColor.h │ ├── ofxAnimatableOfPoint.cpp │ └── ofxAnimatableOfPoint.h └── src ├── ofx2dFunction.cpp ├── ofx2dFunction.h ├── ofx3dFunction.cpp ├── ofx3dFunction.h ├── ofxMathCurve.cpp ├── ofxMathCurve.h ├── ofxMathMesh.h ├── ofxMathSurface.cpp ├── ofxMathSurface.h ├── ofxParametricCurve.cpp ├── ofxParametricCurve.h ├── ofxParametricSurface.cpp └── ofxParametricSurface.h /.gitignore: -------------------------------------------------------------------------------- 1 | example_simple/bin/example_simpleDebug.app 2 | example_SineWaves/bin/example_SineWavesDebug.app 3 | example_Butterfly/bin/example_ButterflyDebug.app 4 | 5 | *.xcuserstate 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ofxMathMesh 2 | 3 | ofxMathMesh allows you to create ofMeshs form mathematical equations. You can create meshes from 3dFunctions, 2dFunctions, Parametric Surfaces and Parametric Curves 4 | 5 | you can see a small demo here - [https://vimeo.com/98150899](https://vimeo.com/98150899) 6 | 7 | ## Features 8 | 9 | * Creates Meshes from 3d Functions, 2d Functions, Parametric Surfaces and Parametric Curves 10 | 11 | * Auto Calculates Surface Normals 12 | 13 | * Customize Colors and TexCoords on both Front and Back Sides 14 | 15 | * Draw wireframe and point meshes with customized color. 16 | 17 | * Control bounds and resolution of your mesh 18 | 19 | 20 | ## How to Use 21 | 22 | #### Step 1 - create a subclass 23 | 24 | you can subclass from anyone of these parents: 25 | 26 | * `ofx3dFunction` - if your equation is of the form y = f(x,z) 27 | * `ofx2dFuntion` - if your equation is of the form y = f(x) 28 | * `ofxParametricSurface` - if your equation is of the form r = r(u,v) 29 | * `ofxParametrixCurve` - if your equation is of the form r = r(t) 30 | 31 | For Example to create a Sphere(which is a parametric Surface) you do this: 32 | 33 | ``` 34 | class Sphere:public ofxParametricSurface 35 | ``` 36 | #### Step 2 - override 37 | in order to customize your mesh you must override one or more of the following functions: 38 | 39 | * `valueForPoint` - mandatory 40 | * `colorForPoint` - optional 41 | * `texCoordForPoint` - optional 42 | * `backColorForPoint`- optional 43 | * `backTexCoordForPoint` - optional 44 | 45 | For example to create a Sphere thats half red half blue you do this: 46 | 47 | ``` 48 | class Sphere:public ofxParametricSurface { 49 | public: 50 | ofPoint valueForPoint(float u, float v){ 51 | float x = cos(u) * sin(v); 52 | float y = sin(u) * sin(v); 53 | float z = cos(v); 54 | return ofPoint(x,y,z); 55 | } 56 | 57 | ofFloatColor colorForPoint(float u,float v,ofPoint value){ 58 | if (u > M_PI && u < 2*M_PI - .0001) { 59 | return ofFloatColor::blue; 60 | }else{ 61 | return ofFloatColor::red; 62 | } 63 | } 64 | 65 | }; 66 | 67 | ``` 68 | 69 | #### Step 4 - call setup 70 | 71 | `setup` must be called in order to create a mesh. In `setup` you specify the bounds and step of your equation. Lower step means higher resolutions. 72 | For example to set up a full sphere you do this: 73 | 74 | ``` 75 | Sphere mySphere; 76 | mySphere.setup(0, 2*M_PI, 0, M_PI, .1, .1); 77 | ``` 78 | here *u* goes form 0 to 2PI, *v* goes from 0 to PI, and uStep = .1, and vStep = .1. Note that if you want to change the bounds of the equation after setup,you cannot go outside the initial setup bounds. 79 | 80 | #### Step 5 - call draw 81 | 82 | to draw your equation you call either `draw ` , `drawWireFrame`, or `drawPoints` 83 | 84 | ``` 85 | mySphere.draw(true, false); 86 | mySphere.drawWireFrame(true); 87 | mySphere.drawPoints(true); 88 | ``` 89 | The 1st argument specifies whether you over-rid `colorForPoint`. The 2nd argument specifies whether you over-rid `texCoordForPoint`. The results looks like this 90 | 91 | ![draw](https://farm4.staticflickr.com/3868/14408118032_2d009e8fee_m.jpg) 92 | 93 | ![drawWireFrame](https://farm3.staticflickr.com/2905/14429600343_d3c075614b_m.jpg) 94 | 95 | ![drawPoints](https://farm4.staticflickr.com/3887/14222986297_d353a68c9f_m.jpg) 96 | 97 | 98 | 99 | #### Step 6 - reloading 100 | 101 | whenever to you update your equation, colors, texcoords,or bounds.You want to call `reload()` 102 | 103 | ``` 104 | mySphere.reload() 105 | ``` 106 | this is useful for animation and live updates of your equation. If you are reloading constantly its a good idea to call this in the `update()` function. 107 | 108 | #### Step 7 - drawing two sided 109 | 110 | if you want to have different colors and textures on front and backside, you need to implement either `backColorForPoint` or `backTexCoordForPoint`. Then call the functions `drawFrontFaces` and `drawBackFaces` 111 | 112 | For example to draw a sphere that is red and blue on the front and green and yellow on the back, you would do this. 113 | 114 | ``` 115 | 116 | class Sphere:public ofxParametricSurface { 117 | public: 118 | ofPoint valueForPoint(float u, float v){ 119 | float x = cos(u)* sin(v); 120 | float y = sin(u)* sin(v); 121 | float z = cos(v); 122 | return ofPoint(x,y,z); 123 | } 124 | 125 | ofFloatColor colorForPoint(float u,float v,ofPoint value){ 126 | if (u > M_PI && u < 2*M_PI - .0001) { 127 | return ofFloatColor::blue; 128 | }else{ 129 | return ofFloatColor::red; 130 | } 131 | } 132 | 133 | ofFloatColor backColorForPoint(float u,float v,ofPoint value){ 134 | if (u > M_PI && u < 2*M_PI - .0001) { 135 | return ofFloatColor::green; 136 | }else{ 137 | return ofFloatColor::yellow; 138 | } 139 | } 140 | }; 141 | 142 | ``` 143 | 144 | 145 | ``` 146 | mySphere.setUMax(1.5 *M_PI); 147 | mySphere.reload(); 148 | mySphere.drawFrontFaces(true, false); 149 | mySphere.drawBackFaces(true, false); 150 | ``` 151 | this is the resulting sphere. Draw part open(uMax set to 1.5PI) 152 | 153 | ![2Sided](https://farm4.staticflickr.com/3903/14222817028_4a919cdca0_m.jpg) 154 | 155 | #### step 8 - getting an ofMesh 156 | 157 | You retrieve an ofMesh from your equation by calling `getMesh()` or `getBackMesh` 158 | 159 | ``` 160 | // returns a mesh which with vertices,frontNormals,frontColors,and frontTexCoords 161 | ofMesh myMesh = mySphere.getMesh(); 162 | 163 | // returns a mesh which with vertices,backNormals,backColors,and backTexCoords 164 | ofMesh myBackMesh = mySphere.getBackMesh(); 165 | ``` 166 | 167 | #### step 9 - normals 168 | 169 | Normals are auto calculated using these [formulas](http://mathworld.wolfram.com/NormalVector.html), if you want to draw the normals you can use the functions `drawNormals(float length)` or `drawFaceNormals(float length)` 170 | 171 | ## Extras 172 | There are a lot more things you can do with this add-on so if you have any questions, you can ask me on the [forum thread](http://forum.openframeworks.cc/t/ofxmathmesh-create-meshes-from-mathematical-equations/16099). Remember Have Fun! 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /example_Butterfly/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=../../.. 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example_Butterfly/Project.xcconfig: -------------------------------------------------------------------------------- 1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT. 2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED 3 | OF_PATH = ../../.. 4 | 5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE 6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig" 7 | 8 | //ICONS - NEW IN 0072 9 | ICON_NAME_DEBUG = icon-debug.icns 10 | ICON_NAME_RELEASE = icon.icns 11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/ 12 | 13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to: 14 | //ICON_FILE_PATH = bin/data/ 15 | 16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS) 17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) 18 | -------------------------------------------------------------------------------- /example_Butterfly/addons.make: -------------------------------------------------------------------------------- 1 | ofxMathMesh 2 | -------------------------------------------------------------------------------- /example_Butterfly/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahbee/ofxMathMesh/acd5041b18e1a9cc86f0239a21f8ac4bdbcacaf2/example_Butterfly/bin/data/.gitkeep -------------------------------------------------------------------------------- /example_Butterfly/config.make: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # CONFIGURE PROJECT MAKEFILE (optional) 3 | # This file is where we make project specific configurations. 4 | ################################################################################ 5 | 6 | ################################################################################ 7 | # OF ROOT 8 | # The location of your root openFrameworks installation 9 | # (default) OF_ROOT = ../../.. 10 | ################################################################################ 11 | # OF_ROOT = ../../.. 12 | 13 | ################################################################################ 14 | # PROJECT ROOT 15 | # The location of the project - a starting place for searching for files 16 | # (default) PROJECT_ROOT = . (this directory) 17 | # 18 | ################################################################################ 19 | # PROJECT_ROOT = . 20 | 21 | ################################################################################ 22 | # PROJECT SPECIFIC CHECKS 23 | # This is a project defined section to create internal makefile flags to 24 | # conditionally enable or disable the addition of various features within 25 | # this makefile. For instance, if you want to make changes based on whether 26 | # GTK is installed, one might test that here and create a variable to check. 27 | ################################################################################ 28 | # None 29 | 30 | ################################################################################ 31 | # PROJECT EXTERNAL SOURCE PATHS 32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder. 33 | # Like source folders in the PROJECT_ROOT, these paths are subject to 34 | # exlclusion via the PROJECT_EXLCUSIONS list. 35 | # 36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) 37 | # 38 | # Note: Leave a leading space when adding list items with the += operator 39 | ################################################################################ 40 | # PROJECT_EXTERNAL_SOURCE_PATHS = 41 | 42 | ################################################################################ 43 | # PROJECT EXCLUSIONS 44 | # These makefiles assume that all folders in your current project directory 45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations 46 | # to look for source code. The any folders or files that match any of the 47 | # items in the PROJECT_EXCLUSIONS list below will be ignored. 48 | # 49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete 50 | # string unless teh user adds a wildcard (%) operator to match subdirectories. 51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is 52 | # treated literally. 53 | # 54 | # (default) PROJECT_EXCLUSIONS = (blank) 55 | # 56 | # Will automatically exclude the following: 57 | # 58 | # $(PROJECT_ROOT)/bin% 59 | # $(PROJECT_ROOT)/obj% 60 | # $(PROJECT_ROOT)/%.xcodeproj 61 | # 62 | # Note: Leave a leading space when adding list items with the += operator 63 | ################################################################################ 64 | # PROJECT_EXCLUSIONS = 65 | 66 | ################################################################################ 67 | # PROJECT LINKER FLAGS 68 | # These flags will be sent to the linker when compiling the executable. 69 | # 70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs 71 | # 72 | # Note: Leave a leading space when adding list items with the += operator 73 | ################################################################################ 74 | 75 | # Currently, shared libraries that are needed are copied to the 76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to 77 | # add a runtime path to search for those shared libraries, since they aren't 78 | # incorporated directly into the final executable application binary. 79 | # TODO: should this be a default setting? 80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs 81 | 82 | ################################################################################ 83 | # PROJECT DEFINES 84 | # Create a space-delimited list of DEFINES. The list will be converted into 85 | # CFLAGS with the "-D" flag later in the makefile. 86 | # 87 | # (default) PROJECT_DEFINES = (blank) 88 | # 89 | # Note: Leave a leading space when adding list items with the += operator 90 | ################################################################################ 91 | # PROJECT_DEFINES = 92 | 93 | ################################################################################ 94 | # PROJECT CFLAGS 95 | # This is a list of fully qualified CFLAGS required when compiling for this 96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS 97 | # defined in your platform specific core configuration files. These flags are 98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. 99 | # 100 | # (default) PROJECT_CFLAGS = (blank) 101 | # 102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in 103 | # your platform specific configuration file will be applied by default and 104 | # further flags here may not be needed. 105 | # 106 | # Note: Leave a leading space when adding list items with the += operator 107 | ################################################################################ 108 | # PROJECT_CFLAGS = 109 | 110 | ################################################################################ 111 | # PROJECT OPTIMIZATION CFLAGS 112 | # These are lists of CFLAGS that are target-specific. While any flags could 113 | # be conditionally added, they are usually limited to optimization flags. 114 | # These flags are added BEFORE the PROJECT_CFLAGS. 115 | # 116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. 117 | # 118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) 119 | # 120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. 121 | # 122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) 123 | # 124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the 125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration 126 | # file will be applied by default and further optimization flags here may not 127 | # be needed. 128 | # 129 | # Note: Leave a leading space when adding list items with the += operator 130 | ################################################################################ 131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE = 132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG = 133 | 134 | ################################################################################ 135 | # PROJECT COMPILERS 136 | # Custom compilers can be set for CC and CXX 137 | # (default) PROJECT_CXX = (blank) 138 | # (default) PROJECT_CC = (blank) 139 | # Note: Leave a leading space when adding list items with the += operator 140 | ################################################################################ 141 | # PROJECT_CXX = 142 | # PROJECT_CC = 143 | -------------------------------------------------------------------------------- /example_Butterfly/example_Butterfly.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example_Butterfly/example_Butterfly.xcodeproj/xcshareddata/xcschemes/example_Butterfly Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example_Butterfly/example_Butterfly.xcodeproj/xcshareddata/xcschemes/example_Butterfly Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example_Butterfly/example_Butterfly.xcodeproj/xcuserdata/Abhi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SuppressBuildableAutocreation 6 | 7 | E4B69B5A0A3A1756003C02F2 8 | 9 | primary 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example_Butterfly/openFrameworks-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | cc.openFrameworks.ofapp 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | CFBundleIconFile 20 | ${ICON} 21 | 22 | 23 | -------------------------------------------------------------------------------- /example_Butterfly/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | cam.setPosition(0, 0, 7); 6 | cam.setNearClip(.001); 7 | cam.setAutoDistance(false); 8 | ofSetLineWidth(3.0); 9 | butterfly.setup(0, 6 * M_PI, .01); 10 | 11 | tMax.setCurve(EASE_OUT); 12 | tMax.setRepeatType(LOOP); 13 | tMax.animateFromTo(0, 6 * M_PI); 14 | tMax.setDuration(20.0); 15 | } 16 | 17 | //-------------------------------------------------------------- 18 | void ofApp::update(){ 19 | float dt = 1/ofGetFrameRate(); 20 | tMax.update(dt); 21 | butterfly.setTMax(tMax); 22 | butterfly.reload(); 23 | } 24 | 25 | //-------------------------------------------------------------- 26 | void ofApp::draw(){ 27 | ofBackground(0); 28 | cam.begin(); 29 | ofSetColor(255, 0, 0); 30 | butterfly.draw(false); 31 | cam.end(); 32 | } 33 | 34 | //-------------------------------------------------------------- 35 | void ofApp::keyPressed(int key){ 36 | 37 | } 38 | 39 | //-------------------------------------------------------------- 40 | void ofApp::keyReleased(int key){ 41 | 42 | } 43 | 44 | //-------------------------------------------------------------- 45 | void ofApp::mouseMoved(int x, int y ){ 46 | 47 | } 48 | 49 | //-------------------------------------------------------------- 50 | void ofApp::mouseDragged(int x, int y, int button){ 51 | 52 | } 53 | 54 | //-------------------------------------------------------------- 55 | void ofApp::mousePressed(int x, int y, int button){ 56 | 57 | } 58 | 59 | //-------------------------------------------------------------- 60 | void ofApp::mouseReleased(int x, int y, int button){ 61 | 62 | } 63 | 64 | //-------------------------------------------------------------- 65 | void ofApp::windowResized(int w, int h){ 66 | 67 | } 68 | 69 | //-------------------------------------------------------------- 70 | void ofApp::gotMessage(ofMessage msg){ 71 | 72 | } 73 | 74 | //-------------------------------------------------------------- 75 | void ofApp::dragEvent(ofDragInfo dragInfo){ 76 | 77 | } 78 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxMathMesh.h" 5 | #include "ofxAnimatableFloat.h" 6 | 7 | class Butterfly:public ofxParametricCurve { 8 | ofPoint valueForPoint(float t){ 9 | float p1 = pow((float)M_E, cos(t)); 10 | float p2 = 2 * cos(4*t); 11 | float p3 = pow(sin(t/12.0), 5); 12 | float x = sin(t) * (p1 - p2 -p3); 13 | float y = cos(t) * (p1 - p2 - p3); 14 | return ofPoint(x,y,0); 15 | } 16 | }; 17 | 18 | 19 | class ofApp : public ofBaseApp{ 20 | 21 | public: 22 | void setup(); 23 | void update(); 24 | void draw(); 25 | 26 | void keyPressed(int key); 27 | void keyReleased(int key); 28 | void mouseMoved(int x, int y ); 29 | void mouseDragged(int x, int y, int button); 30 | void mousePressed(int x, int y, int button); 31 | void mouseReleased(int x, int y, int button); 32 | void windowResized(int w, int h); 33 | void dragEvent(ofDragInfo dragInfo); 34 | void gotMessage(ofMessage msg); 35 | 36 | ofEasyCam cam; 37 | Butterfly butterfly; 38 | ofxAnimatableFloat tMax; 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatable.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 30/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatable.h" 11 | 12 | //from http://www.flong.com/texts/code/shapers_exp/ 13 | 14 | float doublePolynomialSigmoid(float x, int n){ 15 | 16 | float y = 0.0f; 17 | if (n%2 == 0){ 18 | // even polynomial 19 | if (x<=0.5f){ 20 | y = pow(2.0f*x, n)/2.0f; 21 | } else { 22 | y = 1.0f - pow(2.0f*(x-1.0f), n)/2.0f; 23 | } 24 | } 25 | 26 | else { 27 | // odd polynomial 28 | if (x <= 0.5f){ 29 | y = pow( 2.0f * x, n) / 2.0f; 30 | } else { 31 | y = 1.0 + pow( 2.0f * (x-1.0f), n) / 2.0; 32 | } 33 | } 34 | return y; 35 | } 36 | 37 | float doubleExponentialSigmoid (float x, float a){ 38 | 39 | float epsilon = 0.00001f; 40 | float min_param_a = 0.0f + epsilon; 41 | float max_param_a = 1.0f - epsilon; 42 | a = min(max_param_a, max(min_param_a, a)); 43 | a = 1.0f - a; // for sensible results 44 | 45 | float y = 0.0f; 46 | if ( x <= 0.5f ){ 47 | y = ( pow( 2.0f * x, 1.0f/a) ) / 2.0f; 48 | } else { 49 | y = 1.0 - ( pow( 2.0f * (1.0f-x), 1.0f / a) ) / 2.0f; 50 | } 51 | return y; 52 | } 53 | 54 | float doubleExponentialSeat (float x, float a){ 55 | 56 | float epsilon = 0.00001f; 57 | float min_param_a = 0.0f + epsilon; 58 | float max_param_a = 1.0f - epsilon; 59 | a = min(max_param_a, max(min_param_a, a)); 60 | 61 | float y = 0.0f; 62 | if (x <= 0.5f){ 63 | y = (powf(2.0 * x, 1.0f - a) ) / 2.0f; 64 | } else { 65 | y = 1.0f - ( pow(2.0f * ( 1.0f - x ), 1.0f-a) ) / 2.0f; 66 | } 67 | return y; 68 | } 69 | 70 | 71 | float exponentialEasing (float x, float a){ 72 | 73 | float epsilon = 0.00001; 74 | float min_param_a = 0.0f + epsilon; 75 | float max_param_a = 1.0f - epsilon; 76 | a = max(min_param_a, min(max_param_a, a)); 77 | 78 | if (a < 0.5f){ 79 | // emphasis 80 | a = 2.0f*(a); 81 | float y = pow(x, a); 82 | return y; 83 | } else { 84 | // de-emphasis 85 | a = 2.0f*(a-0.5f); 86 | float y = powf(x, 1.0/(1-a)); 87 | return y; 88 | } 89 | } 90 | 91 | 92 | float quadraticBezier (float x, float a, float b){ 93 | // adapted from BEZMATH.PS (1993) 94 | // by Don Lancaster, SYNERGETICS Inc. 95 | // http://www.tinaja.com/text/bezmath.html 96 | 97 | float epsilon = 0.00001; 98 | a = max(0.0f, min(1.0f, a)); 99 | b = max(0.0f, min(1.0f, b)); 100 | if (a == 0.5f){ 101 | a += epsilon; 102 | } 103 | 104 | // solve t from x (an inverse operation) 105 | float om2a = 1 - 2*a; 106 | float t = (sqrt(a*a + om2a*x) - a)/om2a; 107 | float y = (1-2*b)*(t*t) + (2*b)*t; 108 | return y; 109 | } 110 | 111 | 112 | std::string ofxAnimatable::getCurveName(AnimCurve c){ 113 | 114 | switch (c) { 115 | case EASE_IN_EASE_OUT: return "EASE_IN_EASE_OUT"; 116 | case EASE_IN: return "EASE_IN"; 117 | case EASE_OUT: return "EASE_OUT"; 118 | case LINEAR: return "LINEAR"; 119 | case BOUNCY: return "BOUNCY"; 120 | case TANH: return "TANH"; 121 | case SINH: return "SINH"; 122 | case SQUARE: return "SQUARE"; 123 | case LATE_SQUARE: return "LATE_SQUARE"; 124 | case EARLY_SQUARE: return "EARLY_SQUARE"; 125 | case BLINK_5: return "BLINK_5"; 126 | case BLINK_3: return "BLINK_3"; 127 | case BLINK_2: return "BLINK_2"; 128 | case BLINK_AND_FADE_1: return "BLINK_AND_FADE_1"; 129 | case BLINK_AND_FADE_2: return "BLINK_AND_FADE_2"; 130 | case BLINK_AND_FADE_3: return "BLINK_AND_FADE_3"; 131 | case LATE_LINEAR: return "LATE_LINEAR"; 132 | case LATE_EASE_IN_EASE_OUT: return "LATE_EASE_IN_EASE_OUT"; 133 | case EARLY_LINEAR: return "EARLY_LINEAR"; 134 | case VERY_LATE_LINEAR: return "VERY_LATE_LINEAR"; 135 | case VERY_LATE_EASE_IN_EASE_OUT: return "VERY_LATE_EASE_IN_EASE_OUT"; 136 | case QUADRATIC_EASE_IN: return "QUADRATIC_EASE_IN"; 137 | case QUADRATIC_EASE_OUT: return "QUADRATIC_EASE_OUT"; 138 | case EARLY_QUADRATIC_EASE_OUT: return "EARLY_QUADRATIC_EASE_OUT"; 139 | case QUADRATIC_BEZIER_PARAM: return "QUADRATIC_BEZIER_PARAM"; 140 | case EXPONENTIAL_SIGMOID_PARAM: return "EXPONENTIAL_SIGMOID_PARAM"; 141 | case OBJECT_DROP: return "OBJECT_DROP"; 142 | 143 | default: return "UNKNOWN_CURVE!"; 144 | } 145 | return "error"; 146 | } 147 | 148 | void ofxAnimatable::setup(){ 149 | 150 | doubleExpSigmoidParam = 0.5; 151 | quadraticBezierParamA = 0.25; 152 | quadraticBezierParamB = 0.75; 153 | bounceAmp = 0.05; 154 | transitionSpeed_ = 1.0f / DEFAULT_ANIMATION_DURATION; 155 | percentDone_ = 0.0f; 156 | animating_ = false; 157 | paused_ = false; 158 | direction_ = 1; 159 | playcount_ = 0; 160 | repeat_ = PLAY_ONCE; 161 | curveStyle_ = EASE_IN_EASE_OUT; 162 | currentSpeed_ = 0.0f; 163 | lastDT_ = 1; 164 | waitTime_ = 0.0f; 165 | delay_ = 0.0f; 166 | } 167 | 168 | void ofxAnimatable::drawCurve(int x, int y, int size, bool bg){ 169 | 170 | #if (OF_AVAILABLE) 171 | int xx = x; 172 | int yy = y; 173 | float s = size; 174 | if(bg){ 175 | ofSetColor(22); 176 | ofRect(x, y, size, size); 177 | } 178 | float steps = size; 179 | string name = ofxAnimatable::getCurveName(curveStyle_); 180 | glPointSize(1); 181 | glColor4ub(255,255,255, 64); 182 | ofLine(xx,yy + s, xx + s, yy + s); 183 | ofLine(xx,yy, xx, yy + s); 184 | glColor4ub(255,255,255, 32); 185 | ofLine(xx,yy + s, xx + s, yy ); 186 | glColor4ub(255,255,255, 255); 187 | ofMesh m; 188 | m.setMode(OF_PRIMITIVE_LINE_STRIP); 189 | float step = 1./steps; 190 | float p1, p2, p3; 191 | fillInParams(p1,p2,p3); 192 | for (float i = 0.0f ; i< 1.0f; i+= step){ 193 | float val = calcCurveAt(i, curveStyle_, p1, p2, p3); 194 | m.addVertex( ofVec3f(xx + s * i, yy + s - s * val) ); 195 | } 196 | m.draw(); 197 | glColor4ub(255,255,255, 255); 198 | ofDrawBitmapString(name, x, y + s + 15); 199 | #endif 200 | } 201 | 202 | 203 | void ofxAnimatable::fillInParams(float &p1, float &p2, float &p3){ 204 | 205 | switch (curveStyle_) { //in case our curve has extra params, fill them in 206 | case QUADRATIC_BEZIER_PARAM: 207 | p1 = quadraticBezierParamA; 208 | p2 = quadraticBezierParamB; 209 | break; 210 | case EXPONENTIAL_SIGMOID_PARAM: 211 | p1 = doubleExpSigmoidParam; 212 | break; 213 | 214 | case OBJECT_DROP: 215 | p1 = bounceAmp; 216 | break; 217 | 218 | default: 219 | break; 220 | } 221 | } 222 | 223 | float ofxAnimatable::calcCurveAt( float percent ){ 224 | 225 | float p1, p2, p3; 226 | fillInParams(p1,p2,p3); 227 | float r = calcCurveAt(percent, curveStyle_, p1, p2, p3); 228 | 229 | currentSpeed_ = r - prevSpeed_; //this is very ghetto and should be done properly! TODO 230 | prevSpeed_ = r; 231 | return r; 232 | } 233 | 234 | float ofxAnimatable::calcCurveAt(float percent, AnimCurve type, float param1, float param2, float param3){ 235 | 236 | float r = percent; 237 | switch ( type ) { 238 | 239 | case EASE_IN_EASE_OUT: 240 | r = 0.5f - 0.5f * cosf( M_PI * percent ); break; 241 | 242 | case EASE_IN: 243 | r = 1.0f + sinf( M_PI_2 * percent - M_PI_2); break; 244 | 245 | case EASE_OUT: 246 | r = sinf( M_PI_2 * percent ); break; 247 | 248 | case LINEAR: 249 | break; 250 | 251 | case EARLY_LINEAR: 252 | r = ( percent < 0.25f ) ? 0.0f : 1.33333333f * (percent - 0.25f); break; 253 | 254 | case LATE_LINEAR: 255 | r = ( percent < 0.5f ) ? 0.0f : 2.0f * percent - 1.0f; break; 256 | 257 | case VERY_LATE_LINEAR: 258 | r = ( percent < 0.75f ) ? 0.0f : 4.0f * percent - 3.0f; break; 259 | 260 | case TANH: 261 | r = 0.5f + 0.5f * tanh( 2.0f * M_PI * percent - M_PI ) * 1.00374187319732; break; 262 | 263 | case SINH: 264 | r = 0.5f + 0.23482f * sinh( 3.0f * percent - 1.5f ); break; 265 | 266 | case SQUARE: 267 | r = (percent < 0.5f) ? 0.0f : 1.0f; break; 268 | 269 | case BLINK_5:{ 270 | float v = percent * 5.0f; 271 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 272 | }break; 273 | 274 | case BLINK_3:{ 275 | float v = percent * 3.0f; 276 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 277 | }break; 278 | 279 | case BLINK_2:{ 280 | float v = percent * 2.0f; 281 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 282 | }break; 283 | 284 | case BLINK_AND_FADE_1:{ 285 | float v = percent * 2.0f; 286 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 287 | if (percent >= 0.75) r = 4 * percent - 4 * 0.75f ; 288 | }break; 289 | 290 | case BLINK_AND_FADE_2:{ 291 | float v = percent * 3.0f; 292 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 293 | if (percent >= 0.833333f) r = 6 * percent - 6 * 0.833333f ; 294 | }break; 295 | 296 | case BLINK_AND_FADE_3:{ 297 | float v = percent * 4.0f; 298 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 299 | if (percent >= 0.875f) r = 8 * percent - 8 * 0.875f ; 300 | }break; 301 | 302 | 303 | case LATE_SQUARE: 304 | r = (percent < 0.75f) ? 0.0f : 1.0f; break; 305 | 306 | case EARLY_SQUARE: 307 | r = (percent < 0.25f) ? 0.0f : 1.0f; break; 308 | 309 | case LATE_EASE_IN_EASE_OUT: 310 | r = (percent < 0.5f) ? 0.0f : 0.5f + 0.5f * cosf( 2.0f * M_PI * percent); break; 311 | 312 | case VERY_LATE_EASE_IN_EASE_OUT: 313 | r = (percent < 0.75f) ? 0.0f : 0.5f + 0.5f * cosf( 4.0f * M_PI * percent); break; 314 | 315 | case QUADRATIC_EASE_IN: 316 | r = percent * percent; break; 317 | 318 | case QUADRATIC_EASE_OUT: 319 | r = 1.0f - (percent - 1.0f) * (percent - 1.0f); break; 320 | 321 | case EARLY_QUADRATIC_EASE_OUT:{ 322 | float p = 1.333333333f; 323 | float x = (percent - 0.25) * p; 324 | r = (percent < 0.25f) ? 0.0f : 1.0f - ( x - 1.0f) * ( x - 1.0f); 325 | }break; 326 | 327 | case BOUNCY:{ 328 | float k = 0.5f; 329 | r = 0.5f - 0.51f * cosf( M_PI * percent + k * percent - k * 0.5f ); 330 | }break; 331 | 332 | case QUADRATIC_BEZIER_PARAM:{ 333 | r = quadraticBezier(percent, param1, param2); break; 334 | } 335 | 336 | case EXPONENTIAL_SIGMOID_PARAM:{ 337 | r = doubleExponentialSigmoid(percent, param1); break; 338 | } 339 | 340 | case OBJECT_DROP:{ 341 | if ( percent < 0.75f ){ 342 | r = cosf( (2.0f * M_PI / 3.0f) * percent ); 343 | }else{ 344 | float range = 0.125f; 345 | float diffRange = 0.125; 346 | float amp = param1; 347 | float freq = 8; 348 | 349 | if ( percent < 0.75f + range ){ 350 | r = amp * sinf( freq * M_PI * percent ); 351 | }else{ 352 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 353 | if ( percent < 0.75f + range ){ 354 | r = amp * sinf( freq * M_PI * percent ); 355 | }else{ 356 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 357 | if ( percent < 0.75f + range ){ 358 | r = amp * sinf( freq * M_PI * percent ); 359 | }else{ 360 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 361 | if ( percent < 0.75f + range ){ 362 | r = amp * sinf( freq * M_PI * percent ); 363 | }else{ 364 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 365 | if ( percent < 0.75f + range ){ 366 | r = amp * sinf( freq * M_PI * percent ); 367 | }else{ 368 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 369 | if ( percent < 0.75f + range ){ 370 | r = amp * sinf( freq * M_PI * percent ); 371 | }else{ 372 | r = 0; 373 | } 374 | } 375 | } 376 | } 377 | } 378 | } 379 | } 380 | r = 1.0f-r; 381 | break; 382 | } 383 | 384 | default: ; 385 | } 386 | return r; 387 | } 388 | 389 | 390 | void ofxAnimatable::update(float dt){ 391 | 392 | if (delay_ > 0.0f ){ 393 | delay_ -= dt; 394 | if (delay_ < 0.0f){ 395 | startAfterWait(); 396 | } 397 | } 398 | 399 | if (animating_ == true && paused_ == false){ 400 | 401 | percentDone_ += direction_ * transitionSpeed_ * dt; 402 | 403 | if ( percentDone_ >= 1.0f || percentDone_ <= 0.0f ){ 404 | 405 | animating_ = false; 406 | 407 | if (percentDone_ >= 1.0f) percentDone_ = 1.0f; 408 | else percentDone_ = 0.0f; 409 | 410 | switch (repeat_) { 411 | 412 | case PLAY_ONCE: 413 | break; //nothing to do; 414 | 415 | case LOOP_BACK_AND_FORTH: 416 | direction_ = -direction_; 417 | animating_ = true; 418 | break; 419 | 420 | case LOOP: 421 | animating_ = true; 422 | percentDone_ = 0.0f; 423 | break; 424 | 425 | case LOOP_BACK_AND_FORTH_ONCE: 426 | if (playcount_ >= 1){ //time to stop 427 | //we are done 428 | }else{ 429 | direction_ = -direction_; 430 | animating_ = true; 431 | playcount_++; 432 | } 433 | break; 434 | } 435 | } 436 | } 437 | lastDT_ = dt; 438 | } 439 | 440 | 441 | void ofxAnimatable::startAnimation(){ 442 | direction_ = 1; 443 | percentDone_ = 0.0f; 444 | delay_ = 0.0f; 445 | animating_ = true; 446 | playcount_ = 0; 447 | paused_ = false; 448 | currentSpeed_ = 0.0f; 449 | prevSpeed_ = 0.0f; 450 | } 451 | 452 | void ofxAnimatable::startAnimationAfterDelay(float delay){ 453 | direction_ = 1; 454 | delay_ = delay; 455 | waitTime_ = delay_; 456 | //animating_ = false; 457 | } 458 | 459 | 460 | void ofxAnimatable::reset(){ 461 | percentDone_ = 0.0f; 462 | delay_ = 0.0f; 463 | animating_ = false; 464 | playcount_ = 0; 465 | paused_ = false; 466 | currentSpeed_ = 0.0f; 467 | prevSpeed_ = 0.0f; 468 | } 469 | 470 | 471 | void ofxAnimatable::setDuration( float seconds ){ 472 | transitionSpeed_ = 1.0f / seconds; 473 | } 474 | 475 | 476 | void ofxAnimatable::setRepeatType( AnimRepeat repeat ){ 477 | repeat_ = repeat; 478 | } 479 | 480 | 481 | void ofxAnimatable::setCurve( AnimCurve curveStyle){ 482 | curveStyle_ = curveStyle; 483 | } 484 | 485 | 486 | float ofxAnimatable::getPercentDone(){ 487 | return percentDone_; 488 | } 489 | 490 | void ofxAnimatable::setPercentDone(float p){ 491 | if( p < 0.0f ) p = 0.0f; 492 | percentDone_ = p; 493 | } 494 | 495 | bool ofxAnimatable::isAnimating(){ 496 | return animating_; 497 | } 498 | 499 | 500 | bool ofxAnimatable::hasFinishedAnimating(){ 501 | return !animating_; 502 | } 503 | 504 | bool ofxAnimatable::isWaitingForAnimationToStart(){ 505 | return ( delay_ > 0.0f ); 506 | } 507 | 508 | float ofxAnimatable::getCurrentSpeed(){ 509 | float r = fabs( direction_ * currentSpeed_ / (lastDT_ * transitionSpeed_)); 510 | return r; 511 | } 512 | 513 | bool ofxAnimatable::isOrWillBeAnimating(){ 514 | return isAnimating() || isWaitingForAnimationToStart() ; 515 | } 516 | 517 | void ofxAnimatable::pause(){ 518 | paused_ = true; 519 | } 520 | 521 | 522 | void ofxAnimatable::resume(){ 523 | paused_ = false; 524 | } 525 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatable.h 3 | * 4 | * Created by Oriol Ferrer Mesià on 30/10/09. 5 | * Copyright 2009 uri.cat. All rights reserved. 6 | * 7 | */ 8 | 9 | 10 | #define DEFAULT_ANIMATION_DURATION 1.0f 11 | 12 | 13 | #include 14 | #define _USE_MATH_DEFINES 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #pragma once 20 | #include "ofMain.h" 21 | 22 | 23 | enum AnimRepeat{ 24 | PLAY_ONCE = 0, 25 | LOOP, 26 | LOOP_BACK_AND_FORTH, 27 | LOOP_BACK_AND_FORTH_ONCE, 28 | }; 29 | 30 | enum AnimCurve{ 31 | EASE_IN_EASE_OUT = 0, 32 | EASE_IN, 33 | EASE_OUT, 34 | LINEAR, 35 | EARLY_LINEAR, 36 | LATE_LINEAR, 37 | VERY_LATE_LINEAR, 38 | BOUNCY, //this needs work TODO 39 | OBJECT_DROP, 40 | TANH, 41 | SINH, 42 | EARLY_SQUARE, 43 | SQUARE, 44 | LATE_SQUARE, 45 | BLINK_5, 46 | BLINK_3, 47 | BLINK_2, 48 | BLINK_AND_FADE_1, 49 | BLINK_AND_FADE_2, 50 | BLINK_AND_FADE_3, 51 | LATE_EASE_IN_EASE_OUT, 52 | VERY_LATE_EASE_IN_EASE_OUT, 53 | QUADRATIC_EASE_IN, 54 | QUADRATIC_EASE_OUT, 55 | EARLY_QUADRATIC_EASE_OUT, 56 | QUADRATIC_BEZIER_PARAM, //http://www.flong.com/texts/code/shapers_exp/ 57 | EXPONENTIAL_SIGMOID_PARAM, 58 | NUM_ANIM_CURVES //leave that on the last to see how many we have 59 | }; 60 | 61 | 62 | class ofxAnimatable{ 63 | 64 | public: 65 | 66 | void setup(); 67 | void update(float dt); 68 | 69 | void pause(); //really needed? 70 | void resume(); // 71 | 72 | void setCurve( AnimCurve curveStyle_ ); 73 | void setRepeatType( AnimRepeat repeat ); 74 | void setDuration( float seconds ); 75 | 76 | void setDoubleExpSigmoidParam(float param){doubleExpSigmoidParam = param;} //only for QUADRATIC_BEZIER_PARAM curve 77 | void setQuadraticBezierParams(float a, float b){quadraticBezierParamA = a; quadraticBezierParamB = b; } //only for EXPONENTIAL_SIGMOID_PARAM curve 78 | void setDropObjectParams(float bounceHeightPercent){bounceAmp = bounceHeightPercent;} //only for DROP_OBJECT curve 79 | 80 | float getDuration(){ return 1.0f/transitionSpeed_; } 81 | 82 | float getPercentDone(); ///get how much of the animation has been "walked" 83 | void setPercentDone(float p); //Will allow to skip to any point of animation. use carefully 84 | bool isAnimating(); ///is the animation still going on? 85 | bool hasFinishedAnimating(); ///has the animation finished? 86 | bool isWaitingForAnimationToStart(); ///an animation has been scheduled with "animateToAfterDelay" 87 | bool isOrWillBeAnimating(); /// object is either animating now or it's waiting to be launch animation after a delay 88 | float getCurrentSpeed(); ///as a percentage of linear speed 89 | float timeLeftForAnimationToStart(){ return delay_; } 90 | float waitTimeLeftPercent(){ return 1.0f - delay_ / waitTime_; } 91 | 92 | static string getCurveName(AnimCurve c); 93 | 94 | //carefull with those, you'd better know what you are doing, those should almost be protected 95 | static float calcCurveAt(float percent, AnimCurve type, float param1 = 0.5, float param2 = 0.5, float param3 = 0.5); //exposing this to get direct access to simple curve values 96 | float calcCurveAt( float percent ); 97 | void drawCurve(int x, int y, int size, bool bg = false); 98 | 99 | virtual ~ofxAnimatable(void) {} 100 | ofxAnimatable() {} 101 | 102 | 103 | protected: 104 | 105 | bool animating_; 106 | bool paused_; 107 | 108 | int playcount_; 109 | 110 | float transitionSpeed_; ///this is 1/N (N == # of updates) it will take for the transition to end 111 | float percentDone_; /// [0..1] 112 | 113 | 114 | float delay_; //countdown timer that stores delay when startAnimationAfterDelay() is used 115 | float waitTime_; //original wait delay_ 116 | AnimRepeat repeat_; 117 | AnimCurve curveStyle_; 118 | 119 | int direction_; // 1 : forward, -1 : backward 120 | 121 | 122 | 123 | void startAnimation(); ///Used by subclasses to indicate we are starting an anim 124 | void startAnimationAfterDelay(float delay); 125 | void reset(); ///Used by subclasses to indicate a reset of an animation 126 | void fillInParams(float&p1, float &p2, float &p3); 127 | 128 | private: 129 | 130 | virtual void startAfterWait() = 0; 131 | float currentSpeed_; 132 | float prevSpeed_; 133 | float lastDT_; 134 | 135 | //for some of the curves 136 | float doubleExpSigmoidParam; 137 | float quadraticBezierParamA, quadraticBezierParamB; 138 | float bounceAmp; 139 | }; 140 | 141 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatableFloat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ofxAnimatableFloat.cpp 3 | * 4 | * 5 | * Created by Oriol Ferrer Mesia on 2008/10/09. 6 | * 7 | */ 8 | 9 | #include "ofxAnimatableFloat.h" 10 | 11 | ofxAnimatableFloat::ofxAnimatableFloat(){ 12 | 13 | ofxAnimatable::setup(); 14 | originalVal_ = targetVal_= 0.0f; 15 | } 16 | 17 | 18 | void ofxAnimatableFloat::update( float dt ){ 19 | 20 | ofxAnimatable::update( dt ); 21 | } 22 | 23 | 24 | void ofxAnimatableFloat::animateTo( float newVal ){ 25 | 26 | originalVal_ = val(); 27 | targetVal_ = newVal; 28 | 29 | ofxAnimatable::startAnimation(); 30 | } 31 | 32 | 33 | void ofxAnimatableFloat::animateToAfterDelay( float newVal, float delay ){ 34 | 35 | if (delay <= 0.0f){ 36 | animateTo(newVal); 37 | }else{ 38 | //originalTempVal_ = val(); 39 | targetTempVal_ = newVal; 40 | ofxAnimatable::startAnimationAfterDelay(delay); 41 | } 42 | } 43 | 44 | 45 | void ofxAnimatableFloat::animateFromTo( float originalValue, float destinationValue ){ 46 | 47 | ofxAnimatable::startAnimation(); 48 | 49 | originalVal_ = originalValue; 50 | targetVal_ = destinationValue; 51 | } 52 | 53 | 54 | void ofxAnimatableFloat::animateToIfFinished( float newVal ){ 55 | if ( animating_ == false ){ 56 | animateTo(newVal); 57 | } 58 | } 59 | 60 | 61 | float ofxAnimatableFloat::val(){ 62 | 63 | float mappedDistribution = calcCurveAt( percentDone_ ); ///percentDone_ is [0..1] & tells me where we are between orig and target 64 | return originalVal_ + ( targetVal_ - originalVal_ ) * mappedDistribution ; 65 | } 66 | 67 | 68 | void ofxAnimatableFloat::reset( float newVal ){ 69 | 70 | ofxAnimatable::reset(); 71 | originalVal_ = targetVal_ = newVal; 72 | } 73 | 74 | 75 | void ofxAnimatableFloat::reset(){ 76 | 77 | ofxAnimatable::reset(); 78 | targetVal_ = originalVal_; 79 | } 80 | 81 | 82 | void ofxAnimatableFloat::startAfterWait(){ 83 | animateTo(targetTempVal_); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatableFloat.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * ofxAnimatableFloat.h 4 | * 5 | * 6 | * Created by Oriol Ferrer Mesia on 24/09/08. 7 | * 8 | */ 9 | 10 | #pragma once 11 | #include "ofxAnimatable.h" 12 | 13 | class ofxAnimatableFloat : public ofxAnimatable{ 14 | 15 | public: 16 | 17 | ofxAnimatableFloat(); 18 | ~ofxAnimatableFloat(){}; 19 | 20 | void update( float dt ); 21 | 22 | void animateTo( float newVal ); 23 | void animateToAfterDelay( float newVal, float delay ); 24 | void animateToIfFinished( float newVal ); ///starts new animation to newVal only if there isnt an anim going on 25 | void animateFromTo( float originalValue, float destinationValue ); 26 | 27 | 28 | //gets 29 | float val(); ///gives you the current value. 30 | float getCurrentValue(){ return val(); } 31 | float getTargetValue(){ return targetVal_;} 32 | float getOriginalValue(){ return originalVal_;} 33 | 34 | void reset(float newVal); ///sets an original value, and stops animation 35 | void reset(); ///goes back to the original value 36 | 37 | 38 | 39 | ///trying to make everyone life's easier with operators, I want an ofxAnimatableFloat to behave 40 | ///like a float here, but doesn't quite work all the time 41 | ///so you'd better use the .val() method to get the current value 42 | 43 | operator float(){ return val(); } ///return current value when asking for float 44 | operator double(){ return val(); } ///return current value when asking for double 45 | 46 | private: 47 | 48 | // ## MUST IMPLEMENT ## 49 | void startAfterWait(); 50 | float originalVal_; 51 | float targetVal_; 52 | float targetTempVal_; 53 | 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatableOfColor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfColor.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatableOfColor.h" 11 | 12 | 13 | ofxAnimatableOfColor::ofxAnimatableOfColor(){ 14 | 15 | setup(); 16 | originalColor_ = ofColor::black; 17 | targetColor_ = ofColor::white; 18 | } 19 | 20 | 21 | void ofxAnimatableOfColor::update(float dt){ 22 | ofxAnimatable::update( dt ); 23 | } 24 | 25 | 26 | void ofxAnimatableOfColor::applyCurrentColor(){ 27 | ofSetColor( getCurrentColor() ); 28 | } 29 | 30 | 31 | void ofxAnimatableOfColor::setColor(ofColor newColor){ 32 | ofxAnimatable::reset(); 33 | originalColor_ = newColor; 34 | targetColor_ = newColor; 35 | } 36 | 37 | 38 | void ofxAnimatableOfColor::revertToBaseColor(){ 39 | ofxAnimatable::reset(); 40 | } 41 | 42 | 43 | void ofxAnimatableOfColor::setAlphaOnly( float a ){ 44 | 45 | originalColor_ = getCurrentColor(); 46 | originalColor_.a = a; 47 | targetColor_ = originalColor_; 48 | ofxAnimatable::reset(); 49 | } 50 | 51 | 52 | void ofxAnimatableOfColor::animateTo( ofColor col ){ 53 | 54 | originalColor_ = getCurrentColor(); 55 | targetColor_ = col; 56 | ofxAnimatable::startAnimation(); 57 | } 58 | 59 | 60 | void ofxAnimatableOfColor::animateToAfterDelay( ofColor newColor, float delay ){ 61 | 62 | //originalTempColor_ = getCurrentColor(); 63 | targetTempColor_ = newColor; 64 | ofxAnimatable::startAnimationAfterDelay(delay); 65 | } 66 | 67 | 68 | void ofxAnimatableOfColor::animateToIfFinished( ofColor col ){ 69 | if (animating_ == false){ 70 | animateTo( col ); 71 | } 72 | } 73 | 74 | 75 | void ofxAnimatableOfColor::fadeIn(){ 76 | 77 | ofColor targetC = getCurrentColor(); 78 | 79 | if ( sizeof(targetC.r) == sizeof(float) ) 80 | targetC.a = (float)1.0f; 81 | else if ( sizeof(targetC.r) == sizeof(unsigned char) ) 82 | targetC.a = (unsigned char) numeric_limits::max(); 83 | else if ( sizeof(targetC.r) == sizeof(unsigned short) ) 84 | targetC.a = (unsigned char) numeric_limits::max(); 85 | 86 | animateTo( targetC ); 87 | } 88 | 89 | 90 | void ofxAnimatableOfColor::fadeOut(){ 91 | 92 | ofColor targetC = getCurrentColor(); 93 | targetC.a = 0.0f; 94 | animateTo( targetC ); 95 | } 96 | 97 | 98 | void ofxAnimatableOfColor::animateToAlpha( float a ){ 99 | 100 | originalColor_ = getCurrentColor(); 101 | targetColor_ = originalColor_; 102 | targetColor_.a = a; 103 | ofxAnimatable::startAnimation(); 104 | } 105 | 106 | 107 | void ofxAnimatableOfColor::startBlinking( float blinkDuration){ 108 | 109 | setRepeatType(LOOP_BACK_AND_FORTH); 110 | setCurve(EASE_IN_EASE_OUT); 111 | setAlphaOnly(0.0f); 112 | setDuration( blinkDuration ); 113 | ofColor c = getCurrentColor(); 114 | c.a = 255; 115 | animateTo( c ); 116 | } 117 | 118 | 119 | ofColor ofxAnimatableOfColor::getCurrentColor(){ 120 | 121 | float mappedDistribution = calcCurveAt(percentDone_); ///percentDone_ is [0..1] & tells me where we are between orig and target 122 | float newC[4]; 123 | ofColor r; 124 | for (int i = 0; i < 4; i++){ 125 | newC[i] = ( (int)targetColor_[i] - (int)originalColor_[i]) * mappedDistribution; 126 | r[i] = originalColor_[i] + newC[i]; 127 | } 128 | return r; 129 | } 130 | 131 | void ofxAnimatableOfColor::startAfterWait(){ 132 | animateTo(targetTempColor_); 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatableOfColor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfColor.h 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef _ANIMATABLE_COLOR_INC 11 | #define _ANIMATABLE_COLOR_INC 12 | 13 | #include "ofxAnimatable.h" 14 | #include "ofMain.h" 15 | 16 | 17 | class ofxAnimatableOfColor : public ofxAnimatable { 18 | 19 | public: 20 | 21 | ofxAnimatableOfColor(); 22 | ~ofxAnimatableOfColor(){}; 23 | 24 | void update(float dt); 25 | void applyCurrentColor(); //apply current color 26 | 27 | // apply for immediate effect //////////////////////////////////////////////////////////////////// 28 | 29 | void setColor( ofColor newColor ); 30 | void revertToBaseColor(); 31 | void setAlphaOnly( float a ); 32 | 33 | // animated over time /////////////////////////////////////////////////////////////////////////// 34 | 35 | ///starts new fade to "col" regardless, using the current color as the inital value 36 | void animateTo( ofColor col ); 37 | void animateToAfterDelay( ofColor newColor, float delay ); 38 | void animateToIfFinished( ofColor col ); 39 | void fadeIn(); 40 | void fadeOut(); 41 | void animateToAlpha( float a ); 42 | void startBlinking(float blinkDuration = 1.0f); ///will set repeat to LOOP_BACK_AND_FORTH, curve to EASE_IN_EASE_OUT 43 | 44 | //gets 45 | ofColor getCurrentColor(); 46 | ofColor getTargetColor(){ return targetColor_;} 47 | ofColor getOriginalColor(){ return originalColor_;} 48 | 49 | 50 | 51 | private: 52 | 53 | void startAfterWait(); 54 | 55 | ofColor originalColor_; 56 | ofColor targetColor_; 57 | ofColor targetTempColor_; 58 | 59 | }; 60 | 61 | 62 | #endif -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatableOfPoint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfPoint.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatableOfPoint.h" 11 | 12 | 13 | ofxAnimatableOfPoint::ofxAnimatableOfPoint(){ 14 | 15 | ofxAnimatable::setup(); //defaults to (0,0,0) >> (0,0,0) 16 | } 17 | 18 | 19 | void ofxAnimatableOfPoint::update(float dt){ 20 | 21 | ofxAnimatable::update( dt ); 22 | } 23 | 24 | 25 | void ofxAnimatableOfPoint::draw(){ 26 | 27 | ofPushMatrix(); 28 | ofPoint p = getCurrentPosition(); 29 | ofTranslate(p.x, p.y, p.z); 30 | float s = 10.0f; 31 | ofRect( -s * 0.5f, -s * 0.5f, s, s ); 32 | ofPopMatrix(); 33 | 34 | } 35 | 36 | 37 | void ofxAnimatableOfPoint::setPosition( ofPoint newPos ){ 38 | 39 | ofxAnimatable::reset(); 40 | originalPoint_ = newPos; 41 | targetPoint_ = newPos; 42 | } 43 | 44 | 45 | void ofxAnimatableOfPoint::setPositionX( float newX ){ 46 | 47 | originalPoint_ = getCurrentPosition(); 48 | originalPoint_.x = newX; 49 | targetPoint_ = originalPoint_; 50 | ofxAnimatable::reset(); 51 | } 52 | 53 | 54 | void ofxAnimatableOfPoint::setPositionY( float newY ){ 55 | 56 | originalPoint_ = getCurrentPosition(); 57 | originalPoint_.y = newY; 58 | targetPoint_ = originalPoint_; 59 | ofxAnimatable::reset(); 60 | } 61 | 62 | 63 | void ofxAnimatableOfPoint::setPositionZ( float newZ ){ 64 | 65 | originalPoint_ = getCurrentPosition(); 66 | originalPoint_.z = newZ; 67 | targetPoint_ = originalPoint_; 68 | ofxAnimatable::reset(); 69 | } 70 | 71 | 72 | void ofxAnimatableOfPoint::reset(){ 73 | 74 | ofxAnimatable::reset(); 75 | targetPoint_ = originalPoint_; 76 | } 77 | 78 | 79 | void ofxAnimatableOfPoint::animateTo( ofPoint where ){ 80 | 81 | originalPoint_ = getCurrentPosition(); 82 | targetPoint_ = where; 83 | ofxAnimatable::startAnimation(); 84 | } 85 | 86 | void ofxAnimatableOfPoint::animateToAfterDelay( ofPoint where, float delay ){ 87 | 88 | if (delay <= 0.0f){ 89 | animateTo(where); 90 | }else{ 91 | //originalTempPoint_ = getCurrentPosition(); 92 | targetTempPoint_ = where; 93 | ofxAnimatable::startAnimationAfterDelay(delay); 94 | } 95 | } 96 | 97 | 98 | void ofxAnimatableOfPoint::animateToIfFinished( ofPoint where ){ 99 | 100 | if (animating_ == false){ 101 | animateTo(where); 102 | } 103 | } 104 | 105 | 106 | ofPoint ofxAnimatableOfPoint::getCurrentPosition(){ 107 | float mappedDistribution = calcCurveAt(percentDone_); ///percentDone_ is [0..1] & tells me where we are between orig and target 108 | return originalPoint_ + ( targetPoint_ - originalPoint_) * mappedDistribution ; 109 | } 110 | 111 | 112 | void ofxAnimatableOfPoint::startAfterWait(){ 113 | animateTo(targetTempPoint_); 114 | } 115 | -------------------------------------------------------------------------------- /example_Butterfly/src/ofxAnimatableOfPoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfPoint.h 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef _ANIMATABLE_POINT_INC 11 | #define _ANIMATABLE_POINT_INC 12 | 13 | #include "ofxAnimatable.h" 14 | #include "ofMain.h" 15 | 16 | 17 | class ofxAnimatableOfPoint : public ofxAnimatable{ 18 | 19 | public: 20 | 21 | ofxAnimatableOfPoint(); 22 | ~ofxAnimatableOfPoint(){}; 23 | 24 | void update(float dt); 25 | void draw(); //draws the current pos point in space 26 | 27 | 28 | // apply for immediate effect //////////////////////////////////////////////////////////////////// 29 | 30 | void setPosition( ofPoint ); 31 | void setPositionX(float); 32 | void setPositionY(float); 33 | void setPositionZ(float); 34 | void reset(); 35 | 36 | // animated over time /////////////////////////////////////////////////////////////////////////// 37 | 38 | ///starts new animation to "where" regardless, using the current pos as the inital value 39 | void animateTo( ofPoint where ); 40 | void animateToAfterDelay( ofPoint where, float delay ); 41 | 42 | void animateToIfFinished( ofPoint where ); 43 | 44 | //gets 45 | ofPoint getCurrentPosition(); 46 | ofPoint getTargetPosition(){ return targetPoint_;} 47 | ofPoint getOriginalPosition(){ return originalPoint_;} 48 | 49 | 50 | private: 51 | 52 | void startAfterWait(); 53 | 54 | ofPoint originalPoint_; 55 | ofPoint targetPoint_; 56 | ofPoint targetTempPoint_; 57 | 58 | 59 | }; 60 | 61 | 62 | #endif -------------------------------------------------------------------------------- /example_SineWaves/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=../../.. 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example_SineWaves/Project.xcconfig: -------------------------------------------------------------------------------- 1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT. 2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED 3 | OF_PATH = ../../.. 4 | 5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE 6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig" 7 | 8 | //ICONS - NEW IN 0072 9 | ICON_NAME_DEBUG = icon-debug.icns 10 | ICON_NAME_RELEASE = icon.icns 11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/ 12 | 13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to: 14 | //ICON_FILE_PATH = bin/data/ 15 | 16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS) 17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) 18 | -------------------------------------------------------------------------------- /example_SineWaves/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxMathMesh 3 | -------------------------------------------------------------------------------- /example_SineWaves/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahbee/ofxMathMesh/acd5041b18e1a9cc86f0239a21f8ac4bdbcacaf2/example_SineWaves/bin/data/.gitkeep -------------------------------------------------------------------------------- /example_SineWaves/config.make: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # CONFIGURE PROJECT MAKEFILE (optional) 3 | # This file is where we make project specific configurations. 4 | ################################################################################ 5 | 6 | ################################################################################ 7 | # OF ROOT 8 | # The location of your root openFrameworks installation 9 | # (default) OF_ROOT = ../../.. 10 | ################################################################################ 11 | # OF_ROOT = ../../.. 12 | 13 | ################################################################################ 14 | # PROJECT ROOT 15 | # The location of the project - a starting place for searching for files 16 | # (default) PROJECT_ROOT = . (this directory) 17 | # 18 | ################################################################################ 19 | # PROJECT_ROOT = . 20 | 21 | ################################################################################ 22 | # PROJECT SPECIFIC CHECKS 23 | # This is a project defined section to create internal makefile flags to 24 | # conditionally enable or disable the addition of various features within 25 | # this makefile. For instance, if you want to make changes based on whether 26 | # GTK is installed, one might test that here and create a variable to check. 27 | ################################################################################ 28 | # None 29 | 30 | ################################################################################ 31 | # PROJECT EXTERNAL SOURCE PATHS 32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder. 33 | # Like source folders in the PROJECT_ROOT, these paths are subject to 34 | # exlclusion via the PROJECT_EXLCUSIONS list. 35 | # 36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) 37 | # 38 | # Note: Leave a leading space when adding list items with the += operator 39 | ################################################################################ 40 | # PROJECT_EXTERNAL_SOURCE_PATHS = 41 | 42 | ################################################################################ 43 | # PROJECT EXCLUSIONS 44 | # These makefiles assume that all folders in your current project directory 45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations 46 | # to look for source code. The any folders or files that match any of the 47 | # items in the PROJECT_EXCLUSIONS list below will be ignored. 48 | # 49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete 50 | # string unless teh user adds a wildcard (%) operator to match subdirectories. 51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is 52 | # treated literally. 53 | # 54 | # (default) PROJECT_EXCLUSIONS = (blank) 55 | # 56 | # Will automatically exclude the following: 57 | # 58 | # $(PROJECT_ROOT)/bin% 59 | # $(PROJECT_ROOT)/obj% 60 | # $(PROJECT_ROOT)/%.xcodeproj 61 | # 62 | # Note: Leave a leading space when adding list items with the += operator 63 | ################################################################################ 64 | # PROJECT_EXCLUSIONS = 65 | 66 | ################################################################################ 67 | # PROJECT LINKER FLAGS 68 | # These flags will be sent to the linker when compiling the executable. 69 | # 70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs 71 | # 72 | # Note: Leave a leading space when adding list items with the += operator 73 | ################################################################################ 74 | 75 | # Currently, shared libraries that are needed are copied to the 76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to 77 | # add a runtime path to search for those shared libraries, since they aren't 78 | # incorporated directly into the final executable application binary. 79 | # TODO: should this be a default setting? 80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs 81 | 82 | ################################################################################ 83 | # PROJECT DEFINES 84 | # Create a space-delimited list of DEFINES. The list will be converted into 85 | # CFLAGS with the "-D" flag later in the makefile. 86 | # 87 | # (default) PROJECT_DEFINES = (blank) 88 | # 89 | # Note: Leave a leading space when adding list items with the += operator 90 | ################################################################################ 91 | # PROJECT_DEFINES = 92 | 93 | ################################################################################ 94 | # PROJECT CFLAGS 95 | # This is a list of fully qualified CFLAGS required when compiling for this 96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS 97 | # defined in your platform specific core configuration files. These flags are 98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. 99 | # 100 | # (default) PROJECT_CFLAGS = (blank) 101 | # 102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in 103 | # your platform specific configuration file will be applied by default and 104 | # further flags here may not be needed. 105 | # 106 | # Note: Leave a leading space when adding list items with the += operator 107 | ################################################################################ 108 | # PROJECT_CFLAGS = 109 | 110 | ################################################################################ 111 | # PROJECT OPTIMIZATION CFLAGS 112 | # These are lists of CFLAGS that are target-specific. While any flags could 113 | # be conditionally added, they are usually limited to optimization flags. 114 | # These flags are added BEFORE the PROJECT_CFLAGS. 115 | # 116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. 117 | # 118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) 119 | # 120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. 121 | # 122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) 123 | # 124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the 125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration 126 | # file will be applied by default and further optimization flags here may not 127 | # be needed. 128 | # 129 | # Note: Leave a leading space when adding list items with the += operator 130 | ################################################################################ 131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE = 132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG = 133 | 134 | ################################################################################ 135 | # PROJECT COMPILERS 136 | # Custom compilers can be set for CC and CXX 137 | # (default) PROJECT_CXX = (blank) 138 | # (default) PROJECT_CC = (blank) 139 | # Note: Leave a leading space when adding list items with the += operator 140 | ################################################################################ 141 | # PROJECT_CXX = 142 | # PROJECT_CC = 143 | -------------------------------------------------------------------------------- /example_SineWaves/example_SineWaves.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example_SineWaves/example_SineWaves.xcodeproj/xcshareddata/xcschemes/example_SineWaves Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example_SineWaves/example_SineWaves.xcodeproj/xcshareddata/xcschemes/example_SineWaves Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example_SineWaves/example_SineWaves.xcodeproj/xcuserdata/Abhi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SuppressBuildableAutocreation 6 | 7 | E4B69B5A0A3A1756003C02F2 8 | 9 | primary 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example_SineWaves/openFrameworks-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | cc.openFrameworks.ofapp 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | CFBundleIconFile 20 | ${ICON} 21 | 22 | 23 | -------------------------------------------------------------------------------- /example_SineWaves/src/MyEquations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMathMesh.h" 4 | #include "ofxAnimatableFloat.h" 5 | 6 | #define SINEMIN -4*M_PI 7 | #define SINEMAX 4*M_PI 8 | 9 | class SineWaveParent:public ofx2dFunction{ 10 | public: 11 | SineWaveParent():ofx2dFunction(){ 12 | orangeStart.setCurve(LINEAR); 13 | orangeStart.setRepeatType(LOOP); 14 | orangeStart.animateFromTo(SINEMIN, SINEMAX); 15 | orangeStart.setDuration(3.0); 16 | 17 | amplitude.setCurve(LINEAR); 18 | amplitude.setRepeatType(LOOP_BACK_AND_FORTH); 19 | amplitude.animateFromTo(-3.0, 3.0); 20 | amplitude.setDuration(3.0); 21 | 22 | ofAddListener(ofEvents().update, this, &SineWaveParent::update); 23 | } 24 | 25 | float valueForPoint(float x){ 26 | return amplitude.getCurrentValue() * sin(x); 27 | } 28 | 29 | ofFloatColor colorForPoint(float x,float y){ 30 | float colorRange = (SINEMAX - SINEMIN)/3.0; 31 | float fullRange = SINEMAX - SINEMIN; 32 | float orangeBegin = orangeStart.getCurrentValue(); 33 | float purpleBegin = orangeBegin + colorRange; 34 | float yellowBegin = purpleBegin + colorRange; 35 | float xWrapped = ofWrap(x, orangeBegin, orangeBegin + fullRange); 36 | if (xWrapped >= orangeBegin && xWrapped < purpleBegin) { 37 | return ofFloatColor::orange; 38 | }else if (xWrapped >=purpleBegin && xWrapped < yellowBegin){ 39 | return ofFloatColor::purple; 40 | }else{ 41 | return ofFloatColor::yellow; 42 | } 43 | 44 | 45 | } 46 | 47 | void update(ofEventArgs &args){ 48 | float dt = 1.0f/ofGetFrameRate(); 49 | amplitude.update(dt); 50 | orangeStart.update(dt); 51 | } 52 | 53 | public: 54 | ofxAnimatableFloat orangeStart; 55 | ofxAnimatableFloat amplitude; 56 | }; 57 | 58 | class SineWaveChild:public ofx2dFunction { 59 | public: 60 | 61 | ~SineWaveChild(){ 62 | ofRemoveListener(ofEvents().update, this ,&SineWaveChild::update); 63 | } 64 | 65 | void set(int ID,float amplitude,float orangeStart){ 66 | this->ID = ID; 67 | this->amplitude = amplitude; 68 | this->orangeStart = orangeStart; 69 | alpha.setCurve(LINEAR); 70 | alpha.animateFromTo(1.0, 0.0); 71 | alpha.setDuration(1.0); 72 | ofAddListener(ofEvents().update, this, &SineWaveChild::update); 73 | } 74 | 75 | float valueForPoint(float x){ 76 | return amplitude * sin(x); 77 | 78 | } 79 | 80 | ofFloatColor colorForPoint(float x,float y){ 81 | float colorRange = (SINEMAX - SINEMIN)/3.0; 82 | float fullRange = SINEMAX - SINEMIN; 83 | float orangeBegin = orangeStart; 84 | float purpleBegin = orangeBegin + colorRange; 85 | float yellowBegin = purpleBegin + colorRange; 86 | float xWrapped = ofWrap(x, orangeBegin, orangeBegin + fullRange); 87 | ofFloatColor returnColor; 88 | 89 | if (xWrapped >= orangeBegin && xWrapped < purpleBegin) { 90 | returnColor = ofFloatColor::orange; 91 | }else if (xWrapped >=purpleBegin && xWrapped < yellowBegin){ 92 | returnColor = ofFloatColor::purple; 93 | }else{ 94 | returnColor = ofFloatColor::yellow; 95 | } 96 | returnColor.a = alpha; 97 | return returnColor; 98 | } 99 | 100 | void update(ofEventArgs &args){ 101 | float dt = 1.0f/ofGetFrameRate(); 102 | alpha.update(dt); 103 | if (!alpha.isAnimating()) { 104 | ofNotifyEvent(endE, ID, this); 105 | } 106 | } 107 | 108 | public: 109 | int ID; 110 | ofEvent endE; 111 | float percent; 112 | float amplitude; 113 | float orangeStart; 114 | ofxAnimatableFloat alpha; 115 | }; 116 | -------------------------------------------------------------------------------- /example_SineWaves/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | cam.setAutoDistance(false); 6 | cam.setDistance(12); 7 | cam.setNearClip(0.01); 8 | cam.setTarget(ofVec3f::zero()); 9 | cam.lookAt(ofVec3f::zero()); 10 | ofSetLineWidth(5.0); 11 | ofBackground(0); 12 | 13 | gui.setup(); 14 | gui.add(drawChildren.setup("DrawChildren",true)); 15 | sineWave.setup(SINEMIN,SINEMAX,.1); 16 | 17 | } 18 | 19 | //-------------------------------------------------------------- 20 | void ofApp::update(){ 21 | static int ID = 0; 22 | for (int i = 0; i < children.size(); i++) { 23 | children[i]->reload(); 24 | } 25 | sineWave.reload(); 26 | shared_ptr child(new SineWaveChild); 27 | child->setup(SINEMIN, SINEMAX, .1); 28 | child->set(ID, sineWave.amplitude,sineWave.orangeStart); 29 | ofAddListener(child->endE, this, &ofApp::childDied); 30 | children.push_back(child); 31 | ID++; 32 | } 33 | 34 | //-------------------------------------------------------------- 35 | void ofApp::draw(){ 36 | cam.begin(); 37 | sineWave.draw(true); 38 | if (drawChildren) { 39 | for (int i = 0; i < children.size(); i++) { 40 | children[i]->draw(true); 41 | } 42 | } 43 | cam.end(); 44 | gui.draw(); 45 | } 46 | 47 | //-------------------------------------------------------------- 48 | void ofApp::keyPressed(int key){ 49 | 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::keyReleased(int key){ 54 | 55 | } 56 | 57 | //-------------------------------------------------------------- 58 | void ofApp::mouseMoved(int x, int y ){ 59 | 60 | } 61 | 62 | //-------------------------------------------------------------- 63 | void ofApp::mouseDragged(int x, int y, int button){ 64 | 65 | } 66 | 67 | //-------------------------------------------------------------- 68 | void ofApp::mousePressed(int x, int y, int button){ 69 | 70 | } 71 | 72 | //-------------------------------------------------------------- 73 | void ofApp::mouseReleased(int x, int y, int button){ 74 | 75 | } 76 | 77 | //-------------------------------------------------------------- 78 | void ofApp::windowResized(int w, int h){ 79 | 80 | } 81 | 82 | //-------------------------------------------------------------- 83 | void ofApp::gotMessage(ofMessage msg){ 84 | 85 | } 86 | 87 | //-------------------------------------------------------------- 88 | void ofApp::dragEvent(ofDragInfo dragInfo){ 89 | 90 | } 91 | 92 | void ofApp::childDied(int &ID){ 93 | int indexToRemove; 94 | for (int i = 0; i < children.size(); i++) { 95 | if (children[i]->ID == ID) { 96 | indexToRemove = i; 97 | } 98 | } 99 | children.erase(children.begin() + indexToRemove); 100 | } 101 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "MyEquations.h" 5 | #include "ofxGui.h" 6 | 7 | class ofApp : public ofBaseApp{ 8 | 9 | public: 10 | void setup(); 11 | void update(); 12 | void draw(); 13 | void keyPressed(int key); 14 | void keyReleased(int key); 15 | void mouseMoved(int x, int y ); 16 | void mouseDragged(int x, int y, int button); 17 | void mousePressed(int x, int y, int button); 18 | void mouseReleased(int x, int y, int button); 19 | void windowResized(int w, int h); 20 | void dragEvent(ofDragInfo dragInfo); 21 | void gotMessage(ofMessage msg); 22 | 23 | void childDied(int &ID); 24 | 25 | SineWaveParent sineWave; 26 | 27 | vector > children; 28 | 29 | ofxPanel gui; 30 | ofxToggle drawChildren; 31 | 32 | ofEasyCam cam; 33 | }; 34 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatable.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 30/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatable.h" 11 | 12 | //from http://www.flong.com/texts/code/shapers_exp/ 13 | 14 | float doublePolynomialSigmoid(float x, int n){ 15 | 16 | float y = 0.0f; 17 | if (n%2 == 0){ 18 | // even polynomial 19 | if (x<=0.5f){ 20 | y = pow(2.0f*x, n)/2.0f; 21 | } else { 22 | y = 1.0f - pow(2.0f*(x-1.0f), n)/2.0f; 23 | } 24 | } 25 | 26 | else { 27 | // odd polynomial 28 | if (x <= 0.5f){ 29 | y = pow( 2.0f * x, n) / 2.0f; 30 | } else { 31 | y = 1.0 + pow( 2.0f * (x-1.0f), n) / 2.0; 32 | } 33 | } 34 | return y; 35 | } 36 | 37 | float doubleExponentialSigmoid (float x, float a){ 38 | 39 | float epsilon = 0.00001f; 40 | float min_param_a = 0.0f + epsilon; 41 | float max_param_a = 1.0f - epsilon; 42 | a = min(max_param_a, max(min_param_a, a)); 43 | a = 1.0f - a; // for sensible results 44 | 45 | float y = 0.0f; 46 | if ( x <= 0.5f ){ 47 | y = ( pow( 2.0f * x, 1.0f/a) ) / 2.0f; 48 | } else { 49 | y = 1.0 - ( pow( 2.0f * (1.0f-x), 1.0f / a) ) / 2.0f; 50 | } 51 | return y; 52 | } 53 | 54 | float doubleExponentialSeat (float x, float a){ 55 | 56 | float epsilon = 0.00001f; 57 | float min_param_a = 0.0f + epsilon; 58 | float max_param_a = 1.0f - epsilon; 59 | a = min(max_param_a, max(min_param_a, a)); 60 | 61 | float y = 0.0f; 62 | if (x <= 0.5f){ 63 | y = (powf(2.0 * x, 1.0f - a) ) / 2.0f; 64 | } else { 65 | y = 1.0f - ( pow(2.0f * ( 1.0f - x ), 1.0f-a) ) / 2.0f; 66 | } 67 | return y; 68 | } 69 | 70 | 71 | float exponentialEasing (float x, float a){ 72 | 73 | float epsilon = 0.00001; 74 | float min_param_a = 0.0f + epsilon; 75 | float max_param_a = 1.0f - epsilon; 76 | a = max(min_param_a, min(max_param_a, a)); 77 | 78 | if (a < 0.5f){ 79 | // emphasis 80 | a = 2.0f*(a); 81 | float y = pow(x, a); 82 | return y; 83 | } else { 84 | // de-emphasis 85 | a = 2.0f*(a-0.5f); 86 | float y = powf(x, 1.0/(1-a)); 87 | return y; 88 | } 89 | } 90 | 91 | 92 | float quadraticBezier (float x, float a, float b){ 93 | // adapted from BEZMATH.PS (1993) 94 | // by Don Lancaster, SYNERGETICS Inc. 95 | // http://www.tinaja.com/text/bezmath.html 96 | 97 | float epsilon = 0.00001; 98 | a = max(0.0f, min(1.0f, a)); 99 | b = max(0.0f, min(1.0f, b)); 100 | if (a == 0.5f){ 101 | a += epsilon; 102 | } 103 | 104 | // solve t from x (an inverse operation) 105 | float om2a = 1 - 2*a; 106 | float t = (sqrt(a*a + om2a*x) - a)/om2a; 107 | float y = (1-2*b)*(t*t) + (2*b)*t; 108 | return y; 109 | } 110 | 111 | 112 | std::string ofxAnimatable::getCurveName(AnimCurve c){ 113 | 114 | switch (c) { 115 | case EASE_IN_EASE_OUT: return "EASE_IN_EASE_OUT"; 116 | case EASE_IN: return "EASE_IN"; 117 | case EASE_OUT: return "EASE_OUT"; 118 | case LINEAR: return "LINEAR"; 119 | case BOUNCY: return "BOUNCY"; 120 | case TANH: return "TANH"; 121 | case SINH: return "SINH"; 122 | case SQUARE: return "SQUARE"; 123 | case LATE_SQUARE: return "LATE_SQUARE"; 124 | case EARLY_SQUARE: return "EARLY_SQUARE"; 125 | case BLINK_5: return "BLINK_5"; 126 | case BLINK_3: return "BLINK_3"; 127 | case BLINK_2: return "BLINK_2"; 128 | case BLINK_AND_FADE_1: return "BLINK_AND_FADE_1"; 129 | case BLINK_AND_FADE_2: return "BLINK_AND_FADE_2"; 130 | case BLINK_AND_FADE_3: return "BLINK_AND_FADE_3"; 131 | case LATE_LINEAR: return "LATE_LINEAR"; 132 | case LATE_EASE_IN_EASE_OUT: return "LATE_EASE_IN_EASE_OUT"; 133 | case EARLY_LINEAR: return "EARLY_LINEAR"; 134 | case VERY_LATE_LINEAR: return "VERY_LATE_LINEAR"; 135 | case VERY_LATE_EASE_IN_EASE_OUT: return "VERY_LATE_EASE_IN_EASE_OUT"; 136 | case QUADRATIC_EASE_IN: return "QUADRATIC_EASE_IN"; 137 | case QUADRATIC_EASE_OUT: return "QUADRATIC_EASE_OUT"; 138 | case EARLY_QUADRATIC_EASE_OUT: return "EARLY_QUADRATIC_EASE_OUT"; 139 | case QUADRATIC_BEZIER_PARAM: return "QUADRATIC_BEZIER_PARAM"; 140 | case EXPONENTIAL_SIGMOID_PARAM: return "EXPONENTIAL_SIGMOID_PARAM"; 141 | case OBJECT_DROP: return "OBJECT_DROP"; 142 | 143 | default: return "UNKNOWN_CURVE!"; 144 | } 145 | return "error"; 146 | } 147 | 148 | void ofxAnimatable::setup(){ 149 | 150 | doubleExpSigmoidParam = 0.5; 151 | quadraticBezierParamA = 0.25; 152 | quadraticBezierParamB = 0.75; 153 | bounceAmp = 0.05; 154 | transitionSpeed_ = 1.0f / DEFAULT_ANIMATION_DURATION; 155 | percentDone_ = 0.0f; 156 | animating_ = false; 157 | paused_ = false; 158 | direction_ = 1; 159 | playcount_ = 0; 160 | repeat_ = PLAY_ONCE; 161 | curveStyle_ = EASE_IN_EASE_OUT; 162 | currentSpeed_ = 0.0f; 163 | lastDT_ = 1; 164 | waitTime_ = 0.0f; 165 | delay_ = 0.0f; 166 | } 167 | 168 | void ofxAnimatable::drawCurve(int x, int y, int size, bool bg){ 169 | 170 | #if (OF_AVAILABLE) 171 | int xx = x; 172 | int yy = y; 173 | float s = size; 174 | if(bg){ 175 | ofSetColor(22); 176 | ofRect(x, y, size, size); 177 | } 178 | float steps = size; 179 | string name = ofxAnimatable::getCurveName(curveStyle_); 180 | glPointSize(1); 181 | glColor4ub(255,255,255, 64); 182 | ofLine(xx,yy + s, xx + s, yy + s); 183 | ofLine(xx,yy, xx, yy + s); 184 | glColor4ub(255,255,255, 32); 185 | ofLine(xx,yy + s, xx + s, yy ); 186 | glColor4ub(255,255,255, 255); 187 | ofMesh m; 188 | m.setMode(OF_PRIMITIVE_LINE_STRIP); 189 | float step = 1./steps; 190 | float p1, p2, p3; 191 | fillInParams(p1,p2,p3); 192 | for (float i = 0.0f ; i< 1.0f; i+= step){ 193 | float val = calcCurveAt(i, curveStyle_, p1, p2, p3); 194 | m.addVertex( ofVec3f(xx + s * i, yy + s - s * val) ); 195 | } 196 | m.draw(); 197 | glColor4ub(255,255,255, 255); 198 | ofDrawBitmapString(name, x, y + s + 15); 199 | #endif 200 | } 201 | 202 | 203 | void ofxAnimatable::fillInParams(float &p1, float &p2, float &p3){ 204 | 205 | switch (curveStyle_) { //in case our curve has extra params, fill them in 206 | case QUADRATIC_BEZIER_PARAM: 207 | p1 = quadraticBezierParamA; 208 | p2 = quadraticBezierParamB; 209 | break; 210 | case EXPONENTIAL_SIGMOID_PARAM: 211 | p1 = doubleExpSigmoidParam; 212 | break; 213 | 214 | case OBJECT_DROP: 215 | p1 = bounceAmp; 216 | break; 217 | 218 | default: 219 | break; 220 | } 221 | } 222 | 223 | float ofxAnimatable::calcCurveAt( float percent ){ 224 | 225 | float p1, p2, p3; 226 | fillInParams(p1,p2,p3); 227 | float r = calcCurveAt(percent, curveStyle_, p1, p2, p3); 228 | 229 | currentSpeed_ = r - prevSpeed_; //this is very ghetto and should be done properly! TODO 230 | prevSpeed_ = r; 231 | return r; 232 | } 233 | 234 | float ofxAnimatable::calcCurveAt(float percent, AnimCurve type, float param1, float param2, float param3){ 235 | 236 | float r = percent; 237 | switch ( type ) { 238 | 239 | case EASE_IN_EASE_OUT: 240 | r = 0.5f - 0.5f * cosf( M_PI * percent ); break; 241 | 242 | case EASE_IN: 243 | r = 1.0f + sinf( M_PI_2 * percent - M_PI_2); break; 244 | 245 | case EASE_OUT: 246 | r = sinf( M_PI_2 * percent ); break; 247 | 248 | case LINEAR: 249 | break; 250 | 251 | case EARLY_LINEAR: 252 | r = ( percent < 0.25f ) ? 0.0f : 1.33333333f * (percent - 0.25f); break; 253 | 254 | case LATE_LINEAR: 255 | r = ( percent < 0.5f ) ? 0.0f : 2.0f * percent - 1.0f; break; 256 | 257 | case VERY_LATE_LINEAR: 258 | r = ( percent < 0.75f ) ? 0.0f : 4.0f * percent - 3.0f; break; 259 | 260 | case TANH: 261 | r = 0.5f + 0.5f * tanh( 2.0f * M_PI * percent - M_PI ) * 1.00374187319732; break; 262 | 263 | case SINH: 264 | r = 0.5f + 0.23482f * sinh( 3.0f * percent - 1.5f ); break; 265 | 266 | case SQUARE: 267 | r = (percent < 0.5f) ? 0.0f : 1.0f; break; 268 | 269 | case BLINK_5:{ 270 | float v = percent * 5.0f; 271 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 272 | }break; 273 | 274 | case BLINK_3:{ 275 | float v = percent * 3.0f; 276 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 277 | }break; 278 | 279 | case BLINK_2:{ 280 | float v = percent * 2.0f; 281 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 282 | }break; 283 | 284 | case BLINK_AND_FADE_1:{ 285 | float v = percent * 2.0f; 286 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 287 | if (percent >= 0.75) r = 4 * percent - 4 * 0.75f ; 288 | }break; 289 | 290 | case BLINK_AND_FADE_2:{ 291 | float v = percent * 3.0f; 292 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 293 | if (percent >= 0.833333f) r = 6 * percent - 6 * 0.833333f ; 294 | }break; 295 | 296 | case BLINK_AND_FADE_3:{ 297 | float v = percent * 4.0f; 298 | r = (fmod(v, 1.01f) < 0.5f ? 0.0f : 1.0f); 299 | if (percent >= 0.875f) r = 8 * percent - 8 * 0.875f ; 300 | }break; 301 | 302 | 303 | case LATE_SQUARE: 304 | r = (percent < 0.75f) ? 0.0f : 1.0f; break; 305 | 306 | case EARLY_SQUARE: 307 | r = (percent < 0.25f) ? 0.0f : 1.0f; break; 308 | 309 | case LATE_EASE_IN_EASE_OUT: 310 | r = (percent < 0.5f) ? 0.0f : 0.5f + 0.5f * cosf( 2.0f * M_PI * percent); break; 311 | 312 | case VERY_LATE_EASE_IN_EASE_OUT: 313 | r = (percent < 0.75f) ? 0.0f : 0.5f + 0.5f * cosf( 4.0f * M_PI * percent); break; 314 | 315 | case QUADRATIC_EASE_IN: 316 | r = percent * percent; break; 317 | 318 | case QUADRATIC_EASE_OUT: 319 | r = 1.0f - (percent - 1.0f) * (percent - 1.0f); break; 320 | 321 | case EARLY_QUADRATIC_EASE_OUT:{ 322 | float p = 1.333333333f; 323 | float x = (percent - 0.25) * p; 324 | r = (percent < 0.25f) ? 0.0f : 1.0f - ( x - 1.0f) * ( x - 1.0f); 325 | }break; 326 | 327 | case BOUNCY:{ 328 | float k = 0.5f; 329 | r = 0.5f - 0.51f * cosf( M_PI * percent + k * percent - k * 0.5f ); 330 | }break; 331 | 332 | case QUADRATIC_BEZIER_PARAM:{ 333 | r = quadraticBezier(percent, param1, param2); break; 334 | } 335 | 336 | case EXPONENTIAL_SIGMOID_PARAM:{ 337 | r = doubleExponentialSigmoid(percent, param1); break; 338 | } 339 | 340 | case OBJECT_DROP:{ 341 | if ( percent < 0.75f ){ 342 | r = cosf( (2.0f * M_PI / 3.0f) * percent ); 343 | }else{ 344 | float range = 0.125f; 345 | float diffRange = 0.125; 346 | float amp = param1; 347 | float freq = 8; 348 | 349 | if ( percent < 0.75f + range ){ 350 | r = amp * sinf( freq * M_PI * percent ); 351 | }else{ 352 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 353 | if ( percent < 0.75f + range ){ 354 | r = amp * sinf( freq * M_PI * percent ); 355 | }else{ 356 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 357 | if ( percent < 0.75f + range ){ 358 | r = amp * sinf( freq * M_PI * percent ); 359 | }else{ 360 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 361 | if ( percent < 0.75f + range ){ 362 | r = amp * sinf( freq * M_PI * percent ); 363 | }else{ 364 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 365 | if ( percent < 0.75f + range ){ 366 | r = amp * sinf( freq * M_PI * percent ); 367 | }else{ 368 | diffRange *= 0.5; range += diffRange; amp *= 0.5f; freq *= 2.0f; 369 | if ( percent < 0.75f + range ){ 370 | r = amp * sinf( freq * M_PI * percent ); 371 | }else{ 372 | r = 0; 373 | } 374 | } 375 | } 376 | } 377 | } 378 | } 379 | } 380 | r = 1.0f-r; 381 | break; 382 | } 383 | 384 | default: ; 385 | } 386 | return r; 387 | } 388 | 389 | 390 | void ofxAnimatable::update(float dt){ 391 | 392 | if (delay_ > 0.0f ){ 393 | delay_ -= dt; 394 | if (delay_ < 0.0f){ 395 | startAfterWait(); 396 | } 397 | } 398 | 399 | if (animating_ == true && paused_ == false){ 400 | 401 | percentDone_ += direction_ * transitionSpeed_ * dt; 402 | 403 | if ( percentDone_ >= 1.0f || percentDone_ <= 0.0f ){ 404 | 405 | animating_ = false; 406 | 407 | if (percentDone_ >= 1.0f) percentDone_ = 1.0f; 408 | else percentDone_ = 0.0f; 409 | 410 | switch (repeat_) { 411 | 412 | case PLAY_ONCE: 413 | break; //nothing to do; 414 | 415 | case LOOP_BACK_AND_FORTH: 416 | direction_ = -direction_; 417 | animating_ = true; 418 | break; 419 | 420 | case LOOP: 421 | animating_ = true; 422 | percentDone_ = 0.0f; 423 | break; 424 | 425 | case LOOP_BACK_AND_FORTH_ONCE: 426 | if (playcount_ >= 1){ //time to stop 427 | //we are done 428 | }else{ 429 | direction_ = -direction_; 430 | animating_ = true; 431 | playcount_++; 432 | } 433 | break; 434 | } 435 | } 436 | } 437 | lastDT_ = dt; 438 | } 439 | 440 | 441 | void ofxAnimatable::startAnimation(){ 442 | direction_ = 1; 443 | percentDone_ = 0.0f; 444 | delay_ = 0.0f; 445 | animating_ = true; 446 | playcount_ = 0; 447 | paused_ = false; 448 | currentSpeed_ = 0.0f; 449 | prevSpeed_ = 0.0f; 450 | } 451 | 452 | void ofxAnimatable::startAnimationAfterDelay(float delay){ 453 | direction_ = 1; 454 | delay_ = delay; 455 | waitTime_ = delay_; 456 | //animating_ = false; 457 | } 458 | 459 | 460 | void ofxAnimatable::reset(){ 461 | percentDone_ = 0.0f; 462 | delay_ = 0.0f; 463 | animating_ = false; 464 | playcount_ = 0; 465 | paused_ = false; 466 | currentSpeed_ = 0.0f; 467 | prevSpeed_ = 0.0f; 468 | } 469 | 470 | 471 | void ofxAnimatable::setDuration( float seconds ){ 472 | transitionSpeed_ = 1.0f / seconds; 473 | } 474 | 475 | 476 | void ofxAnimatable::setRepeatType( AnimRepeat repeat ){ 477 | repeat_ = repeat; 478 | } 479 | 480 | 481 | void ofxAnimatable::setCurve( AnimCurve curveStyle){ 482 | curveStyle_ = curveStyle; 483 | } 484 | 485 | 486 | float ofxAnimatable::getPercentDone(){ 487 | return percentDone_; 488 | } 489 | 490 | void ofxAnimatable::setPercentDone(float p){ 491 | if( p < 0.0f ) p = 0.0f; 492 | percentDone_ = p; 493 | } 494 | 495 | bool ofxAnimatable::isAnimating(){ 496 | return animating_; 497 | } 498 | 499 | 500 | bool ofxAnimatable::hasFinishedAnimating(){ 501 | return !animating_; 502 | } 503 | 504 | bool ofxAnimatable::isWaitingForAnimationToStart(){ 505 | return ( delay_ > 0.0f ); 506 | } 507 | 508 | float ofxAnimatable::getCurrentSpeed(){ 509 | float r = fabs( direction_ * currentSpeed_ / (lastDT_ * transitionSpeed_)); 510 | return r; 511 | } 512 | 513 | bool ofxAnimatable::isOrWillBeAnimating(){ 514 | return isAnimating() || isWaitingForAnimationToStart() ; 515 | } 516 | 517 | void ofxAnimatable::pause(){ 518 | paused_ = true; 519 | } 520 | 521 | 522 | void ofxAnimatable::resume(){ 523 | paused_ = false; 524 | } 525 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatable.h 3 | * 4 | * Created by Oriol Ferrer Mesià on 30/10/09. 5 | * Copyright 2009 uri.cat. All rights reserved. 6 | * 7 | */ 8 | 9 | 10 | #define DEFAULT_ANIMATION_DURATION 1.0f 11 | 12 | 13 | #include 14 | #define _USE_MATH_DEFINES 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #pragma once 20 | #include "ofMain.h" 21 | 22 | 23 | enum AnimRepeat{ 24 | PLAY_ONCE = 0, 25 | LOOP, 26 | LOOP_BACK_AND_FORTH, 27 | LOOP_BACK_AND_FORTH_ONCE, 28 | }; 29 | 30 | enum AnimCurve{ 31 | EASE_IN_EASE_OUT = 0, 32 | EASE_IN, 33 | EASE_OUT, 34 | LINEAR, 35 | EARLY_LINEAR, 36 | LATE_LINEAR, 37 | VERY_LATE_LINEAR, 38 | BOUNCY, //this needs work TODO 39 | OBJECT_DROP, 40 | TANH, 41 | SINH, 42 | EARLY_SQUARE, 43 | SQUARE, 44 | LATE_SQUARE, 45 | BLINK_5, 46 | BLINK_3, 47 | BLINK_2, 48 | BLINK_AND_FADE_1, 49 | BLINK_AND_FADE_2, 50 | BLINK_AND_FADE_3, 51 | LATE_EASE_IN_EASE_OUT, 52 | VERY_LATE_EASE_IN_EASE_OUT, 53 | QUADRATIC_EASE_IN, 54 | QUADRATIC_EASE_OUT, 55 | EARLY_QUADRATIC_EASE_OUT, 56 | QUADRATIC_BEZIER_PARAM, //http://www.flong.com/texts/code/shapers_exp/ 57 | EXPONENTIAL_SIGMOID_PARAM, 58 | NUM_ANIM_CURVES //leave that on the last to see how many we have 59 | }; 60 | 61 | 62 | class ofxAnimatable{ 63 | 64 | public: 65 | 66 | void setup(); 67 | void update(float dt); 68 | 69 | void pause(); //really needed? 70 | void resume(); // 71 | 72 | void setCurve( AnimCurve curveStyle_ ); 73 | void setRepeatType( AnimRepeat repeat ); 74 | void setDuration( float seconds ); 75 | 76 | void setDoubleExpSigmoidParam(float param){doubleExpSigmoidParam = param;} //only for QUADRATIC_BEZIER_PARAM curve 77 | void setQuadraticBezierParams(float a, float b){quadraticBezierParamA = a; quadraticBezierParamB = b; } //only for EXPONENTIAL_SIGMOID_PARAM curve 78 | void setDropObjectParams(float bounceHeightPercent){bounceAmp = bounceHeightPercent;} //only for DROP_OBJECT curve 79 | 80 | float getDuration(){ return 1.0f/transitionSpeed_; } 81 | 82 | float getPercentDone(); ///get how much of the animation has been "walked" 83 | void setPercentDone(float p); //Will allow to skip to any point of animation. use carefully 84 | bool isAnimating(); ///is the animation still going on? 85 | bool hasFinishedAnimating(); ///has the animation finished? 86 | bool isWaitingForAnimationToStart(); ///an animation has been scheduled with "animateToAfterDelay" 87 | bool isOrWillBeAnimating(); /// object is either animating now or it's waiting to be launch animation after a delay 88 | float getCurrentSpeed(); ///as a percentage of linear speed 89 | float timeLeftForAnimationToStart(){ return delay_; } 90 | float waitTimeLeftPercent(){ return 1.0f - delay_ / waitTime_; } 91 | 92 | static string getCurveName(AnimCurve c); 93 | 94 | //carefull with those, you'd better know what you are doing, those should almost be protected 95 | static float calcCurveAt(float percent, AnimCurve type, float param1 = 0.5, float param2 = 0.5, float param3 = 0.5); //exposing this to get direct access to simple curve values 96 | float calcCurveAt( float percent ); 97 | void drawCurve(int x, int y, int size, bool bg = false); 98 | 99 | virtual ~ofxAnimatable(void) {} 100 | ofxAnimatable() {} 101 | 102 | 103 | protected: 104 | 105 | bool animating_; 106 | bool paused_; 107 | 108 | int playcount_; 109 | 110 | float transitionSpeed_; ///this is 1/N (N == # of updates) it will take for the transition to end 111 | float percentDone_; /// [0..1] 112 | 113 | 114 | float delay_; //countdown timer that stores delay when startAnimationAfterDelay() is used 115 | float waitTime_; //original wait delay_ 116 | AnimRepeat repeat_; 117 | AnimCurve curveStyle_; 118 | 119 | int direction_; // 1 : forward, -1 : backward 120 | 121 | 122 | 123 | void startAnimation(); ///Used by subclasses to indicate we are starting an anim 124 | void startAnimationAfterDelay(float delay); 125 | void reset(); ///Used by subclasses to indicate a reset of an animation 126 | void fillInParams(float&p1, float &p2, float &p3); 127 | 128 | private: 129 | 130 | virtual void startAfterWait() = 0; 131 | float currentSpeed_; 132 | float prevSpeed_; 133 | float lastDT_; 134 | 135 | //for some of the curves 136 | float doubleExpSigmoidParam; 137 | float quadraticBezierParamA, quadraticBezierParamB; 138 | float bounceAmp; 139 | }; 140 | 141 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatableFloat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ofxAnimatableFloat.cpp 3 | * 4 | * 5 | * Created by Oriol Ferrer Mesia on 2008/10/09. 6 | * 7 | */ 8 | 9 | #include "ofxAnimatableFloat.h" 10 | 11 | ofxAnimatableFloat::ofxAnimatableFloat(){ 12 | 13 | ofxAnimatable::setup(); 14 | originalVal_ = targetVal_= 0.0f; 15 | } 16 | 17 | 18 | void ofxAnimatableFloat::update( float dt ){ 19 | 20 | ofxAnimatable::update( dt ); 21 | } 22 | 23 | 24 | void ofxAnimatableFloat::animateTo( float newVal ){ 25 | 26 | originalVal_ = val(); 27 | targetVal_ = newVal; 28 | 29 | ofxAnimatable::startAnimation(); 30 | } 31 | 32 | 33 | void ofxAnimatableFloat::animateToAfterDelay( float newVal, float delay ){ 34 | 35 | if (delay <= 0.0f){ 36 | animateTo(newVal); 37 | }else{ 38 | //originalTempVal_ = val(); 39 | targetTempVal_ = newVal; 40 | ofxAnimatable::startAnimationAfterDelay(delay); 41 | } 42 | } 43 | 44 | 45 | void ofxAnimatableFloat::animateFromTo( float originalValue, float destinationValue ){ 46 | 47 | ofxAnimatable::startAnimation(); 48 | 49 | originalVal_ = originalValue; 50 | targetVal_ = destinationValue; 51 | } 52 | 53 | 54 | void ofxAnimatableFloat::animateToIfFinished( float newVal ){ 55 | if ( animating_ == false ){ 56 | animateTo(newVal); 57 | } 58 | } 59 | 60 | 61 | float ofxAnimatableFloat::val(){ 62 | 63 | float mappedDistribution = calcCurveAt( percentDone_ ); ///percentDone_ is [0..1] & tells me where we are between orig and target 64 | return originalVal_ + ( targetVal_ - originalVal_ ) * mappedDistribution ; 65 | } 66 | 67 | 68 | void ofxAnimatableFloat::reset( float newVal ){ 69 | 70 | ofxAnimatable::reset(); 71 | originalVal_ = targetVal_ = newVal; 72 | } 73 | 74 | 75 | void ofxAnimatableFloat::reset(){ 76 | 77 | ofxAnimatable::reset(); 78 | targetVal_ = originalVal_; 79 | } 80 | 81 | 82 | void ofxAnimatableFloat::startAfterWait(){ 83 | animateTo(targetTempVal_); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatableFloat.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * ofxAnimatableFloat.h 4 | * 5 | * 6 | * Created by Oriol Ferrer Mesia on 24/09/08. 7 | * 8 | */ 9 | 10 | #pragma once 11 | #include "ofxAnimatable.h" 12 | 13 | class ofxAnimatableFloat : public ofxAnimatable{ 14 | 15 | public: 16 | 17 | ofxAnimatableFloat(); 18 | ~ofxAnimatableFloat(){}; 19 | 20 | void update( float dt ); 21 | 22 | void animateTo( float newVal ); 23 | void animateToAfterDelay( float newVal, float delay ); 24 | void animateToIfFinished( float newVal ); ///starts new animation to newVal only if there isnt an anim going on 25 | void animateFromTo( float originalValue, float destinationValue ); 26 | 27 | 28 | //gets 29 | float val(); ///gives you the current value. 30 | float getCurrentValue(){ return val(); } 31 | float getTargetValue(){ return targetVal_;} 32 | float getOriginalValue(){ return originalVal_;} 33 | 34 | void reset(float newVal); ///sets an original value, and stops animation 35 | void reset(); ///goes back to the original value 36 | 37 | 38 | 39 | ///trying to make everyone life's easier with operators, I want an ofxAnimatableFloat to behave 40 | ///like a float here, but doesn't quite work all the time 41 | ///so you'd better use the .val() method to get the current value 42 | 43 | operator float(){ return val(); } ///return current value when asking for float 44 | operator double(){ return val(); } ///return current value when asking for double 45 | 46 | private: 47 | 48 | // ## MUST IMPLEMENT ## 49 | void startAfterWait(); 50 | float originalVal_; 51 | float targetVal_; 52 | float targetTempVal_; 53 | 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatableOfColor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfColor.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatableOfColor.h" 11 | 12 | 13 | ofxAnimatableOfColor::ofxAnimatableOfColor(){ 14 | 15 | setup(); 16 | originalColor_ = ofColor::black; 17 | targetColor_ = ofColor::white; 18 | } 19 | 20 | 21 | void ofxAnimatableOfColor::update(float dt){ 22 | ofxAnimatable::update( dt ); 23 | } 24 | 25 | 26 | void ofxAnimatableOfColor::applyCurrentColor(){ 27 | ofSetColor( getCurrentColor() ); 28 | } 29 | 30 | 31 | void ofxAnimatableOfColor::setColor(ofColor newColor){ 32 | ofxAnimatable::reset(); 33 | originalColor_ = newColor; 34 | targetColor_ = newColor; 35 | } 36 | 37 | 38 | void ofxAnimatableOfColor::revertToBaseColor(){ 39 | ofxAnimatable::reset(); 40 | } 41 | 42 | 43 | void ofxAnimatableOfColor::setAlphaOnly( float a ){ 44 | 45 | originalColor_ = getCurrentColor(); 46 | originalColor_.a = a; 47 | targetColor_ = originalColor_; 48 | ofxAnimatable::reset(); 49 | } 50 | 51 | 52 | void ofxAnimatableOfColor::animateTo( ofColor col ){ 53 | 54 | originalColor_ = getCurrentColor(); 55 | targetColor_ = col; 56 | ofxAnimatable::startAnimation(); 57 | } 58 | 59 | 60 | void ofxAnimatableOfColor::animateToAfterDelay( ofColor newColor, float delay ){ 61 | 62 | //originalTempColor_ = getCurrentColor(); 63 | targetTempColor_ = newColor; 64 | ofxAnimatable::startAnimationAfterDelay(delay); 65 | } 66 | 67 | 68 | void ofxAnimatableOfColor::animateToIfFinished( ofColor col ){ 69 | if (animating_ == false){ 70 | animateTo( col ); 71 | } 72 | } 73 | 74 | 75 | void ofxAnimatableOfColor::fadeIn(){ 76 | 77 | ofColor targetC = getCurrentColor(); 78 | 79 | if ( sizeof(targetC.r) == sizeof(float) ) 80 | targetC.a = (float)1.0f; 81 | else if ( sizeof(targetC.r) == sizeof(unsigned char) ) 82 | targetC.a = (unsigned char) numeric_limits::max(); 83 | else if ( sizeof(targetC.r) == sizeof(unsigned short) ) 84 | targetC.a = (unsigned char) numeric_limits::max(); 85 | 86 | animateTo( targetC ); 87 | } 88 | 89 | 90 | void ofxAnimatableOfColor::fadeOut(){ 91 | 92 | ofColor targetC = getCurrentColor(); 93 | targetC.a = 0.0f; 94 | animateTo( targetC ); 95 | } 96 | 97 | 98 | void ofxAnimatableOfColor::animateToAlpha( float a ){ 99 | 100 | originalColor_ = getCurrentColor(); 101 | targetColor_ = originalColor_; 102 | targetColor_.a = a; 103 | ofxAnimatable::startAnimation(); 104 | } 105 | 106 | 107 | void ofxAnimatableOfColor::startBlinking( float blinkDuration){ 108 | 109 | setRepeatType(LOOP_BACK_AND_FORTH); 110 | setCurve(EASE_IN_EASE_OUT); 111 | setAlphaOnly(0.0f); 112 | setDuration( blinkDuration ); 113 | ofColor c = getCurrentColor(); 114 | c.a = 255; 115 | animateTo( c ); 116 | } 117 | 118 | 119 | ofColor ofxAnimatableOfColor::getCurrentColor(){ 120 | 121 | float mappedDistribution = calcCurveAt(percentDone_); ///percentDone_ is [0..1] & tells me where we are between orig and target 122 | float newC[4]; 123 | ofColor r; 124 | for (int i = 0; i < 4; i++){ 125 | newC[i] = ( (int)targetColor_[i] - (int)originalColor_[i]) * mappedDistribution; 126 | r[i] = originalColor_[i] + newC[i]; 127 | } 128 | return r; 129 | } 130 | 131 | void ofxAnimatableOfColor::startAfterWait(){ 132 | animateTo(targetTempColor_); 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatableOfColor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfColor.h 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef _ANIMATABLE_COLOR_INC 11 | #define _ANIMATABLE_COLOR_INC 12 | 13 | #include "ofxAnimatable.h" 14 | #include "ofMain.h" 15 | 16 | 17 | class ofxAnimatableOfColor : public ofxAnimatable { 18 | 19 | public: 20 | 21 | ofxAnimatableOfColor(); 22 | ~ofxAnimatableOfColor(){}; 23 | 24 | void update(float dt); 25 | void applyCurrentColor(); //apply current color 26 | 27 | // apply for immediate effect //////////////////////////////////////////////////////////////////// 28 | 29 | void setColor( ofColor newColor ); 30 | void revertToBaseColor(); 31 | void setAlphaOnly( float a ); 32 | 33 | // animated over time /////////////////////////////////////////////////////////////////////////// 34 | 35 | ///starts new fade to "col" regardless, using the current color as the inital value 36 | void animateTo( ofColor col ); 37 | void animateToAfterDelay( ofColor newColor, float delay ); 38 | void animateToIfFinished( ofColor col ); 39 | void fadeIn(); 40 | void fadeOut(); 41 | void animateToAlpha( float a ); 42 | void startBlinking(float blinkDuration = 1.0f); ///will set repeat to LOOP_BACK_AND_FORTH, curve to EASE_IN_EASE_OUT 43 | 44 | //gets 45 | ofColor getCurrentColor(); 46 | ofColor getTargetColor(){ return targetColor_;} 47 | ofColor getOriginalColor(){ return originalColor_;} 48 | 49 | 50 | 51 | private: 52 | 53 | void startAfterWait(); 54 | 55 | ofColor originalColor_; 56 | ofColor targetColor_; 57 | ofColor targetTempColor_; 58 | 59 | }; 60 | 61 | 62 | #endif -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatableOfPoint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfPoint.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatableOfPoint.h" 11 | 12 | 13 | ofxAnimatableOfPoint::ofxAnimatableOfPoint(){ 14 | 15 | ofxAnimatable::setup(); //defaults to (0,0,0) >> (0,0,0) 16 | } 17 | 18 | 19 | void ofxAnimatableOfPoint::update(float dt){ 20 | 21 | ofxAnimatable::update( dt ); 22 | } 23 | 24 | 25 | void ofxAnimatableOfPoint::draw(){ 26 | 27 | ofPushMatrix(); 28 | ofPoint p = getCurrentPosition(); 29 | ofTranslate(p.x, p.y, p.z); 30 | float s = 10.0f; 31 | ofRect( -s * 0.5f, -s * 0.5f, s, s ); 32 | ofPopMatrix(); 33 | 34 | } 35 | 36 | 37 | void ofxAnimatableOfPoint::setPosition( ofPoint newPos ){ 38 | 39 | ofxAnimatable::reset(); 40 | originalPoint_ = newPos; 41 | targetPoint_ = newPos; 42 | } 43 | 44 | 45 | void ofxAnimatableOfPoint::setPositionX( float newX ){ 46 | 47 | originalPoint_ = getCurrentPosition(); 48 | originalPoint_.x = newX; 49 | targetPoint_ = originalPoint_; 50 | ofxAnimatable::reset(); 51 | } 52 | 53 | 54 | void ofxAnimatableOfPoint::setPositionY( float newY ){ 55 | 56 | originalPoint_ = getCurrentPosition(); 57 | originalPoint_.y = newY; 58 | targetPoint_ = originalPoint_; 59 | ofxAnimatable::reset(); 60 | } 61 | 62 | 63 | void ofxAnimatableOfPoint::setPositionZ( float newZ ){ 64 | 65 | originalPoint_ = getCurrentPosition(); 66 | originalPoint_.z = newZ; 67 | targetPoint_ = originalPoint_; 68 | ofxAnimatable::reset(); 69 | } 70 | 71 | 72 | void ofxAnimatableOfPoint::reset(){ 73 | 74 | ofxAnimatable::reset(); 75 | targetPoint_ = originalPoint_; 76 | } 77 | 78 | 79 | void ofxAnimatableOfPoint::animateTo( ofPoint where ){ 80 | 81 | originalPoint_ = getCurrentPosition(); 82 | targetPoint_ = where; 83 | ofxAnimatable::startAnimation(); 84 | } 85 | 86 | void ofxAnimatableOfPoint::animateToAfterDelay( ofPoint where, float delay ){ 87 | 88 | if (delay <= 0.0f){ 89 | animateTo(where); 90 | }else{ 91 | //originalTempPoint_ = getCurrentPosition(); 92 | targetTempPoint_ = where; 93 | ofxAnimatable::startAnimationAfterDelay(delay); 94 | } 95 | } 96 | 97 | 98 | void ofxAnimatableOfPoint::animateToIfFinished( ofPoint where ){ 99 | 100 | if (animating_ == false){ 101 | animateTo(where); 102 | } 103 | } 104 | 105 | 106 | ofPoint ofxAnimatableOfPoint::getCurrentPosition(){ 107 | float mappedDistribution = calcCurveAt(percentDone_); ///percentDone_ is [0..1] & tells me where we are between orig and target 108 | return originalPoint_ + ( targetPoint_ - originalPoint_) * mappedDistribution ; 109 | } 110 | 111 | 112 | void ofxAnimatableOfPoint::startAfterWait(){ 113 | animateTo(targetTempPoint_); 114 | } 115 | -------------------------------------------------------------------------------- /example_SineWaves/src/ofxAnimatableOfPoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfPoint.h 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef _ANIMATABLE_POINT_INC 11 | #define _ANIMATABLE_POINT_INC 12 | 13 | #include "ofxAnimatable.h" 14 | #include "ofMain.h" 15 | 16 | 17 | class ofxAnimatableOfPoint : public ofxAnimatable{ 18 | 19 | public: 20 | 21 | ofxAnimatableOfPoint(); 22 | ~ofxAnimatableOfPoint(){}; 23 | 24 | void update(float dt); 25 | void draw(); //draws the current pos point in space 26 | 27 | 28 | // apply for immediate effect //////////////////////////////////////////////////////////////////// 29 | 30 | void setPosition( ofPoint ); 31 | void setPositionX(float); 32 | void setPositionY(float); 33 | void setPositionZ(float); 34 | void reset(); 35 | 36 | // animated over time /////////////////////////////////////////////////////////////////////////// 37 | 38 | ///starts new animation to "where" regardless, using the current pos as the inital value 39 | void animateTo( ofPoint where ); 40 | void animateToAfterDelay( ofPoint where, float delay ); 41 | 42 | void animateToIfFinished( ofPoint where ); 43 | 44 | //gets 45 | ofPoint getCurrentPosition(); 46 | ofPoint getTargetPosition(){ return targetPoint_;} 47 | ofPoint getOriginalPosition(){ return originalPoint_;} 48 | 49 | 50 | private: 51 | 52 | void startAfterWait(); 53 | 54 | ofPoint originalPoint_; 55 | ofPoint targetPoint_; 56 | ofPoint targetTempPoint_; 57 | 58 | 59 | }; 60 | 61 | 62 | #endif -------------------------------------------------------------------------------- /example_simple/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=../../.. 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example_simple/Project.xcconfig: -------------------------------------------------------------------------------- 1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT. 2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED 3 | OF_PATH = ../../.. 4 | 5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE 6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig" 7 | 8 | //ICONS - NEW IN 0072 9 | ICON_NAME_DEBUG = icon-debug.icns 10 | ICON_NAME_RELEASE = icon.icns 11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/ 12 | 13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to: 14 | //ICON_FILE_PATH = bin/data/ 15 | 16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS) 17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS) 18 | -------------------------------------------------------------------------------- /example_simple/addons.make: -------------------------------------------------------------------------------- 1 | ofxGui 2 | ofxMathMesh 3 | -------------------------------------------------------------------------------- /example_simple/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahbee/ofxMathMesh/acd5041b18e1a9cc86f0239a21f8ac4bdbcacaf2/example_simple/bin/data/.gitkeep -------------------------------------------------------------------------------- /example_simple/bin/data/flower.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahbee/ofxMathMesh/acd5041b18e1a9cc86f0239a21f8ac4bdbcacaf2/example_simple/bin/data/flower.jpg -------------------------------------------------------------------------------- /example_simple/bin/data/verdana.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ahbee/ofxMathMesh/acd5041b18e1a9cc86f0239a21f8ac4bdbcacaf2/example_simple/bin/data/verdana.ttf -------------------------------------------------------------------------------- /example_simple/config.make: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # CONFIGURE PROJECT MAKEFILE (optional) 3 | # This file is where we make project specific configurations. 4 | ################################################################################ 5 | 6 | ################################################################################ 7 | # OF ROOT 8 | # The location of your root openFrameworks installation 9 | # (default) OF_ROOT = ../../.. 10 | ################################################################################ 11 | # OF_ROOT = ../../.. 12 | 13 | ################################################################################ 14 | # PROJECT ROOT 15 | # The location of the project - a starting place for searching for files 16 | # (default) PROJECT_ROOT = . (this directory) 17 | # 18 | ################################################################################ 19 | # PROJECT_ROOT = . 20 | 21 | ################################################################################ 22 | # PROJECT SPECIFIC CHECKS 23 | # This is a project defined section to create internal makefile flags to 24 | # conditionally enable or disable the addition of various features within 25 | # this makefile. For instance, if you want to make changes based on whether 26 | # GTK is installed, one might test that here and create a variable to check. 27 | ################################################################################ 28 | # None 29 | 30 | ################################################################################ 31 | # PROJECT EXTERNAL SOURCE PATHS 32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder. 33 | # Like source folders in the PROJECT_ROOT, these paths are subject to 34 | # exlclusion via the PROJECT_EXLCUSIONS list. 35 | # 36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) 37 | # 38 | # Note: Leave a leading space when adding list items with the += operator 39 | ################################################################################ 40 | # PROJECT_EXTERNAL_SOURCE_PATHS = 41 | 42 | ################################################################################ 43 | # PROJECT EXCLUSIONS 44 | # These makefiles assume that all folders in your current project directory 45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations 46 | # to look for source code. The any folders or files that match any of the 47 | # items in the PROJECT_EXCLUSIONS list below will be ignored. 48 | # 49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete 50 | # string unless teh user adds a wildcard (%) operator to match subdirectories. 51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is 52 | # treated literally. 53 | # 54 | # (default) PROJECT_EXCLUSIONS = (blank) 55 | # 56 | # Will automatically exclude the following: 57 | # 58 | # $(PROJECT_ROOT)/bin% 59 | # $(PROJECT_ROOT)/obj% 60 | # $(PROJECT_ROOT)/%.xcodeproj 61 | # 62 | # Note: Leave a leading space when adding list items with the += operator 63 | ################################################################################ 64 | # PROJECT_EXCLUSIONS = 65 | 66 | ################################################################################ 67 | # PROJECT LINKER FLAGS 68 | # These flags will be sent to the linker when compiling the executable. 69 | # 70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs 71 | # 72 | # Note: Leave a leading space when adding list items with the += operator 73 | ################################################################################ 74 | 75 | # Currently, shared libraries that are needed are copied to the 76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to 77 | # add a runtime path to search for those shared libraries, since they aren't 78 | # incorporated directly into the final executable application binary. 79 | # TODO: should this be a default setting? 80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs 81 | 82 | ################################################################################ 83 | # PROJECT DEFINES 84 | # Create a space-delimited list of DEFINES. The list will be converted into 85 | # CFLAGS with the "-D" flag later in the makefile. 86 | # 87 | # (default) PROJECT_DEFINES = (blank) 88 | # 89 | # Note: Leave a leading space when adding list items with the += operator 90 | ################################################################################ 91 | # PROJECT_DEFINES = 92 | 93 | ################################################################################ 94 | # PROJECT CFLAGS 95 | # This is a list of fully qualified CFLAGS required when compiling for this 96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS 97 | # defined in your platform specific core configuration files. These flags are 98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. 99 | # 100 | # (default) PROJECT_CFLAGS = (blank) 101 | # 102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in 103 | # your platform specific configuration file will be applied by default and 104 | # further flags here may not be needed. 105 | # 106 | # Note: Leave a leading space when adding list items with the += operator 107 | ################################################################################ 108 | # PROJECT_CFLAGS = 109 | 110 | ################################################################################ 111 | # PROJECT OPTIMIZATION CFLAGS 112 | # These are lists of CFLAGS that are target-specific. While any flags could 113 | # be conditionally added, they are usually limited to optimization flags. 114 | # These flags are added BEFORE the PROJECT_CFLAGS. 115 | # 116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. 117 | # 118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) 119 | # 120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. 121 | # 122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) 123 | # 124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the 125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration 126 | # file will be applied by default and further optimization flags here may not 127 | # be needed. 128 | # 129 | # Note: Leave a leading space when adding list items with the += operator 130 | ################################################################################ 131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE = 132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG = 133 | 134 | ################################################################################ 135 | # PROJECT COMPILERS 136 | # Custom compilers can be set for CC and CXX 137 | # (default) PROJECT_CXX = (blank) 138 | # (default) PROJECT_CC = (blank) 139 | # Note: Leave a leading space when adding list items with the += operator 140 | ################################################################################ 141 | # PROJECT_CXX = 142 | # PROJECT_CC = 143 | -------------------------------------------------------------------------------- /example_simple/example_simple.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example_simple/example_simple.xcodeproj/xcshareddata/xcschemes/example_simple Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example_simple/example_simple.xcodeproj/xcshareddata/xcschemes/example_simple Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example_simple/example_simple.xcodeproj/xcuserdata/Abhi.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SuppressBuildableAutocreation 6 | 7 | E4B69B5A0A3A1756003C02F2 8 | 9 | primary 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example_simple/openFrameworks-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | cc.openFrameworks.ofapp 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | APPL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | CFBundleIconFile 20 | ${ICON} 21 | 22 | 23 | -------------------------------------------------------------------------------- /example_simple/src/MyEquations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMathMesh.h" 4 | #include "ofxAnimatableFloat.h" 5 | #include "MyEquations.h" 6 | 7 | class Parabala:public ofx3dFunction { 8 | public: 9 | Parabala():ofx3dFunction(){ 10 | a.setCurve(EASE_IN_EASE_OUT); 11 | a.setRepeatType(LOOP_BACK_AND_FORTH); 12 | a.setDuration(3.0); 13 | a.animateFromTo(-.4, .4); 14 | ofAddListener(ofEvents().update, this, &Parabala::update); 15 | } 16 | 17 | float valueForPoint(float x,float z){ 18 | return a.getCurrentValue() * pow(x, 2) + a.getCurrentValue() * pow(z, 2); 19 | } 20 | 21 | ofFloatColor colorForPoint(float x, float z,float y){ 22 | float maxY = valueForPoint(getXMax(), getZMax()); 23 | ofFloatColor color; 24 | float hueValue = ofMap(y, 0, maxY, 0, ofFloatColor::limit()); 25 | color.setHsb(hueValue, 1.0, 1.0); 26 | return color; 27 | } 28 | 29 | void update(ofEventArgs &args){ 30 | float dt = 1/ofGetFrameRate(); 31 | a.update(dt); 32 | } 33 | 34 | public: 35 | ofxAnimatableFloat a; 36 | }; 37 | 38 | 39 | class Torus:public ofxParametricSurface{ 40 | public: 41 | Torus():ofxParametricSurface(){ 42 | minU.setCurve(EASE_OUT); 43 | minU.setRepeatType(LOOP_BACK_AND_FORTH); 44 | minU.setDuration(4.0); 45 | minU.animateFromTo(2*M_PI,0); 46 | 47 | minV.setCurve(LINEAR); 48 | minV.setRepeatType(LOOP_BACK_AND_FORTH); 49 | minV.setDuration(4.0); 50 | minV.animateFromTo(2*M_PI,0); 51 | ofAddListener(ofEvents().update, this, &Torus::update); 52 | } 53 | ofPoint valueForPoint(float u,float v){ 54 | float c = 2; 55 | float a = 1; 56 | float x = (c+ a* cos(v)) * cos(u); 57 | float y = a* sin(v); 58 | float z = (c+ a*cos(v)) *sin(u); 59 | return ofPoint(x,y,z); 60 | } 61 | 62 | glm::vec2 texCoordForPoint(float u,float v,ofPoint value){ 63 | float s = u/(2*M_PI); 64 | float t = v/(2*M_PI); 65 | return glm::vec2(s,t); 66 | } 67 | 68 | ofFloatColor backColorForPoint(float u,float v,ofPoint value){ 69 | if (u <= M_PI/2) { 70 | return ofFloatColor::green; 71 | }else if(u <= M_PI ){ 72 | return ofFloatColor::orange; 73 | }else if (u <= 3*M_PI/2){ 74 | return ofFloatColor::pink; 75 | }else{ 76 | return ofFloatColor::violet; 77 | } 78 | } 79 | 80 | void update(ofEventArgs &args){ 81 | float dt = 1/ofGetFrameRate(); 82 | minU.update(dt); 83 | minV.update(dt); 84 | setUMin(minU); 85 | setVMin(minV); 86 | } 87 | 88 | public: 89 | ofxAnimatableFloat minU; 90 | ofxAnimatableFloat minV; 91 | }; 92 | 93 | 94 | class Mobius:public ofxParametricSurface { 95 | 96 | public: 97 | ofPoint valueForPoint(float u,float v){ 98 | float a = 2.0; 99 | float x = (a + (v/2.0) * cos(u/2.0)) * cos(u); 100 | float y = (a + (v/2.0) * cos(u/2.0)) * sin(u); 101 | float z = (v/2.0) * sin(u/2.0); 102 | return ofPoint(x,y,z); 103 | } 104 | 105 | ofFloatColor colorForPoint(float u, float v, ofPoint value){ 106 | if (u <= M_PI/2) { 107 | return ofFloatColor::red; 108 | }else if(u <= M_PI ){ 109 | return ofFloatColor::green; 110 | }else if (u <= 3*M_PI/2){ 111 | return ofFloatColor::white; 112 | }else{ 113 | return ofFloatColor::yellow; 114 | } 115 | } 116 | }; 117 | 118 | class Tube:public ofx3dFunction{ 119 | public: 120 | Tube():ofx3dFunction(){ 121 | height.setCurve(LINEAR); 122 | height.setRepeatType(LOOP_BACK_AND_FORTH); 123 | height.setDuration(4.0); 124 | height.animateFromTo(2,4); 125 | ofAddListener(ofEvents().update, this, &Tube::update); 126 | } 127 | 128 | float valueForPoint(float x,float z){ 129 | return 1.0/(5 * (pow(x, 2.0f) + pow(z, 2.0f))); 130 | } 131 | 132 | void update(ofEventArgs &args){ 133 | float dt = 1/ofGetFrameRate(); 134 | height.update(dt); 135 | setYMax(height); 136 | } 137 | public: 138 | ofxAnimatableFloat height; 139 | 140 | }; 141 | 142 | class Spiral:public ofxParametricCurve { 143 | 144 | public: 145 | Spiral():ofxParametricCurve(){ 146 | greenStart.setCurve(LINEAR); 147 | greenStart.setRepeatType(LOOP); 148 | greenStart.setDuration(40.0); 149 | greenStart.animateFromTo(0,2*M_PI); 150 | ofAddListener(ofEvents().update, this, &Spiral::update); 151 | } 152 | 153 | ofPoint valueForPoint(float t){ 154 | float a = 1; 155 | float r = 1; 156 | float x = t*cos(6*t); 157 | float z = t*sin(6*t); 158 | float y = t; 159 | return ofPoint(x,y,z); 160 | } 161 | 162 | ofFloatColor colorForPoint(float t, ofPoint value){ 163 | float colorRange = .1; 164 | float redStart = greenStart.getCurrentValue() + colorRange/2.0; 165 | float tWrapped = ofWrap(t, greenStart, (float)greenStart + colorRange); 166 | if (tWrapped >= (float)greenStart && tWrapped < redStart) { 167 | return ofFloatColor::green; 168 | }else{ 169 | return ofFloatColor::red; 170 | } 171 | 172 | } 173 | void update(ofEventArgs &args){ 174 | float dt = 1/ofGetFrameRate(); 175 | greenStart.update(dt); 176 | } 177 | public: 178 | ofxAnimatableFloat greenStart; 179 | }; 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /example_simple/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | 7 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context 8 | 9 | // this kicks off the running of my app 10 | // can be OF_WINDOW or OF_FULLSCREEN 11 | // pass in width and height too: 12 | ofRunApp(new ofApp()); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /example_simple/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | cam.setAutoDistance(false); 6 | cam.setNearClip(.001); 7 | cam.setTarget(glm::vec3()); 8 | cam.setPosition(0, 0, 10); 9 | ofDisableArbTex(); 10 | ofSetSmoothLighting(true); 11 | glPointSize(3.0); 12 | 13 | gui.setup(); 14 | gui.add(drawWireFrame.setup("draw wireframe",false)); 15 | gui.add(drawPoints.setup("draw points",false)); 16 | gui.add(drawNoramls.setup("draw normals",false)); 17 | gui.add(lightingOn.setup("Lighting On",false)); 18 | 19 | currentScene = 0; 20 | 21 | info.load("verdana.ttf", 20); 22 | 23 | light.setPosition(0, 3, 0); 24 | light.setScale(.01); 25 | light.setAttenuation(1.0,.2); 26 | 27 | 28 | torus.enableFlatColors(); 29 | mobius.enableFlatColors(); 30 | 31 | parabala.setup(-2, 2, -2, 2, .1, .1); 32 | torus.setup(0, 2*M_PI, 0,2*M_PI, .1, .1); 33 | mobius.setup(0, 2*M_PI, 0, 1, .1, .1); 34 | tube.setup(-2, 2, -2, 2,0,2,.1, .1); 35 | spriral.setup(0, 2*M_PI, .01); 36 | 37 | flower.load("flower.jpg"); 38 | } 39 | 40 | //-------------------------------------------------------------- 41 | void ofApp::update(){ 42 | if (currentScene == 0) { 43 | parabala.reload(); 44 | } 45 | if (currentScene == 1) { 46 | torus.reload(); 47 | } 48 | if (currentScene == 3) { 49 | tube.reload(); 50 | } 51 | if (currentScene == 4) { 52 | spriral.reload(); 53 | } 54 | } 55 | 56 | //-------------------------------------------------------------- 57 | void ofApp::draw(){ 58 | ofBackground(0); 59 | ofEnableDepthTest(); 60 | 61 | cam.begin(); 62 | if (lightingOn) { 63 | ofEnableLighting(); 64 | light.enable(); 65 | } 66 | if (currentScene == 0) { 67 | if (drawNoramls) { 68 | ofSetColor(ofColor::turquoise); 69 | parabala.drawNormals(.2); 70 | } 71 | if (drawPoints) { 72 | parabala.drawPoints(true); 73 | }else{ 74 | parabala.draw(true, false); 75 | if (drawWireFrame) { 76 | ofSetColor(ofColor::black); 77 | glEnable(GL_POLYGON_OFFSET_LINE); 78 | glPolygonOffset(-1, -1); 79 | parabala.drawWireFrame(false); 80 | glDisable(GL_POLYGON_OFFSET_LINE); 81 | } 82 | } 83 | }else if(currentScene == 1){ 84 | if (drawNoramls) { 85 | ofSetColor(ofColor::turquoise); 86 | torus.drawNormals(.2); 87 | } 88 | if (drawPoints) { 89 | torus.drawPoints(true); 90 | }else{ 91 | ofSetColor(255, 255, 255); 92 | flower.bind(); 93 | torus.drawFrontFaces(false, true); 94 | flower.unbind(); 95 | torus.drawBackFaces(true, false); 96 | if (drawWireFrame) { 97 | ofSetColor(ofColor::black); 98 | glEnable(GL_POLYGON_OFFSET_LINE); 99 | glPolygonOffset(-.01, -1); 100 | torus.drawWireFrame(false); 101 | glDisable(GL_POLYGON_OFFSET_LINE); 102 | } 103 | } 104 | }else if (currentScene == 2){ 105 | if (drawNoramls) { 106 | ofSetColor(ofColor::turquoise); 107 | mobius.drawNormals(.2); 108 | } 109 | if (drawPoints) { 110 | mobius.drawPoints(true); 111 | }else{ 112 | mobius.draw(true, false); 113 | if (drawWireFrame) { 114 | ofSetColor(ofColor::black); 115 | glEnable(GL_POLYGON_OFFSET_LINE); 116 | glPolygonOffset(-.01, -1); 117 | mobius.drawWireFrame(false); 118 | glDisable(GL_POLYGON_OFFSET_LINE); 119 | } 120 | } 121 | }else if (currentScene == 3){ 122 | if (drawNoramls) { 123 | ofSetColor(ofColor::turquoise); 124 | tube.drawNormals(.2); 125 | } 126 | if (drawPoints) { 127 | ofSetColor(ofColor::fireBrick); 128 | tube.drawPoints(false); 129 | }else{ 130 | ofSetColor(ofColor::fireBrick); 131 | tube.draw(false, false); 132 | if (drawWireFrame) { 133 | ofSetColor(ofColor::black); 134 | glEnable(GL_POLYGON_OFFSET_LINE); 135 | glPolygonOffset(-.01, -1); 136 | tube.drawWireFrame(false); 137 | glDisable(GL_POLYGON_OFFSET_LINE); 138 | } 139 | } 140 | }else if (currentScene == 4){ 141 | ofPushMatrix(); 142 | ofTranslate(-1, -4); 143 | ofSetLineWidth(3.0); 144 | if (drawPoints) { 145 | spriral.drawPoints(true); 146 | }else{ 147 | spriral.draw(true); 148 | } 149 | ofSetLineWidth(1.0); 150 | ofPopMatrix(); 151 | } 152 | 153 | if (lightingOn) { 154 | light.draw(); 155 | light.disable(); 156 | ofDisableLighting(); 157 | } 158 | 159 | cam.end(); 160 | 161 | ofDisableDepthTest(); 162 | gui.draw(); 163 | ofSetColor(ofColor::white); 164 | info.drawString("press right/left arrows move to next scene",240, 700); 165 | if (currentScene == 0) { 166 | info.drawString("Parabala with custom colors", 250, 50); 167 | }else if (currentScene == 1){ 168 | info.drawString("Torus with texture on front side\nand custom colors on back side", 250, 50); 169 | }else if (currentScene == 2){ 170 | info.drawString("Mobius Strip with custom colors", 250, 50); 171 | }else if (currentScene == 3){ 172 | info.drawString("Tube with no custom colors, varying yBounds", 250, 50); 173 | }else if (currentScene == 4){ 174 | info.drawString("Spiral with custom colors", 250, 50); 175 | } 176 | } 177 | 178 | //-------------------------------------------------------------- 179 | void ofApp::keyPressed(int key){ 180 | if (key == OF_KEY_RIGHT) { 181 | currentScene++; 182 | if (currentScene == 5) { 183 | currentScene = 0; 184 | } 185 | }else if(key == OF_KEY_LEFT){ 186 | currentScene--; 187 | if (currentScene == -1) { 188 | currentScene = 4; 189 | } 190 | } 191 | } 192 | 193 | //-------------------------------------------------------------- 194 | void ofApp::keyReleased(int key){ 195 | 196 | } 197 | 198 | //-------------------------------------------------------------- 199 | void ofApp::mouseMoved(int x, int y ){ 200 | 201 | } 202 | 203 | //-------------------------------------------------------------- 204 | void ofApp::mouseDragged(int x, int y, int button){ 205 | 206 | } 207 | 208 | //-------------------------------------------------------------- 209 | void ofApp::mousePressed(int x, int y, int button){ 210 | 211 | } 212 | 213 | //-------------------------------------------------------------- 214 | void ofApp::mouseReleased(int x, int y, int button){ 215 | 216 | } 217 | 218 | //-------------------------------------------------------------- 219 | void ofApp::windowResized(int w, int h){ 220 | 221 | } 222 | 223 | //-------------------------------------------------------------- 224 | void ofApp::gotMessage(ofMessage msg){ 225 | 226 | } 227 | 228 | //-------------------------------------------------------------- 229 | void ofApp::dragEvent(ofDragInfo dragInfo){ 230 | 231 | } 232 | 233 | 234 | -------------------------------------------------------------------------------- /example_simple/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGui.h" 5 | #include "MyEquations.h" 6 | 7 | class ofApp : public ofBaseApp{ 8 | 9 | public: 10 | void setup(); 11 | void update(); 12 | void draw(); 13 | 14 | void keyPressed(int key); 15 | void keyReleased(int key); 16 | void mouseMoved(int x, int y ); 17 | void mouseDragged(int x, int y, int button); 18 | void mousePressed(int x, int y, int button); 19 | void mouseReleased(int x, int y, int button); 20 | void windowResized(int w, int h); 21 | void dragEvent(ofDragInfo dragInfo); 22 | void gotMessage(ofMessage msg); 23 | 24 | int currentScene; 25 | 26 | ofxPanel gui; 27 | ofxToggle drawWireFrame; 28 | ofxToggle drawPoints; 29 | ofxToggle drawNoramls; 30 | ofxToggle lightingOn; 31 | 32 | ofTrueTypeFont info; 33 | 34 | ofEasyCam cam; 35 | 36 | ofLight light; 37 | Parabala parabala; 38 | Torus torus; 39 | Mobius mobius; 40 | Tube tube; 41 | Spiral spriral; 42 | 43 | ofImage flower; 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatable.h 3 | * 4 | * Created by Oriol Ferrer Mesià on 30/10/09. 5 | * Copyright 2009 uri.cat. All rights reserved. 6 | * 7 | */ 8 | 9 | 10 | #define DEFAULT_ANIMATION_DURATION 1.0f 11 | 12 | 13 | #include 14 | #define _USE_MATH_DEFINES 15 | #include 16 | #include 17 | using namespace std; 18 | 19 | #pragma once 20 | #include "ofMain.h" 21 | 22 | 23 | enum AnimRepeat{ 24 | PLAY_ONCE = 0, 25 | LOOP, 26 | LOOP_BACK_AND_FORTH, 27 | LOOP_BACK_AND_FORTH_ONCE, 28 | }; 29 | 30 | enum AnimCurve{ 31 | EASE_IN_EASE_OUT = 0, 32 | EASE_IN, 33 | EASE_OUT, 34 | LINEAR, 35 | EARLY_LINEAR, 36 | LATE_LINEAR, 37 | VERY_LATE_LINEAR, 38 | BOUNCY, //this needs work TODO 39 | OBJECT_DROP, 40 | TANH, 41 | SINH, 42 | EARLY_SQUARE, 43 | SQUARE, 44 | LATE_SQUARE, 45 | BLINK_5, 46 | BLINK_3, 47 | BLINK_2, 48 | BLINK_AND_FADE_1, 49 | BLINK_AND_FADE_2, 50 | BLINK_AND_FADE_3, 51 | LATE_EASE_IN_EASE_OUT, 52 | VERY_LATE_EASE_IN_EASE_OUT, 53 | QUADRATIC_EASE_IN, 54 | QUADRATIC_EASE_OUT, 55 | EARLY_QUADRATIC_EASE_OUT, 56 | QUADRATIC_BEZIER_PARAM, //http://www.flong.com/texts/code/shapers_exp/ 57 | EXPONENTIAL_SIGMOID_PARAM, 58 | NUM_ANIM_CURVES //leave that on the last to see how many we have 59 | }; 60 | 61 | 62 | class ofxAnimatable{ 63 | 64 | public: 65 | 66 | void setup(); 67 | void update(float dt); 68 | 69 | void pause(); //really needed? 70 | void resume(); // 71 | 72 | void setCurve( AnimCurve curveStyle_ ); 73 | void setRepeatType( AnimRepeat repeat ); 74 | void setDuration( float seconds ); 75 | 76 | void setDoubleExpSigmoidParam(float param){doubleExpSigmoidParam = param;} //only for QUADRATIC_BEZIER_PARAM curve 77 | void setQuadraticBezierParams(float a, float b){quadraticBezierParamA = a; quadraticBezierParamB = b; } //only for EXPONENTIAL_SIGMOID_PARAM curve 78 | void setDropObjectParams(float bounceHeightPercent){bounceAmp = bounceHeightPercent;} //only for DROP_OBJECT curve 79 | 80 | float getDuration(){ return 1.0f/transitionSpeed_; } 81 | 82 | float getPercentDone(); ///get how much of the animation has been "walked" 83 | void setPercentDone(float p); //Will allow to skip to any point of animation. use carefully 84 | bool isAnimating(); ///is the animation still going on? 85 | bool hasFinishedAnimating(); ///has the animation finished? 86 | bool isWaitingForAnimationToStart(); ///an animation has been scheduled with "animateToAfterDelay" 87 | bool isOrWillBeAnimating(); /// object is either animating now or it's waiting to be launch animation after a delay 88 | float getCurrentSpeed(); ///as a percentage of linear speed 89 | float timeLeftForAnimationToStart(){ return delay_; } 90 | float waitTimeLeftPercent(){ return 1.0f - delay_ / waitTime_; } 91 | 92 | static string getCurveName(AnimCurve c); 93 | 94 | //carefull with those, you'd better know what you are doing, those should almost be protected 95 | static float calcCurveAt(float percent, AnimCurve type, float param1 = 0.5, float param2 = 0.5, float param3 = 0.5); //exposing this to get direct access to simple curve values 96 | float calcCurveAt( float percent ); 97 | void drawCurve(int x, int y, int size, bool bg = false); 98 | 99 | virtual ~ofxAnimatable(void) {} 100 | ofxAnimatable() {} 101 | 102 | 103 | protected: 104 | 105 | bool animating_; 106 | bool paused_; 107 | 108 | int playcount_; 109 | 110 | float transitionSpeed_; ///this is 1/N (N == # of updates) it will take for the transition to end 111 | float percentDone_; /// [0..1] 112 | 113 | 114 | float delay_; //countdown timer that stores delay when startAnimationAfterDelay() is used 115 | float waitTime_; //original wait delay_ 116 | AnimRepeat repeat_; 117 | AnimCurve curveStyle_; 118 | 119 | int direction_; // 1 : forward, -1 : backward 120 | 121 | 122 | 123 | void startAnimation(); ///Used by subclasses to indicate we are starting an anim 124 | void startAnimationAfterDelay(float delay); 125 | void reset(); ///Used by subclasses to indicate a reset of an animation 126 | void fillInParams(float&p1, float &p2, float &p3); 127 | 128 | private: 129 | 130 | virtual void startAfterWait() = 0; 131 | float currentSpeed_; 132 | float prevSpeed_; 133 | float lastDT_; 134 | 135 | //for some of the curves 136 | float doubleExpSigmoidParam; 137 | float quadraticBezierParamA, quadraticBezierParamB; 138 | float bounceAmp; 139 | }; 140 | 141 | -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatableFloat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * ofxAnimatableFloat.cpp 3 | * 4 | * 5 | * Created by Oriol Ferrer Mesia on 2008/10/09. 6 | * 7 | */ 8 | 9 | #include "ofxAnimatableFloat.h" 10 | 11 | ofxAnimatableFloat::ofxAnimatableFloat(){ 12 | 13 | ofxAnimatable::setup(); 14 | originalVal_ = targetVal_= 0.0f; 15 | } 16 | 17 | 18 | void ofxAnimatableFloat::update( float dt ){ 19 | 20 | ofxAnimatable::update( dt ); 21 | } 22 | 23 | 24 | void ofxAnimatableFloat::animateTo( float newVal ){ 25 | 26 | originalVal_ = val(); 27 | targetVal_ = newVal; 28 | 29 | ofxAnimatable::startAnimation(); 30 | } 31 | 32 | 33 | void ofxAnimatableFloat::animateToAfterDelay( float newVal, float delay ){ 34 | 35 | if (delay <= 0.0f){ 36 | animateTo(newVal); 37 | }else{ 38 | //originalTempVal_ = val(); 39 | targetTempVal_ = newVal; 40 | ofxAnimatable::startAnimationAfterDelay(delay); 41 | } 42 | } 43 | 44 | 45 | void ofxAnimatableFloat::animateFromTo( float originalValue, float destinationValue ){ 46 | 47 | ofxAnimatable::startAnimation(); 48 | 49 | originalVal_ = originalValue; 50 | targetVal_ = destinationValue; 51 | } 52 | 53 | 54 | void ofxAnimatableFloat::animateToIfFinished( float newVal ){ 55 | if ( animating_ == false ){ 56 | animateTo(newVal); 57 | } 58 | } 59 | 60 | 61 | float ofxAnimatableFloat::val(){ 62 | 63 | float mappedDistribution = calcCurveAt( percentDone_ ); ///percentDone_ is [0..1] & tells me where we are between orig and target 64 | return originalVal_ + ( targetVal_ - originalVal_ ) * mappedDistribution ; 65 | } 66 | 67 | 68 | void ofxAnimatableFloat::reset( float newVal ){ 69 | 70 | ofxAnimatable::reset(); 71 | originalVal_ = targetVal_ = newVal; 72 | } 73 | 74 | 75 | void ofxAnimatableFloat::reset(){ 76 | 77 | ofxAnimatable::reset(); 78 | targetVal_ = originalVal_; 79 | } 80 | 81 | 82 | void ofxAnimatableFloat::startAfterWait(){ 83 | animateTo(targetTempVal_); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatableFloat.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * ofxAnimatableFloat.h 4 | * 5 | * 6 | * Created by Oriol Ferrer Mesia on 24/09/08. 7 | * 8 | */ 9 | 10 | #pragma once 11 | #include "ofxAnimatable.h" 12 | 13 | class ofxAnimatableFloat : public ofxAnimatable{ 14 | 15 | public: 16 | 17 | ofxAnimatableFloat(); 18 | ~ofxAnimatableFloat(){}; 19 | 20 | void update( float dt ); 21 | 22 | void animateTo( float newVal ); 23 | void animateToAfterDelay( float newVal, float delay ); 24 | void animateToIfFinished( float newVal ); ///starts new animation to newVal only if there isnt an anim going on 25 | void animateFromTo( float originalValue, float destinationValue ); 26 | 27 | 28 | //gets 29 | float val(); ///gives you the current value. 30 | float getCurrentValue(){ return val(); } 31 | float getTargetValue(){ return targetVal_;} 32 | float getOriginalValue(){ return originalVal_;} 33 | 34 | void reset(float newVal); ///sets an original value, and stops animation 35 | void reset(); ///goes back to the original value 36 | 37 | 38 | 39 | ///trying to make everyone life's easier with operators, I want an ofxAnimatableFloat to behave 40 | ///like a float here, but doesn't quite work all the time 41 | ///so you'd better use the .val() method to get the current value 42 | 43 | operator float(){ return val(); } ///return current value when asking for float 44 | operator double(){ return val(); } ///return current value when asking for double 45 | 46 | private: 47 | 48 | // ## MUST IMPLEMENT ## 49 | void startAfterWait(); 50 | float originalVal_; 51 | float targetVal_; 52 | float targetTempVal_; 53 | 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatableOfColor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfColor.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatableOfColor.h" 11 | 12 | 13 | ofxAnimatableOfColor::ofxAnimatableOfColor(){ 14 | 15 | setup(); 16 | originalColor_ = ofColor::black; 17 | targetColor_ = ofColor::white; 18 | } 19 | 20 | 21 | void ofxAnimatableOfColor::update(float dt){ 22 | ofxAnimatable::update( dt ); 23 | } 24 | 25 | 26 | void ofxAnimatableOfColor::applyCurrentColor(){ 27 | ofSetColor( getCurrentColor() ); 28 | } 29 | 30 | 31 | void ofxAnimatableOfColor::setColor(ofColor newColor){ 32 | ofxAnimatable::reset(); 33 | originalColor_ = newColor; 34 | targetColor_ = newColor; 35 | } 36 | 37 | 38 | void ofxAnimatableOfColor::revertToBaseColor(){ 39 | ofxAnimatable::reset(); 40 | } 41 | 42 | 43 | void ofxAnimatableOfColor::setAlphaOnly( float a ){ 44 | 45 | originalColor_ = getCurrentColor(); 46 | originalColor_.a = a; 47 | targetColor_ = originalColor_; 48 | ofxAnimatable::reset(); 49 | } 50 | 51 | 52 | void ofxAnimatableOfColor::animateTo( ofColor col ){ 53 | 54 | originalColor_ = getCurrentColor(); 55 | targetColor_ = col; 56 | ofxAnimatable::startAnimation(); 57 | } 58 | 59 | 60 | void ofxAnimatableOfColor::animateToAfterDelay( ofColor newColor, float delay ){ 61 | 62 | //originalTempColor_ = getCurrentColor(); 63 | targetTempColor_ = newColor; 64 | ofxAnimatable::startAnimationAfterDelay(delay); 65 | } 66 | 67 | 68 | void ofxAnimatableOfColor::animateToIfFinished( ofColor col ){ 69 | if (animating_ == false){ 70 | animateTo( col ); 71 | } 72 | } 73 | 74 | 75 | void ofxAnimatableOfColor::fadeIn(){ 76 | 77 | ofColor targetC = getCurrentColor(); 78 | 79 | if ( sizeof(targetC.r) == sizeof(float) ) 80 | targetC.a = (float)1.0f; 81 | else if ( sizeof(targetC.r) == sizeof(unsigned char) ) 82 | targetC.a = (unsigned char) numeric_limits::max(); 83 | else if ( sizeof(targetC.r) == sizeof(unsigned short) ) 84 | targetC.a = (unsigned char) numeric_limits::max(); 85 | 86 | animateTo( targetC ); 87 | } 88 | 89 | 90 | void ofxAnimatableOfColor::fadeOut(){ 91 | 92 | ofColor targetC = getCurrentColor(); 93 | targetC.a = 0.0f; 94 | animateTo( targetC ); 95 | } 96 | 97 | 98 | void ofxAnimatableOfColor::animateToAlpha( float a ){ 99 | 100 | originalColor_ = getCurrentColor(); 101 | targetColor_ = originalColor_; 102 | targetColor_.a = a; 103 | ofxAnimatable::startAnimation(); 104 | } 105 | 106 | 107 | void ofxAnimatableOfColor::startBlinking( float blinkDuration){ 108 | 109 | setRepeatType(LOOP_BACK_AND_FORTH); 110 | setCurve(EASE_IN_EASE_OUT); 111 | setAlphaOnly(0.0f); 112 | setDuration( blinkDuration ); 113 | ofColor c = getCurrentColor(); 114 | c.a = 255; 115 | animateTo( c ); 116 | } 117 | 118 | 119 | ofColor ofxAnimatableOfColor::getCurrentColor(){ 120 | 121 | float mappedDistribution = calcCurveAt(percentDone_); ///percentDone_ is [0..1] & tells me where we are between orig and target 122 | float newC[4]; 123 | ofColor r; 124 | for (int i = 0; i < 4; i++){ 125 | newC[i] = ( (int)targetColor_[i] - (int)originalColor_[i]) * mappedDistribution; 126 | r[i] = originalColor_[i] + newC[i]; 127 | } 128 | return r; 129 | } 130 | 131 | void ofxAnimatableOfColor::startAfterWait(){ 132 | animateTo(targetTempColor_); 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatableOfColor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfColor.h 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef _ANIMATABLE_COLOR_INC 11 | #define _ANIMATABLE_COLOR_INC 12 | 13 | #include "ofxAnimatable.h" 14 | #include "ofMain.h" 15 | 16 | 17 | class ofxAnimatableOfColor : public ofxAnimatable { 18 | 19 | public: 20 | 21 | ofxAnimatableOfColor(); 22 | ~ofxAnimatableOfColor(){}; 23 | 24 | void update(float dt); 25 | void applyCurrentColor(); //apply current color 26 | 27 | // apply for immediate effect //////////////////////////////////////////////////////////////////// 28 | 29 | void setColor( ofColor newColor ); 30 | void revertToBaseColor(); 31 | void setAlphaOnly( float a ); 32 | 33 | // animated over time /////////////////////////////////////////////////////////////////////////// 34 | 35 | ///starts new fade to "col" regardless, using the current color as the inital value 36 | void animateTo( ofColor col ); 37 | void animateToAfterDelay( ofColor newColor, float delay ); 38 | void animateToIfFinished( ofColor col ); 39 | void fadeIn(); 40 | void fadeOut(); 41 | void animateToAlpha( float a ); 42 | void startBlinking(float blinkDuration = 1.0f); ///will set repeat to LOOP_BACK_AND_FORTH, curve to EASE_IN_EASE_OUT 43 | 44 | //gets 45 | ofColor getCurrentColor(); 46 | ofColor getTargetColor(){ return targetColor_;} 47 | ofColor getOriginalColor(){ return originalColor_;} 48 | 49 | 50 | 51 | private: 52 | 53 | void startAfterWait(); 54 | 55 | ofColor originalColor_; 56 | ofColor targetColor_; 57 | ofColor targetTempColor_; 58 | 59 | }; 60 | 61 | 62 | #endif -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatableOfPoint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfPoint.cpp 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "ofxAnimatableOfPoint.h" 11 | 12 | 13 | ofxAnimatableOfPoint::ofxAnimatableOfPoint(){ 14 | 15 | ofxAnimatable::setup(); //defaults to (0,0,0) >> (0,0,0) 16 | } 17 | 18 | 19 | void ofxAnimatableOfPoint::update(float dt){ 20 | 21 | ofxAnimatable::update( dt ); 22 | } 23 | 24 | 25 | void ofxAnimatableOfPoint::draw(){ 26 | 27 | ofPushMatrix(); 28 | ofPoint p = getCurrentPosition(); 29 | ofTranslate(p.x, p.y, p.z); 30 | float s = 10.0f; 31 | ofDrawRectangle( -s * 0.5f, -s * 0.5f, s, s ); 32 | ofPopMatrix(); 33 | 34 | } 35 | 36 | 37 | void ofxAnimatableOfPoint::setPosition( ofPoint newPos ){ 38 | 39 | ofxAnimatable::reset(); 40 | originalPoint_ = newPos; 41 | targetPoint_ = newPos; 42 | } 43 | 44 | 45 | void ofxAnimatableOfPoint::setPositionX( float newX ){ 46 | 47 | originalPoint_ = getCurrentPosition(); 48 | originalPoint_.x = newX; 49 | targetPoint_ = originalPoint_; 50 | ofxAnimatable::reset(); 51 | } 52 | 53 | 54 | void ofxAnimatableOfPoint::setPositionY( float newY ){ 55 | 56 | originalPoint_ = getCurrentPosition(); 57 | originalPoint_.y = newY; 58 | targetPoint_ = originalPoint_; 59 | ofxAnimatable::reset(); 60 | } 61 | 62 | 63 | void ofxAnimatableOfPoint::setPositionZ( float newZ ){ 64 | 65 | originalPoint_ = getCurrentPosition(); 66 | originalPoint_.z = newZ; 67 | targetPoint_ = originalPoint_; 68 | ofxAnimatable::reset(); 69 | } 70 | 71 | 72 | void ofxAnimatableOfPoint::reset(){ 73 | 74 | ofxAnimatable::reset(); 75 | targetPoint_ = originalPoint_; 76 | } 77 | 78 | 79 | void ofxAnimatableOfPoint::animateTo( ofPoint where ){ 80 | 81 | originalPoint_ = getCurrentPosition(); 82 | targetPoint_ = where; 83 | ofxAnimatable::startAnimation(); 84 | } 85 | 86 | void ofxAnimatableOfPoint::animateToAfterDelay( ofPoint where, float delay ){ 87 | 88 | if (delay <= 0.0f){ 89 | animateTo(where); 90 | }else{ 91 | //originalTempPoint_ = getCurrentPosition(); 92 | targetTempPoint_ = where; 93 | ofxAnimatable::startAnimationAfterDelay(delay); 94 | } 95 | } 96 | 97 | 98 | void ofxAnimatableOfPoint::animateToIfFinished( ofPoint where ){ 99 | 100 | if (animating_ == false){ 101 | animateTo(where); 102 | } 103 | } 104 | 105 | 106 | ofPoint ofxAnimatableOfPoint::getCurrentPosition(){ 107 | float mappedDistribution = calcCurveAt(percentDone_); ///percentDone_ is [0..1] & tells me where we are between orig and target 108 | return originalPoint_ + ( targetPoint_ - originalPoint_) * mappedDistribution ; 109 | } 110 | 111 | 112 | void ofxAnimatableOfPoint::startAfterWait(){ 113 | animateTo(targetTempPoint_); 114 | } 115 | -------------------------------------------------------------------------------- /example_simple/src/ofxAnimatableOfPoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ofxAnimatableOfPoint.h 3 | * Cocoa Test 4 | * 5 | * Created by Oriol Ferrer Mesià on 28/10/09. 6 | * Copyright 2009 uri.cat. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef _ANIMATABLE_POINT_INC 11 | #define _ANIMATABLE_POINT_INC 12 | 13 | #include "ofxAnimatable.h" 14 | #include "ofMain.h" 15 | 16 | 17 | class ofxAnimatableOfPoint : public ofxAnimatable{ 18 | 19 | public: 20 | 21 | ofxAnimatableOfPoint(); 22 | ~ofxAnimatableOfPoint(){}; 23 | 24 | void update(float dt); 25 | void draw(); //draws the current pos point in space 26 | 27 | 28 | // apply for immediate effect //////////////////////////////////////////////////////////////////// 29 | 30 | void setPosition( ofPoint ); 31 | void setPositionX(float); 32 | void setPositionY(float); 33 | void setPositionZ(float); 34 | void reset(); 35 | 36 | // animated over time /////////////////////////////////////////////////////////////////////////// 37 | 38 | ///starts new animation to "where" regardless, using the current pos as the inital value 39 | void animateTo( ofPoint where ); 40 | void animateToAfterDelay( ofPoint where, float delay ); 41 | 42 | void animateToIfFinished( ofPoint where ); 43 | 44 | //gets 45 | ofPoint getCurrentPosition(); 46 | ofPoint getTargetPosition(){ return targetPoint_;} 47 | ofPoint getOriginalPosition(){ return originalPoint_;} 48 | 49 | 50 | private: 51 | 52 | void startAfterWait(); 53 | 54 | ofPoint originalPoint_; 55 | ofPoint targetPoint_; 56 | ofPoint targetTempPoint_; 57 | 58 | 59 | }; 60 | 61 | 62 | #endif -------------------------------------------------------------------------------- /src/ofx2dFunction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ofx2dFunction.h" 3 | 4 | 5 | void ofx2dFunction::setXMax(float xMax_){ 6 | if (xMax_ <= absXMax) { 7 | xMax = xMax_; 8 | }else{ 9 | xMax = absXMax; 10 | ofLogWarning("ofxMathMesh") << "cannot set xMax greater than setup xMax"; 11 | } 12 | } 13 | 14 | void ofx2dFunction::setXMin(float xMin_){ 15 | if (xMin_ >= absXMin) { 16 | xMin = xMin_; 17 | }else{ 18 | xMin = absXMin; 19 | ofLogWarning("ofxMathMesh") << "cannot set xMin smaller than setup xMin"; 20 | } 21 | } 22 | 23 | void ofx2dFunction::setXBounds(float xMin_, float xMax_){ 24 | setXMin(xMin_); 25 | setXMax(xMax_); 26 | } 27 | 28 | void ofx2dFunction::setYBounds(float yMin, float yMax){ 29 | setUseYBounds(true); 30 | this->yMin = yMin; 31 | this->yMax = yMax; 32 | } 33 | 34 | void ofx2dFunction::loadDomainPoints(){ 35 | float epsilon = step/100.0; 36 | for (float x = absXMin; x <= absXMax + epsilon; x+=step) { 37 | domainPoints.push_back(x); 38 | } 39 | } 40 | 41 | void ofx2dFunction::setStep(float step_){ 42 | float range = absXMax - absXMin; 43 | if (step_ > range) { 44 | ofLogWarning("ofxMathMesh") << "cannot set step greater than range"; 45 | step = range; 46 | return; 47 | } 48 | int res = round(range/step_); 49 | step = range/(float)res; 50 | } 51 | 52 | void ofx2dFunction::setup(float xMin_, float xMax_, float step_){ 53 | if (step_ <= 0) { 54 | ofLogWarning("ofxMathMesh") << "step must be greater than zero"; 55 | return; 56 | } 57 | isSetup = true; 58 | absXMax = xMax_; 59 | absXMin = xMin_; 60 | setStep(step_); 61 | setXBounds(xMin_, xMax_); 62 | loadDomainPoints(); 63 | reload(); 64 | } 65 | 66 | void ofx2dFunction::setup(float xMin_, float xMax_, float yMin_, float yMax_, float step_){ 67 | setYBounds(yMin_, yMax_); 68 | setup(xMin_, xMax_, step_); 69 | } 70 | 71 | void ofx2dFunction::reload(){ 72 | if (!isSetup) { 73 | ofLogError("ofxMathMesh") << "cannot reload if the function is not setup"; 74 | return; 75 | } 76 | clear(); 77 | int xMinDomainPoint = round(ofMap(xMin, absXMin, absXMax, 0, domainPoints.size() - 1)); 78 | int xMaxDomainPoint = round(ofMap(xMax, absXMin, absXMax, 0, domainPoints.size()-1)); 79 | for (int i = xMinDomainPoint; i < xMaxDomainPoint; i++){ 80 | glm::vec2 one = glm::vec2(domainPoints[i],valueForPoint(domainPoints[i])); 81 | glm::vec2 two = glm::vec2(domainPoints[i+1],valueForPoint(domainPoints[i+1])); 82 | if (bUseYBounds) { 83 | addLineSegClip(one,two); 84 | }else{ 85 | addLineSeg(one, two); 86 | } 87 | } 88 | } 89 | 90 | void ofx2dFunction::addLineSeg(const glm::vec2 &one, const glm::vec2 &two){ 91 | glm::vec3 one2D = glm::vec3(one.x,one.y,0.0f); 92 | glm::vec3 two2D = glm::vec3(two.x,two.y,0.0f); 93 | vertices.push_back(one2D); 94 | vertices.push_back(two2D); 95 | 96 | ofFloatColor color1 = colorForPoint(one.x, one.y); 97 | ofFloatColor color2 = colorForPoint(two.x, two.y); 98 | 99 | colors.push_back(color1); 100 | colors.push_back(color2); 101 | } 102 | 103 | 104 | void ofx2dFunction::addLineSegClip(const glm::vec2 &one, const glm::vec2 &two){ 105 | ofMesh tempMesh; 106 | glm::vec2 yMaxLine[2]; 107 | glm::vec2 intersection; 108 | yMaxLine[0] = glm::vec2(xMin-10,yMax); 109 | yMaxLine[1] = glm::vec2(xMax+10, yMax); 110 | 111 | if (one.y > yMax && two.y < yMax) { 112 | ofLineSegmentIntersection(one, two, yMaxLine[0], yMaxLine[1], intersection); 113 | tempMesh.addVertex(glm::vec3(intersection.x, intersection.y, 0.0f)); 114 | glm::vec3 two2D = glm::vec3(two.x,two.y,0.0f); 115 | tempMesh.addVertex(two2D); 116 | }else if (one.y < yMax && two.y > yMax ){ 117 | ofLineSegmentIntersection(one, two, yMaxLine[0], yMaxLine[1], intersection); 118 | glm::vec3 one2D = glm::vec3(one.x,one.y,0.0f); 119 | tempMesh.addVertex(one2D); 120 | tempMesh.addVertex(glm::vec3(intersection.x, intersection.y, 0.0f)); 121 | }else if (one.y <= yMax && two.y <=yMax){ 122 | tempMesh.addVertex(glm::vec3(one.x, one.y, 0.0f)); 123 | tempMesh.addVertex(glm::vec3(two.x, two.y, 0.0f)); 124 | }else if (one.y > yMax && two.y > yMax){ 125 | 126 | } 127 | glm::vec2 yMinLine[2]; 128 | yMinLine[0] = glm::vec2(xMin-10,yMin); 129 | yMinLine[1] = glm::vec2(xMax+10,yMin); 130 | for (int i = 0 ; i < tempMesh.getVertices().size(); i+=2) { 131 | glm::vec2 a = glm::vec2(tempMesh.getVertices()[i]); 132 | glm::vec2 b = glm::vec2(tempMesh.getVertices()[i+1]); 133 | if (a.y < yMin && b.y > yMin) { 134 | ofLineSegmentIntersection(a, b, yMinLine[0], yMinLine[1], intersection); 135 | addLineSeg(intersection, b); 136 | }else if (a.y > yMin && b.y < yMin){ 137 | ofLineSegmentIntersection(a, b, yMinLine[0], yMinLine[1], intersection); 138 | addLineSeg(a, intersection); 139 | }else if (a.y >= yMin && b.y >=yMin){ 140 | addLineSeg(a, b); 141 | }else if (a.y < yMin && b.y < yMin){ 142 | 143 | } 144 | } 145 | } 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/ofx2dFunction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxMathCurve.h" 5 | 6 | // creates meshes of the form y = f(x) 7 | class ofx2dFunction:public ofxMathCurve { 8 | public: 9 | virtual ~ofx2dFunction(){} 10 | ofx2dFunction(){bUseYBounds = false; isSetup= false;} 11 | 12 | // override these functions to configure your function 13 | // valueForPoint is mandatory, the rest are optional 14 | // x is the domain and y is the range 15 | virtual float valueForPoint(float x) = 0; 16 | virtual ofFloatColor colorForPoint(float x,float y) {return ofFloatColor::white;} 17 | 18 | // setups the function. You must call this before anything else. 19 | // You want to set xMin and xMax to the largest possible range (xMax-xMin) 20 | // that will be displayed on screen. Step defines the resoultion of your function. 21 | // Smaller Values give better Resolution. 22 | void setup(float xMin,float xMax,float step); 23 | void setup(float xMin,float xMax,float yMin,float yMax,float step); 24 | 25 | // reloads data. Whenever you make a change to the equation or bounds call reload. 26 | void reload(); 27 | 28 | void setXBounds(float xMin,float xMax); 29 | void setYBounds(float yMin,float yMax); 30 | void setXMin(float xMin); 31 | void setXMax(float xMax); 32 | void setYMin(float yMin){this->yMin = yMin;} 33 | void setYMax(float yMax){this->yMax = yMax;} 34 | 35 | void setUseYBounds(bool useYBounds){bUseYBounds = useYBounds;} 36 | 37 | 38 | float getXmin()const{return xMin;} 39 | float getXMax()const{return xMax;} 40 | float getYMin()const{return yMin;} 41 | float getYMax()const{return yMax;} 42 | 43 | float getStep()const{return step;} 44 | 45 | private: 46 | void addLineSeg(const glm::vec2 &one, const glm::vec2 &two); 47 | void addLineSegClip(const glm::vec2 &one, const glm::vec2 &two); 48 | void setStep(float step); 49 | void loadDomainPoints(); 50 | 51 | vector domainPoints; 52 | bool isSetup; 53 | float step; 54 | float xMin; 55 | float xMax; 56 | float yMin; 57 | float yMax; 58 | float absXMin; 59 | float absXMax; 60 | float bUseYBounds; 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /src/ofx3dFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "ofx3dFunction.h" 2 | 3 | void ofx3dFunction::setXStep(float step_){ 4 | float range = absXMax - absXMin; 5 | if (step_ > range) { 6 | ofLogWarning("ofxMathMesh") << "cannot set step greater than range"; 7 | xStep = range; 8 | return; 9 | } 10 | int res = round(range/step_); 11 | xStep = range/(float)res; 12 | } 13 | 14 | void ofx3dFunction::setZStep(float step_){ 15 | float range = absZMax - absZMin; 16 | if (step_ > range) { 17 | ofLogWarning("ofxMathMesh") << "cannot set step greater than range"; 18 | zStep = range; 19 | return; 20 | } 21 | int res = round(range/step_); 22 | zStep = range/(float)res; 23 | } 24 | 25 | void ofx3dFunction::setXMin(float xMin_){ 26 | if (xMin_ >= absXMin) { 27 | xMin = xMin_; 28 | }else{ 29 | xMin = absXMin; 30 | ofLogWarning("ofxMathMesh") << "cannot set xMin smaller than setup xMin"; 31 | } 32 | } 33 | 34 | void ofx3dFunction::setXMax(float xMax_){ 35 | if (xMax_ <= absXMax) { 36 | xMax = xMax_; 37 | }else{ 38 | xMax = absXMax; 39 | ofLogWarning("ofxMathMesh") << "cannot set xMax bigger than setup xMax"; 40 | 41 | } 42 | } 43 | 44 | void ofx3dFunction::setZMin(float zMin_){ 45 | if (zMin_ >= absZMin) { 46 | zMin = zMin_; 47 | }else{ 48 | zMin = absZMin; 49 | ofLogWarning("ofxMathMesh") << "cannot set zMin smaller than setup zMin"; 50 | } 51 | } 52 | 53 | void ofx3dFunction::setZMax(float zMax_){ 54 | if (zMax_ <= absZMax) { 55 | zMax = zMax_; 56 | }else{ 57 | zMax = absZMax; 58 | ofLogWarning("ofxMathMesh") << "cannot set zMax bigger than setup zMax"; 59 | } 60 | } 61 | 62 | void ofx3dFunction::loadDomainPoints(){ 63 | float epsilon = xStep/100.0; 64 | for (float x = absXMin; x <= absXMax + epsilon; x+=xStep) { 65 | xDomainPoints.push_back(x); 66 | } 67 | epsilon = zStep/100.0; 68 | for (float z = absZMin; z <= absZMax + epsilon; z+=zStep) { 69 | zDomainPoints.push_back(z); 70 | } 71 | } 72 | 73 | void ofx3dFunction::setXBounds(float xMin_, float xMax_){ 74 | setXMin(xMin_); 75 | setXMax(xMax_); 76 | } 77 | 78 | void ofx3dFunction::setZBounds(float zMin_, float zMax_){ 79 | setZMin(zMin_); 80 | setZMax(zMax_); 81 | } 82 | 83 | void ofx3dFunction::setYBounds(float yMin, float yMax){ 84 | setUseYBounds(true); 85 | this->yMin = yMin; 86 | this->yMax = yMax; 87 | } 88 | 89 | void ofx3dFunction::setup(float xMin_, float xMax_, float zMin_, float zMax_,float xStep_,float zStep_){ 90 | if (xStep_ <= 0 || zStep_ <= 0 ) { 91 | ofLogWarning("ofxMathMesh") << "step must be greater than zero"; 92 | return; 93 | } 94 | isSetup = true; 95 | absXMin = xMin_; 96 | absXMax = xMax_; 97 | absZMin = zMin_; 98 | absZMax = zMax_; 99 | setXStep(xStep_); 100 | setZStep(zStep_); 101 | loadDomainPoints(); 102 | setXBounds(xMin_, xMax_); 103 | setZBounds(zMin_, zMax_); 104 | reload(); 105 | } 106 | 107 | void ofx3dFunction::setup(float xMin_, float xMax_, float zMin_, float zMax_, float yMin_, float yMax_,float xStep_, float zStep_){ 108 | setYBounds(yMin_, yMax_); 109 | setup(xMin_,xMax_,zMin_,zMax_,xStep_,zStep_); 110 | } 111 | 112 | void ofx3dFunction::reload(){ 113 | if (!isSetup) { 114 | ofLogError("ofxMathMesh") << "cannot reload if function is not setup"; 115 | return; 116 | } 117 | clear(); 118 | int xMinDomainPoint = round(ofMap(xMin, absXMin, absXMax, 0, xDomainPoints.size() - 1)); 119 | int xMaxDomainPoint = round(ofMap(xMax, absXMin, absXMax, 0, xDomainPoints.size()-1)); 120 | int zMinDomainPoint = round(ofMap(zMin, absZMin, absZMax, 0, zDomainPoints.size() - 1)); 121 | int zMaxDomainPoint = round(ofMap(zMax, absZMin, absZMax, 0, zDomainPoints.size()-1)); 122 | for (int x = xMinDomainPoint; x < xMaxDomainPoint; x++) { 123 | for (int z = zMinDomainPoint; z < zMaxDomainPoint; z++) { 124 | float y1 = valueForPoint(xDomainPoints[x], zDomainPoints[z]); 125 | float y2 = valueForPoint(xDomainPoints[x], zDomainPoints[z+1]); 126 | float y3 = valueForPoint(xDomainPoints[x+1], zDomainPoints[z+1]); 127 | float y4 = valueForPoint(xDomainPoints[x+1], zDomainPoints[z]); 128 | 129 | glm::vec3 one = glm::vec3(xDomainPoints[x],y1,zDomainPoints[z]); 130 | glm::vec3 two = glm::vec3(xDomainPoints[x],y2,zDomainPoints[z+1]); 131 | glm::vec3 three = glm::vec3(xDomainPoints[x+1],y3,zDomainPoints[z+1]); 132 | glm::vec3 four = glm::vec3(xDomainPoints[x+1],y4,zDomainPoints[z]); 133 | if (bUseYBounds) { 134 | addTriangleWithClip(one, two, four); 135 | addTriangleWithClip(two, three, four); 136 | }else{ 137 | addQuad(one,two,three,four); 138 | } 139 | } 140 | } 141 | } 142 | 143 | glm::vec3 ofx3dFunction::normalForPoint(float x, float z,float y){ 144 | float yValue = y; 145 | float delta = xStep; 146 | 147 | // get derivative x in positive direction 148 | float derivativeXPos = (valueForPoint(x + delta, z) - yValue)/delta; 149 | // get derivative x in negative direction 150 | float derivativeXNeg = (valueForPoint(x-delta,z) - yValue)/(-delta); 151 | // average the two to get derivative x 152 | float derivativeX = (derivativeXPos + derivativeXNeg)/2.0 ; 153 | 154 | delta = zStep; 155 | // repaeat same procedure for z 156 | float derivativeZPos = (valueForPoint(x, z+delta) - yValue)/delta; 157 | float derivativeZNeg = (valueForPoint(x,z-delta) - yValue)/(-delta); 158 | float derivativeZ = (derivativeZPos + derivativeZNeg)/2.0; 159 | 160 | // the mathWorld formula gives back faced normals so we have to reverse the normal; 161 | glm::vec3 normal = -glm::normalize(glm::vec3(derivativeX,-1.0f,derivativeZ)); 162 | 163 | return normal; 164 | } 165 | 166 | void ofx3dFunction::addQuad(const glm::vec3 &one, const glm::vec3 &two, const glm::vec3 &three, const glm::vec3 &four){ 167 | addTriangle(one, two, four); 168 | addTriangle(two, three, four); 169 | } 170 | 171 | void ofx3dFunction::addTriangle(const glm::vec3 &one, const glm::vec3 &two, const glm::vec3 &three){ 172 | vertices.push_back(one); 173 | vertices.push_back(two); 174 | vertices.push_back(three); 175 | 176 | // load normals 177 | glm::vec3 normal1 = normalForPoint(one.x, one.z,one.y); 178 | glm::vec3 normal2 = normalForPoint(two.x, two.z,two.y); 179 | glm::vec3 normal3 = normalForPoint(three.x,three.z,three.y); 180 | 181 | frontFaceNormals.push_back(normal1); 182 | frontFaceNormals.push_back(normal2); 183 | frontFaceNormals.push_back(normal3); 184 | 185 | backFaceNormals.push_back(-normal1); 186 | backFaceNormals.push_back(-normal2); 187 | backFaceNormals.push_back(-normal3); 188 | 189 | 190 | // load colors 191 | ofFloatColor color1 = colorForPoint(one.x,one.z,one.y); 192 | ofFloatColor color2 = colorForPoint(two.x,two.z,two.y); 193 | ofFloatColor color3 = colorForPoint(three.x,three.z,three.y); 194 | 195 | if (flatColors) { 196 | frontFaceColors.push_back(color1); 197 | frontFaceColors.push_back(color1); 198 | frontFaceColors.push_back(color1); 199 | }else{ 200 | frontFaceColors.push_back(color1); 201 | frontFaceColors.push_back(color2); 202 | frontFaceColors.push_back(color3); 203 | } 204 | 205 | color1 = backColorForPoint(one.x,one.z,one.y); 206 | color2 = backColorForPoint(two.x,two.z,two.y); 207 | color3 = backColorForPoint(three.x,three.z,three.y); 208 | 209 | 210 | if (flatColors) { 211 | backFaceColors.push_back(color1); 212 | backFaceColors.push_back(color1); 213 | backFaceColors.push_back(color1); 214 | }else{ 215 | backFaceColors.push_back(color1); 216 | backFaceColors.push_back(color2); 217 | backFaceColors.push_back(color3); 218 | } 219 | 220 | //load texCoords 221 | glm::vec2 tex1 = texCoordForPoint(one.x, one.z,one.y); 222 | glm::vec2 tex2 = texCoordForPoint(two.x,two.z,two.y); 223 | glm::vec2 tex3 = texCoordForPoint(three.x,three.z,three.y); 224 | 225 | frontFaceTexCoords.push_back(tex1); 226 | frontFaceTexCoords.push_back(tex2); 227 | frontFaceTexCoords.push_back(tex3); 228 | 229 | tex1 = backTexCoordForPoint(one.x, one.z,one.y); 230 | tex2 = backTexCoordForPoint(two.x,two.z,two.y); 231 | tex3 = backTexCoordForPoint(three.x,three.z,three.y); 232 | 233 | backFaceTexCoords.push_back(tex1); 234 | backFaceTexCoords.push_back(tex2); 235 | backFaceTexCoords.push_back(tex3); 236 | 237 | } 238 | 239 | void ofx3dFunction::addTriangleWithClip(const glm::vec3 &a,const glm::vec3 &b,const glm::vec3 &c){ 240 | ofMesh mesh; 241 | glm::vec3 planeNormal = glm::vec3(0,1,0); 242 | float planeD = -yMin; 243 | glm::vec3 lineSeg[2]; 244 | 245 | if (a.y < yMin && b.y > yMin && c.y > yMin) { 246 | getSegmentPlaneIntersection(a, b, lineSeg[0], planeNormal, planeD); 247 | getSegmentPlaneIntersection(a, c, lineSeg[1], planeNormal, planeD); 248 | addQuadToMesh(mesh, lineSeg[0], b, c, lineSeg[1]); 249 | }else if (a.y > yMin && b.y < yMin && c.y > yMin){ 250 | getSegmentPlaneIntersection(b, a, lineSeg[0], planeNormal, planeD); 251 | getSegmentPlaneIntersection(b, c, lineSeg[1], planeNormal, planeD); 252 | addQuadToMesh(mesh,a, lineSeg[0], lineSeg[1], c); 253 | }else if (a.y > yMin && b.y > yMin && c.y < yMin){ 254 | getSegmentPlaneIntersection(c, b, lineSeg[0], planeNormal, planeD); 255 | getSegmentPlaneIntersection(c, a, lineSeg[1], planeNormal, planeD); 256 | addQuadToMesh(mesh, a, b, lineSeg[0], lineSeg[1]); 257 | }else if (a.y <= yMin && b.y <= yMin && c.y > yMin){ 258 | getSegmentPlaneIntersection(c, a, lineSeg[0], planeNormal, planeD); 259 | getSegmentPlaneIntersection(c, b, lineSeg[1], planeNormal, planeD); 260 | addTriangleToMesh(mesh, lineSeg[0], lineSeg[1],c); 261 | }else if (a.y > yMin && b.y <= yMin && c.y <= yMin){ 262 | getSegmentPlaneIntersection(a, b, lineSeg[0], planeNormal, planeD); 263 | getSegmentPlaneIntersection(a, c, lineSeg[1], planeNormal, planeD); 264 | addTriangleToMesh(mesh,a,lineSeg[0], lineSeg[1]); 265 | }else if (a.y <= yMin && b.y > yMin && c.y <= yMin){ 266 | getSegmentPlaneIntersection(b, a, lineSeg[0], planeNormal, planeD); 267 | getSegmentPlaneIntersection(b, c, lineSeg[1], planeNormal, planeD); 268 | addTriangleToMesh(mesh, lineSeg[0], b, lineSeg[1]); 269 | }else if (a.y >= yMin && b.y >= yMin && c.y >= yMin){ 270 | addTriangleToMesh(mesh, a, b, c); 271 | }else if (a.y < yMin && b.y < yMin && c.y < yMin){ 272 | 273 | } 274 | 275 | planeD = -yMax; 276 | for (int i = 0; i < mesh.getVertices().size();i+=3) { 277 | glm::vec3 a = mesh.getVertices()[i]; 278 | glm::vec3 b = mesh.getVertices()[i+1]; 279 | glm::vec3 c = mesh.getVertices()[i+2]; 280 | if (a.y > yMax && b.y < yMax && c.y < yMax) { 281 | getSegmentPlaneIntersection(a, b, lineSeg[0], planeNormal, planeD); 282 | getSegmentPlaneIntersection(a, c, lineSeg[1], planeNormal, planeD); 283 | addQuad(lineSeg[0], b, c, lineSeg[1]); 284 | }else if (a.y < yMax && b.y > yMax && c.y < yMax){ 285 | getSegmentPlaneIntersection(b, a, lineSeg[0], planeNormal, planeD); 286 | getSegmentPlaneIntersection(b, c, lineSeg[1], planeNormal, planeD); 287 | addQuad(a, lineSeg[0], lineSeg[1], c); 288 | }else if (a.y < yMax && b.y < yMax && c.y > yMax){ 289 | getSegmentPlaneIntersection(c, b, lineSeg[0], planeNormal, planeD); 290 | getSegmentPlaneIntersection(c, a, lineSeg[1], planeNormal, planeD); 291 | addQuad(a, b, lineSeg[0], lineSeg[1]); 292 | }else if (a.y < yMax && b.y >= yMax && c.y >=yMax){ 293 | getSegmentPlaneIntersection(a, b, lineSeg[0], planeNormal, planeD); 294 | getSegmentPlaneIntersection(a, c, lineSeg[1], planeNormal, planeD); 295 | addTriangle(a, lineSeg[0], lineSeg[1]); 296 | }else if (a.y >= yMax && b.y < yMax && c.y >=yMax){ 297 | getSegmentPlaneIntersection(b, a, lineSeg[0], planeNormal, planeD); 298 | getSegmentPlaneIntersection(b, c, lineSeg[1], planeNormal, planeD); 299 | addTriangle(lineSeg[0], b, lineSeg[1]); 300 | }else if (a.y >=yMax && b.y >= yMax && c.y < yMax){ 301 | getSegmentPlaneIntersection(c, a, lineSeg[0], planeNormal, planeD); 302 | getSegmentPlaneIntersection(c, b, lineSeg[1], planeNormal, planeD); 303 | addTriangle(lineSeg[0], lineSeg[1], c); 304 | }else if (a.y <= yMax && b.y <= yMax && c.y <= yMax){ 305 | addTriangle(a, b, c); 306 | }else if (a.y > yMax && b.y > yMax && c.y > yMax){ 307 | 308 | } 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /src/ofx3dFunction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMathSurface.h" 4 | 5 | // creates a mesh for equations of the form y = f(x,z) 6 | class ofx3dFunction:public ofxMathSurface{ 7 | public: 8 | virtual ~ofx3dFunction(){} 9 | ofx3dFunction(){bUseYBounds = false;isSetup = false;flatColors = false;} 10 | 11 | // override these functions to configure your function 12 | // valueForPoint is mandatory, the rest are optional 13 | // override backColor and/or backTexCoord if you are using the 2 sided draw function; 14 | // x and z make up the point in your domain, while y is the corresponding range value 15 | virtual float valueForPoint(float x,float z) = 0; 16 | virtual ofFloatColor colorForPoint(float x,float z, float y) {return ofFloatColor::white;} 17 | virtual glm::vec2 texCoordForPoint(float x,float z ,float y){ return glm::vec2();} 18 | virtual ofFloatColor backColorForPoint(float x, float z,float y){return ofFloatColor::white;} 19 | virtual glm::vec2 backTexCoordForPoint(float x,float z, float y){return glm::vec2();} 20 | 21 | // retrives normal at point see http://mathworld.wolfram.com/NormalVector.html 22 | // really no need to override this 23 | virtual glm::vec3 normalForPoint(float x,float z,float y); 24 | 25 | // setups the function. You must call this before anything else. 26 | // You want to set xMin,xMax,zMin,and zMax to the largest possible ranges (Max-Min) 27 | // that will be displayed on screen. Step defines the resoultion of your function. 28 | // Smaller Values give better Resolution. 29 | void setup(float xMin,float xMax,float zMin,float zMax, float xStep ,float zStep); 30 | void setup(float xMin,float xMax,float zMin,float zMax,float yMin, float yMax, float xStep, float zStep); 31 | 32 | // reloads data. Whenever you make a change to the function you want to call reload 33 | void reload(); 34 | 35 | void setXBounds(float xMin,float xMax); 36 | void setZBounds(float zMin,float zMax); 37 | void setYBounds(float yMin,float yMax); 38 | void setUseYBounds(bool useYBounds){bUseYBounds = useYBounds;} 39 | 40 | void setXMin(float xMin); 41 | void setXMax(float xMax); 42 | void setZMin(float zMin); 43 | void setZMax(float zMax); 44 | void setYMin(float yMin){this->yMin = yMin;} 45 | void setYMax(float yMax){this->yMax = yMax;} 46 | 47 | float getXMin()const{return xMin;} 48 | float getXMax()const{return xMax;} 49 | float getZMin()const{return zMin;} 50 | float getZMax()const{return zMax;} 51 | float getYMin()const{return yMin;} 52 | float getYMax()const{return yMax;} 53 | float getAbsXMin()const{return absXMin;} 54 | float getAbsZMin()const{return absZMin;} 55 | float getAbsXMax()const{return absXMax;} 56 | float getAbsZMax()const{return absZMax;} 57 | 58 | float getXStep()const{return xStep;} 59 | float getZStep()const{return zStep;} 60 | 61 | bool getUseYBounds()const{return bUseYBounds;} 62 | 63 | 64 | private: 65 | void addQuad(const glm::vec3 &one,const glm::vec3 &two,const glm::vec3 &three,const glm::vec3 &four); 66 | void addTriangle(const glm::vec3 &one,const glm::vec3 &two,const glm::vec3 &three); 67 | void addTriangleWithClip(const glm::vec3 &a,const glm::vec3 &b,const glm::vec3 &c); 68 | void setXStep(float step_); 69 | void setZStep(float step_); 70 | void loadDomainPoints(); 71 | 72 | vector xDomainPoints; 73 | vector zDomainPoints; 74 | bool bUseYBounds; 75 | bool isSetup; 76 | float xMin; 77 | float xMax; 78 | float zMin; 79 | float zMax; 80 | float yMin; 81 | float yMax; 82 | float xStep; 83 | float zStep; 84 | float absXMin; 85 | float absXMax; 86 | float absZMin; 87 | float absZMax; 88 | }; 89 | -------------------------------------------------------------------------------- /src/ofxMathCurve.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMathCurve.h" 2 | 3 | 4 | ofMesh ofxMathCurve::getMesh()const{ 5 | ofMesh mesh; 6 | mesh.addVertices(vertices); 7 | mesh.addColors(colors); 8 | return mesh; 9 | } 10 | 11 | ofVbo ofxMathCurve::getVbo()const{ 12 | ofVbo mesh; 13 | mesh.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 14 | mesh.setColorData(colors.data(), colors.size(), GL_DYNAMIC_DRAW); 15 | return mesh; 16 | } 17 | 18 | 19 | void ofxMathCurve::draw(bool colors_){ 20 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 21 | if (colors_) { 22 | vbo.enableColors(); 23 | vbo.setColorData(colors.data(), colors.size(), GL_DYNAMIC_DRAW); 24 | }else{ 25 | vbo.disableColors(); 26 | } 27 | vbo.draw(GL_LINES, 0, vertices.size()); 28 | } 29 | 30 | void ofxMathCurve::drawPoints(bool colors_){ 31 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 32 | if (colors_) { 33 | vbo.enableColors(); 34 | vbo.setColorData(colors.data(), colors.size(), GL_DYNAMIC_DRAW); 35 | }else{ 36 | vbo.disableColors(); 37 | } 38 | vbo.draw(GL_POINTS, 0, vertices.size()); 39 | } 40 | 41 | 42 | void ofxMathCurve::clear(){ 43 | vertices.clear(); 44 | colors.clear(); 45 | } 46 | -------------------------------------------------------------------------------- /src/ofxMathCurve.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | // This class is an abstract base for ofx2dFunction and ofxParametricCurve 6 | 7 | class ofxMathCurve { 8 | public: 9 | void draw(bool colors); 10 | void drawPoints(bool colors); 11 | ofMesh getMesh() const; 12 | ofVbo getVbo() const; 13 | private: 14 | ofVbo vbo; 15 | protected: 16 | vector vertices; 17 | vector colors; 18 | protected: 19 | void clear(); 20 | }; 21 | -------------------------------------------------------------------------------- /src/ofxMathMesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofx3dFunction.h" 4 | #include "ofxParametricCurve.h" 5 | #include "ofxParametricSurface.h" 6 | #include "ofx2dFunction.h" 7 | -------------------------------------------------------------------------------- /src/ofxMathSurface.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ofxMathSurface.h" 3 | 4 | void ofxMathSurface::draw(bool colors,bool texCoords){ 5 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 6 | if (colors) { 7 | vbo.enableColors(); 8 | vbo.setColorData(frontFaceColors.data(), frontFaceColors.size(), GL_DYNAMIC_DRAW); 9 | }else{ 10 | vbo.disableColors(); 11 | } 12 | 13 | if (texCoords) { 14 | vbo.enableTexCoords(); 15 | vbo.setTexCoordData(frontFaceTexCoords.data(), frontFaceTexCoords.size(), GL_DYNAMIC_DRAW); 16 | }else{ 17 | vbo.disableTexCoords(); 18 | } 19 | 20 | glEnable(GL_CULL_FACE); 21 | glCullFace(GL_BACK); 22 | vbo.setNormalData(frontFaceNormals.data(), frontFaceNormals.size(), GL_DYNAMIC_DRAW); 23 | vbo.draw(GL_TRIANGLES, 0, vertices.size()); 24 | glCullFace(GL_FRONT); 25 | vbo.setNormalData(backFaceNormals.data(), backFaceNormals.size(), GL_DYNAMIC_DRAW); 26 | vbo.draw(GL_TRIANGLES, 0, vertices.size()); 27 | glDisable(GL_CULL_FACE); 28 | } 29 | 30 | void ofxMathSurface::drawFrontFaces(bool colors, bool texCoords){ 31 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 32 | vbo.setNormalData(frontFaceNormals.data(), frontFaceNormals.size(), GL_DYNAMIC_DRAW); 33 | if (colors) { 34 | vbo.enableColors(); 35 | vbo.setColorData(frontFaceColors.data(), frontFaceColors.size(), GL_DYNAMIC_DRAW); 36 | }else{ 37 | vbo.disableColors(); 38 | } 39 | if (texCoords) { 40 | vbo.enableTexCoords(); 41 | vbo.setTexCoordData(frontFaceTexCoords.data(), frontFaceTexCoords.size(), GL_DYNAMIC_DRAW); 42 | }else{ 43 | vbo.disableTexCoords(); 44 | } 45 | glEnable(GL_CULL_FACE); 46 | glCullFace(GL_BACK); 47 | vbo.draw(GL_TRIANGLES, 0, vertices.size()); 48 | glDisable(GL_CULL_FACE); 49 | } 50 | 51 | void ofxMathSurface::drawBackFaces(bool colors,bool texCoords){ 52 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 53 | vbo.setNormalData(backFaceNormals.data(), backFaceNormals.size(), GL_DYNAMIC_DRAW); 54 | if (colors) { 55 | vbo.enableColors(); 56 | vbo.setColorData(backFaceColors.data(), backFaceColors.size(), GL_DYNAMIC_DRAW); 57 | }else{ 58 | vbo.disableColors(); 59 | } 60 | if (texCoords) { 61 | vbo.enableTexCoords(); 62 | vbo.setTexCoordData(backFaceTexCoords.data(), backFaceTexCoords.size(), GL_DYNAMIC_DRAW); 63 | }else{ 64 | vbo.disableTexCoords(); 65 | } 66 | glEnable(GL_CULL_FACE); 67 | glCullFace(GL_FRONT); 68 | vbo.draw(GL_TRIANGLES, 0, vertices.size()); 69 | glDisable(GL_CULL_FACE); 70 | } 71 | 72 | void ofxMathSurface::drawWireFrame(bool colors){ 73 | if (colors) { 74 | vbo.enableColors(); 75 | vbo.setColorData(frontFaceColors.data(), frontFaceColors.size(), GL_DYNAMIC_DRAW); 76 | }else{ 77 | vbo.disableColors(); 78 | } 79 | vbo.setNormalData(frontFaceNormals.data(), frontFaceNormals.size(), GL_DYNAMIC_DRAW); 80 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 81 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 82 | vbo.draw(GL_TRIANGLES, 0, vertices.size()); 83 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 84 | } 85 | 86 | void ofxMathSurface::drawPoints(bool colors){ 87 | vbo.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 88 | if (colors) { 89 | vbo.enableColors(); 90 | vbo.setColorData(frontFaceColors.data(), frontFaceColors.size(), GL_DYNAMIC_DRAW); 91 | }else{ 92 | vbo.disableColors(); 93 | } 94 | vbo.setNormalData(frontFaceNormals.data(), frontFaceNormals.size(), GL_DYNAMIC_DRAW); 95 | vbo.draw(GL_POINTS, 0, vertices.size()); 96 | } 97 | 98 | void ofxMathSurface::drawNormals(float length) const{ 99 | ofMesh normalsMesh; 100 | normalsMesh.setMode( OF_PRIMITIVE_LINES ); 101 | normalsMesh.getVertices().resize( frontFaceNormals.size() * 2); 102 | const vector& normals = frontFaceNormals; 103 | glm::vec3 normal; 104 | glm::vec3 vert; 105 | 106 | for(int i = 0; i < (int)frontFaceNormals.size(); i++) { 107 | vert = vertices[i]; 108 | normal = normals[i]; 109 | normal = glm::normalize(normal); 110 | normalsMesh.setVertex( i*2, vert); 111 | normal *= length; 112 | normalsMesh.setVertex(i*2+1, normal+vert); 113 | } 114 | glEnable(GL_CULL_FACE); 115 | glCullFace(GL_FRONT); 116 | normalsMesh.draw(); 117 | 118 | normalsMesh.getVertices().resize( backFaceNormals.size() * 2); 119 | const vector& backNormals = backFaceNormals; 120 | for(int i = 0; i < (int)backNormals.size(); i++) { 121 | vert = vertices[i]; 122 | normal = backNormals[i]; 123 | normal = glm::normalize(normal); 124 | normalsMesh.setVertex( i*2, vert); 125 | normal *= length; 126 | normalsMesh.setVertex(i*2+1, normal+vert); 127 | } 128 | glCullFace(GL_BACK); 129 | normalsMesh.draw(); 130 | glDisable(GL_CULL_FACE); 131 | } 132 | 133 | glm::vec3 ofxMathSurface::getCenter(const ofMeshFace& meshface){ 134 | const glm::vec3 &v1 = meshface.getVertex(0); 135 | const glm::vec3 &v2 = meshface.getVertex(1); 136 | const glm::vec3 &v3 = meshface.getVertex(2); 137 | return (v1 + v2 + v3)/3.0; 138 | } 139 | 140 | void ofxMathSurface::drawFaceNormals(float length) const { 141 | ofMesh nMesh; 142 | nMesh.setMode(OF_PRIMITIVE_LINES); 143 | const vector &verts = vertices; 144 | for (int i = 0; i < verts.size(); i+=3) { 145 | glm::vec3 v1 = verts[i]; 146 | glm::vec3 v2 = verts[i+1]; 147 | glm::vec3 v3 = verts[i+2]; 148 | ofMeshFace meshFace; 149 | meshFace.setVertex(0, v1); 150 | meshFace.setVertex(1, v2); 151 | meshFace.setVertex(2, v3); 152 | glm::vec3 norm = meshFace.getFaceNormal() * length; 153 | glm::vec3 center = getCenter(meshFace); 154 | nMesh.addVertex(center); 155 | nMesh.addVertex(center + norm); 156 | } 157 | nMesh.draw(); 158 | } 159 | 160 | ofVbo ofxMathSurface::getVbo()const{ 161 | ofVbo mesh; 162 | mesh.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 163 | mesh.setNormalData(frontFaceNormals.data(), frontFaceNormals.size(), GL_DYNAMIC_DRAW); 164 | mesh.setColorData(frontFaceColors.data(), frontFaceColors.size(), GL_DYNAMIC_DRAW); 165 | mesh.setTexCoordData(frontFaceTexCoords.data(), frontFaceTexCoords.size(), GL_DYNAMIC_DRAW); 166 | return mesh; 167 | } 168 | 169 | ofVbo ofxMathSurface::getBackVbo()const{ 170 | ofVbo mesh; 171 | mesh.setVertexData(vertices.data(), vertices.size(), GL_DYNAMIC_DRAW); 172 | mesh.setNormalData(backFaceNormals.data(), backFaceNormals.size(), GL_DYNAMIC_DRAW); 173 | mesh.setColorData(backFaceColors.data(), backFaceColors.size(), GL_DYNAMIC_DRAW); 174 | mesh.setTexCoordData(backFaceTexCoords.data(), backFaceTexCoords.size(), GL_DYNAMIC_DRAW); 175 | return mesh; 176 | } 177 | 178 | ofMesh ofxMathSurface::getMesh()const{ 179 | ofMesh mesh; 180 | mesh.addVertices(vertices); 181 | mesh.addNormals(frontFaceNormals); 182 | mesh.addColors(frontFaceColors); 183 | mesh.addTexCoords(frontFaceTexCoords); 184 | return mesh; 185 | } 186 | 187 | ofMesh ofxMathSurface::getBackMesh()const{ 188 | ofMesh mesh; 189 | mesh.addVertices(vertices); 190 | mesh.addNormals(backFaceNormals); 191 | mesh.addColors(backFaceColors); 192 | mesh.addTexCoords(backFaceTexCoords); 193 | return mesh; 194 | } 195 | 196 | void ofxMathSurface::clear(){ 197 | vertices.resize(0); 198 | frontFaceNormals.resize(0); 199 | backFaceNormals.resize(0); 200 | frontFaceColors.resize(0); 201 | backFaceColors.resize(0); 202 | frontFaceTexCoords.resize(0); 203 | backFaceTexCoords.resize(0); 204 | } 205 | 206 | float ofxMathSurface::distFromPlane(const glm::vec3 &point, const glm::vec3 &planeNormal, const float &planeD){ 207 | return glm::dot(planeNormal, point) + planeD; 208 | } 209 | 210 | bool ofxMathSurface::getSegmentPlaneIntersection(const glm::vec3 &a, const glm::vec3 &b, glm::vec3 &intersectionPoint, const glm::vec3 &planeNormal, const float &planeD){ 211 | float d1 = distFromPlane(a, planeNormal, planeD); 212 | float d2 = distFromPlane(b, planeNormal, planeD); 213 | if (d1*d2 > 0) { 214 | return false; 215 | } 216 | float t = d1/(d1-d2); 217 | intersectionPoint = a + t * (b-a); 218 | return true; 219 | } 220 | 221 | void ofxMathSurface::addTriangleToMesh(ofMesh &mesh, const glm::vec3 &one, const glm::vec3 &two, const glm::vec3 &three){ 222 | mesh.addVertex(one); 223 | mesh.addVertex(two); 224 | mesh.addVertex(three); 225 | } 226 | 227 | void ofxMathSurface::addQuadToMesh(ofMesh &mesh, const glm::vec3 &one, const glm::vec3 &two, const glm::vec3 &three, const glm::vec3 &four){ 228 | mesh.addVertex(one); 229 | mesh.addVertex(two); 230 | mesh.addVertex(four); 231 | mesh.addVertex(two); 232 | mesh.addVertex(three); 233 | mesh.addVertex(four); 234 | } 235 | 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /src/ofxMathSurface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ofMain.h" 3 | 4 | // This class is an abstract base for ofx3dFunction and ofxParametricCurve 5 | class ofxMathSurface{ 6 | public: 7 | 8 | // 'colors' and 'texcoords' arguments specify if you want to use the colorForPoint and texCoordForPoint functions 9 | // you defined. drawBackFaces will use functions 'backColorForPoint' and 'backTexCoordForPoint', if you pass 'true' to 'colors' and 'texCoords' 10 | void draw(bool colors,bool texCoords); 11 | void drawFrontFaces(bool colors, bool texCoords); 12 | void drawBackFaces(bool colors,bool texCoords); 13 | void drawWireFrame(bool colors); 14 | void drawPoints(bool colors); 15 | void drawNormals(float length) const; 16 | void drawFaceNormals(float length) const; 17 | 18 | // flatColors will set the same color for each vertex in a quad; 19 | void enableFlatColors(){flatColors = true;} 20 | void disableFlatColors(){flatColors = false;} 21 | 22 | // returns a vbo which with vertices,frontNormals,frontColors,and frontTexCoords 23 | ofVbo getVbo() const; 24 | 25 | // returns a vbo which with vertices,backNormals,backColors,and backTexCoords 26 | ofVbo getBackVbo() const; 27 | 28 | // returns a mesh which with vertices,frontNormals,frontColors,and frontTexCoords 29 | ofMesh getMesh() const; 30 | 31 | // returns a mesh which with vertices,backNormals,backColors,and backTexCoords 32 | ofMesh getBackMesh() const; 33 | 34 | private: 35 | ofVbo vbo; 36 | 37 | protected: 38 | vector backFaceColors; 39 | vector backFaceTexCoords; 40 | vector frontFaceColors; 41 | vector frontFaceTexCoords; 42 | vector frontFaceNormals; 43 | vector backFaceNormals; 44 | vector vertices; 45 | bool flatColors; 46 | 47 | protected: 48 | void clear(); 49 | static float distFromPlane(const glm::vec3 &point,const glm::vec3 &planeNormal,const float &planeD); 50 | static bool getSegmentPlaneIntersection(const glm::vec3 &a,const glm::vec3 &b,glm::vec3 &intersectionPoint,const glm::vec3 &planeNormal,const float &planeD); 51 | static void addTriangleToMesh(ofMesh &mesh,const glm::vec3 &one,const glm::vec3 &two,const glm::vec3 &three); 52 | static void addQuadToMesh(ofMesh &mesh,const glm::vec3 &one,const glm::vec3 &two,const glm::vec3 &three,const glm::vec3 &four); 53 | static glm::vec3 getCenter(const ofMeshFace& face); 54 | }; 55 | -------------------------------------------------------------------------------- /src/ofxParametricCurve.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ofxParametricCurve.h" 3 | 4 | void ofxParametricCurve::setTMin(float tMin_){ 5 | if (tMin_ >= absTMin) { 6 | tMin = tMin_; 7 | }else{ 8 | tMin = absTMin; 9 | ofLogWarning("ofxMathMesh") << "cannot set tMin smaller than setup tMin"; 10 | } 11 | } 12 | 13 | void ofxParametricCurve::setTMax(float tMax_){ 14 | if (tMax_ <= absTMax) { 15 | tMax = tMax_; 16 | }else{ 17 | tMax = absTMax; 18 | ofLogWarning("ofxMathMesh") << "cannot set tMax bigger than setup tMax;"; 19 | } 20 | } 21 | 22 | void ofxParametricCurve::setStep(float step_){ 23 | float range = absTMax - absTMin; 24 | if (step_ > range) { 25 | ofLogWarning("ofxMathMesh") << "cannot set step greater than range"; 26 | step = range; 27 | return; 28 | } 29 | int res = round(range/step_); 30 | step = range/(float)res; 31 | } 32 | 33 | void ofxParametricCurve::loadDomainPoints(){ 34 | float epsilon = step/100.0; 35 | for (float t = absTMin; t <= absTMax + epsilon; t+=step) { 36 | domainPoints.push_back(t); 37 | } 38 | } 39 | 40 | void ofxParametricCurve::setTBounds(float tMin_, float tMax_){ 41 | setTMin(tMin_); 42 | setTMax(tMax_); 43 | } 44 | 45 | void ofxParametricCurve::setup(float tMin_, float tMax_, float step_){ 46 | if (step_ <= 0) { 47 | ofLogWarning("ofxMathMesh") << "step must be greater than zero"; 48 | return; 49 | } 50 | isSetup = true; 51 | absTMin = tMin_; 52 | absTMax = tMax_; 53 | setStep(step_); 54 | setTBounds(tMin_, tMax_); 55 | loadDomainPoints(); 56 | reload(); 57 | } 58 | 59 | void ofxParametricCurve::reload(){ 60 | if (!isSetup) { 61 | ofLogError("ofxMathMesh") << "cannot reload if the function is not setup"; 62 | return; 63 | } 64 | clear(); 65 | int tMinDomainPoint = round(ofMap(tMin, absTMin, absTMax, 0, domainPoints.size() - 1)); 66 | int tMaxDomainPoint = round(ofMap(tMax, absTMin, absTMax, 0, domainPoints.size()-1)); 67 | for (int t = tMinDomainPoint; t < tMaxDomainPoint; t++) { 68 | ParametricPosition one(domainPoints[t],valueForPoint(domainPoints[t])); 69 | ParametricPosition two(domainPoints[t+1],valueForPoint(domainPoints[t+1])); 70 | addLineSeg(one, two); 71 | } 72 | 73 | } 74 | 75 | void ofxParametricCurve::addLineSeg(const ofxParametricCurve::ParametricPosition &one, const ofxParametricCurve::ParametricPosition &two){ 76 | vertices.push_back(one.value); 77 | vertices.push_back(two.value); 78 | ofFloatColor color1 = colorForPoint(one.t, one.value); 79 | ofFloatColor color2 = colorForPoint(two.t, one.value); 80 | colors.push_back(color1); 81 | colors.push_back(color2); 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/ofxParametricCurve.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ofxMathCurve.h" 3 | 4 | class ofxParametricCurve:public ofxMathCurve { 5 | public: 6 | virtual ~ofxParametricCurve(){} 7 | ofxParametricCurve(){isSetup= false;} 8 | // override these functions to configure your function 9 | // valueForPoint is mandatory, the rest are optional 10 | // valueForPoint should return a 3dPoint for a given t value 11 | virtual ofPoint valueForPoint(float t) = 0; 12 | virtual ofFloatColor colorForPoint(float t, ofPoint value){return ofFloatColor::white;} 13 | 14 | // setups the function. You must call this before anything else. 15 | // You want to set tMin and tMax to the largest possible range (tMax-tMin) 16 | // that will be displayed on screen. Step defines the resoultion of your function. 17 | // Smaller Values give better Resolution. 18 | void setup(float tMin,float tMax,float step); 19 | 20 | // reloads data. Whenever you make a change to the equation or bounds call reload. 21 | void reload(); 22 | void setTBounds(float tMin,float tMax); 23 | void setTMin(float tMin); 24 | void setTMax(float tMax); 25 | 26 | float getTMin()const{return tMin;} 27 | float getTMax()const{return tMax;} 28 | 29 | float getStep()const {return step;} 30 | 31 | private: 32 | bool isSetup; 33 | float absTMin; 34 | float absTMax; 35 | float tMin; 36 | float tMax; 37 | float step; 38 | vector domainPoints; 39 | 40 | private: 41 | struct ParametricPosition{ 42 | ParametricPosition(const float &t, const ofPoint &value){ 43 | this->t = t; 44 | this->value = value; 45 | } 46 | float t; 47 | ofPoint value; 48 | }; 49 | void addLineSeg(const ParametricPosition &one, const ParametricPosition &two); 50 | void loadDomainPoints(); 51 | void setStep(float step_); 52 | }; -------------------------------------------------------------------------------- /src/ofxParametricSurface.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "ofxParametricSurface.h" 4 | 5 | void ofxParametricSurface::setUMin(float uMin_){ 6 | if (uMin_ >= absUMin) { 7 | uMin = uMin_; 8 | }else{ 9 | uMin = absUMin; 10 | ofLogWarning("ofxMathMesh") << "Cannot set uMin smaller than setup uMin"; 11 | } 12 | } 13 | 14 | void ofxParametricSurface::setUMax(float uMax_){ 15 | if (uMax_ <= absUMax) { 16 | uMax = uMax_; 17 | }else{ 18 | uMax = absUMax; 19 | ofLogWarning("ofxMathMesh") << "Cannot set uMax bigger than setup uMax"; 20 | } 21 | } 22 | 23 | void ofxParametricSurface::setVMin(float vMin_){ 24 | if (vMin_ >= absVMin) { 25 | vMin = vMin_; 26 | }else{ 27 | vMin = absVMin; 28 | ofLogWarning("ofxMathMesh") << "Cannot set vMin smaller than setup vMin"; 29 | } 30 | } 31 | 32 | void ofxParametricSurface::setVMax(float vMax_){ 33 | if (vMax_ <= absVMax) { 34 | vMax = vMax_; 35 | }else{ 36 | vMax = absVMax; 37 | ofLogWarning("ofxMathMesh") << "Cannot set vMax bigger than setup vMax"; 38 | 39 | } 40 | } 41 | 42 | void ofxParametricSurface::setVStep(float step_){ 43 | float range = absVMax - absVMin; 44 | if (step_ > range) { 45 | ofLogWarning("ofxMathMesh") << "cannot set step greater than range"; 46 | vStep = range; 47 | return; 48 | } 49 | int res = round(range/step_); 50 | vStep = range/(float)res; 51 | } 52 | 53 | void ofxParametricSurface::setUStep(float step_){ 54 | float range = absUMax - absUMin; 55 | if (step_ > range) { 56 | ofLogWarning("ofxMathMesh") << "cannot set step greater than range"; 57 | uStep = range; 58 | return; 59 | } 60 | int res = round(range/step_); 61 | uStep = range/(float)res; 62 | } 63 | 64 | void ofxParametricSurface::setUBounds(float uMin_,float uMax_){ 65 | setUMin(uMin_); 66 | setUMax(uMax_); 67 | } 68 | void ofxParametricSurface::setVBounds(float vMin_,float vMax_){ 69 | setVMin(vMin_); 70 | setVMax(vMax_); 71 | } 72 | 73 | void ofxParametricSurface::loadDomainPoints(){ 74 | float epsilon = uStep/100.0; 75 | for (float u = absUMin; u <= absUMax + epsilon; u+=uStep) { 76 | uDomainPoints.push_back(u); 77 | } 78 | epsilon = vStep/100.0; 79 | for (float v = absVMin; v <= absVMax + epsilon; v+=vStep) { 80 | vDomainPoints.push_back(v); 81 | } 82 | } 83 | 84 | void ofxParametricSurface::setup(float uMin_, float uMax_, float vMin_, float vMax_, float uStep_ ,float vStep_){ 85 | if (uStep_ <= 0 || vStep_ <= 0 ) { 86 | ofLogWarning("ofxMathMesh") << "step must be greater than zero"; 87 | return; 88 | } 89 | isSetup = true; 90 | absUMin = uMin_; 91 | absUMax = uMax_; 92 | absVMin = vMin_; 93 | absVMax = vMax_; 94 | setUStep(uStep_); 95 | setVStep(vStep_); 96 | loadDomainPoints(); 97 | setUBounds(uMin_, uMax_); 98 | setVBounds(vMin_, vMax_); 99 | reload(); 100 | } 101 | 102 | glm::vec3 ofxParametricSurface::normalForPoint(float u, float v,ofPoint value){ 103 | // derivative u to the right 104 | glm::vec3 duRight; 105 | float delta = uStep; 106 | glm::vec3 valuePlus = valueForPoint(u+delta, v); 107 | duRight.x = (valuePlus.x - value.x)/delta; 108 | duRight.y = (valuePlus.y - value.y)/delta; 109 | duRight.z = (valuePlus.z - value.z)/delta; 110 | 111 | // // derivative u to the left 112 | // glm::vec3 duLeft; 113 | // glm::vec3 valueMinus = valueForPoint(u-delta, v); 114 | // duLeft.x = (valueMinus.x - value.x)/delta; 115 | // duLeft.y = (valueMinus.y - value.y)/delta; 116 | // duLeft.z = (valueMinus.z - value.z)/delta; 117 | // 118 | // glm::vec3 du = (-duLeft + duRight); 119 | 120 | // derivative v to the right 121 | glm::vec3 dvRight; 122 | delta = vStep; 123 | valuePlus = valueForPoint(u, v+delta); 124 | dvRight.x = (valuePlus.x - value.x)/delta; 125 | dvRight.y = (valuePlus.y - value.y)/delta; 126 | dvRight.z = (valuePlus.z - value.z)/delta; 127 | 128 | // // deravative v to the left 129 | // glm::vec3 dvLeft; 130 | // valueMinus = valueForPoint(u, v-delta); 131 | // dvLeft.x = (valueMinus.x - value.x)/delta; 132 | // dvLeft.y = (valueMinus.y - value.y)/delta; 133 | // dvLeft.z = (valueMinus.z - value.z)/delta; 134 | // 135 | // glm::vec3 dv = (dvRight + -dvLeft); 136 | 137 | 138 | glm::vec3 normal = glm::normalize(glm::cross(duRight, dvRight)); 139 | return -normal; 140 | } 141 | 142 | void ofxParametricSurface::reload(){ 143 | if (!isSetup) { 144 | ofLogError("ofxMathMesh") << "cannot reload if the surface is not setup"; 145 | return; 146 | } 147 | clear(); 148 | int uMinDomainPoint = round(ofMap(uMin, absUMin, absUMax, 0, uDomainPoints.size()-1)); 149 | int uMaxDomainPoint = round(ofMap(uMax, absUMin, absUMax, 0, uDomainPoints.size()-1)); 150 | int vMinDomainPoint = round(ofMap(vMin, absVMin, absVMax, 0, vDomainPoints.size()-1)); 151 | int vMaxDomianPoint = round(ofMap(vMax, absVMin, absVMax, 0, vDomainPoints.size()-1)); 152 | 153 | for (int u = uMinDomainPoint; u < uMaxDomainPoint; u++) { 154 | for (int v = vMinDomainPoint; v < vMaxDomianPoint; v++) { 155 | ofPoint value1 = valueForPoint(uDomainPoints[u], vDomainPoints[v]); 156 | ofPoint value2 = valueForPoint(uDomainPoints[u], vDomainPoints[v+1]); 157 | ofPoint value3 = valueForPoint(uDomainPoints[u+1], vDomainPoints[v+1]); 158 | ofPoint value4 = valueForPoint(uDomainPoints[u+1], vDomainPoints[v]); 159 | ParametricPosition one(uDomainPoints[u],vDomainPoints[v],value1); 160 | ParametricPosition two(uDomainPoints[u],vDomainPoints[v+1],value2); 161 | ParametricPosition three(uDomainPoints[u+1],vDomainPoints[v+1],value3); 162 | ParametricPosition four(uDomainPoints[u+1],vDomainPoints[v],value4); 163 | addQuad(one, two, three, four); 164 | } 165 | } 166 | 167 | } 168 | 169 | void ofxParametricSurface::addQuad(const ofxParametricSurface::ParametricPosition &one, const ofxParametricSurface::ParametricPosition &two, const ofxParametricSurface::ParametricPosition &three, const ofxParametricSurface::ParametricPosition &four){ 170 | vertices.push_back(one.value); 171 | vertices.push_back(two.value); 172 | vertices.push_back(four.value); 173 | vertices.push_back(two.value); 174 | vertices.push_back(three.value); 175 | vertices.push_back(four.value); 176 | 177 | // load normals 178 | glm::vec3 normal1 = normalForPoint(one.u, one.v,one.value); 179 | glm::vec3 normal2 = normalForPoint(two.u,two.v,two.value); 180 | glm::vec3 normal3 = normalForPoint(three.u,three.v,three.value); 181 | glm::vec3 normal4 = normalForPoint(four.u,four.v,four.value); 182 | 183 | frontFaceNormals.push_back(normal1); 184 | frontFaceNormals.push_back(normal2); 185 | frontFaceNormals.push_back(normal4); 186 | frontFaceNormals.push_back(normal2); 187 | frontFaceNormals.push_back(normal3); 188 | frontFaceNormals.push_back(normal4); 189 | 190 | backFaceNormals.push_back(-normal1); 191 | backFaceNormals.push_back(-normal2); 192 | backFaceNormals.push_back(-normal4); 193 | backFaceNormals.push_back(-normal2); 194 | backFaceNormals.push_back(-normal3); 195 | backFaceNormals.push_back(-normal4); 196 | 197 | // load colors 198 | ofFloatColor color1 = colorForPoint(one.u,one.v,one.value); 199 | ofFloatColor color2 = colorForPoint(two.u,two.v,two.value); 200 | ofFloatColor color3 = colorForPoint(three.u,three.v,three.value); 201 | ofFloatColor color4 = colorForPoint(four.u,four.v,four.value); 202 | if (flatColors) { 203 | frontFaceColors.push_back(color1); 204 | frontFaceColors.push_back(color1); 205 | frontFaceColors.push_back(color1); 206 | frontFaceColors.push_back(color1); 207 | frontFaceColors.push_back(color1); 208 | frontFaceColors.push_back(color1); 209 | }else{ 210 | frontFaceColors.push_back(color1); 211 | frontFaceColors.push_back(color2); 212 | frontFaceColors.push_back(color4); 213 | frontFaceColors.push_back(color2); 214 | frontFaceColors.push_back(color3); 215 | frontFaceColors.push_back(color4); 216 | } 217 | 218 | color1 = backColorForPoint(one.u,one.v,one.value); 219 | color2 = backColorForPoint(two.u,two.v,two.value); 220 | color3 = backColorForPoint(three.u,three.v,three.value); 221 | color4 = backColorForPoint(four.u,four.v,four.value); 222 | 223 | if (flatColors) { 224 | backFaceColors.push_back(color1); 225 | backFaceColors.push_back(color1); 226 | backFaceColors.push_back(color1); 227 | backFaceColors.push_back(color1); 228 | backFaceColors.push_back(color1); 229 | backFaceColors.push_back(color1); 230 | }else{ 231 | backFaceColors.push_back(color1); 232 | backFaceColors.push_back(color2); 233 | backFaceColors.push_back(color4); 234 | backFaceColors.push_back(color2); 235 | backFaceColors.push_back(color3); 236 | backFaceColors.push_back(color4); 237 | } 238 | 239 | //load texCoords 240 | glm::vec2 tex1 = texCoordForPoint(one.u, one.v,one.value); 241 | glm::vec2 tex2 = texCoordForPoint(two.u,two.v,two.value); 242 | glm::vec2 tex3 = texCoordForPoint(three.u,three.v,three.value); 243 | glm::vec2 tex4 = texCoordForPoint(four.u,four.v,four.value); 244 | 245 | frontFaceTexCoords.push_back(tex1); 246 | frontFaceTexCoords.push_back(tex2); 247 | frontFaceTexCoords.push_back(tex4); 248 | frontFaceTexCoords.push_back(tex2); 249 | frontFaceTexCoords.push_back(tex3); 250 | frontFaceTexCoords.push_back(tex4); 251 | 252 | tex1 = backTexCoordForPoint(one.u, one.v,one.value); 253 | tex2 = backTexCoordForPoint(two.u,two.v,two.value); 254 | tex3 = backTexCoordForPoint(three.u,three.v,three.value); 255 | tex4 = backTexCoordForPoint(four.u,four.v,four.value); 256 | 257 | backFaceTexCoords.push_back(tex1); 258 | backFaceTexCoords.push_back(tex2); 259 | backFaceTexCoords.push_back(tex4); 260 | backFaceTexCoords.push_back(tex2); 261 | backFaceTexCoords.push_back(tex3); 262 | backFaceTexCoords.push_back(tex4); 263 | } 264 | 265 | 266 | 267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /src/ofxParametricSurface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMathSurface.h" 4 | 5 | // create meshs of the form r = r(u,v) 6 | class ofxParametricSurface:public ofxMathSurface{ 7 | public: 8 | virtual ~ofxParametricSurface(){} 9 | ofxParametricSurface(){isSetup = false;flatColors = false;} 10 | 11 | // override these functions to configure your mesh 12 | // valueForPoint is mandatory, the rest are optional 13 | // valueForPoint should return a 3dpoint for a given u,v coordinate 14 | // override backColor and/or backTexCoord if you are using the 2 sided draw function; 15 | virtual ofPoint valueForPoint(float u,float v) = 0; 16 | virtual ofFloatColor colorForPoint(float u, float v, ofPoint value){return ofFloatColor::white;} 17 | virtual glm::vec2 texCoordForPoint(float u,float v,ofPoint value){return glm::vec2();} 18 | virtual ofFloatColor backColorForPoint(float u, float v, ofPoint value){return ofFloatColor::white;} 19 | virtual glm::vec2 backTexCoordForPoint(float u,float v, ofPoint value){return glm::vec2();} 20 | 21 | // retrives normal at point see http://mathworld.wolfram.com/NormalVector.html 22 | // really no need to override this 23 | virtual glm::vec3 normalForPoint(float u,float v,ofPoint value); 24 | 25 | void setup(float uMin,float uMax,float vMin,float vMax,float uStep,float vStep); 26 | 27 | void reload(); 28 | 29 | void setUBounds(float uMin,float uMax); 30 | void setVBounds(float vMin,float vMax); 31 | 32 | void setUMin(float uMin); 33 | void setUMax(float uMax); 34 | void setVMin(float vMin); 35 | void setVMax(float vMax); 36 | 37 | float getUMin()const{return uMin;} 38 | float getUMax()const{return uMax;} 39 | float getVMin()const{return vMin;} 40 | float getVMax()const{return vMax;} 41 | float getAbsUMin()const{return absUMin;} 42 | float getAbsVMin()const{return absVMin;} 43 | float getAbsUMax()const{return absUMax;} 44 | float getAbsVMax()const{return absVMax;} 45 | 46 | float getUStep()const{return uStep;} 47 | float getVStep()const{return vStep;} 48 | 49 | 50 | 51 | private: 52 | bool isSetup; 53 | float absUMin; 54 | float absUMax; 55 | float absVMin; 56 | float absVMax; 57 | float uMin; 58 | float uMax; 59 | float vMin; 60 | float vMax; 61 | float uStep; 62 | float vStep; 63 | vector uDomainPoints; 64 | vector vDomainPoints; 65 | 66 | private: 67 | struct ParametricPosition{ 68 | ParametricPosition(const float &u,const float &v, const ofPoint &value){ 69 | this->u = u; 70 | this->v = v; 71 | this->value = value; 72 | } 73 | float u; 74 | float v; 75 | ofPoint value; 76 | }; 77 | void addQuad(const ParametricPosition &one,const ParametricPosition &two,const ParametricPosition &three,const ParametricPosition &four); 78 | void loadDomainPoints(); 79 | void setUStep(float step_); 80 | void setVStep(float step_); 81 | }; 82 | 83 | --------------------------------------------------------------------------------