cailean
2 months ago
commit
0e4ec7b7b1
22 changed files with 2020 additions and 0 deletions
@ -0,0 +1,91 @@ |
|||||
|
#.gitignore is a file which makes git ignore files which should |
||||
|
# not go into version control in the first place |
||||
|
# Questions? See |
||||
|
# http://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#Ignoring-Files |
||||
|
# http://git-scm.com/docs/gitignore |
||||
|
|
||||
|
########################### |
||||
|
# ignore generated binaries |
||||
|
# but not the data folder |
||||
|
########################### |
||||
|
|
||||
|
/bin/data/images |
||||
|
/bin/data/recordings |
||||
|
|
||||
|
######### |
||||
|
# general |
||||
|
######### |
||||
|
|
||||
|
[Bb]uild/ |
||||
|
[Oo]bj/ |
||||
|
*.o |
||||
|
[Dd]ebug*/ |
||||
|
[Rr]elease*/ |
||||
|
*.mode* |
||||
|
*.app/ |
||||
|
*.pyc |
||||
|
.svn/ |
||||
|
*.log |
||||
|
|
||||
|
######################## |
||||
|
# IDE files which should |
||||
|
# be ignored |
||||
|
######################## |
||||
|
|
||||
|
# XCode |
||||
|
*.pbxuser |
||||
|
*.perspective |
||||
|
*.perspectivev3 |
||||
|
*.mode1v3 |
||||
|
*.mode2v3 |
||||
|
# XCode 4 |
||||
|
*.xccheckout |
||||
|
xcuserdata/ |
||||
|
|
||||
|
# Visual Studio |
||||
|
*.sdf |
||||
|
*.opensdf |
||||
|
*.suo |
||||
|
*.pdb |
||||
|
*.ilk |
||||
|
*.aps |
||||
|
ipch/ |
||||
|
|
||||
|
# Eclipse |
||||
|
.metadata |
||||
|
local.properties |
||||
|
.externalToolBuilders |
||||
|
|
||||
|
# Android Studio |
||||
|
.gradle |
||||
|
/local.properties |
||||
|
/.idea/workspace.xml |
||||
|
/.idea/libraries |
||||
|
|
||||
|
################## |
||||
|
# operating system |
||||
|
################## |
||||
|
|
||||
|
# Linux |
||||
|
*~ |
||||
|
# KDE |
||||
|
.directory |
||||
|
.AppleDouble |
||||
|
|
||||
|
# OSX |
||||
|
.DS_Store |
||||
|
*.swp |
||||
|
*~.nib |
||||
|
# Thumbnails |
||||
|
._* |
||||
|
|
||||
|
# Windows |
||||
|
# Image file caches |
||||
|
Thumbs.db |
||||
|
# Folder config file |
||||
|
Desktop.ini |
||||
|
|
||||
|
# Android |
||||
|
.csettings |
||||
|
|
||||
|
/bin/data/ |
@ -0,0 +1,194 @@ |
|||||
|
{ |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"name": "Mac", |
||||
|
"includePath": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/", |
||||
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/3d", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/app", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/communication", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/events", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/gl", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/graphics", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/math", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/sound", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/types", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/utils", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/video", |
||||
|
"${workspaceRoot}/../../../libs/boost/include", |
||||
|
"${workspaceRoot}/../../../libs/cairo/include", |
||||
|
"${workspaceRoot}/../../../libs/curl/include", |
||||
|
"${workspaceRoot}/../../../libs/fmod/include", |
||||
|
"${workspaceRoot}/../../../libs/FreeImage/include", |
||||
|
"${workspaceRoot}/../../../libs/freetype/include", |
||||
|
"${workspaceRoot}/../../../libs/glew/include", |
||||
|
"${workspaceRoot}/../../../libs/glfw/include", |
||||
|
"${workspaceRoot}/../../../libs/glm/include", |
||||
|
"${workspaceRoot}/../../../libs/json/include", |
||||
|
"${workspaceRoot}/../../../libs/pugixml/include", |
||||
|
"${workspaceRoot}/../../../libs/rtAudio/include", |
||||
|
"${workspaceRoot}/../../../libs/tess2/include", |
||||
|
"${workspaceRoot}/../../../libs/uriparser/include", |
||||
|
"${workspaceRoot}/../../../libs/utf8/include" |
||||
|
], |
||||
|
"browse": { |
||||
|
"limitSymbolsToIncludedHeaders": true, |
||||
|
"databaseFilename": "${workspaceRoot}/.vscode/browse.db", |
||||
|
"path": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"/System/Library/Frameworks", |
||||
|
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/", |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks" |
||||
|
] |
||||
|
}, |
||||
|
"intelliSenseMode": "clang-x64", |
||||
|
"macFrameworkPath": [ |
||||
|
"/System/Library/Frameworks", |
||||
|
"/Library/Frameworks" |
||||
|
], |
||||
|
"compilerPath": "/usr/local/bin/gcc-8", |
||||
|
"cStandard": "c11", |
||||
|
"cppStandard": "c++17" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Linux", |
||||
|
"includePath": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"/usr/include/c++/5", |
||||
|
"/usr/include/c++/5/backward", |
||||
|
"/usr/lib/gcc/x86_64-linux-gnu/5/include", |
||||
|
"/usr/lib/x86_64-linux-gnu/glib-2.0/include", |
||||
|
"/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include", |
||||
|
"/usr/local/include", |
||||
|
"/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed", |
||||
|
"/usr/include/x86_64-linux-gnu", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/3d", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/app", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/communication", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/events", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/gl", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/graphics", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/math", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/sound", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/types", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/utils", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/video", |
||||
|
"${workspaceRoot}/../../../libs/boost/include", |
||||
|
"${workspaceRoot}/../../../libs/cairo/include", |
||||
|
"${workspaceRoot}/../../../libs/curl/include", |
||||
|
"${workspaceRoot}/../../../libs/fmod/include", |
||||
|
"${workspaceRoot}/../../../libs/FreeImage/include", |
||||
|
"${workspaceRoot}/../../../libs/freetype/include", |
||||
|
"${workspaceRoot}/../../../libs/glew/include", |
||||
|
"${workspaceRoot}/../../../libs/glfw/include", |
||||
|
"${workspaceRoot}/../../../libs/glm/include", |
||||
|
"${workspaceRoot}/../../../libs/json/include", |
||||
|
"${workspaceRoot}/../../../libs/pugixml/include", |
||||
|
"${workspaceRoot}/../../../libs/rtAudio/include", |
||||
|
"${workspaceRoot}/../../../libs/tess2/include", |
||||
|
"${workspaceRoot}/../../../libs/uriparser/include", |
||||
|
"${workspaceRoot}/../../../libs/utf8/include", |
||||
|
"${workspaceRoot}/../../../libs/poco/include", |
||||
|
"${workspaceRoot}/../../../libs/kiss/include", |
||||
|
"/usr/include/x86_64-linux-gnu/c++/5", |
||||
|
"/usr/include/pulse", |
||||
|
"/usr/include/cairo", |
||||
|
"/usr/include/gstreamer-1.0", |
||||
|
"/usr/include/glib-2.0", |
||||
|
"${workspaceRoot}", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOpenCv/libs/opencv/include/opencv4", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOpenCv/src", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBox2d/src", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBox2d/libs/Box2D", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBox2d/libs", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/libs", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/src", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/src/shapes", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/src/events", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/src/render", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/libs/bullet2.8.2/include/BulletCollision/CollisionShapes", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/libs/bullet2.8.2/include", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/src/joints", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxFFmpeg/src", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxVideoRecorder/src" |
||||
|
], |
||||
|
"browse": { |
||||
|
"limitSymbolsToIncludedHeaders": true, |
||||
|
"databaseFilename": "", |
||||
|
"path": [ |
||||
|
"/usr/include", |
||||
|
"/usr/local/include", |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOpenCv/src", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBox2d/src", |
||||
|
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxBullet/src" |
||||
|
] |
||||
|
}, |
||||
|
"intelliSenseMode": "clang-x64", |
||||
|
"compilerPath": "/usr/bin/gcc", |
||||
|
"cStandard": "c17", |
||||
|
"cppStandard": "c++17" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Win32", |
||||
|
"includePath": [ |
||||
|
"C:/msys64/mingw32/include/c++/7.4.0", |
||||
|
"C:/msys64/mingw32/i686-w64-mingw32/include", |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/3d", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/app", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/communication", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/events", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/gl", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/graphics", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/math", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/sound", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/types", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/utils", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks/video", |
||||
|
"${workspaceRoot}/../../../libs/boost/include", |
||||
|
"${workspaceRoot}/../../../libs/cairo/include", |
||||
|
"${workspaceRoot}/../../../libs/curl/include", |
||||
|
"${workspaceRoot}/../../../libs/fmod/include", |
||||
|
"${workspaceRoot}/../../../libs/FreeImage/include", |
||||
|
"${workspaceRoot}/../../../libs/freetype/include", |
||||
|
"${workspaceRoot}/../../../libs/glew/include", |
||||
|
"${workspaceRoot}/../../../libs/glfw/include", |
||||
|
"${workspaceRoot}/../../../libs/glm/include", |
||||
|
"${workspaceRoot}/../../../libs/json/include", |
||||
|
"${workspaceRoot}/../../../libs/pugixml/include", |
||||
|
"${workspaceRoot}/../../../libs/rtAudio/include", |
||||
|
"${workspaceRoot}/../../../libs/tess2/include", |
||||
|
"${workspaceRoot}/../../../libs/uriparser/include", |
||||
|
"${workspaceRoot}/../../../libs/utf8/include" |
||||
|
], |
||||
|
"browse": { |
||||
|
"limitSymbolsToIncludedHeaders": true, |
||||
|
"databaseFilename": "", |
||||
|
"path": [ |
||||
|
"${workspaceRoot}/../../../libs", |
||||
|
"${workspaceRoot}/../../../addons", |
||||
|
"${workspaceRoot}/../../../libs/openFrameworks" |
||||
|
] |
||||
|
}, |
||||
|
"intelliSenseMode": "clang-x64", |
||||
|
"compilerPath": "C:/msys64/mingw32/bin/g++.exe", |
||||
|
"cStandard": "c11", |
||||
|
"cppStandard": "c++17" |
||||
|
} |
||||
|
], |
||||
|
"version": 4 |
||||
|
} |
@ -0,0 +1,72 @@ |
|||||
|
{ |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"name": "C++ Launch", |
||||
|
"type": "cppdbg", |
||||
|
"request": "launch", |
||||
|
"args": [], |
||||
|
"stopAtEntry": false, |
||||
|
"cwd": "${workspaceRoot}", |
||||
|
"environment": [], |
||||
|
"externalConsole": false, |
||||
|
"linux": { |
||||
|
"MIMode": "gdb", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
], |
||||
|
"program": "${workspaceRoot}/bin/${workspaceFolderBasename}_debug" |
||||
|
}, |
||||
|
"osx": { |
||||
|
"MIMode": "lldb", |
||||
|
"program": "${workspaceRoot}/bin/${workspaceFolderBasename}_debug.app/Contents/MacOS/${workspaceFolderBasename}_debug" |
||||
|
}, |
||||
|
"windows": { |
||||
|
"MIMode": "gdb", |
||||
|
"miDebuggerPath": "gdb.exe", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
], |
||||
|
"program": "${workspaceRoot}/bin/${workspaceFolderBasename}_debug" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"name": "C++ Attach", |
||||
|
"type": "cppdbg", |
||||
|
"request": "attach", |
||||
|
"program": "enter program name, for example ${workspaceRoot}/a.out", |
||||
|
"processId": "${command:pickProcess}", |
||||
|
"linux": { |
||||
|
"MIMode": "gdb", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"osx": { |
||||
|
"MIMode": "lldb" |
||||
|
}, |
||||
|
"windows": { |
||||
|
"MIMode": "gdb", |
||||
|
"setupCommands": [ |
||||
|
{ |
||||
|
"description": "Enable pretty-printing for gdb", |
||||
|
"text": "-enable-pretty-printing", |
||||
|
"ignoreFailures": true |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,133 @@ |
|||||
|
{ |
||||
|
"version": "2.0.0", |
||||
|
"shell":{ |
||||
|
"task": true |
||||
|
}, |
||||
|
"tasks": [ |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Build RELEASE", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make -j -s 2>&1 && make RunRelease", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Build DEBUG", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make Debug -j -s 2>&1 || exit 1", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Clean DEBUG", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make CleanDebug", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Clean RELEASE", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make CleanRelease", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"type": "shell", |
||||
|
"label": "Clean ALL", |
||||
|
"presentation": { |
||||
|
"reveal": "always", |
||||
|
"panel": "shared" |
||||
|
}, |
||||
|
"command": "make clean", |
||||
|
"group": { |
||||
|
"kind": "build", |
||||
|
"isDefault": true |
||||
|
}, |
||||
|
"problemMatcher": { |
||||
|
"owner": "cpp", |
||||
|
"fileLocation": ["relative", "${workspaceFolder}"], |
||||
|
"pattern": { |
||||
|
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", |
||||
|
"file": 1, |
||||
|
"line": 2, |
||||
|
"column": 3, |
||||
|
"severity": 4, |
||||
|
"message": 5 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
# Attempt to load a config.make file.
|
||||
|
# If none is found, project defaults in config.project.make will be used.
|
||||
|
ifneq ($(wildcard config.make),) |
||||
|
include config.make |
||||
|
endif |
||||
|
|
||||
|
# make sure the the OF_ROOT location is defined
|
||||
|
ifndef OF_ROOT |
||||
|
OF_ROOT=$(realpath ../../..) |
||||
|
endif |
||||
|
|
||||
|
# call the project makefile!
|
||||
|
include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk |
@ -0,0 +1,4 @@ |
|||||
|
ofxOpenCv |
||||
|
ofxOpenCv |
||||
|
ofxBullet |
||||
|
ofxBullet |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,142 @@ |
|||||
|
################################################################################ |
||||
|
# CONFIGURE PROJECT MAKEFILE (optional) |
||||
|
# This file is where we make project specific configurations. |
||||
|
################################################################################ |
||||
|
|
||||
|
################################################################################ |
||||
|
# OF ROOT |
||||
|
# The location of your root openFrameworks installation |
||||
|
# (default) OF_ROOT = ../../.. |
||||
|
################################################################################ |
||||
|
OF_ROOT = ../../.. |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT ROOT |
||||
|
# The location of the project - a starting place for searching for files |
||||
|
# (default) PROJECT_ROOT = . (this directory) |
||||
|
# |
||||
|
################################################################################ |
||||
|
# PROJECT_ROOT = . |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT SPECIFIC CHECKS |
||||
|
# This is a project defined section to create internal makefile flags to |
||||
|
# conditionally enable or disable the addition of various features within |
||||
|
# this makefile. For instance, if you want to make changes based on whether |
||||
|
# GTK is installed, one might test that here and create a variable to check. |
||||
|
################################################################################ |
||||
|
# None |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT EXTERNAL SOURCE PATHS |
||||
|
# These are fully qualified paths that are not within the PROJECT_ROOT folder. |
||||
|
# Like source folders in the PROJECT_ROOT, these paths are subject to |
||||
|
# exlclusion via the PROJECT_EXLCUSIONS list. |
||||
|
# |
||||
|
# (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_EXTERNAL_SOURCE_PATHS = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT EXCLUSIONS |
||||
|
# These makefiles assume that all folders in your current project directory |
||||
|
# and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations |
||||
|
# to look for source code. The any folders or files that match any of the |
||||
|
# items in the PROJECT_EXCLUSIONS list below will be ignored. |
||||
|
# |
||||
|
# Each item in the PROJECT_EXCLUSIONS list will be treated as a complete |
||||
|
# string unless teh user adds a wildcard (%) operator to match subdirectories. |
||||
|
# GNU make only allows one wildcard for matching. The second wildcard (%) is |
||||
|
# treated literally. |
||||
|
# |
||||
|
# (default) PROJECT_EXCLUSIONS = (blank) |
||||
|
# |
||||
|
# Will automatically exclude the following: |
||||
|
# |
||||
|
# $(PROJECT_ROOT)/bin% |
||||
|
# $(PROJECT_ROOT)/obj% |
||||
|
# $(PROJECT_ROOT)/%.xcodeproj |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_EXCLUSIONS = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT LINKER FLAGS |
||||
|
# These flags will be sent to the linker when compiling the executable. |
||||
|
# |
||||
|
# (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
|
||||
|
# Currently, shared libraries that are needed are copied to the |
||||
|
# $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to |
||||
|
# add a runtime path to search for those shared libraries, since they aren't |
||||
|
# incorporated directly into the final executable application binary. |
||||
|
# TODO: should this be a default setting? |
||||
|
# PROJECT_LDFLAGS=-Wl,-rpath=./libs |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT DEFINES |
||||
|
# Create a space-delimited list of DEFINES. The list will be converted into |
||||
|
# CFLAGS with the "-D" flag later in the makefile. |
||||
|
# |
||||
|
# (default) PROJECT_DEFINES = (blank) |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_DEFINES = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT CFLAGS |
||||
|
# This is a list of fully qualified CFLAGS required when compiling for this |
||||
|
# project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS |
||||
|
# defined in your platform specific core configuration files. These flags are |
||||
|
# presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. |
||||
|
# |
||||
|
# (default) PROJECT_CFLAGS = (blank) |
||||
|
# |
||||
|
# Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in |
||||
|
# your platform specific configuration file will be applied by default and |
||||
|
# further flags here may not be needed. |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_CFLAGS = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT OPTIMIZATION CFLAGS |
||||
|
# These are lists of CFLAGS that are target-specific. While any flags could |
||||
|
# be conditionally added, they are usually limited to optimization flags. |
||||
|
# These flags are added BEFORE the PROJECT_CFLAGS. |
||||
|
# |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. |
||||
|
# |
||||
|
# (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) |
||||
|
# |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. |
||||
|
# |
||||
|
# (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) |
||||
|
# |
||||
|
# Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the |
||||
|
# PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration |
||||
|
# file will be applied by default and further optimization flags here may not |
||||
|
# be needed. |
||||
|
# |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_RELEASE = |
||||
|
# PROJECT_OPTIMIZATION_CFLAGS_DEBUG = |
||||
|
|
||||
|
################################################################################ |
||||
|
# PROJECT COMPILERS |
||||
|
# Custom compilers can be set for CC and CXX |
||||
|
# (default) PROJECT_CXX = (blank) |
||||
|
# (default) PROJECT_CC = (blank) |
||||
|
# Note: Leave a leading space when adding list items with the += operator |
||||
|
################################################################################ |
||||
|
# PROJECT_CXX = |
||||
|
# PROJECT_CC = |
@ -0,0 +1,107 @@ |
|||||
|
{ |
||||
|
"folders": [ |
||||
|
{ |
||||
|
"path": "." |
||||
|
}, |
||||
|
{ |
||||
|
"path": "${workspaceRoot}/../../../../libs/openFrameworks" |
||||
|
}, |
||||
|
{ |
||||
|
"path": "${workspaceRoot}/../../../../addons" |
||||
|
} |
||||
|
], |
||||
|
"settings": { |
||||
|
"files.associations": { |
||||
|
"ostream": "cpp", |
||||
|
"*.ipp": "cpp", |
||||
|
"functional": "cpp", |
||||
|
"cctype": "cpp", |
||||
|
"clocale": "cpp", |
||||
|
"cmath": "cpp", |
||||
|
"csignal": "cpp", |
||||
|
"cstdarg": "cpp", |
||||
|
"cstddef": "cpp", |
||||
|
"cstdio": "cpp", |
||||
|
"cstdlib": "cpp", |
||||
|
"cstring": "cpp", |
||||
|
"ctime": "cpp", |
||||
|
"cwchar": "cpp", |
||||
|
"cwctype": "cpp", |
||||
|
"any": "cpp", |
||||
|
"array": "cpp", |
||||
|
"atomic": "cpp", |
||||
|
"strstream": "cpp", |
||||
|
"bit": "cpp", |
||||
|
"*.tcc": "cpp", |
||||
|
"bitset": "cpp", |
||||
|
"cfenv": "cpp", |
||||
|
"charconv": "cpp", |
||||
|
"chrono": "cpp", |
||||
|
"codecvt": "cpp", |
||||
|
"compare": "cpp", |
||||
|
"complex": "cpp", |
||||
|
"concepts": "cpp", |
||||
|
"condition_variable": "cpp", |
||||
|
"cstdint": "cpp", |
||||
|
"deque": "cpp", |
||||
|
"forward_list": "cpp", |
||||
|
"list": "cpp", |
||||
|
"map": "cpp", |
||||
|
"set": "cpp", |
||||
|
"string": "cpp", |
||||
|
"unordered_map": "cpp", |
||||
|
"unordered_set": "cpp", |
||||
|
"vector": "cpp", |
||||
|
"exception": "cpp", |
||||
|
"expected": "cpp", |
||||
|
"algorithm": "cpp", |
||||
|
"iterator": "cpp", |
||||
|
"memory": "cpp", |
||||
|
"memory_resource": "cpp", |
||||
|
"numeric": "cpp", |
||||
|
"optional": "cpp", |
||||
|
"random": "cpp", |
||||
|
"ratio": "cpp", |
||||
|
"regex": "cpp", |
||||
|
"source_location": "cpp", |
||||
|
"string_view": "cpp", |
||||
|
"system_error": "cpp", |
||||
|
"tuple": "cpp", |
||||
|
"type_traits": "cpp", |
||||
|
"utility": "cpp", |
||||
|
"fstream": "cpp", |
||||
|
"future": "cpp", |
||||
|
"initializer_list": "cpp", |
||||
|
"iomanip": "cpp", |
||||
|
"iosfwd": "cpp", |
||||
|
"iostream": "cpp", |
||||
|
"istream": "cpp", |
||||
|
"limits": "cpp", |
||||
|
"mutex": "cpp", |
||||
|
"new": "cpp", |
||||
|
"numbers": "cpp", |
||||
|
"ranges": "cpp", |
||||
|
"semaphore": "cpp", |
||||
|
"shared_mutex": "cpp", |
||||
|
"span": "cpp", |
||||
|
"sstream": "cpp", |
||||
|
"stdexcept": "cpp", |
||||
|
"stop_token": "cpp", |
||||
|
"streambuf": "cpp", |
||||
|
"thread": "cpp", |
||||
|
"cinttypes": "cpp", |
||||
|
"typeindex": "cpp", |
||||
|
"typeinfo": "cpp", |
||||
|
"valarray": "cpp", |
||||
|
"variant": "cpp", |
||||
|
"format": "cpp", |
||||
|
"stdfloat": "cpp", |
||||
|
"__nullptr": "cpp", |
||||
|
"__hash_table": "cpp", |
||||
|
"__split_buffer": "cpp", |
||||
|
"__tree": "cpp", |
||||
|
"queue": "cpp", |
||||
|
"stack": "cpp" |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,71 @@ |
|||||
|
import qbs |
||||
|
import qbs.Process |
||||
|
import qbs.File |
||||
|
import qbs.FileInfo |
||||
|
import qbs.TextFile |
||||
|
import "../../../libs/openFrameworksCompiled/project/qtcreator/ofApp.qbs" as ofApp |
||||
|
|
||||
|
Project{ |
||||
|
property string of_root: "../../.." |
||||
|
|
||||
|
ofApp { |
||||
|
name: { return FileInfo.baseName(sourceDirectory) } |
||||
|
|
||||
|
files: [ |
||||
|
'src/main.cpp', |
||||
|
'src/ofApp.cpp', |
||||
|
'src/ofApp.h', |
||||
|
] |
||||
|
|
||||
|
of.addons: [ |
||||
|
'ofxBox2d', |
||||
|
'ofxBox2d', |
||||
|
'ofxOpenCv', |
||||
|
'ofxOpenCv', |
||||
|
] |
||||
|
|
||||
|
// additional flags for the project. the of module sets some |
||||
|
// flags by default to add the core libraries, search paths... |
||||
|
// this flags can be augmented through the following properties: |
||||
|
of.pkgConfigs: [] // list of additional system pkgs to include |
||||
|
of.includePaths: [] // include search paths |
||||
|
of.cFlags: [] // flags passed to the c compiler |
||||
|
of.cxxFlags: [] // flags passed to the c++ compiler |
||||
|
of.linkerFlags: [] // flags passed to the linker |
||||
|
of.defines: [] // defines are passed as -D to the compiler |
||||
|
// and can be checked with #ifdef or #if in the code |
||||
|
of.frameworks: [] // osx only, additional frameworks to link with the project |
||||
|
of.staticLibraries: [] // static libraries |
||||
|
of.dynamicLibraries: [] // dynamic libraries |
||||
|
|
||||
|
// other flags can be set through the cpp module: http://doc.qt.io/qbs/cpp-module.html |
||||
|
// eg: this will enable ccache when compiling |
||||
|
// |
||||
|
// cpp.compilerWrapper: 'ccache' |
||||
|
|
||||
|
Depends{ |
||||
|
name: "cpp" |
||||
|
} |
||||
|
|
||||
|
// common rules that parse the include search paths, core libraries... |
||||
|
Depends{ |
||||
|
name: "of" |
||||
|
} |
||||
|
|
||||
|
// dependency with the OF library |
||||
|
Depends{ |
||||
|
name: "openFrameworks" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
property bool makeOF: true // use makfiles to compile the OF library |
||||
|
// will compile OF only once for all your projects |
||||
|
// otherwise compiled per project with qbs |
||||
|
|
||||
|
|
||||
|
property bool precompileOfMain: false // precompile ofMain.h |
||||
|
// faster to recompile when including ofMain.h |
||||
|
// but might use a lot of space per project |
||||
|
|
||||
|
references: [FileInfo.joinPaths(of_root, "/libs/openFrameworksCompiled/project/qtcreator/openFrameworks.qbs")] |
||||
|
} |
@ -0,0 +1,267 @@ |
|||||
|
#include "Bullet.h" |
||||
|
|
||||
|
void Bullet::setup(){ |
||||
|
/* setup camera & world */ |
||||
|
camera_start_pos = ofVec3f(0, -3.f, -40.f); |
||||
|
camera_end_position = glm::vec3(ofRandom(-100, 100), ofRandom(-100, 100), ofRandom(0, 0)); |
||||
|
camera_move_duration = 10.f; |
||||
|
camera_move_start_time = ofGetElapsedTimef(); |
||||
|
is_camera_moving = false; |
||||
|
|
||||
|
camera.setPosition(camera_start_pos); |
||||
|
camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0)); |
||||
|
camera.enableOrtho(); |
||||
|
camera.setScale(0.01); |
||||
|
camera.setNearClip(-10000); |
||||
|
camera.setFarClip(10000); |
||||
|
|
||||
|
world.setup(); |
||||
|
world.setCamera(&camera); |
||||
|
world.setGravity( ofVec3f(0, 0, 0) ); |
||||
|
|
||||
|
for (int i = 0; i < numThreads; ++i) { |
||||
|
workerThreads.emplace_back(&Bullet::workerThreadFunction, this, i); |
||||
|
} |
||||
|
|
||||
|
shader.load("vertex_snap"); |
||||
|
|
||||
|
std::cout << workerThreads.size() << std::endl; |
||||
|
} |
||||
|
|
||||
|
void Bullet::update(){ |
||||
|
updateRepulsionNode(); |
||||
|
cameraBounds = getCameraBounds(camera); |
||||
|
world.update(); |
||||
|
if(is_camera_moving){ |
||||
|
float t = (ofGetElapsedTimef() - camera_move_start_time) / camera_move_duration; |
||||
|
if (t >= 1.0f){ |
||||
|
t = 1.0f; |
||||
|
is_camera_moving = false; |
||||
|
} |
||||
|
|
||||
|
float easedT = easeInOutCubic(t); |
||||
|
|
||||
|
glm::vec3 new_position = glm::mix(camera_start_pos, camera_end_position, easedT); |
||||
|
camera.setPosition(new_position); |
||||
|
|
||||
|
float baseZoom = 0.01f; |
||||
|
float peakZoom = 0.04f; |
||||
|
float zoomT = 1.0f - abs(2.0f * easedT - 1.0f); // Triangle wave using easedT
|
||||
|
float easedZoomT = easeInOutCubic(zoomT); // Apply easing to the zoom
|
||||
|
float currentZoom = glm::mix(baseZoom, peakZoom, easedZoomT); |
||||
|
camera.setScale(currentZoom); |
||||
|
} else { |
||||
|
//setNewCameraEndpoint();
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void Bullet::draw(){ |
||||
|
std::lock_guard<std::mutex> lock(shapeMutex); |
||||
|
float shapes_drawn = 0; |
||||
|
|
||||
|
gridSize = calculateGridSize(camera.getScale().x); |
||||
|
|
||||
|
camera.begin(); |
||||
|
glEnable( GL_DEPTH_TEST ); |
||||
|
|
||||
|
ofSetLineWidth(10.f); |
||||
|
ofDrawGrid(20, 10, true, false, false, true); |
||||
|
|
||||
|
ofNoFill(); |
||||
|
ofSetColor(ofColor::yellow); |
||||
|
|
||||
|
ofNoFill(); |
||||
|
|
||||
|
ofSetColor(ofColor::orange); |
||||
|
for(const auto& n : nodes){ |
||||
|
if(checkNodeVisibility(n)){ |
||||
|
ofPushMatrix(); |
||||
|
n.collider->transformGL(); |
||||
|
ofScale(n.scale * 1.4); |
||||
|
n.col_mesh.draw(); |
||||
|
n.collider->restoreTransformGL(); |
||||
|
ofPopMatrix(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
ofSetColor(ofColor::white); |
||||
|
ofFill(); |
||||
|
|
||||
|
for(const auto& n : nodes){ |
||||
|
|
||||
|
if(checkNodeVisibility(n)){ |
||||
|
ofPushMatrix(); |
||||
|
shader.begin(); |
||||
|
shader.setUniform1f("gridSize", gridSize); |
||||
|
shader.setUniformTexture("tex0", n.tex, 0); |
||||
|
n.collider->transformGL(); |
||||
|
ofScale(n.scale); |
||||
|
n.mesh.draw(); |
||||
|
n.collider->restoreTransformGL(); |
||||
|
shader.end(); |
||||
|
ofPopMatrix(); |
||||
|
shapes_drawn++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
camera.end(); |
||||
|
glDisable(GL_DEPTH_TEST); |
||||
|
|
||||
|
|
||||
|
|
||||
|
int totalShapes = nodes.size(); |
||||
|
ofVec3f gravity = world.getGravity(); |
||||
|
stringstream ss; |
||||
|
ss << "Total Shapes: " << totalShapes << endl; |
||||
|
ss << "FPS: " << ofGetFrameRate() << endl; |
||||
|
ss << "Shapes Drawn: " << shapes_drawn << endl; |
||||
|
ss << "Camera Position: " << camera.getPosition() << std::endl; |
||||
|
ss << "Camera Scale: " << camera.getScale() << std::endl; |
||||
|
ss << "Camera Bounds: " << cameraBounds.z << std::endl; |
||||
|
ofSetColor(255, 255, 255); |
||||
|
ofDrawBitmapString(ss.str().c_str(), 20, 20); |
||||
|
now = false; |
||||
|
} |
||||
|
|
||||
|
void Bullet::addMesh(ofMesh _mesh, ofMesh _simple_mesh, ofTexture _tex){ |
||||
|
std::lock_guard<std::mutex> lock(shapeMutex); |
||||
|
Node n; |
||||
|
n.tex = _tex; |
||||
|
float rand = ofRandom(0.01, 0.02); |
||||
|
glm::vec3 random_szie(rand, rand, rand); |
||||
|
n.scale = random_szie; |
||||
|
ofQuaternion startRot = ofQuaternion(0., 0., 0., PI); |
||||
|
ofVec3f target_location = ofVec3f( ofRandom(0, 0), ofRandom(0, 0), -5 ); |
||||
|
ofVec3f start_location = ofVec3f( ofRandom(-300, 300), ofRandom(-300, 300), -5 ); |
||||
|
|
||||
|
ofxBulletCustomShape* s = new ofxBulletCustomShape(); |
||||
|
s->addMesh(_simple_mesh, n.scale * 1.4, true); |
||||
|
s->create( world.world, start_location, startRot, 3.); |
||||
|
s->add(); |
||||
|
s->getRigidBody()->setAngularFactor(btVector3(0, 0, 1)); |
||||
|
s->getRigidBody()->setDamping(btScalar(0.001), btScalar(0.05)); |
||||
|
s->getRigidBody()->setLinearFactor(btVector3(1, 1, 0)); |
||||
|
s->getRigidBody()->setActivationState(DISABLE_DEACTIVATION); |
||||
|
s->getRigidBody()->setRestitution(btScalar(0.5)); |
||||
|
s->getRigidBody()->setFriction(btScalar(1.0)); |
||||
|
|
||||
|
positions.push_back(target_location); |
||||
|
|
||||
|
// Set how the col mesh is drawn!
|
||||
|
_simple_mesh.setMode(OF_PRIMITIVE_LINES); |
||||
|
|
||||
|
n.collider = s; |
||||
|
n.mesh = _mesh; |
||||
|
n.col_mesh = _simple_mesh; |
||||
|
nodes.push_back(n); |
||||
|
} |
||||
|
|
||||
|
void Bullet::workerThreadFunction(int threadId) { |
||||
|
while (!shouldTerminate) { |
||||
|
size_t batchSize = shapes.size() / numThreads; |
||||
|
size_t start = threadId * batchSize; |
||||
|
size_t end = (threadId == numThreads - 1) ? nodes.size() : start + batchSize; |
||||
|
|
||||
|
updateShapeBatch(start, end); |
||||
|
|
||||
|
// Add a small sleep to prevent busy-waiting
|
||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void Bullet::updateShapeBatch(size_t start, size_t end) { |
||||
|
// for (size_t i = start; i < end; ++i) {
|
||||
|
// std::lock_guard<std::mutex> lock(shapeMutex);
|
||||
|
// glm::vec3 pos = nodes[i].collider->getPosition();
|
||||
|
// glm::vec3 direction = glm::vec3(0, 0, -5) - pos;
|
||||
|
// float dist_sq = glm::length(direction);
|
||||
|
// glm::vec3 norm_dir = glm::normalize(direction);
|
||||
|
// nodes[i].collider->applyCentralForce(1.0 * norm_dir);
|
||||
|
|
||||
|
// if(now){
|
||||
|
// std::lock_guard<std::mutex> lock(shapeMutex);
|
||||
|
// nodes[i].collider->applyCentralForce(glm::vec3(ofRandom(-1, 1), ofRandom(-1, 1), ofRandom(-1, 1)));
|
||||
|
// }
|
||||
|
|
||||
|
// if (dist_sq > FORCE_RADIUS_SQ){
|
||||
|
// glm::vec3 norm_dir = glm::normalize(direction);
|
||||
|
// std::lock_guard<std::mutex> lock(shapeMutex);
|
||||
|
// nodes[i].collider->applyCentralForce(0.001 * direction);
|
||||
|
// }
|
||||
|
|
||||
|
|
||||
|
// btVector3 vel = nodes[i].collider->getRigidBody()->getLinearVelocity();
|
||||
|
// float vel_mag = vel.length();
|
||||
|
|
||||
|
// if (vel_mag > 1.0f) { // Cap at magnitude 1
|
||||
|
// vel.normalize(); // Normalize the velocity
|
||||
|
// vel *= 1.0f; // Scale to cap
|
||||
|
// nodes[i].collider->getRigidBody()->setLinearVelocity(vel); // Set the capped velocity
|
||||
|
// }
|
||||
|
|
||||
|
//}
|
||||
|
for (size_t i = start; i < end; ++i) { |
||||
|
std::lock_guard<std::mutex> lock(shapeMutex); |
||||
|
|
||||
|
glm::vec3 pos = nodes[i].collider->getPosition(); |
||||
|
glm::vec3 direction = glm::vec3(0, 0, -5) - pos; |
||||
|
float dist_sq = glm::length(direction); |
||||
|
glm::vec3 norm_dir = glm::normalize(direction); |
||||
|
nodes[i].collider->applyCentralForce(1.0f * norm_dir); |
||||
|
|
||||
|
// Apply repulsion force if needed
|
||||
|
if (shouldApplyRepulsion && i != repulsionNodeIndex) { |
||||
|
const Node& repulsionNode = nodes[repulsionNodeIndex]; |
||||
|
glm::vec3 repulsionDir = pos - repulsionNode.collider->getPosition(); |
||||
|
float repulsionDist = glm::length(repulsionDir); |
||||
|
|
||||
|
if (repulsionDist < repulsionRadius && repulsionDist > 0) { |
||||
|
repulsionDir = glm::normalize(repulsionDir); |
||||
|
float forceMagnitude = repulsionStrength * (1.0f - repulsionDist / repulsionRadius); |
||||
|
glm::vec3 repulsionForce = repulsionDir * forceMagnitude; |
||||
|
nodes[i].collider->applyCentralForce(repulsionForce * 100.0f); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
float Bullet::easeInOutCubic(float t) { |
||||
|
return t < 0.5 ? 4 * t * t * t : 1 - pow(-2 * t + 2, 3) / 2; |
||||
|
} |
||||
|
|
||||
|
float Bullet::calculateGridSize(float zoom){ |
||||
|
const float ref_zoom = 0.01; |
||||
|
const float ref_scale = 20; |
||||
|
float new_grid_size = (ref_zoom * ref_scale) / zoom; |
||||
|
if(new_grid_size < 5){ |
||||
|
new_grid_size = 5; |
||||
|
} |
||||
|
return new_grid_size; |
||||
|
} |
||||
|
|
||||
|
void Bullet::setNewCameraEndpoint(){ |
||||
|
camera_move_start_time = ofGetElapsedTimef(); |
||||
|
is_camera_moving = true; |
||||
|
camera_start_pos = camera.getPosition(); |
||||
|
camera_end_position = glm::vec3(ofRandom(-75, 75), ofRandom(-75, 75), 0.0); |
||||
|
} |
||||
|
|
||||
|
glm::vec4 Bullet::getCameraBounds(const ofCamera& cam){ |
||||
|
|
||||
|
glm::vec3 cam_pos = cam.getPosition(); |
||||
|
float cam_scale = cam.getScale().x; |
||||
|
float bounds = ofMap(cam_scale, 0.01, 0.2, 10, 120) + 20; |
||||
|
return glm::vec4(cam_pos.x + bounds, cam_pos.x - bounds, cam_pos.y + bounds, cam_pos.y - bounds); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
bool Bullet::checkNodeVisibility(const Node& n){ |
||||
|
glm::vec3 n_pos = n.collider->getPosition(); |
||||
|
if(n_pos.x < cameraBounds.x && n_pos.x > cameraBounds.y && n_pos.y < cameraBounds.z && n_pos.y > cameraBounds.w ){ |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
@ -0,0 +1,128 @@ |
|||||
|
#pragma once |
||||
|
#include "ofMain.h" |
||||
|
#include "ofxBullet.h" |
||||
|
#include <thread> |
||||
|
#include <mutex> |
||||
|
#include <atomic> |
||||
|
#include <vector> |
||||
|
|
||||
|
struct Node { |
||||
|
ofxBulletCustomShape* collider; |
||||
|
ofMesh col_mesh; |
||||
|
ofMesh mesh; |
||||
|
ofImage img; |
||||
|
ofTexture tex; |
||||
|
glm::vec3 scale; |
||||
|
}; |
||||
|
|
||||
|
class Bullet{ |
||||
|
public: |
||||
|
void setup(); |
||||
|
void update(); |
||||
|
void draw(); |
||||
|
void addMesh(ofMesh _mesh, ofMesh _simple_mesh, ofTexture _tex); |
||||
|
float easeInOutCubic(float t); |
||||
|
float calculateGridSize(float zoom); |
||||
|
void setNewCameraEndpoint(); |
||||
|
glm::vec4 getCameraBounds(const ofCamera& cam); |
||||
|
bool checkNodeVisibility(const Node& n); |
||||
|
ofxBulletWorldRigid world; |
||||
|
vector <ofxBulletBox*> bounds; |
||||
|
ofxBulletCustomShape* boundsShape; |
||||
|
ofMaterial boundsMat; |
||||
|
ofMaterial shapeMat; |
||||
|
float boundsWidth; |
||||
|
vector<ofxBulletCustomShape*> shapes; |
||||
|
vector<ofxBulletCustomShape*> simplifiedShapes; |
||||
|
vector<glm::vec3> positions; |
||||
|
ofMaterial logoMat; |
||||
|
vector<Node> nodes; |
||||
|
|
||||
|
bool bDrawDebug; |
||||
|
|
||||
|
|
||||
|
ofMesh mesh; |
||||
|
ofMesh simple_mesh; |
||||
|
|
||||
|
ofEasyCam camera; |
||||
|
glm::vec3 camera_start_pos; |
||||
|
glm::vec3 camera_end_position; |
||||
|
bool is_camera_moving; |
||||
|
float camera_move_duration; |
||||
|
float camera_move_start_time; |
||||
|
|
||||
|
ofLight light; |
||||
|
ofTexture tex; |
||||
|
|
||||
|
ofShader shader; |
||||
|
float gridSize = 20.0f; |
||||
|
|
||||
|
glm::vec4 cameraBounds; |
||||
|
|
||||
|
void updateRepulsionNode() { |
||||
|
static int frameCount = 0; |
||||
|
static const int repulsionInterval = 60; // Apply repulsion every 60 frames
|
||||
|
|
||||
|
if (frameCount % repulsionInterval == 0 && !nodes.empty()) { |
||||
|
repulsionNodeIndex = ofRandom(nodes.size()); |
||||
|
shouldApplyRepulsion = true; |
||||
|
} else if (frameCount % repulsionInterval == repulsionInterval - 1) { |
||||
|
shouldApplyRepulsion = false; |
||||
|
} |
||||
|
frameCount++; |
||||
|
} |
||||
|
|
||||
|
ofRectangle calculateMeshBounds(const ofMesh& mesh) { |
||||
|
if (mesh.getVertices().empty()) { |
||||
|
return ofRectangle(); |
||||
|
} |
||||
|
|
||||
|
ofVec3f min = mesh.getVertices()[0]; |
||||
|
ofVec3f max = min; |
||||
|
|
||||
|
for (const auto& vertex : mesh.getVertices()) { |
||||
|
min.x = std::min(min.x, vertex.x); |
||||
|
min.y = std::min(min.y, vertex.y); |
||||
|
min.z = std::min(min.z, vertex.z); |
||||
|
|
||||
|
max.x = std::max(max.x, vertex.x); |
||||
|
max.y = std::max(max.y, vertex.y); |
||||
|
max.z = std::max(max.z, vertex.z); |
||||
|
} |
||||
|
|
||||
|
return ofRectangle(min.x, min.y, max.x - min.x, max.y - min.y); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void cleanup() { |
||||
|
shouldTerminate = true; |
||||
|
for (auto& thread : workerThreads) { |
||||
|
if (thread.joinable()) { |
||||
|
thread.join(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
~Bullet() { |
||||
|
cleanup(); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
std::vector<std::thread> workerThreads; |
||||
|
std::mutex shapeMutex; |
||||
|
std::atomic<bool> shouldTerminate{false}; |
||||
|
|
||||
|
std::atomic<size_t> repulsionNodeIndex{0}; |
||||
|
std::atomic<bool> shouldApplyRepulsion{false}; |
||||
|
const float repulsionRadius = 10.0f; |
||||
|
const float repulsionStrength = 1.0f; |
||||
|
|
||||
|
const int numThreads = std::thread::hardware_concurrency(); |
||||
|
const float FORCE_RADIUS = 200.0f; // Radius beyond which force is applied
|
||||
|
const float FORCE_RADIUS_SQ = FORCE_RADIUS * FORCE_RADIUS; // Squared radius for faster comparisons
|
||||
|
const float INNER_RADIUS = 10.0f; // Inner radius where objects are considered "arrived"
|
||||
|
const float INNER_RADIUS_SQ = INNER_RADIUS * INNER_RADIUS; |
||||
|
void workerThreadFunction(int threadId); |
||||
|
void updateShapeBatch(size_t start, size_t end); |
||||
|
bool now = true; |
||||
|
}; |
@ -0,0 +1,151 @@ |
|||||
|
#include "MeshGenerator.h" |
||||
|
|
||||
|
vector<ofMesh> MeshGenerator::generateSimplifiedMesh(ofImage& image) { |
||||
|
ofMesh mesh; |
||||
|
ofMesh simple_mesh; |
||||
|
|
||||
|
// Convert ofImage to cv::Mat
|
||||
|
cv::Mat imageMat(image.getHeight(), image.getWidth(), CV_8UC4, image.getPixels().getData()); |
||||
|
|
||||
|
// Split the channels
|
||||
|
std::vector<cv::Mat> channels; |
||||
|
cv::split(imageMat, channels); |
||||
|
|
||||
|
// Use the alpha channel for processing
|
||||
|
cv::Mat alphaMat = channels[3]; |
||||
|
|
||||
|
// Threshold the alpha channel
|
||||
|
cv::Mat binaryMat; |
||||
|
cv::threshold(alphaMat, binaryMat, 1, 255, cv::THRESH_BINARY); |
||||
|
|
||||
|
ofImage debugImage; |
||||
|
debugImage.setFromPixels(binaryMat.data, image.getWidth(), image.getHeight(), OF_IMAGE_GRAYSCALE); |
||||
|
debugImage.save("debug_binaryMat.png"); |
||||
|
|
||||
|
|
||||
|
// Find contours
|
||||
|
std::vector<std::vector<cv::Point>> contours; |
||||
|
cv::findContours(binaryMat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); |
||||
|
|
||||
|
// Clear existing mesh
|
||||
|
mesh.clear(); |
||||
|
simple_mesh.clear(); |
||||
|
|
||||
|
// Filter and process contours
|
||||
|
double minContourArea = 100.0; // Adjust this value as needed
|
||||
|
std::vector<std::vector<cv::Point>> filteredContours; |
||||
|
|
||||
|
for (const auto& contour : contours) { |
||||
|
double area = cv::contourArea(contour); |
||||
|
if (area > minContourArea) { |
||||
|
filteredContours.push_back(contour); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Sort contours by area (largest first)
|
||||
|
std::sort(filteredContours.begin(), filteredContours.end(), |
||||
|
[](const std::vector<cv::Point>& c1, const std::vector<cv::Point>& c2) { |
||||
|
return cv::contourArea(c1) > cv::contourArea(c2); |
||||
|
}); |
||||
|
|
||||
|
// Process only the largest contour (or a few largest if needed)
|
||||
|
size_t numContoursToProcess = std::min(size_t(1), filteredContours.size()); |
||||
|
|
||||
|
// Vector to hold the vertices
|
||||
|
std::vector<ofVec3f> vertices; |
||||
|
|
||||
|
for (size_t i = 0; i < numContoursToProcess; ++i) { |
||||
|
const auto& contour = filteredContours[i]; |
||||
|
std::vector<cv::Point> approxCurve; |
||||
|
|
||||
|
// Simplify the contour 0.005 (0.05) -> v simple mesh
|
||||
|
double epsilon = 0.005 * cv::arcLength(contour, true); |
||||
|
cv::approxPolyDP(contour, approxCurve, epsilon, true); |
||||
|
|
||||
|
// Add vertices and calculate the texture coordinates based on contour points
|
||||
|
if (approxCurve.size() > 1) { |
||||
|
for (const auto& point : approxCurve) { |
||||
|
float x = point.x; |
||||
|
float y = point.y; |
||||
|
vertices.emplace_back(x, y, 0); |
||||
|
|
||||
|
// Map the texture coordinates to the non-transparent parts directly
|
||||
|
float texCoordX = ofMap(x, 0, image.getWidth() - 1, 0, 1); // use image width
|
||||
|
float texCoordY = ofMap(y, 0, image.getHeight() - 1, 0, 1); // use image height
|
||||
|
mesh.addTexCoord(ofVec2f(texCoordX, texCoordY)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Calculate the centroid
|
||||
|
ofVec3f centroid(0, 0, 0); |
||||
|
for (const auto& vertex : vertices) { |
||||
|
centroid += vertex; |
||||
|
} |
||||
|
centroid /= vertices.size(); |
||||
|
|
||||
|
// Add vertices to the mesh, adjusting for centroid
|
||||
|
for (const auto& vertex : vertices) { |
||||
|
mesh.addVertex(vertex - centroid); // Translate each vertex to center it
|
||||
|
} |
||||
|
|
||||
|
// Create indices for drawing
|
||||
|
for (size_t i = 0; i < vertices.size(); ++i) { |
||||
|
mesh.addIndex(i); |
||||
|
mesh.addIndex((i + 1) % vertices.size()); |
||||
|
} |
||||
|
|
||||
|
/* simplified mesh */ |
||||
|
|
||||
|
vertices.clear(); |
||||
|
|
||||
|
for (size_t i = 0; i < numContoursToProcess; ++i) { |
||||
|
const auto& contour = filteredContours[i]; |
||||
|
std::vector<cv::Point> approxCurve; |
||||
|
|
||||
|
// Simplify the contour 0.005 (0.05) -> v simple mesh
|
||||
|
double epsilon = 0.025 * cv::arcLength(contour, true); |
||||
|
cv::approxPolyDP(contour, approxCurve, epsilon, true); |
||||
|
|
||||
|
// Add vertices and calculate the texture coordinates based on contour points
|
||||
|
if (approxCurve.size() > 1) { |
||||
|
for (const auto& point : approxCurve) { |
||||
|
float x = point.x; |
||||
|
float y = point.y; |
||||
|
vertices.emplace_back(x, y, 0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Calculate the centroid
|
||||
|
centroid = glm::vec3(0, 0, 0); |
||||
|
for (const auto& vertex : vertices) { |
||||
|
centroid += vertex; |
||||
|
} |
||||
|
centroid /= vertices.size(); |
||||
|
|
||||
|
// Add vertices to the mesh, adjusting for centroid
|
||||
|
for (const auto& vertex : vertices) { |
||||
|
simple_mesh.addVertex(vertex - centroid); // Translate each vertex to center it
|
||||
|
} |
||||
|
|
||||
|
// Create indices for drawing
|
||||
|
for (size_t i = 0; i < vertices.size(); ++i) { |
||||
|
simple_mesh.addIndex(i); |
||||
|
simple_mesh.addIndex((i + 1) % vertices.size()); |
||||
|
} |
||||
|
|
||||
|
// Set the primitive mode to triangles to allow proper texture mapping
|
||||
|
mesh.setMode(OF_PRIMITIVE_TRIANGLE_FAN); |
||||
|
simple_mesh.setMode(OF_PRIMITIVE_TRIANGLES); |
||||
|
|
||||
|
vector<ofMesh> mesh_list; |
||||
|
mesh_list.emplace_back(mesh); |
||||
|
mesh_list.emplace_back(simple_mesh); |
||||
|
return mesh_list; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,11 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include "ofMain.h" |
||||
|
#include "ofxOpenCv.h" |
||||
|
|
||||
|
class MeshGenerator{ |
||||
|
|
||||
|
public: |
||||
|
vector<ofMesh> generateSimplifiedMesh(ofImage& img); |
||||
|
|
||||
|
}; |
@ -0,0 +1,31 @@ |
|||||
|
#include "VP.h" |
||||
|
|
||||
|
// Function to generate random vectors
|
||||
|
std::vector<std::vector<double>> VP::generateRandomVectors(int count, int dimension) { |
||||
|
std::vector<std::vector<double>> vectors; |
||||
|
std::random_device rd; |
||||
|
std::mt19937 gen(rd()); |
||||
|
std::uniform_real_distribution<> dis(0.0, 1.0); |
||||
|
|
||||
|
for (int i = 0; i < count; ++i) { |
||||
|
std::vector<double> vec; |
||||
|
for (int j = 0; j < dimension; ++j) { |
||||
|
vec.push_back(dis(gen)); |
||||
|
} |
||||
|
vectors.push_back(vec); |
||||
|
} |
||||
|
return vectors; |
||||
|
} |
||||
|
|
||||
|
vpt::VpTree VP::loadTree(std::string path){ |
||||
|
return vpt::VpTree::load(path); |
||||
|
} |
||||
|
|
||||
|
void VP::saveTree(std::string filename, vpt::VpTree& tree){ |
||||
|
tree.save(filename); |
||||
|
} |
||||
|
|
||||
|
vpt::VpTree VP::buildTree(std::vector<vpt::Vector> vectors){ |
||||
|
vpt::VpTree tree(vectors); |
||||
|
return tree; |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
#pragma once |
||||
|
#include <iostream> |
||||
|
#include <vector> |
||||
|
#include <random> |
||||
|
#include <chrono> |
||||
|
#include "VpTree.hpp" |
||||
|
|
||||
|
class VP{ |
||||
|
public: |
||||
|
std::vector<std::vector<double>> generateRandomVectors(int count, int dimension); |
||||
|
vpt::VpTree loadTree(std::string path); |
||||
|
void saveTree(std::string filename, vpt::VpTree& tree); |
||||
|
vpt::VpTree buildTree(std::vector<vpt::Vector> vectors); |
||||
|
}; |
@ -0,0 +1,346 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <algorithm> |
||||
|
#include <vector> |
||||
|
#include <queue> |
||||
|
#include <limits> |
||||
|
#include <random> |
||||
|
#include <cmath> |
||||
|
#include <stdexcept> |
||||
|
#include <functional> |
||||
|
#include <optional> |
||||
|
#include <fstream> |
||||
|
#include <iostream> |
||||
|
#include <numeric> |
||||
|
#include "ofFileUtils.h" |
||||
|
|
||||
|
namespace vpt { |
||||
|
|
||||
|
using Vector = std::vector<double>; |
||||
|
using Metric = std::function<double(const Vector&, const Vector&)>; |
||||
|
using DistancesIndices = std::pair<std::vector<double>, std::vector<int>>; |
||||
|
using BatchDistancesIndices = std::pair<std::vector<std::vector<double>>, std::vector<std::vector<int>>>; |
||||
|
|
||||
|
template<class InputIterator> |
||||
|
inline double sum(InputIterator begin, InputIterator end) { |
||||
|
return std::accumulate(begin, end, 0.0); |
||||
|
} |
||||
|
|
||||
|
struct EuclideanMetric { |
||||
|
inline double operator()(const Vector& v1, const Vector& v2) const { |
||||
|
Vector diffSquares(v1.size()); |
||||
|
std::transform(v1.begin(), v1.end(), v2.begin(), diffSquares.begin(), |
||||
|
[](double lhs, double rhs) { return (lhs - rhs) * (lhs - rhs); }); |
||||
|
return std::sqrt(sum(diffSquares.begin(), diffSquares.end())); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
class DimensionMismatch : public std::runtime_error { |
||||
|
public: |
||||
|
inline DimensionMismatch(int expected, int got) |
||||
|
: std::runtime_error("Item dimension doesn't match: expected " + std::to_string(expected) + |
||||
|
", got " + std::to_string(got)) {} |
||||
|
}; |
||||
|
|
||||
|
class VpTree { |
||||
|
public: |
||||
|
template<typename InputIterator> |
||||
|
inline explicit VpTree(InputIterator start, InputIterator end, Metric metric = EuclideanMetric()); |
||||
|
|
||||
|
template<typename Container> |
||||
|
inline explicit VpTree(const Container& container, Metric metric = EuclideanMetric()); |
||||
|
|
||||
|
inline explicit VpTree(std::initializer_list<Vector> list, Metric metric = EuclideanMetric()); |
||||
|
|
||||
|
inline DistancesIndices getNearestNeighbors(const Vector& target, int neighborsCount) const; |
||||
|
|
||||
|
template<typename VectorLike> |
||||
|
inline DistancesIndices getNearestNeighbors(const VectorLike& target, int neighborsCount) const; |
||||
|
|
||||
|
inline DistancesIndices getNearestNeighbors(std::initializer_list<double> target, int neighborsCount) const; |
||||
|
|
||||
|
template<typename Container> |
||||
|
inline BatchDistancesIndices getNearestNeighborsBatch(const Container& targets, int neighborsCount) const; |
||||
|
|
||||
|
inline BatchDistancesIndices getNearestNeighborsBatch(std::initializer_list<Vector> targets, int neighborsCount) const; |
||||
|
|
||||
|
// Save the VpTree to a file
|
||||
|
inline void save(const std::string& filename) const { |
||||
|
std::ofstream out(filename, std::ios::binary); |
||||
|
if (!out) { |
||||
|
throw std::runtime_error("Cannot open file for writing: " + filename); |
||||
|
} |
||||
|
|
||||
|
// Save dimension
|
||||
|
out.write(reinterpret_cast<const char*>(&dimension_), sizeof(dimension_)); |
||||
|
|
||||
|
// Save items
|
||||
|
size_t itemsSize = items_.size(); |
||||
|
out.write(reinterpret_cast<const char*>(&itemsSize), sizeof(itemsSize)); |
||||
|
for (const auto& item : items_) { |
||||
|
size_t vecSize = item.first.size(); |
||||
|
out.write(reinterpret_cast<const char*>(&vecSize), sizeof(vecSize)); |
||||
|
out.write(reinterpret_cast<const char*>(item.first.data()), vecSize * sizeof(double)); |
||||
|
out.write(reinterpret_cast<const char*>(&item.second), sizeof(item.second)); |
||||
|
} |
||||
|
|
||||
|
// Save nodes
|
||||
|
size_t nodesSize = nodes_.size(); |
||||
|
out.write(reinterpret_cast<const char*>(&nodesSize), sizeof(nodesSize)); |
||||
|
out.write(reinterpret_cast<const char*>(nodes_.data()), nodesSize * sizeof(Node)); |
||||
|
|
||||
|
if (!out) { |
||||
|
throw std::runtime_error("Error writing to file: " + filename); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Load the VpTree from a file
|
||||
|
inline static VpTree load(const std::string& filename, Metric metric = EuclideanMetric()) { |
||||
|
std::ifstream in(filename, std::ios::binary); |
||||
|
if (!in) { |
||||
|
throw std::runtime_error("Cannot open file for reading: " + filename); |
||||
|
} |
||||
|
|
||||
|
VpTree tree; |
||||
|
tree.distance_ = std::move(metric); |
||||
|
|
||||
|
// Load dimension
|
||||
|
in.read(reinterpret_cast<char*>(&tree.dimension_), sizeof(tree.dimension_)); |
||||
|
|
||||
|
// Load items
|
||||
|
size_t itemsSize; |
||||
|
in.read(reinterpret_cast<char*>(&itemsSize), sizeof(itemsSize)); |
||||
|
tree.items_.resize(itemsSize); |
||||
|
for (auto& item : tree.items_) { |
||||
|
size_t vecSize; |
||||
|
in.read(reinterpret_cast<char*>(&vecSize), sizeof(vecSize)); |
||||
|
item.first.resize(vecSize); |
||||
|
in.read(reinterpret_cast<char*>(item.first.data()), vecSize * sizeof(double)); |
||||
|
in.read(reinterpret_cast<char*>(&item.second), sizeof(item.second)); |
||||
|
} |
||||
|
|
||||
|
// Load nodes
|
||||
|
size_t nodesSize; |
||||
|
in.read(reinterpret_cast<char*>(&nodesSize), sizeof(nodesSize)); |
||||
|
tree.nodes_.resize(nodesSize); |
||||
|
in.read(reinterpret_cast<char*>(tree.nodes_.data()), nodesSize * sizeof(Node)); |
||||
|
|
||||
|
if (!in) { |
||||
|
throw std::runtime_error("Error reading from file: " + filename); |
||||
|
} else { |
||||
|
std::cout << "Tree loaded from disk." << std::endl; |
||||
|
} |
||||
|
|
||||
|
return tree; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
struct Node { |
||||
|
static constexpr int Leaf = -1; |
||||
|
int item; |
||||
|
double threshold; |
||||
|
int left; |
||||
|
int right; |
||||
|
|
||||
|
// Default constructor
|
||||
|
Node() : item(Leaf), threshold(0.0), left(Leaf), right(Leaf) {} |
||||
|
|
||||
|
Node(int item, double threshold = 0., int left = Leaf, int right = Leaf) |
||||
|
: item(item), threshold(threshold), left(left), right(right) {} |
||||
|
}; |
||||
|
|
||||
|
using Item = std::pair<Vector, int>; |
||||
|
|
||||
|
std::vector<Item> items_; |
||||
|
std::vector<Node> nodes_; |
||||
|
std::mt19937 rng_; |
||||
|
int dimension_; |
||||
|
Metric distance_; |
||||
|
|
||||
|
template<typename InputIterator> |
||||
|
inline std::vector<Item> makeItems(InputIterator start, InputIterator end); |
||||
|
|
||||
|
inline std::optional<int> makeTree(int lower, int upper); |
||||
|
inline void selectRoot(int lower, int upper); |
||||
|
inline void partitionByDistance(int lower, int pos, int upper); |
||||
|
inline int makeNode(int item); |
||||
|
inline Node root() const { return nodes_[0]; } |
||||
|
|
||||
|
// Default constructor for use in load function
|
||||
|
inline VpTree() : rng_(std::random_device()()) {} |
||||
|
|
||||
|
class Searcher { |
||||
|
public: |
||||
|
inline explicit Searcher(const VpTree* tree, const Vector& target, int neighborsCount); |
||||
|
inline DistancesIndices search(); |
||||
|
|
||||
|
private: |
||||
|
struct HeapItem { |
||||
|
inline bool operator<(const HeapItem& other) const { return dist < other.dist; } |
||||
|
int item; |
||||
|
double dist; |
||||
|
}; |
||||
|
|
||||
|
inline void searchInNode(const Node& node); |
||||
|
|
||||
|
const VpTree* tree_; |
||||
|
Vector target_; |
||||
|
int neighborsCount_; |
||||
|
double tau_; |
||||
|
std::priority_queue<HeapItem> heap_; |
||||
|
}; |
||||
|
|
||||
|
friend class Searcher; |
||||
|
}; |
||||
|
|
||||
|
template<typename InputIterator> |
||||
|
inline VpTree::VpTree(InputIterator start, InputIterator end, Metric metric) |
||||
|
: items_(makeItems(start, end)), nodes_(), rng_(std::random_device()()), distance_(std::move(metric)) { |
||||
|
nodes_.reserve(items_.size()); |
||||
|
makeTree(0, items_.size()); |
||||
|
} |
||||
|
|
||||
|
template<typename Container> |
||||
|
inline VpTree::VpTree(const Container& container, Metric metric) |
||||
|
: VpTree(container.begin(), container.end(), std::move(metric)) {} |
||||
|
|
||||
|
inline VpTree::VpTree(std::initializer_list<Vector> list, Metric metric) |
||||
|
: VpTree(list.begin(), list.end(), std::move(metric)) {} |
||||
|
|
||||
|
inline std::optional<int> VpTree::makeTree(int lower, int upper) { |
||||
|
if (lower >= upper) { |
||||
|
return std::nullopt; |
||||
|
} else if (lower + 1 == upper) { |
||||
|
return makeNode(lower); |
||||
|
} else { |
||||
|
selectRoot(lower, upper); |
||||
|
int median = (upper + lower) / 2; |
||||
|
partitionByDistance(lower, median, upper); |
||||
|
auto node = makeNode(lower); |
||||
|
nodes_[node].threshold = distance_(items_[lower].first, items_[median].first); |
||||
|
nodes_[node].left = makeTree(lower + 1, median).value_or(Node::Leaf); |
||||
|
nodes_[node].right = makeTree(median, upper).value_or(Node::Leaf); |
||||
|
return node; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
inline void VpTree::selectRoot(int lower, int upper) { |
||||
|
std::uniform_int_distribution<int> uni(lower, upper - 1); |
||||
|
int root = uni(rng_); |
||||
|
std::swap(items_[lower], items_[root]); |
||||
|
} |
||||
|
|
||||
|
inline void VpTree::partitionByDistance(int lower, int pos, int upper) { |
||||
|
std::nth_element( |
||||
|
items_.begin() + lower + 1, items_.begin() + pos, items_.begin() + upper, |
||||
|
[this, &lower](const Item& i1, const Item& i2) { |
||||
|
return distance_(items_[lower].first, i1.first) < distance_(items_[lower].first, i2.first); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
inline int VpTree::makeNode(int item) { |
||||
|
nodes_.emplace_back(item); |
||||
|
return static_cast<int>(nodes_.size() - 1); |
||||
|
} |
||||
|
|
||||
|
template<typename InputIterator> |
||||
|
inline std::vector<VpTree::Item> VpTree::makeItems(InputIterator begin, InputIterator end) { |
||||
|
if (begin != end) { |
||||
|
dimension_ = begin->size(); |
||||
|
} else { |
||||
|
dimension_ = -1; |
||||
|
} |
||||
|
|
||||
|
std::vector<Item> res; |
||||
|
for (int i = 0; begin != end; ++begin, ++i) { |
||||
|
res.emplace_back(Vector(begin->begin(), begin->end()), i); |
||||
|
auto lastDimension = res.back().first.size(); |
||||
|
if (lastDimension != dimension_) { |
||||
|
throw DimensionMismatch(dimension_, lastDimension); |
||||
|
} |
||||
|
} |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
template<typename VectorLike> |
||||
|
inline DistancesIndices VpTree::getNearestNeighbors(const VectorLike& target, int neighborsCount) const { |
||||
|
return getNearestNeighbors(Vector(target.begin(), target.end()), neighborsCount); |
||||
|
} |
||||
|
|
||||
|
inline DistancesIndices VpTree::getNearestNeighbors(std::initializer_list<double> target, int neighborsCount) const { |
||||
|
return getNearestNeighbors(Vector(target.begin(), target.end()), neighborsCount); |
||||
|
} |
||||
|
|
||||
|
inline DistancesIndices VpTree::getNearestNeighbors(const Vector& target, int neighborsCount) const { |
||||
|
auto targetDimension = target.size(); |
||||
|
if (targetDimension != dimension_) { |
||||
|
throw DimensionMismatch(dimension_, targetDimension); |
||||
|
} |
||||
|
Searcher searcher(this, target, neighborsCount); |
||||
|
return searcher.search(); |
||||
|
} |
||||
|
|
||||
|
template<typename Container> |
||||
|
inline BatchDistancesIndices VpTree::getNearestNeighborsBatch(const Container& targets, int neighborsCount) const { |
||||
|
std::vector<std::vector<double>> batchDistances(targets.size()); |
||||
|
std::vector<std::vector<int>> batchIndices(targets.size()); |
||||
|
#pragma omp parallel for schedule(dynamic) |
||||
|
for (size_t i = 0; i < targets.size(); ++i) { |
||||
|
std::tie(batchDistances[i], batchIndices[i]) = getNearestNeighbors(targets[i], neighborsCount); |
||||
|
} |
||||
|
return {batchDistances, batchIndices}; |
||||
|
} |
||||
|
|
||||
|
inline BatchDistancesIndices VpTree::getNearestNeighborsBatch(std::initializer_list<Vector> targets, int neighborsCount) const { |
||||
|
return getNearestNeighborsBatch(std::vector<Vector>(targets.begin(), targets.end()), neighborsCount); |
||||
|
} |
||||
|
|
||||
|
inline VpTree::Searcher::Searcher(const VpTree* tree, const Vector& target, int neighborsCount) |
||||
|
: tree_(tree), target_(target), neighborsCount_(neighborsCount), |
||||
|
tau_(std::numeric_limits<double>::max()), heap_() {} |
||||
|
|
||||
|
inline DistancesIndices VpTree::Searcher::search() { |
||||
|
searchInNode(tree_->root()); |
||||
|
|
||||
|
DistancesIndices results; |
||||
|
results.first.reserve(heap_.size()); |
||||
|
results.second.reserve(heap_.size()); |
||||
|
while (!heap_.empty()) { |
||||
|
results.first.push_back(heap_.top().dist); |
||||
|
results.second.push_back(tree_->items_[heap_.top().item].second); |
||||
|
heap_.pop(); |
||||
|
} |
||||
|
std::reverse(results.first.begin(), results.first.end()); |
||||
|
std::reverse(results.second.begin(), results.second.end()); |
||||
|
return results; |
||||
|
} |
||||
|
|
||||
|
inline void VpTree::Searcher::searchInNode(const Node& node) { |
||||
|
double dist = tree_->distance_(tree_->items_[node.item].first, target_); |
||||
|
|
||||
|
if (dist < tau_) { |
||||
|
if (heap_.size() == neighborsCount_) |
||||
|
heap_.pop(); |
||||
|
|
||||
|
heap_.push({node.item, dist}); |
||||
|
|
||||
|
if (heap_.size() == neighborsCount_) |
||||
|
tau_ = heap_.top().dist; |
||||
|
} |
||||
|
|
||||
|
if (dist < node.threshold) { |
||||
|
if (node.left != Node::Leaf && dist - tau_ <= node.threshold) |
||||
|
searchInNode(tree_->nodes_[node.left]); |
||||
|
|
||||
|
if (node.right != Node::Leaf && dist + tau_ >= node.threshold) |
||||
|
searchInNode(tree_->nodes_[node.right]); |
||||
|
} else { |
||||
|
if (node.right != Node::Leaf && dist + tau_ >= node.threshold) |
||||
|
searchInNode(tree_->nodes_[node.right]); |
||||
|
|
||||
|
if (node.left != Node::Leaf && dist - tau_ <= node.threshold) |
||||
|
searchInNode(tree_->nodes_[node.left]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} // namespace vpt
|
@ -0,0 +1,18 @@ |
|||||
|
#include "ofMain.h" |
||||
|
#include "ofApp.h" |
||||
|
|
||||
|
//========================================================================
|
||||
|
int main( ){ |
||||
|
|
||||
|
//Use ofGLFWWindowSettings for more options like multi-monitor fullscreen
|
||||
|
ofGLWindowSettings settings; |
||||
|
settings.setSize(1920, 960); |
||||
|
settings.setGLVersion(3, 2); |
||||
|
settings.windowMode = OF_WINDOW; //can also be OF_FULLSCREEN
|
||||
|
|
||||
|
auto window = ofCreateWindow(settings); |
||||
|
|
||||
|
ofRunApp(window, make_shared<ofApp>()); |
||||
|
ofRunMainLoop(); |
||||
|
|
||||
|
} |
@ -0,0 +1,184 @@ |
|||||
|
#include "ofApp.h" |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::setup(){ |
||||
|
|
||||
|
const int vectorCount = 10000; |
||||
|
const int dimension = 7; |
||||
|
const int queryCount = 10; |
||||
|
const int k = 5; // Number of nearest neighbors to find
|
||||
|
|
||||
|
// Generate random vectors
|
||||
|
auto vectors = vp_tree.generateRandomVectors(vectorCount, dimension); |
||||
|
|
||||
|
vpt::VpTree tree = vp_tree.buildTree(vectors); |
||||
|
vp_tree.saveTree("./data/vp-tree.bin", tree); |
||||
|
|
||||
|
// Generate query vectors
|
||||
|
auto queries = vp_tree.generateRandomVectors(queryCount, dimension); |
||||
|
for (const auto& query : queries) { |
||||
|
auto [distances, indices] = tree.getNearestNeighbors(query, k); |
||||
|
|
||||
|
// Uncomment the following lines to print results for each query
|
||||
|
std::cout << "Query: "; |
||||
|
for (double d : query) std::cout << d << " "; |
||||
|
std::cout << "\nNearest neighbors:\n"; |
||||
|
for (int i = 0; i < k; ++i) { |
||||
|
std::cout << " Index: " << indices[i] << ", Distance: " << distances[i] << "\n"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
record_fbo.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGB); |
||||
|
shader_fbo.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGBA); |
||||
|
out_fbo.allocate(ofGetWindowWidth(), ofGetWindowHeight(), GL_RGBA); |
||||
|
ofSetVerticalSync(true); |
||||
|
ofDisableArbTex(); |
||||
|
//ofEnableDepthTest();
|
||||
|
ofDisableDepthTest(); |
||||
|
ofDisableAntiAliasing(); |
||||
|
ofEnableAlphaBlending(); |
||||
|
shaders.load("dither"); |
||||
|
|
||||
|
std::string path = "images"; |
||||
|
ofDirectory dir(path); |
||||
|
dir.allowExt("png"); |
||||
|
dir.listDir(); |
||||
|
|
||||
|
ofLoadImage(bayer, "images/bayer.png"); |
||||
|
bayer.setTextureWrap(GL_REPEAT, GL_REPEAT); |
||||
|
|
||||
|
// Loop through files and load images
|
||||
|
for (size_t i = 0; i < dir.size(); i++) { |
||||
|
std::string filePath = dir.getPath(i); |
||||
|
ofImage img; |
||||
|
if (img.load(filePath)) { // Load the image
|
||||
|
images.push_back(img); // Add the image to the list
|
||||
|
} else { |
||||
|
ofLog() << "Failed to load: " << filePath; // Log if failed to load
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bullet.setup(); |
||||
|
|
||||
|
vector<ofMesh> mesh_list; |
||||
|
|
||||
|
for(auto& img : images){ |
||||
|
mesh_list = mesh_generator.generateSimplifiedMesh(img); |
||||
|
bullet.addMesh(mesh_list[0], mesh_list[1], img.getTexture()); |
||||
|
mesh_list.clear(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::update(){ |
||||
|
bullet.update(); |
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::draw(){ |
||||
|
|
||||
|
ofPushStyle(); |
||||
|
shader_fbo.begin(); |
||||
|
ofClear(ofColor::grey); |
||||
|
bullet.draw(); |
||||
|
shader_fbo.end(); |
||||
|
ofPopStyle(); |
||||
|
|
||||
|
ofTexture t = shader_fbo.getTexture(); |
||||
|
|
||||
|
|
||||
|
out_fbo.begin(); |
||||
|
shaders.begin(); |
||||
|
shaders.setUniformTexture("tex0", t, 0); |
||||
|
shaders.setUniformTexture("tex1", bayer, 1); |
||||
|
shaders.setUniform2f("resolution", ofGetWidth(), ofGetHeight()); |
||||
|
shaders.setUniform1f("time", ofGetElapsedTimef()); |
||||
|
shaders.setUniform1i("frame", ofGetFrameNum()); |
||||
|
ofClear(0, 0, 0, 0); |
||||
|
shader_fbo.draw(0,0); |
||||
|
|
||||
|
shaders.end(); |
||||
|
out_fbo.end(); |
||||
|
|
||||
|
|
||||
|
out_fbo.draw(0,0); |
||||
|
//shader_fbo.draw(0, 0);
|
||||
|
// float planeScale = 0.75;
|
||||
|
// int planeWidth = ofGetWidth() * planeScale;
|
||||
|
// int planeHeight = ofGetHeight() * planeScale;
|
||||
|
// int planeGridSize = 20;
|
||||
|
// int planeColumns = planeWidth / planeGridSize;
|
||||
|
// int planeRows = planeHeight / planeGridSize;
|
||||
|
|
||||
|
// plane.set(planeWidth, planeHeight, planeColumns, planeRows, OF_PRIMITIVE_TRIANGLES);
|
||||
|
|
||||
|
// plane.mapTexCoordsFromTexture(t);
|
||||
|
|
||||
|
// t.bind();
|
||||
|
// shaders.begin();
|
||||
|
// ofPushMatrix();
|
||||
|
// ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
|
||||
|
// plane.draw();
|
||||
|
// ofPopMatrix();
|
||||
|
// shaders.end();
|
||||
|
// t.unbind();
|
||||
|
|
||||
|
|
||||
|
//t.draw(ofGetWindowWidth() / 2, 0);
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::keyPressed(int key){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::keyReleased(int key){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseMoved(int x, int y ){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseDragged(int x, int y, int button){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mousePressed(int x, int y, int button){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseReleased(int x, int y, int button){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseEntered(int x, int y){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::mouseExited(int x, int y){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::windowResized(int w, int h){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::gotMessage(ofMessage msg){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------
|
||||
|
void ofApp::dragEvent(ofDragInfo dragInfo){ |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,43 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include "ofMain.h" |
||||
|
#include "MeshGenerator.h" |
||||
|
#include "Bullet.h" |
||||
|
#include "VP.h" |
||||
|
|
||||
|
class ofApp : public ofBaseApp{ |
||||
|
|
||||
|
public: |
||||
|
void setup(); |
||||
|
void update(); |
||||
|
void draw(); |
||||
|
|
||||
|
void keyPressed(int key); |
||||
|
void keyReleased(int key); |
||||
|
void mouseMoved(int x, int y ); |
||||
|
void mouseDragged(int x, int y, int button); |
||||
|
void mousePressed(int x, int y, int button); |
||||
|
void mouseReleased(int x, int y, int button); |
||||
|
void mouseEntered(int x, int y); |
||||
|
void mouseExited(int x, int y); |
||||
|
void windowResized(int w, int h); |
||||
|
void dragEvent(ofDragInfo dragInfo); |
||||
|
void gotMessage(ofMessage msg); |
||||
|
|
||||
|
ofEasyCam cam; |
||||
|
ofImage img; |
||||
|
ofMesh mesh; |
||||
|
MeshGenerator mesh_generator; |
||||
|
Bullet bullet; |
||||
|
vector<ofImage> images; |
||||
|
|
||||
|
ofFbo record_fbo; |
||||
|
ofFbo shader_fbo; |
||||
|
ofFbo out_fbo; |
||||
|
|
||||
|
ofShader shaders; |
||||
|
|
||||
|
ofPlanePrimitive plane; |
||||
|
ofTexture bayer; |
||||
|
VP vp_tree; |
||||
|
}; |
Loading…
Reference in new issue