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