Compare commits
214 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e188a0594 | ||
|
|
c1f41cb6f6 | ||
|
|
50143076ab | ||
|
|
c33cdabdec | ||
|
|
ad16643111 | ||
|
|
45f5f8098e | ||
|
|
28b619c566 | ||
|
|
4f512405b2 | ||
|
|
fe80488c5e | ||
|
|
f8f4d7b21a | ||
|
|
5651570c2b | ||
|
|
71c236abb0 | ||
|
|
c0fc061834 | ||
|
|
61ce9d3543 | ||
|
|
9849c16f66 | ||
|
|
aacd4f6c9e | ||
|
|
5b6b627a43 | ||
|
|
4f2e327533 | ||
|
|
c858b4dcde | ||
|
|
7a43a98816 | ||
|
|
47e31714f3 | ||
|
|
424d58c59b | ||
|
|
5996e38e6e | ||
|
|
b00bb75189 | ||
|
|
0aa949c60b | ||
|
|
420203e95d | ||
|
|
c667ce26d7 | ||
|
|
13cc2c0ff9 | ||
|
|
1c4018e47a | ||
|
|
083a5b600f | ||
|
|
3a2d21b787 | ||
|
|
441d758845 | ||
|
|
5da0c10182 | ||
|
|
b89f9ec331 | ||
|
|
add3d7c861 | ||
|
|
4e241a1871 | ||
|
|
15a861802a | ||
|
|
66a8b98aeb | ||
|
|
0f945b69cc | ||
|
|
314da11005 | ||
|
|
8437ab8753 | ||
|
|
d514219ae6 | ||
|
|
efa47f28ca | ||
|
|
e653855556 | ||
|
|
1510de3b36 | ||
|
|
8550d4068f | ||
|
|
cd93b67274 | ||
|
|
18965fe1bd | ||
|
|
57eff4830e | ||
|
|
b5ee92c544 | ||
|
|
e57b5715e8 | ||
|
|
73012b6dd1 | ||
|
|
2488cc6319 | ||
|
|
518ac260e1 | ||
|
|
2725b5f657 | ||
|
|
c17bfadc76 | ||
|
|
6bef6a1b77 | ||
|
|
e33cf0d5f0 | ||
|
|
c41cbaeea8 | ||
|
|
3a8600d274 | ||
|
|
f8aa5cc920 | ||
|
|
30db4d7ca1 | ||
|
|
317148a37d | ||
|
|
5c6a5afef6 | ||
|
|
90e79576a2 | ||
|
|
a31ae5b2ef | ||
|
|
2ebc177d9d | ||
|
|
6a2c5a77ae | ||
|
|
d6ae062f7f | ||
|
|
3ebe403de0 | ||
|
|
f5685a45e1 | ||
|
|
7209244f48 | ||
|
|
1b6c14691b | ||
|
|
107b612130 | ||
|
|
5bbd036fc5 | ||
|
|
1ceabe7e62 | ||
|
|
3e37b5ca44 | ||
|
|
5c10d65c8d | ||
|
|
83c12dbd83 | ||
|
|
3cfbb604b0 | ||
|
|
36962275f6 | ||
|
|
a1c53fc9cc | ||
|
|
0be3236a03 | ||
|
|
344c36cd78 | ||
|
|
478b1f0af1 | ||
|
|
1cebcd4f8b | ||
|
|
aab9df0802 | ||
|
|
d05a0fb4d0 | ||
|
|
21749695b6 | ||
|
|
1fbe682572 | ||
|
|
ace7d53571 | ||
|
|
0ac44c3539 | ||
|
|
c4b680789e | ||
|
|
53f66b554b | ||
|
|
307c125eba | ||
|
|
b4ae737b40 | ||
|
|
8ceb68fdff | ||
|
|
c369d2fe2d | ||
|
|
2926166ce6 | ||
|
|
e61382a129 | ||
|
|
a6f0422bd1 | ||
|
|
a4ddfddbf3 | ||
|
|
f1849cdbc1 | ||
|
|
9174424d91 | ||
|
|
0369bee306 | ||
|
|
ed347e304d | ||
|
|
7a96d42874 | ||
|
|
1c00077949 | ||
|
|
5e4cfb84e6 | ||
|
|
aded6bb943 | ||
|
|
2ea4abdce7 | ||
|
|
831a096281 | ||
|
|
3011544e8f | ||
|
|
d1965caf8d | ||
|
|
7bbe5e843b | ||
|
|
7c794f0496 | ||
|
|
80f59efa43 | ||
|
|
f226664fe3 | ||
|
|
0650ac7b44 | ||
|
|
d87bbb184e | ||
|
|
b9bacd3ac9 | ||
|
|
1d685de8fd | ||
|
|
9c35cfc4f3 | ||
|
|
56095169eb | ||
|
|
60db274214 | ||
|
|
566be9bcf6 | ||
|
|
dac74007ea | ||
|
|
b251b632ac | ||
|
|
81e323fdf4 | ||
|
|
c9021974f6 | ||
|
|
4d4c4a7453 | ||
|
|
935c8ebff7 | ||
|
|
4cdf7a4264 | ||
|
|
51a6bbebb9 | ||
|
|
e45dbad59e | ||
|
|
3db0aaaeac | ||
|
|
df52cb36db | ||
|
|
89dd74fa7c | ||
|
|
7337ae4837 | ||
|
|
9fffb68026 | ||
|
|
7687581e83 | ||
|
|
75cf59cc1a | ||
|
|
9d0db6a635 | ||
|
|
66c1582a5f | ||
|
|
2a8fe61388 | ||
|
|
f8c60da05e | ||
|
|
de315d06f9 | ||
|
|
cf5597ad6d | ||
|
|
5198888df6 | ||
|
|
10ae695f01 | ||
|
|
d4fae2dbe2 | ||
|
|
daef0c078f | ||
|
|
a477b137e7 | ||
|
|
ba1ae34855 | ||
|
|
bc047cd89e | ||
|
|
863bb2a34b | ||
|
|
14c3044acf | ||
|
|
4b4d2b7819 | ||
|
|
9e1f448e0f | ||
|
|
457f5d04e4 | ||
|
|
999419dfe1 | ||
|
|
be6b472472 | ||
|
|
aa078f4d46 | ||
|
|
dbaa6eea2c | ||
|
|
a82b67faa4 | ||
|
|
efe46e2864 | ||
|
|
60d639f3a7 | ||
|
|
ddaefafa1a | ||
|
|
9f764018d3 | ||
|
|
6200e5ed56 | ||
|
|
be245523c9 | ||
|
|
11a00a6e74 | ||
|
|
af96d52c5a | ||
|
|
5a4f9f4dc4 | ||
|
|
df4ec9794a | ||
|
|
db9f2c0203 | ||
|
|
88fcd48481 | ||
|
|
5e295c06b2 | ||
|
|
4dd7a3af39 | ||
|
|
1aab8f6619 | ||
|
|
27ec4d5567 | ||
|
|
a64b1288a5 | ||
|
|
77907499a4 | ||
|
|
cf00e62c5a | ||
|
|
5086a5c82f | ||
|
|
b84ed7496b | ||
|
|
b4bd8bd4b7 | ||
|
|
c1e7496d21 | ||
|
|
674831b370 | ||
|
|
8cc2272b50 | ||
|
|
2e2d8c143c | ||
|
|
a8ca88640b | ||
|
|
9bdfb26f7e | ||
|
|
5ebed12f4f | ||
|
|
73d60fb7e4 | ||
|
|
4a9379c0b2 | ||
|
|
aeb4669162 | ||
|
|
a8194169c5 | ||
|
|
656ff52204 | ||
|
|
00b283053e | ||
|
|
b799e5f819 | ||
|
|
cabe7ff147 | ||
|
|
17aebe6538 | ||
|
|
a1087a9871 | ||
|
|
c4418683c6 | ||
|
|
1900d1f45d | ||
|
|
513cd9d7eb | ||
|
|
01a0de09ab | ||
|
|
8faf1db3be | ||
|
|
79af9fbc97 | ||
|
|
1e2588441f | ||
|
|
1f4b14c896 | ||
|
|
dee4b9ae91 | ||
|
|
514bd649c1 |
44
.github/workflows/cmake.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: CMake
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
continue-on-error: ${{ matrix.allow_failure }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ ubuntu-18.04, ubuntu-20.04, ubuntu-latest ]
|
||||||
|
allow_failure: [false]
|
||||||
|
# include:
|
||||||
|
# - os: macos-latest
|
||||||
|
# allow_failure: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Configure CMake
|
||||||
|
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||||
|
|
||||||
|
- name: Test round 1
|
||||||
|
working-directory: ${{github.workspace}}/build
|
||||||
|
run: make test
|
||||||
|
|
||||||
|
- name: Test round 2
|
||||||
|
working-directory: ${{github.workspace}}/build/tests
|
||||||
|
run: make test
|
||||||
|
|
||||||
6
.gitmodules
vendored
@@ -1,12 +1,12 @@
|
|||||||
[submodule "external/googletest"]
|
[submodule "external/googletest"]
|
||||||
path = external/googletest
|
path = external/googletest
|
||||||
url = https://github.com/google/googletest.git
|
url = https://github.com/google/googletest.git
|
||||||
[submodule "external/nanogui"]
|
|
||||||
path = external/nanogui
|
|
||||||
url = https://github.com/Godzil/nanogui.git
|
|
||||||
[submodule "external/glfw"]
|
[submodule "external/glfw"]
|
||||||
path = external/glfw
|
path = external/glfw
|
||||||
url = https://github.com/glfw/glfw.git
|
url = https://github.com/glfw/glfw.git
|
||||||
[submodule "external/lodepng"]
|
[submodule "external/lodepng"]
|
||||||
path = external/lodepng
|
path = external/lodepng
|
||||||
url = https://github.com/lvandeve/lodepng
|
url = https://github.com/lvandeve/lodepng
|
||||||
|
[submodule "external/coveralls-cmake"]
|
||||||
|
path = external/coveralls-cmake
|
||||||
|
url = https://github.com/Godzil/coveralls-cmake.git
|
||||||
|
|||||||
87
.travis.yml
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
language: c
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- lcov
|
||||||
|
- imagemagick
|
||||||
|
homebrew:
|
||||||
|
packages:
|
||||||
|
- imagemagick
|
||||||
|
|
||||||
|
script:
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- cmake ..
|
||||||
|
- make
|
||||||
|
- make test
|
||||||
|
- cd tests
|
||||||
|
- ./testMyRays
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink python@2 ; fi
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install imagemagick ; fi
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- os: linux
|
||||||
|
dist: bionic
|
||||||
|
arch: amd64
|
||||||
|
compiler: gcc
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
dist: bionic
|
||||||
|
arch: amd64
|
||||||
|
compiler: clang
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
dist: focal
|
||||||
|
arch: amd64
|
||||||
|
compiler: gcc
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
dist: focal
|
||||||
|
arch: amd64
|
||||||
|
compiler: clang
|
||||||
|
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
compiler: clang
|
||||||
|
osx_image: xcode12.2
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
dist: focal
|
||||||
|
arch: arm64
|
||||||
|
compiler: gcc
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
compiler: clang
|
||||||
|
osx_image: xcode10.3
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
compiler: clang
|
||||||
|
osx_image: xcode11.6
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
compiler: clang
|
||||||
|
osx_image: xcode12
|
||||||
|
|
||||||
|
- stage: "Coverage"
|
||||||
|
os: linux
|
||||||
|
dist: bionic
|
||||||
|
arch: amd64
|
||||||
|
compiler: gcc
|
||||||
|
script:
|
||||||
|
- mkdir coverage
|
||||||
|
- cd coverage
|
||||||
|
- cmake .. -DCOVERALLS=ON -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
- cmake --build .
|
||||||
|
- cmake --build . --target coveralls
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
|
||||||
|
allow_failures:
|
||||||
|
- os: linux
|
||||||
|
arch: arm64
|
||||||
|
|
||||||
|
- os: osx
|
||||||
106
CMakeLists.txt
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.1)
|
cmake_minimum_required(VERSION 3.11)
|
||||||
|
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
@@ -6,24 +6,106 @@ project(DoRayMe)
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
|
option(COVERALLS "Generate coveralls data" OFF)
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/external/coveralls-cmake/cmake)
|
||||||
|
|
||||||
#Add external projects that directly need to be builded
|
option(PACKAGE_TESTS "Build the tests" ON)
|
||||||
ExternalProject_Add(googletest
|
option(ENABLE_COVERAGE "Build for code coverage" OFF)
|
||||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/googletest"
|
|
||||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/external/googletest"
|
option(SHOW_STATS "Show rendering stat" OFF)
|
||||||
CONFIGURE_COMMAND ""
|
if (SHOW_STATS)
|
||||||
BUILD_COMMAND ""
|
add_compile_options(-DRENDER_STATS)
|
||||||
INSTALL_COMMAND ""
|
endif()
|
||||||
TEST_COMMAND ""
|
|
||||||
)
|
option(USE_GPROF "Enable profiling" OFF)
|
||||||
|
if (USE_GPROF)
|
||||||
|
add_compile_options(-pg)
|
||||||
|
add_link_options(-pg)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(USE_LUA "Enable the use of Lua" ON)
|
||||||
|
if (USE_LUA)
|
||||||
|
add_compile_options(-DENABLE_LUA_SUPPORT)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_COVERAGE AND COVERALLS)
|
||||||
|
message(FATAL_ERROR "You can't enable both ENABLE_COVERAGE and COVERALLS at the same time")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (COVERALLS)
|
||||||
|
include(Coveralls)
|
||||||
|
coveralls_turn_on_coverage()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_COVERAGE)
|
||||||
|
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang" OR
|
||||||
|
"${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||||
|
message("Building with LLVM Code Coverage Tools")
|
||||||
|
set(CMAKE_CXX_FLAGS "-fprofile-instr-generate -fcoverage-mapping")
|
||||||
|
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
message("Building with lcov Code Coverage Tools")
|
||||||
|
set(CMAKE_CXX_FLAGS "--coverage")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Compiler ${CMAKE_C_COMPILER_ID} is not supported for code coverage")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
# LodePNG don't make a .a or .so, so let's build a library here
|
# LodePNG don't make a .a or .so, so let's build a library here
|
||||||
add_library(LodePNG STATIC)
|
add_library(LodePNG STATIC)
|
||||||
set(LODEPNG_INCLUDE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/external/lodepng)
|
set(LODEPNG_INCLUDE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/external/lodepng)
|
||||||
target_sources(LodePNG PRIVATE external/lodepng/lodepng.cpp external/lodepng/lodepng.h)
|
target_sources(LodePNG PRIVATE external/lodepng/lodepng.cpp external/lodepng/lodepng.h)
|
||||||
|
|
||||||
|
if (USE_LUA)
|
||||||
|
if (CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
|
||||||
|
set(LUA_MAKE_TARGET linux)
|
||||||
|
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
|
||||||
|
set(LUA_MAKE_TARGET macosx)
|
||||||
|
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
|
||||||
|
set(LUA_MAKE_TARGET posix)
|
||||||
|
else()
|
||||||
|
set(LUA_MAKE_TARGET posix)
|
||||||
|
endif()
|
||||||
|
message("-- Lua: Building Lua for ${LUA_MAKE_TARGET}")
|
||||||
|
|
||||||
|
ExternalProject_Add(LuaCore
|
||||||
|
URL "https://www.lua.org/ftp/lua-5.3.5.tar.gz"
|
||||||
|
URL_HASH SHA1=112eb10ff04d1b4c9898e121d6bdf54a81482447
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/lua
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_IN_SOURCE True
|
||||||
|
BUILD_COMMAND make ${LUA_MAKE_TARGET}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/lua/src")
|
||||||
|
set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/external/lua/src/liblua.a" -ldl)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# NanoJPEG
|
||||||
|
file(DOWNLOAD
|
||||||
|
http://svn.emphy.de/nanojpeg/trunk/nanojpeg/nanojpeg.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/external/nanojpeg/nanojpeg.c
|
||||||
|
EXPECTED_HASH MD5=03ce304a71ae0ad1c43663fb386cc233
|
||||||
|
)
|
||||||
|
add_library(NanoJPEG STATIC)
|
||||||
|
set(NANOJPEG_INCLUDE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/external/nanojpeg)
|
||||||
|
target_sources(NanoJPEG PRIVATE external/nanojpeg/nanojpeg.c)
|
||||||
|
|
||||||
# Main app
|
# Main app
|
||||||
add_subdirectory(source)
|
add_subdirectory(source)
|
||||||
# Unit Tests
|
|
||||||
add_subdirectory(tests)
|
if(PACKAGE_TESTS OR COVERALLS)
|
||||||
|
enable_testing()
|
||||||
|
include(GoogleTest)
|
||||||
|
add_subdirectory("${PROJECT_SOURCE_DIR}/external/googletest" "external/googletest")
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (COVERALLS)
|
||||||
|
# Create the coveralls target.
|
||||||
|
coveralls_setup(
|
||||||
|
"${COVERAGE_SRCS}" # The source files.
|
||||||
|
ON # If we should upload.
|
||||||
|
) # (Optional) Alternate project cmake module path.
|
||||||
|
endif()
|
||||||
340
COPYING
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
14
LICENSE
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Copyright (C) 2020 Manoel <Godzil> Trapier
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
102
README.md
@@ -0,0 +1,102 @@
|
|||||||
|
[](https://codecov.io/gh/Godzil/DoRayMe) [](https://www.codacy.com/manual/Godzil/DoRayMe?utm_source=github.com&utm_medium=referral&utm_content=Godzil/DoRayMe&utm_campaign=Badge_Grade) [](https://coveralls.io/github/Godzil/DoRayMe?branch=master) [](https://github.com/Godzil/DoRayMe/actions/workflows/cmake.yml)
|
||||||
|
|
||||||
|
DoRayMe
|
||||||
|
=======
|
||||||
|
|
||||||
|
A Quick and dirty raytracer.
|
||||||
|
|
||||||
|
|
||||||
|
This raytracer is made following the book
|
||||||
|
"[The Ray Tracer Challenge](https://pragprog.com/book/jbtracer/the-ray-tracer-challenge)" by Jamis Buck.
|
||||||
|
|
||||||
|
It is writen in C++ with no STL and use [LodePNG](https://github.com/lvandeve/lodepng) to output PNG file and use them
|
||||||
|
as texture, also use [NanoJPEG](https://keyj.emphy.de/nanojpeg/) to use jpeg file as texture, and can use use
|
||||||
|
[Lua 5.3](https://www.lua.org/) for 3D pattern definition and more to come on the Lua side later..
|
||||||
|
|
||||||
|
|
||||||
|
Examples outputs
|
||||||
|
----------------
|
||||||
|
|
||||||
|
#### From chapter 05 - Sphere intersections:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 06 - Phong shading:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 07 - World / Camera / Scenes:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 08 - Shadows:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 09 - Planes:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 10 - Patterns:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 11 - Reflections, Transparency & Refractions:
|
||||||
|

|
||||||
|
|
||||||
|
###### Bonus: Zooming on a reflective ball:
|
||||||
|

|
||||||
|
|
||||||
|
###### Zooming on a reflection on that ball:
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 12 - Cubes:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 13 - Cylinders:
|
||||||
|

|
||||||
|
###### Bonus:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 14 - Groups & Bounding boxes:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 15 - Triangles, Wavefrom OBJ files - Smooth trianges:
|
||||||
|

|
||||||
|
|
||||||
|
#### From Chapter 16 - Constructive Solid Geomety:
|
||||||
|

|
||||||
|
|
||||||
|
#### Bonus (from the forum):
|
||||||
|
[Merry Christmas](https://forum.raytracerchallenge.com/thread/16/merry-christmas-scene-description)
|
||||||
|

|
||||||
|
(about 1min render time using OpenMP on a 2.6Ghz Core i7 3720QM)
|
||||||
|
|
||||||
|
#### Bonus chapter - Soft shadow / Area light
|
||||||
|
###### Without jitter:
|
||||||
|

|
||||||
|
###### With jitter:
|
||||||
|

|
||||||
|
|
||||||
|
#### Bonus chapter - Texture mapping
|
||||||
|
###### Spherical mapping:
|
||||||
|

|
||||||
|
|
||||||
|
###### Planar mapping:
|
||||||
|

|
||||||
|
|
||||||
|
###### Cylindrical mapping:
|
||||||
|

|
||||||
|
|
||||||
|
###### Aligncheck plane:
|
||||||
|

|
||||||
|
|
||||||
|
###### Cubical mapping:
|
||||||
|

|
||||||
|
|
||||||
|
###### Image mapping:
|
||||||
|

|
||||||
|
|
||||||
|
###### Skybox:
|
||||||
|

|
||||||
|
|
||||||
|
###### Large OBJ file:
|
||||||
|

|
||||||
|
|||||||
1
external/coveralls-cmake
vendored
Submodule
2
external/glfw
vendored
2
external/googletest
vendored
2
external/lodepng
vendored
1
external/nanogui
vendored
494
external/teapot-low.obj
vendored
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
#
|
||||||
|
# object Teapot001
|
||||||
|
#
|
||||||
|
|
||||||
|
v 7.0000 0.0000 12.0000
|
||||||
|
v 4.9700 -4.9700 12.0000
|
||||||
|
v 4.9811 -4.9811 12.4922
|
||||||
|
v 7.0156 0.0000 12.4922
|
||||||
|
v 5.3250 -5.3250 12.0000
|
||||||
|
v 7.5000 0.0000 12.0000
|
||||||
|
v 0.0000 -7.0000 12.0000
|
||||||
|
v 0.0000 -7.0156 12.4922
|
||||||
|
v 0.0000 -7.5000 12.0000
|
||||||
|
v -5.1387 -4.9700 12.0000
|
||||||
|
v -5.0022 -4.9811 12.4922
|
||||||
|
v -5.3250 -5.3250 12.0000
|
||||||
|
v -7.0000 0.0000 12.0000
|
||||||
|
v -7.0156 0.0000 12.4922
|
||||||
|
v -7.5000 0.0000 12.0000
|
||||||
|
v -4.9700 4.9700 12.0000
|
||||||
|
v -4.9811 4.9811 12.4922
|
||||||
|
v -5.3250 5.3250 12.0000
|
||||||
|
v 0.0000 7.0000 12.0000
|
||||||
|
v 0.0000 7.0156 12.4922
|
||||||
|
v 0.0000 7.5000 12.0000
|
||||||
|
v 4.9700 4.9700 12.0000
|
||||||
|
v 4.9811 4.9811 12.4922
|
||||||
|
v 5.3250 5.3250 12.0000
|
||||||
|
v 6.5453 -6.5453 8.1094
|
||||||
|
v 9.2188 0.0000 8.1094
|
||||||
|
v 7.1000 -7.1000 4.5000
|
||||||
|
v 10.0000 0.0000 4.5000
|
||||||
|
v 0.0000 -9.2188 8.1094
|
||||||
|
v 0.0000 -10.0000 4.5000
|
||||||
|
v -6.5453 -6.5453 8.1094
|
||||||
|
v -7.1000 -7.1000 4.5000
|
||||||
|
v -9.2188 0.0000 8.1094
|
||||||
|
v -10.0000 0.0000 4.5000
|
||||||
|
v -6.5453 6.5453 8.1094
|
||||||
|
v -7.1000 7.1000 4.5000
|
||||||
|
v 0.0000 9.2188 8.1094
|
||||||
|
v 0.0000 10.0000 4.5000
|
||||||
|
v 6.5453 6.5453 8.1094
|
||||||
|
v 7.1000 7.1000 4.5000
|
||||||
|
v 6.2125 -6.2125 1.9219
|
||||||
|
v 8.7500 0.0000 1.9219
|
||||||
|
v 5.3250 -5.3250 0.7500
|
||||||
|
v 7.5000 0.0000 0.7500
|
||||||
|
v 0.0000 -8.7500 1.9219
|
||||||
|
v 0.0000 -7.5000 0.7500
|
||||||
|
v -6.2125 -6.2125 1.9219
|
||||||
|
v -5.3250 -5.3250 0.7500
|
||||||
|
v -8.7500 0.0000 1.9219
|
||||||
|
v -7.5000 0.0000 0.7500
|
||||||
|
v -6.2125 6.2125 1.9219
|
||||||
|
v -5.3250 5.3250 0.7500
|
||||||
|
v 0.0000 8.7500 1.9219
|
||||||
|
v 0.0000 7.5000 0.7500
|
||||||
|
v 6.2125 6.2125 1.9219
|
||||||
|
v 5.3250 5.3250 0.7500
|
||||||
|
v 4.5595 -4.5595 0.2344
|
||||||
|
v 6.4219 0.0000 0.2344
|
||||||
|
v 0.0000 0.0000 0.0000
|
||||||
|
v 0.0000 -6.4219 0.2344
|
||||||
|
v -4.5595 -4.5595 0.2344
|
||||||
|
v -6.4219 0.0000 0.2344
|
||||||
|
v -4.5595 4.5595 0.2344
|
||||||
|
v 0.0000 6.4219 0.2344
|
||||||
|
v 4.5595 4.5595 0.2344
|
||||||
|
v -8.0000 0.0000 10.1250
|
||||||
|
v -7.7500 -1.1250 10.6875
|
||||||
|
v -12.5938 -1.1250 10.4766
|
||||||
|
v -12.0625 0.0000 9.9844
|
||||||
|
v -14.2500 -1.1250 9.0000
|
||||||
|
v -13.5000 0.0000 9.0000
|
||||||
|
v -7.5000 0.0000 11.2500
|
||||||
|
v -13.1250 0.0000 10.9688
|
||||||
|
v -15.0000 0.0000 9.0000
|
||||||
|
v -7.7500 1.1250 10.6875
|
||||||
|
v -12.5938 1.1250 10.4766
|
||||||
|
v -14.2500 1.1250 9.0000
|
||||||
|
v -13.1719 -1.1250 6.2695
|
||||||
|
v -12.6875 0.0000 6.7500
|
||||||
|
v -9.7500 -1.1250 3.7500
|
||||||
|
v -13.6563 0.0000 5.7891
|
||||||
|
v -9.5000 0.0000 3.0000
|
||||||
|
v -13.1719 1.1250 6.2695
|
||||||
|
v -9.7500 1.1250 3.7500
|
||||||
|
v 8.5000 0.0000 7.1250
|
||||||
|
v 8.5000 -2.4750 5.0625
|
||||||
|
v 12.6875 -1.7062 8.1094
|
||||||
|
v 11.9375 0.0000 9.0000
|
||||||
|
v 15.0000 -0.9375 12.0000
|
||||||
|
v 13.5000 0.0000 12.0000
|
||||||
|
v 8.5000 0.0000 3.0000
|
||||||
|
v 13.4375 0.0000 7.2187
|
||||||
|
v 16.5000 0.0000 12.0000
|
||||||
|
v 8.5000 2.4750 5.0625
|
||||||
|
v 12.6875 1.7062 8.1094
|
||||||
|
v 15.0000 0.9375 12.0000
|
||||||
|
v 15.6328 -0.7500 12.3340
|
||||||
|
v 14.1250 0.0000 12.2813
|
||||||
|
v 15.0000 -0.5625 12.0000
|
||||||
|
v 14.0000 0.0000 12.0000
|
||||||
|
v 17.1406 0.0000 12.3867
|
||||||
|
v 16.0000 0.0000 12.0000
|
||||||
|
v 15.6328 0.7500 12.3340
|
||||||
|
v 15.0000 0.5625 12.0000
|
||||||
|
v 1.1552 -1.1552 14.9063
|
||||||
|
v 1.6250 0.0000 14.9063
|
||||||
|
v 0.0000 0.0000 15.7500
|
||||||
|
v 0.7100 -0.7100 13.5000
|
||||||
|
v 1.0000 0.0000 13.5000
|
||||||
|
v 0.0000 -1.6250 14.9063
|
||||||
|
v 0.0000 -1.0000 13.5000
|
||||||
|
v -1.1552 -1.1552 14.9063
|
||||||
|
v -0.7100 -0.7100 13.5000
|
||||||
|
v -1.6250 0.0000 14.9063
|
||||||
|
v -1.0000 0.0000 13.5000
|
||||||
|
v -1.1552 1.1552 14.9063
|
||||||
|
v -0.7100 0.7100 13.5000
|
||||||
|
v 0.0000 1.6250 14.9063
|
||||||
|
v 0.0000 1.0000 13.5000
|
||||||
|
v 1.1552 1.1552 14.9063
|
||||||
|
v 0.7100 0.7100 13.5000
|
||||||
|
v 2.9288 -2.9288 12.7500
|
||||||
|
v 4.1250 0.0000 12.7500
|
||||||
|
v 4.6150 -4.6150 12.0000
|
||||||
|
v 6.5000 0.0000 12.0000
|
||||||
|
v 0.0000 -4.1250 12.7500
|
||||||
|
v 0.0000 -6.5000 12.0000
|
||||||
|
v -2.9288 -2.9288 12.7500
|
||||||
|
v -4.6150 -4.6150 12.0000
|
||||||
|
v -4.1250 0.0000 12.7500
|
||||||
|
v -6.5000 0.0000 12.0000
|
||||||
|
v -2.9288 2.9288 12.7500
|
||||||
|
v -4.6150 4.6150 12.0000
|
||||||
|
v 0.0000 4.1250 12.7500
|
||||||
|
v 0.0000 6.5000 12.0000
|
||||||
|
v 2.9288 2.9288 12.7500
|
||||||
|
v 4.6150 4.6150 12.0000
|
||||||
|
# 137 vertices
|
||||||
|
|
||||||
|
vn -0.9995 -0.0000 0.0317
|
||||||
|
vn -0.7067 0.7067 0.0319
|
||||||
|
vn -0.0966 0.0966 0.9906
|
||||||
|
vn -0.1416 0.0000 0.9899
|
||||||
|
vn 0.5936 -0.5936 0.5435
|
||||||
|
vn 0.8400 0.0000 0.5425
|
||||||
|
vn -0.0010 0.9996 0.0283
|
||||||
|
vn -0.0008 0.1421 0.9899
|
||||||
|
vn 0.0000 -0.8400 0.5425
|
||||||
|
vn 0.7268 0.6636 -0.1773
|
||||||
|
vn 0.0816 0.2165 0.9729
|
||||||
|
vn -0.5949 -0.5971 0.5381
|
||||||
|
vn 0.9994 -0.0148 0.0317
|
||||||
|
vn 0.1496 -0.0134 0.9886
|
||||||
|
vn -0.8403 0.0004 0.5422
|
||||||
|
vn 0.7067 -0.7067 0.0319
|
||||||
|
vn 0.0966 -0.0966 0.9906
|
||||||
|
vn -0.5936 0.5936 0.5435
|
||||||
|
vn 0.0000 -0.9995 0.0317
|
||||||
|
vn -0.0000 -0.1416 0.9899
|
||||||
|
vn -0.0000 0.8400 0.5425
|
||||||
|
vn -0.7067 -0.7067 0.0319
|
||||||
|
vn -0.0966 -0.0966 0.9906
|
||||||
|
vn 0.5936 0.5936 0.5435
|
||||||
|
vn 0.6738 -0.6738 0.3034
|
||||||
|
vn 0.9532 -0.0000 0.3025
|
||||||
|
vn 0.7028 -0.7028 -0.1107
|
||||||
|
vn 0.9939 -0.0000 -0.1105
|
||||||
|
vn -0.0000 -0.9532 0.3025
|
||||||
|
vn -0.0000 -0.9939 -0.1105
|
||||||
|
vn -0.6738 -0.6738 0.3034
|
||||||
|
vn -0.7028 -0.7028 -0.1107
|
||||||
|
vn -0.9532 0.0000 0.3025
|
||||||
|
vn -0.9939 0.0000 -0.1105
|
||||||
|
vn -0.6738 0.6738 0.3034
|
||||||
|
vn -0.7028 0.7028 -0.1107
|
||||||
|
vn 0.0000 0.9532 0.3025
|
||||||
|
vn 0.0000 0.9939 -0.1105
|
||||||
|
vn 0.6738 0.6738 0.3034
|
||||||
|
vn 0.7028 0.7028 -0.1107
|
||||||
|
vn 0.5792 -0.5792 -0.5735
|
||||||
|
vn 0.8198 0.0000 -0.5726
|
||||||
|
vn 0.4157 -0.4157 -0.8089
|
||||||
|
vn 0.5888 -0.0000 -0.8083
|
||||||
|
vn 0.0000 -0.8198 -0.5726
|
||||||
|
vn -0.0000 -0.5888 -0.8083
|
||||||
|
vn -0.5792 -0.5792 -0.5735
|
||||||
|
vn -0.4157 -0.4157 -0.8089
|
||||||
|
vn -0.8198 -0.0000 -0.5726
|
||||||
|
vn -0.5888 0.0000 -0.8083
|
||||||
|
vn -0.5792 0.5792 -0.5735
|
||||||
|
vn -0.4157 0.4157 -0.8089
|
||||||
|
vn -0.0000 0.8198 -0.5726
|
||||||
|
vn 0.0000 0.5888 -0.8083
|
||||||
|
vn 0.5792 0.5792 -0.5735
|
||||||
|
vn 0.4157 0.4157 -0.8089
|
||||||
|
vn 0.2016 -0.2016 -0.9585
|
||||||
|
vn 0.2850 -0.0000 -0.9585
|
||||||
|
vn 0.0000 -0.0000 -1.0000
|
||||||
|
vn -0.0000 -0.2850 -0.9585
|
||||||
|
vn -0.2016 -0.2016 -0.9585
|
||||||
|
vn -0.2850 0.0000 -0.9585
|
||||||
|
vn -0.2016 0.2016 -0.9585
|
||||||
|
vn 0.0000 0.2850 -0.9585
|
||||||
|
vn 0.2016 0.2016 -0.9585
|
||||||
|
vn 0.0384 0.0031 -0.9993
|
||||||
|
vn -0.0182 -0.9619 0.2727
|
||||||
|
vn -0.0190 -0.9786 0.2047
|
||||||
|
vn 0.2817 0.0145 -0.9594
|
||||||
|
vn -0.2938 -0.9475 0.1264
|
||||||
|
vn 0.9324 0.0422 -0.3590
|
||||||
|
vn -0.0473 -0.0015 0.9989
|
||||||
|
vn -0.4420 -0.0127 0.8969
|
||||||
|
vn -0.9859 -0.0106 0.1669
|
||||||
|
vn -0.0177 0.9631 0.2685
|
||||||
|
vn -0.0097 0.9839 0.1786
|
||||||
|
vn -0.2735 0.9565 0.1013
|
||||||
|
vn -0.1217 -0.9875 -0.0998
|
||||||
|
vn 0.8176 0.0138 0.5756
|
||||||
|
vn -0.3352 -0.7946 -0.5061
|
||||||
|
vn 0.6216 0.0294 0.7828
|
||||||
|
vn -0.7747 -0.0079 -0.6322
|
||||||
|
vn -0.5711 -0.0076 -0.8208
|
||||||
|
vn -0.1055 0.9904 -0.0889
|
||||||
|
vn -0.3009 0.8200 -0.4869
|
||||||
|
vn -0.4862 0.0074 0.8738
|
||||||
|
vn 0.3271 -0.9145 -0.2382
|
||||||
|
vn 0.1595 -0.9869 0.0246
|
||||||
|
vn -0.6970 -0.0236 0.7167
|
||||||
|
vn -0.0062 -0.9245 0.3812
|
||||||
|
vn -0.7234 -0.0562 0.6881
|
||||||
|
vn 0.6538 0.0025 -0.7567
|
||||||
|
vn 0.7677 0.0173 -0.6406
|
||||||
|
vn 0.6465 0.0447 -0.7616
|
||||||
|
vn 0.3456 0.9087 -0.2343
|
||||||
|
vn 0.1845 0.9828 0.0081
|
||||||
|
vn 0.0506 0.9476 0.3154
|
||||||
|
vn 0.2319 -0.5821 0.7793
|
||||||
|
vn 0.0415 -0.0704 0.9967
|
||||||
|
vn 0.3158 0.9477 -0.0454
|
||||||
|
vn 0.9011 -0.0135 -0.4334
|
||||||
|
vn 0.9533 0.0371 0.2997
|
||||||
|
vn -0.3219 0.0032 0.9468
|
||||||
|
vn 0.3655 0.5783 0.7294
|
||||||
|
vn 0.3394 -0.9333 -0.1174
|
||||||
|
vn 0.6774 -0.6773 0.2871
|
||||||
|
vn 0.9576 -0.0001 0.2882
|
||||||
|
vn 0.0000 0.0000 1.0000
|
||||||
|
vn 0.5955 -0.5952 0.5396
|
||||||
|
vn 0.8436 -0.0002 0.5370
|
||||||
|
vn -0.0001 -0.9576 0.2882
|
||||||
|
vn -0.0002 -0.8436 0.5370
|
||||||
|
vn -0.6773 -0.6774 0.2871
|
||||||
|
vn -0.5952 -0.5955 0.5396
|
||||||
|
vn -0.9576 0.0001 0.2882
|
||||||
|
vn -0.8436 0.0002 0.5370
|
||||||
|
vn -0.6774 0.6773 0.2871
|
||||||
|
vn -0.5955 0.5952 0.5396
|
||||||
|
vn 0.0001 0.9576 0.2882
|
||||||
|
vn 0.0002 0.8436 0.5370
|
||||||
|
vn 0.6773 0.6774 0.2871
|
||||||
|
vn 0.5952 0.5955 0.5396
|
||||||
|
vn 0.1942 -0.1942 0.9616
|
||||||
|
vn 0.2754 0.0000 0.9613
|
||||||
|
vn 0.2121 -0.2121 0.9539
|
||||||
|
vn 0.3011 0.0000 0.9536
|
||||||
|
vn 0.0000 -0.2754 0.9613
|
||||||
|
vn 0.0000 -0.3011 0.9536
|
||||||
|
vn -0.1942 -0.1942 0.9616
|
||||||
|
vn -0.2121 -0.2121 0.9539
|
||||||
|
vn -0.2754 -0.0000 0.9613
|
||||||
|
vn -0.3011 -0.0000 0.9536
|
||||||
|
vn -0.1942 0.1942 0.9616
|
||||||
|
vn -0.2121 0.2121 0.9539
|
||||||
|
vn -0.0000 0.2754 0.9613
|
||||||
|
vn -0.0000 0.3011 0.9536
|
||||||
|
vn 0.1942 0.1942 0.9616
|
||||||
|
vn 0.2121 0.2121 0.9539
|
||||||
|
# 138 vertex normals
|
||||||
|
|
||||||
|
vt 2.0000 2.0000 0.0000
|
||||||
|
vt 1.5000 2.0000 0.0000
|
||||||
|
vt 1.5000 1.9500 0.0000
|
||||||
|
vt 2.0000 1.9500 0.0000
|
||||||
|
vt 1.5000 1.9000 0.0000
|
||||||
|
vt 2.0000 1.9000 0.0000
|
||||||
|
vt 1.0000 2.0000 0.0000
|
||||||
|
vt 1.0000 1.9500 0.0000
|
||||||
|
vt 1.0000 1.9000 0.0000
|
||||||
|
vt 0.5000 2.0000 0.0000
|
||||||
|
vt 0.5000 1.9500 0.0000
|
||||||
|
vt 0.5000 1.9000 0.0000
|
||||||
|
vt 0.0000 2.0000 0.0000
|
||||||
|
vt 0.0000 1.9500 0.0000
|
||||||
|
vt 0.0000 1.9000 0.0000
|
||||||
|
vt 1.5000 1.4500 0.0000
|
||||||
|
vt 2.0000 1.4500 0.0000
|
||||||
|
vt 1.5000 1.0000 0.0000
|
||||||
|
vt 2.0000 1.0000 0.0000
|
||||||
|
vt 1.0000 1.4500 0.0000
|
||||||
|
vt 1.0000 1.0000 0.0000
|
||||||
|
vt 0.5000 1.4500 0.0000
|
||||||
|
vt 0.5000 1.0000 0.0000
|
||||||
|
vt 0.0000 1.4500 0.0000
|
||||||
|
vt 0.0000 1.0000 0.0000
|
||||||
|
vt 1.5000 0.7000 0.0000
|
||||||
|
vt 2.0000 0.7000 0.0000
|
||||||
|
vt 1.5000 0.4000 0.0000
|
||||||
|
vt 2.0000 0.4000 0.0000
|
||||||
|
vt 1.0000 0.7000 0.0000
|
||||||
|
vt 1.0000 0.4000 0.0000
|
||||||
|
vt 0.5000 0.7000 0.0000
|
||||||
|
vt 0.5000 0.4000 0.0000
|
||||||
|
vt 0.0000 0.7000 0.0000
|
||||||
|
vt 0.0000 0.4000 0.0000
|
||||||
|
vt 1.5000 0.2000 0.0000
|
||||||
|
vt 2.0000 0.2000 0.0000
|
||||||
|
vt 1.5000 0.0000 0.0000
|
||||||
|
vt 1.0000 0.2000 0.0000
|
||||||
|
vt 1.0000 0.0000 0.0000
|
||||||
|
vt 0.5000 0.2000 0.0000
|
||||||
|
vt 0.5000 0.0000 0.0000
|
||||||
|
vt 0.0000 0.2000 0.0000
|
||||||
|
vt 0.0000 0.0000 0.0000
|
||||||
|
vt 0.7500 1.0000 0.0000
|
||||||
|
vt 0.7500 0.7500 0.0000
|
||||||
|
vt 1.0000 0.7500 0.0000
|
||||||
|
vt 0.7500 0.5000 0.0000
|
||||||
|
vt 1.0000 0.5000 0.0000
|
||||||
|
vt 0.5000 0.7500 0.0000
|
||||||
|
vt 0.5000 0.5000 0.0000
|
||||||
|
vt 0.2500 1.0000 0.0000
|
||||||
|
vt 0.2500 0.7500 0.0000
|
||||||
|
vt 0.2500 0.5000 0.0000
|
||||||
|
vt 0.0000 0.7500 0.0000
|
||||||
|
vt 0.0000 0.5000 0.0000
|
||||||
|
vt 0.7500 0.2500 0.0000
|
||||||
|
vt 1.0000 0.2500 0.0000
|
||||||
|
vt 0.7500 0.0000 0.0000
|
||||||
|
vt 0.5000 0.2500 0.0000
|
||||||
|
vt 0.2500 0.2500 0.0000
|
||||||
|
vt 0.2500 0.0000 0.0000
|
||||||
|
vt 0.0000 0.2500 0.0000
|
||||||
|
vt 0.7500 0.4500 0.0000
|
||||||
|
vt 0.5000 0.4500 0.0000
|
||||||
|
vt 0.7500 0.9000 0.0000
|
||||||
|
vt 0.5000 0.9000 0.0000
|
||||||
|
vt 1.0000 0.4500 0.0000
|
||||||
|
vt 1.0000 0.9000 0.0000
|
||||||
|
vt 0.2500 0.4500 0.0000
|
||||||
|
vt 0.0000 0.4500 0.0000
|
||||||
|
vt 0.2500 0.9000 0.0000
|
||||||
|
vt 0.0000 0.9000 0.0000
|
||||||
|
vt 0.7500 0.9500 0.0000
|
||||||
|
vt 0.5000 0.9500 0.0000
|
||||||
|
vt 1.0000 0.9500 0.0000
|
||||||
|
vt 0.2500 0.9500 0.0000
|
||||||
|
vt 0.0000 0.9500 0.0000
|
||||||
|
# 78 texture coords
|
||||||
|
|
||||||
|
g Teapot001
|
||||||
|
f 1/1/1 2/2/2 3/3/3 4/4/4
|
||||||
|
f 4/4/4 3/3/3 5/5/5 6/6/6
|
||||||
|
f 2/2/2 7/7/7 8/8/8 3/3/3
|
||||||
|
f 3/3/3 8/8/8 9/9/9 5/5/5
|
||||||
|
f 7/7/7 10/10/10 11/11/11 8/8/8
|
||||||
|
f 8/8/8 11/11/11 12/12/12 9/9/9
|
||||||
|
f 10/10/10 13/13/13 14/14/14 11/11/11
|
||||||
|
f 11/11/11 14/14/14 15/15/15 12/12/12
|
||||||
|
f 13/1/13 16/2/16 17/3/17 14/4/14
|
||||||
|
f 14/4/14 17/3/17 18/5/18 15/6/15
|
||||||
|
f 16/2/16 19/7/19 20/8/20 17/3/17
|
||||||
|
f 17/3/17 20/8/20 21/9/21 18/5/18
|
||||||
|
f 19/7/19 22/10/22 23/11/23 20/8/20
|
||||||
|
f 20/8/20 23/11/23 24/12/24 21/9/21
|
||||||
|
f 22/10/22 1/13/1 4/14/4 23/11/23
|
||||||
|
f 23/11/23 4/14/4 6/15/6 24/12/24
|
||||||
|
f 6/6/6 5/5/5 25/16/25 26/17/26
|
||||||
|
f 26/17/26 25/16/25 27/18/27 28/19/28
|
||||||
|
f 5/5/5 9/9/9 29/20/29 25/16/25
|
||||||
|
f 25/16/25 29/20/29 30/21/30 27/18/27
|
||||||
|
f 9/9/9 12/12/12 31/22/31 29/20/29
|
||||||
|
f 29/20/29 31/22/31 32/23/32 30/21/30
|
||||||
|
f 12/12/12 15/15/15 33/24/33 31/22/31
|
||||||
|
f 31/22/31 33/24/33 34/25/34 32/23/32
|
||||||
|
f 15/6/15 18/5/18 35/16/35 33/17/33
|
||||||
|
f 33/17/33 35/16/35 36/18/36 34/19/34
|
||||||
|
f 18/5/18 21/9/21 37/20/37 35/16/35
|
||||||
|
f 35/16/35 37/20/37 38/21/38 36/18/36
|
||||||
|
f 21/9/21 24/12/24 39/22/39 37/20/37
|
||||||
|
f 37/20/37 39/22/39 40/23/40 38/21/38
|
||||||
|
f 24/12/24 6/15/6 26/24/26 39/22/39
|
||||||
|
f 39/22/39 26/24/26 28/25/28 40/23/40
|
||||||
|
f 28/19/28 27/18/27 41/26/41 42/27/42
|
||||||
|
f 42/27/42 41/26/41 43/28/43 44/29/44
|
||||||
|
f 27/18/27 30/21/30 45/30/45 41/26/41
|
||||||
|
f 41/26/41 45/30/45 46/31/46 43/28/43
|
||||||
|
f 30/21/30 32/23/32 47/32/47 45/30/45
|
||||||
|
f 45/30/45 47/32/47 48/33/48 46/31/46
|
||||||
|
f 32/23/32 34/25/34 49/34/49 47/32/47
|
||||||
|
f 47/32/47 49/34/49 50/35/50 48/33/48
|
||||||
|
f 34/19/34 36/18/36 51/26/51 49/27/49
|
||||||
|
f 49/27/49 51/26/51 52/28/52 50/29/50
|
||||||
|
f 36/18/36 38/21/38 53/30/53 51/26/51
|
||||||
|
f 51/26/51 53/30/53 54/31/54 52/28/52
|
||||||
|
f 38/21/38 40/23/40 55/32/55 53/30/53
|
||||||
|
f 53/30/53 55/32/55 56/33/56 54/31/54
|
||||||
|
f 40/23/40 28/25/28 42/34/42 55/32/55
|
||||||
|
f 55/32/55 42/34/42 44/35/44 56/33/56
|
||||||
|
f 44/29/44 43/28/43 57/36/57 58/37/58
|
||||||
|
f 58/37/58 57/36/57 59/38/59
|
||||||
|
f 43/28/43 46/31/46 60/39/60 57/36/57
|
||||||
|
f 57/36/57 60/39/60 59/40/59
|
||||||
|
f 46/31/46 48/33/48 61/41/61 60/39/60
|
||||||
|
f 60/39/60 61/41/61 59/42/59
|
||||||
|
f 48/33/48 50/35/50 62/43/62 61/41/61
|
||||||
|
f 61/41/61 62/43/62 59/44/59
|
||||||
|
f 50/29/50 52/28/52 63/36/63 62/37/62
|
||||||
|
f 62/37/62 63/36/63 59/38/59
|
||||||
|
f 52/28/52 54/31/54 64/39/64 63/36/63
|
||||||
|
f 63/36/63 64/39/64 59/40/59
|
||||||
|
f 54/31/54 56/33/56 65/41/65 64/39/64
|
||||||
|
f 64/39/64 65/41/65 59/42/59
|
||||||
|
f 56/33/56 44/35/44 58/43/58 65/41/65
|
||||||
|
f 65/41/65 58/43/58 59/44/59
|
||||||
|
f 66/21/66 67/45/67 68/46/68 69/47/69
|
||||||
|
f 69/47/69 68/46/68 70/48/70 71/49/71
|
||||||
|
f 67/45/67 72/23/72 73/50/73 68/46/68
|
||||||
|
f 68/46/68 73/50/73 74/51/74 70/48/70
|
||||||
|
f 72/23/72 75/52/75 76/53/76 73/50/73
|
||||||
|
f 73/50/73 76/53/76 77/54/77 74/51/74
|
||||||
|
f 75/52/75 66/25/66 69/55/69 76/53/76
|
||||||
|
f 76/53/76 69/55/69 71/56/71 77/54/77
|
||||||
|
f 71/49/71 70/48/70 78/57/78 79/58/79
|
||||||
|
f 79/58/79 78/57/78 80/59/80 34/40/81
|
||||||
|
f 70/48/70 74/51/74 81/60/82 78/57/78
|
||||||
|
f 78/57/78 81/60/82 82/42/83 80/59/80
|
||||||
|
f 74/51/74 77/54/77 83/61/84 81/60/82
|
||||||
|
f 81/60/82 83/61/84 84/62/85 82/42/83
|
||||||
|
f 77/54/77 71/56/71 79/63/79 83/61/84
|
||||||
|
f 83/61/84 79/63/79 34/44/81 84/62/85
|
||||||
|
f 85/42/86 86/59/87 87/64/88 88/65/89
|
||||||
|
f 88/65/89 87/64/88 89/66/90 90/67/91
|
||||||
|
f 86/59/87 91/40/92 92/68/93 87/64/88
|
||||||
|
f 87/64/88 92/68/93 93/69/94 89/66/90
|
||||||
|
f 91/44/92 94/62/95 95/70/96 92/71/93
|
||||||
|
f 92/71/93 95/70/96 96/72/97 93/73/94
|
||||||
|
f 94/62/95 85/42/86 88/65/89 95/70/96
|
||||||
|
f 95/70/96 88/65/89 90/67/91 96/72/97
|
||||||
|
f 90/67/91 89/66/90 97/74/98 98/75/99
|
||||||
|
f 98/75/99 97/74/98 99/45/100 100/23/101
|
||||||
|
f 89/66/90 93/69/94 101/76/102 97/74/98
|
||||||
|
f 97/74/98 101/76/102 102/21/103 99/45/100
|
||||||
|
f 93/73/94 96/72/97 103/77/104 101/78/102
|
||||||
|
f 101/78/102 103/77/104 104/52/105 102/25/103
|
||||||
|
f 96/72/97 90/67/91 98/75/99 103/77/104
|
||||||
|
f 103/77/104 98/75/99 100/23/101 104/52/105
|
||||||
|
f 105/48/106 106/49/107 107/21/108
|
||||||
|
f 106/49/107 105/48/106 108/59/109 109/40/110
|
||||||
|
f 110/51/111 105/48/106 107/45/108
|
||||||
|
f 105/48/106 110/51/111 111/42/112 108/59/109
|
||||||
|
f 112/54/113 110/51/111 107/23/108
|
||||||
|
f 110/51/111 112/54/113 113/62/114 111/42/112
|
||||||
|
f 114/56/115 112/54/113 107/52/108
|
||||||
|
f 112/54/113 114/56/115 115/44/116 113/62/114
|
||||||
|
f 116/48/117 114/49/115 107/21/108
|
||||||
|
f 114/49/115 116/48/117 117/59/118 115/40/116
|
||||||
|
f 118/51/119 116/48/117 107/45/108
|
||||||
|
f 116/48/117 118/51/119 119/42/120 117/59/118
|
||||||
|
f 120/54/121 118/51/119 107/23/108
|
||||||
|
f 118/51/119 120/54/121 121/62/122 119/42/120
|
||||||
|
f 106/56/107 120/54/121 107/52/108
|
||||||
|
f 120/54/121 106/56/107 109/44/110 121/62/122
|
||||||
|
f 109/21/110 108/45/109 122/48/123 123/49/124
|
||||||
|
f 123/49/124 122/48/123 124/59/125 125/40/126
|
||||||
|
f 108/45/109 111/23/112 126/51/127 122/48/123
|
||||||
|
f 122/48/123 126/51/127 127/42/128 124/59/125
|
||||||
|
f 111/23/112 113/52/114 128/54/129 126/51/127
|
||||||
|
f 126/51/127 128/54/129 129/62/130 127/42/128
|
||||||
|
f 113/52/114 115/25/116 130/56/131 128/54/129
|
||||||
|
f 128/54/129 130/56/131 131/44/132 129/62/130
|
||||||
|
f 115/21/116 117/45/118 132/48/133 130/49/131
|
||||||
|
f 130/49/131 132/48/133 133/59/134 131/40/132
|
||||||
|
f 117/45/118 119/23/120 134/51/135 132/48/133
|
||||||
|
f 132/48/133 134/51/135 135/42/136 133/59/134
|
||||||
|
f 119/23/120 121/52/122 136/54/137 134/51/135
|
||||||
|
f 134/51/135 136/54/137 137/62/138 135/42/136
|
||||||
|
f 121/52/122 109/25/110 123/56/124 136/54/137
|
||||||
|
f 136/54/137 123/56/124 125/44/126 137/62/138
|
||||||
|
# 112 polygons - 16 triangles
|
||||||
|
|
||||||
274
external/teapot-lowtri.obj
vendored
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
#
|
||||||
|
# object Teapot001
|
||||||
|
#
|
||||||
|
|
||||||
|
v 7.0000 0.0000 12.0000
|
||||||
|
v 4.9700 -4.9700 12.0000
|
||||||
|
v 4.9811 -4.9811 12.4922
|
||||||
|
v 7.0156 0.0000 12.4922
|
||||||
|
v 5.3250 -5.3250 12.0000
|
||||||
|
v 7.5000 0.0000 12.0000
|
||||||
|
v 0.0000 -7.0000 12.0000
|
||||||
|
v 0.0000 -7.0156 12.4922
|
||||||
|
v 0.0000 -7.5000 12.0000
|
||||||
|
v -5.1387 -4.9700 12.0000
|
||||||
|
v -5.0022 -4.9811 12.4922
|
||||||
|
v -5.3250 -5.3250 12.0000
|
||||||
|
v -7.0000 0.0000 12.0000
|
||||||
|
v -7.0156 0.0000 12.4922
|
||||||
|
v -7.5000 0.0000 12.0000
|
||||||
|
v -4.9700 4.9700 12.0000
|
||||||
|
v -4.9811 4.9811 12.4922
|
||||||
|
v -5.3250 5.3250 12.0000
|
||||||
|
v 0.0000 7.0000 12.0000
|
||||||
|
v 0.0000 7.0156 12.4922
|
||||||
|
v 0.0000 7.5000 12.0000
|
||||||
|
v 4.9700 4.9700 12.0000
|
||||||
|
v 4.9811 4.9811 12.4922
|
||||||
|
v 5.3250 5.3250 12.0000
|
||||||
|
v 6.5453 -6.5453 8.1094
|
||||||
|
v 9.2188 0.0000 8.1094
|
||||||
|
v 7.1000 -7.1000 4.5000
|
||||||
|
v 10.0000 0.0000 4.5000
|
||||||
|
v 0.0000 -9.2188 8.1094
|
||||||
|
v 0.0000 -10.0000 4.5000
|
||||||
|
v -6.5453 -6.5453 8.1094
|
||||||
|
v -7.1000 -7.1000 4.5000
|
||||||
|
v -9.2188 0.0000 8.1094
|
||||||
|
v -10.0000 0.0000 4.5000
|
||||||
|
v -6.5453 6.5453 8.1094
|
||||||
|
v -7.1000 7.1000 4.5000
|
||||||
|
v 0.0000 9.2188 8.1094
|
||||||
|
v 0.0000 10.0000 4.5000
|
||||||
|
v 6.5453 6.5453 8.1094
|
||||||
|
v 7.1000 7.1000 4.5000
|
||||||
|
v 6.2125 -6.2125 1.9219
|
||||||
|
v 8.7500 0.0000 1.9219
|
||||||
|
v 5.3250 -5.3250 0.7500
|
||||||
|
v 7.5000 0.0000 0.7500
|
||||||
|
v 0.0000 -8.7500 1.9219
|
||||||
|
v 0.0000 -7.5000 0.7500
|
||||||
|
v -6.2125 -6.2125 1.9219
|
||||||
|
v -5.3250 -5.3250 0.7500
|
||||||
|
v -8.7500 0.0000 1.9219
|
||||||
|
v -7.5000 0.0000 0.7500
|
||||||
|
v -6.2125 6.2125 1.9219
|
||||||
|
v -5.3250 5.3250 0.7500
|
||||||
|
v 0.0000 8.7500 1.9219
|
||||||
|
v 0.0000 7.5000 0.7500
|
||||||
|
v 6.2125 6.2125 1.9219
|
||||||
|
v 5.3250 5.3250 0.7500
|
||||||
|
v 4.5595 -4.5595 0.2344
|
||||||
|
v 6.4219 0.0000 0.2344
|
||||||
|
v 0.0000 0.0000 0.0000
|
||||||
|
v 0.0000 -6.4219 0.2344
|
||||||
|
v -4.5595 -4.5595 0.2344
|
||||||
|
v -6.4219 0.0000 0.2344
|
||||||
|
v -4.5595 4.5595 0.2344
|
||||||
|
v 0.0000 6.4219 0.2344
|
||||||
|
v 4.5595 4.5595 0.2344
|
||||||
|
v -8.0000 0.0000 10.1250
|
||||||
|
v -7.7500 -1.1250 10.6875
|
||||||
|
v -12.5938 -1.1250 10.4766
|
||||||
|
v -12.0625 0.0000 9.9844
|
||||||
|
v -14.2500 -1.1250 9.0000
|
||||||
|
v -13.5000 0.0000 9.0000
|
||||||
|
v -7.5000 0.0000 11.2500
|
||||||
|
v -13.1250 0.0000 10.9688
|
||||||
|
v -15.0000 0.0000 9.0000
|
||||||
|
v -7.7500 1.1250 10.6875
|
||||||
|
v -12.5938 1.1250 10.4766
|
||||||
|
v -14.2500 1.1250 9.0000
|
||||||
|
v -13.1719 -1.1250 6.2695
|
||||||
|
v -12.6875 0.0000 6.7500
|
||||||
|
v -9.7500 -1.1250 3.7500
|
||||||
|
v -13.6563 0.0000 5.7891
|
||||||
|
v -9.5000 0.0000 3.0000
|
||||||
|
v -13.1719 1.1250 6.2695
|
||||||
|
v -9.7500 1.1250 3.7500
|
||||||
|
v 8.5000 0.0000 7.1250
|
||||||
|
v 8.5000 -2.4750 5.0625
|
||||||
|
v 12.6875 -1.7062 8.1094
|
||||||
|
v 11.9375 0.0000 9.0000
|
||||||
|
v 15.0000 -0.9375 12.0000
|
||||||
|
v 13.5000 0.0000 12.0000
|
||||||
|
v 8.5000 0.0000 3.0000
|
||||||
|
v 13.4375 0.0000 7.2187
|
||||||
|
v 16.5000 0.0000 12.0000
|
||||||
|
v 8.5000 2.4750 5.0625
|
||||||
|
v 12.6875 1.7062 8.1094
|
||||||
|
v 15.0000 0.9375 12.0000
|
||||||
|
v 15.6328 -0.7500 12.3340
|
||||||
|
v 14.1250 0.0000 12.2813
|
||||||
|
v 15.0000 -0.5625 12.0000
|
||||||
|
v 14.0000 0.0000 12.0000
|
||||||
|
v 17.1406 0.0000 12.3867
|
||||||
|
v 16.0000 0.0000 12.0000
|
||||||
|
v 15.6328 0.7500 12.3340
|
||||||
|
v 15.0000 0.5625 12.0000
|
||||||
|
v 1.1552 -1.1552 14.9063
|
||||||
|
v 1.6250 0.0000 14.9063
|
||||||
|
v 0.0000 0.0000 15.7500
|
||||||
|
v 0.7100 -0.7100 13.5000
|
||||||
|
v 1.0000 0.0000 13.5000
|
||||||
|
v 0.0000 -1.6250 14.9063
|
||||||
|
v 0.0000 -1.0000 13.5000
|
||||||
|
v -1.1552 -1.1552 14.9063
|
||||||
|
v -0.7100 -0.7100 13.5000
|
||||||
|
v -1.6250 0.0000 14.9063
|
||||||
|
v -1.0000 0.0000 13.5000
|
||||||
|
v -1.1552 1.1552 14.9063
|
||||||
|
v -0.7100 0.7100 13.5000
|
||||||
|
v 0.0000 1.6250 14.9063
|
||||||
|
v 0.0000 1.0000 13.5000
|
||||||
|
v 1.1552 1.1552 14.9063
|
||||||
|
v 0.7100 0.7100 13.5000
|
||||||
|
v 2.9288 -2.9288 12.7500
|
||||||
|
v 4.1250 0.0000 12.7500
|
||||||
|
v 4.6150 -4.6150 12.0000
|
||||||
|
v 6.5000 0.0000 12.0000
|
||||||
|
v 0.0000 -4.1250 12.7500
|
||||||
|
v 0.0000 -6.5000 12.0000
|
||||||
|
v -2.9288 -2.9288 12.7500
|
||||||
|
v -4.6150 -4.6150 12.0000
|
||||||
|
v -4.1250 0.0000 12.7500
|
||||||
|
v -6.5000 0.0000 12.0000
|
||||||
|
v -2.9288 2.9288 12.7500
|
||||||
|
v -4.6150 4.6150 12.0000
|
||||||
|
v 0.0000 4.1250 12.7500
|
||||||
|
v 0.0000 6.5000 12.0000
|
||||||
|
v 2.9288 2.9288 12.7500
|
||||||
|
v 4.6150 4.6150 12.0000
|
||||||
|
# 137 vertices
|
||||||
|
|
||||||
|
g Teapot001
|
||||||
|
f 1 2 3 4
|
||||||
|
f 4 3 5 6
|
||||||
|
f 2 7 8 3
|
||||||
|
f 3 8 9 5
|
||||||
|
f 7 10 11 8
|
||||||
|
f 8 11 12 9
|
||||||
|
f 10 13 14 11
|
||||||
|
f 11 14 15 12
|
||||||
|
f 13 16 17 14
|
||||||
|
f 14 17 18 15
|
||||||
|
f 16 19 20 17
|
||||||
|
f 17 20 21 18
|
||||||
|
f 19 22 23 20
|
||||||
|
f 20 23 24 21
|
||||||
|
f 22 1 4 23
|
||||||
|
f 23 4 6 24
|
||||||
|
f 6 5 25 26
|
||||||
|
f 26 25 27 28
|
||||||
|
f 5 9 29 25
|
||||||
|
f 25 29 30 27
|
||||||
|
f 9 12 31 29
|
||||||
|
f 29 31 32 30
|
||||||
|
f 12 15 33 31
|
||||||
|
f 31 33 34 32
|
||||||
|
f 15 18 35 33
|
||||||
|
f 33 35 36 34
|
||||||
|
f 18 21 37 35
|
||||||
|
f 35 37 38 36
|
||||||
|
f 21 24 39 37
|
||||||
|
f 37 39 40 38
|
||||||
|
f 24 6 26 39
|
||||||
|
f 39 26 28 40
|
||||||
|
f 28 27 41 42
|
||||||
|
f 42 41 43 44
|
||||||
|
f 27 30 45 41
|
||||||
|
f 41 45 46 43
|
||||||
|
f 30 32 47 45
|
||||||
|
f 45 47 48 46
|
||||||
|
f 32 34 49 47
|
||||||
|
f 47 49 50 48
|
||||||
|
f 34 36 51 49
|
||||||
|
f 49 51 52 50
|
||||||
|
f 36 38 53 51
|
||||||
|
f 51 53 54 52
|
||||||
|
f 38 40 55 53
|
||||||
|
f 53 55 56 54
|
||||||
|
f 40 28 42 55
|
||||||
|
f 55 42 44 56
|
||||||
|
f 44 43 57 58
|
||||||
|
f 58 57 59
|
||||||
|
f 43 46 60 57
|
||||||
|
f 57 60 59
|
||||||
|
f 46 48 61 60
|
||||||
|
f 60 61 59
|
||||||
|
f 48 50 62 61
|
||||||
|
f 61 62 59
|
||||||
|
f 50 52 63 62
|
||||||
|
f 62 63 59
|
||||||
|
f 52 54 64 63
|
||||||
|
f 63 64 59
|
||||||
|
f 54 56 65 64
|
||||||
|
f 64 65 59
|
||||||
|
f 56 44 58 65
|
||||||
|
f 65 58 59
|
||||||
|
f 66 67 68 69
|
||||||
|
f 69 68 70 71
|
||||||
|
f 67 72 73 68
|
||||||
|
f 68 73 74 70
|
||||||
|
f 72 75 76 73
|
||||||
|
f 73 76 77 74
|
||||||
|
f 75 66 69 76
|
||||||
|
f 76 69 71 77
|
||||||
|
f 71 70 78 79
|
||||||
|
f 79 78 80 34
|
||||||
|
f 70 74 81 78
|
||||||
|
f 78 81 82 80
|
||||||
|
f 74 77 83 81
|
||||||
|
f 81 83 84 82
|
||||||
|
f 77 71 79 83
|
||||||
|
f 83 79 34 84
|
||||||
|
f 85 86 87 88
|
||||||
|
f 88 87 89 90
|
||||||
|
f 86 91 92 87
|
||||||
|
f 87 92 93 89
|
||||||
|
f 91 94 95 92
|
||||||
|
f 92 95 96 93
|
||||||
|
f 94 85 88 95
|
||||||
|
f 95 88 90 96
|
||||||
|
f 90 89 97 98
|
||||||
|
f 98 97 99 100
|
||||||
|
f 89 93 101 97
|
||||||
|
f 97 101 102 99
|
||||||
|
f 93 96 103 101
|
||||||
|
f 101 103 104 102
|
||||||
|
f 96 90 98 103
|
||||||
|
f 103 98 100 104
|
||||||
|
f 105 106 107
|
||||||
|
f 106 105 108 109
|
||||||
|
f 110 105 107
|
||||||
|
f 105 110 111 108
|
||||||
|
f 112 110 107
|
||||||
|
f 110 112 113 111
|
||||||
|
f 114 112 107
|
||||||
|
f 112 114 115 113
|
||||||
|
f 116 114 107
|
||||||
|
f 114 116 117 115
|
||||||
|
f 118 116 107
|
||||||
|
f 116 118 119 117
|
||||||
|
f 120 118 107
|
||||||
|
f 118 120 121 119
|
||||||
|
f 106 120 107
|
||||||
|
f 120 106 109 121
|
||||||
|
f 109 108 122 123
|
||||||
|
f 123 122 124 125
|
||||||
|
f 108 111 126 122
|
||||||
|
f 122 126 127 124
|
||||||
|
f 111 113 128 126
|
||||||
|
f 126 128 129 127
|
||||||
|
f 113 115 130 128
|
||||||
|
f 128 130 131 129
|
||||||
|
f 115 117 132 130
|
||||||
|
f 130 132 133 131
|
||||||
|
f 117 119 134 132
|
||||||
|
f 132 134 135 133
|
||||||
|
f 119 121 136 134
|
||||||
|
f 134 136 137 135
|
||||||
|
f 121 109 123 136
|
||||||
|
f 136 123 125 137
|
||||||
|
# 112 polygons - 16 triangles
|
||||||
|
|
||||||
11284
external/teapot.obj
vendored
Normal file
BIN
output/arealight_test.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
output/arealight_test_nojitter.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
output/ch10_test.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
output/ch11_reflection.png
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
output/ch11_reflection_on_ball.png
Normal file
|
After Width: | Height: | Size: 949 KiB |
BIN
output/ch11_refraction.png
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
output/ch11_test.png
Normal file
|
After Width: | Height: | Size: 194 KiB |
BIN
output/ch11_zooming_on_reflective_ball.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
output/ch12_test.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
output/ch13_cone.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
output/ch13_test.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
output/ch14_test.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
output/ch15_teapot_objfile.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
output/ch16_test.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
output/ch5_test.png
Normal file
|
After Width: | Height: | Size: 273 B |
BIN
output/ch6_test.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
output/ch7_test.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
output/ch8_test.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
output/ch9_test.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
output/christmasball.png
Normal file
|
After Width: | Height: | Size: 598 KiB |
BIN
output/dragon_scene.png
Normal file
|
After Width: | Height: | Size: 152 KiB |
BIN
output/uvmap_aligncheckplane.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
output/uvmap_checkeredcube.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
output/uvmap_checkeredcylinder.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
output/uvmap_checkeredplane.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
output/uvmap_checkeredsphere.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
output/uvmap_earth.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
output/uvmap_skybox.png
Normal file
|
After Width: | Height: | Size: 453 KiB |
685
samplescenes/orrery.yml
Normal file
@@ -0,0 +1,685 @@
|
|||||||
|
# ======================================================
|
||||||
|
# orrery.yml
|
||||||
|
#
|
||||||
|
# This file describes the title image for the "Texture
|
||||||
|
# Mapping" bonus chapter at:
|
||||||
|
#
|
||||||
|
# http://www.raytracerchallenge.com/bonus/texture-mapping.html
|
||||||
|
#
|
||||||
|
# It requires several additional resources, provided as a
|
||||||
|
# separate download. The resources were found on the following
|
||||||
|
# sites:
|
||||||
|
#
|
||||||
|
# * https://www.bittbox.com/freebies/free-hi-resolution-wood-textures
|
||||||
|
# : the wooden texture for the table
|
||||||
|
# * https://astrogeology.usgs.gov/search/map/Mercury/Messenger/Global/Mercury_MESSENGER_MDIS_Basemap_LOI_Mosaic_Global_166m
|
||||||
|
# : the map of Mercury
|
||||||
|
# * http://planetpixelemporium.com/planets.html
|
||||||
|
# : maps of Earth, Mars, Jupiter, Saturn, Uranus, and Neptune
|
||||||
|
# * https://hdrihaven.com/hdri/?c=indoor&h=artist_workshop
|
||||||
|
# : the "artist workshop" environment map
|
||||||
|
#
|
||||||
|
# by Jamis Buck <jamis@jamisbuck.org>
|
||||||
|
# ======================================================
|
||||||
|
|
||||||
|
- add: camera
|
||||||
|
width: 800
|
||||||
|
height: 400
|
||||||
|
field-of-view: 1.2
|
||||||
|
from: [ 2, 4, -10]
|
||||||
|
to: [ -1, -1, 0 ]
|
||||||
|
up: [ 0, 1, 0 ]
|
||||||
|
|
||||||
|
# The scene as shown in the bonus chapter is rendered using an area light,
|
||||||
|
# precisely as described in the "Rendering soft shadows" bonus chapter,
|
||||||
|
# here: http://www.raytracerchallenge.com/bonus/area-light.html
|
||||||
|
#
|
||||||
|
# if you haven't implemented area lights, you can replace this with a point
|
||||||
|
# light located at [0, 2.5, -10].
|
||||||
|
|
||||||
|
- add: light
|
||||||
|
corner: [-5, 0, -10 ]
|
||||||
|
uvec: [ 10, 0, 0 ]
|
||||||
|
vvec: [ 0, 5, 0 ]
|
||||||
|
usteps: 10
|
||||||
|
vsteps: 5
|
||||||
|
jitter: true
|
||||||
|
intensity: [ 1, 1, 1 ]
|
||||||
|
|
||||||
|
# -------------------------------------------
|
||||||
|
# some common textures
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
- define: GOLD
|
||||||
|
value:
|
||||||
|
color: [ 1, 0.8, 0.1 ]
|
||||||
|
ambient: 0.1
|
||||||
|
diffuse: 0.6
|
||||||
|
specular: 0.3
|
||||||
|
shininess: 15
|
||||||
|
|
||||||
|
- define: SILVER
|
||||||
|
value:
|
||||||
|
color: [ 1, 1, 1 ]
|
||||||
|
ambient: 0.1
|
||||||
|
diffuse: 0.7
|
||||||
|
specular: 0.3
|
||||||
|
shininess: 15
|
||||||
|
|
||||||
|
# -----------------------------------------------
|
||||||
|
# CSG definition for the gears used to construct
|
||||||
|
# the orrery.
|
||||||
|
#
|
||||||
|
# NOTCH is a helper object used to create the
|
||||||
|
# teeth for the gears.
|
||||||
|
#
|
||||||
|
# GEAR is the actual gear object itself.
|
||||||
|
# -----------------------------------------------
|
||||||
|
|
||||||
|
- define: NOTCH
|
||||||
|
value:
|
||||||
|
add: csg
|
||||||
|
operation: difference
|
||||||
|
left:
|
||||||
|
type: cube
|
||||||
|
transform:
|
||||||
|
- [ scale, 1, 0.25, 1 ]
|
||||||
|
- [ translate, 1, 0, 1 ]
|
||||||
|
- [ rotate-y, 0.7854 ]
|
||||||
|
- [ scale, 1, 1, 0.1 ]
|
||||||
|
right:
|
||||||
|
type: cylinder
|
||||||
|
min: -0.26
|
||||||
|
max: 0.26
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.8, 1, 0.8 ]
|
||||||
|
|
||||||
|
- define: GEAR
|
||||||
|
value:
|
||||||
|
add: csg
|
||||||
|
operation: difference
|
||||||
|
left:
|
||||||
|
type: cylinder
|
||||||
|
min: -0.025
|
||||||
|
max: 0.025
|
||||||
|
closed: true
|
||||||
|
right:
|
||||||
|
type: group
|
||||||
|
children:
|
||||||
|
# center hole
|
||||||
|
- add: cylinder
|
||||||
|
min: -0.06
|
||||||
|
max: 0.06
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.1, 1, 0.1 ]
|
||||||
|
# crescents
|
||||||
|
- add: csg
|
||||||
|
operation: difference
|
||||||
|
left:
|
||||||
|
type: cylinder
|
||||||
|
min: -0.06
|
||||||
|
max: 0.06
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.7, 1, 0.7 ]
|
||||||
|
right:
|
||||||
|
type: cube
|
||||||
|
transform:
|
||||||
|
- [ scale, 1, 0.1, 0.2 ]
|
||||||
|
# teeth
|
||||||
|
- add: NOTCH
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 0.31415 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 0.6283 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 0.94245 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 1.2566 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 1.57075 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 1.8849 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 2.19905 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 2.5132 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 2.82735 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 3.1415 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -0.31415 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -0.6283 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -0.94245 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -1.2566 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -1.57075 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -1.8849 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -2.19905 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -2.5132 ]
|
||||||
|
- add: NOTCH
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -2.82735 ]
|
||||||
|
|
||||||
|
# mechanism: top plate
|
||||||
|
- add: csg
|
||||||
|
operation: difference
|
||||||
|
material: GOLD
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -1 ]
|
||||||
|
left:
|
||||||
|
type: cylinder
|
||||||
|
min: -1.51
|
||||||
|
max: -1.5
|
||||||
|
closed: true
|
||||||
|
right:
|
||||||
|
type: group
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -1.52
|
||||||
|
max: -1.49
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.1, 1, 0.1 ]
|
||||||
|
- add: csg
|
||||||
|
operation: difference
|
||||||
|
left:
|
||||||
|
type: cylinder
|
||||||
|
min: -1.52
|
||||||
|
max: -1.49
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.75, 1, 0.75 ]
|
||||||
|
right:
|
||||||
|
type: cube
|
||||||
|
transform:
|
||||||
|
- [ scale, 1, 0.1, 0.2 ]
|
||||||
|
- [ translate, 0, -1.5, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.5, 0.5, 0.5 ]
|
||||||
|
- [ translate, 0.4, -1.45, -0.4 ]
|
||||||
|
|
||||||
|
# mechanism: gear
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 0.8 ]
|
||||||
|
- [ scale, 0.4, 0.4, 0.4 ]
|
||||||
|
- [ translate, -0.4, -1.45, 0.2 ]
|
||||||
|
|
||||||
|
# sun
|
||||||
|
- add: group
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
shadow: false
|
||||||
|
material:
|
||||||
|
color: [1, 1, 0]
|
||||||
|
ambient: 0.1
|
||||||
|
diffuse: 0.6
|
||||||
|
specular: 0 # count on the skybox reflection being the specular highlight
|
||||||
|
reflective: 0.2
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -4
|
||||||
|
max: -0.5
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
|
||||||
|
# base
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ translate, 0, -4, 0 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: checkers
|
||||||
|
width: 16
|
||||||
|
height: 8
|
||||||
|
colors:
|
||||||
|
- [ 0, 0, 0 ]
|
||||||
|
- [ 0.5, 0.5, 0.5 ]
|
||||||
|
diffuse: 0.6
|
||||||
|
specular: 0 # count on the skybox reflection being the specular highlight
|
||||||
|
ambient: 0.1
|
||||||
|
reflective: 0.2
|
||||||
|
|
||||||
|
# table
|
||||||
|
- add: cube
|
||||||
|
transform:
|
||||||
|
- [ scale, 5, 0.1, 5 ]
|
||||||
|
- [ translate, 0, -4, 0 ]
|
||||||
|
material:
|
||||||
|
diffuse: 0.9
|
||||||
|
ambient: 0.1
|
||||||
|
specular: 0
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: planar
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/wood.ppm
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.5, 0.5, 0.5 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between top & mercury
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -0.4 ]
|
||||||
|
- [ scale, 0.9, 0.9, 0.9 ]
|
||||||
|
- [ translate, 0, -1.75, 0 ]
|
||||||
|
|
||||||
|
# mercury
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 2, 0, 0 ]
|
||||||
|
- [ rotate-y, 0.7 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.25, 0.25, 0.25 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/mercury-small.ppm
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 2
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between mercury & venus
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, 1.3 ]
|
||||||
|
- [ translate, 0, -2.05, 0 ]
|
||||||
|
|
||||||
|
# venus
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 3, 0, 0 ]
|
||||||
|
- [ rotate-y, 0.3 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.25, 0.25, 0.25 ]
|
||||||
|
material:
|
||||||
|
color: [ 1, 1, 0.8 ]
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.1
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.1, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 3
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.1, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between venus & earth
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.9, 0.9, 0.9 ]
|
||||||
|
- [ rotate-y, -2.2 ]
|
||||||
|
- [ translate, 0, -2.15, 0 ]
|
||||||
|
|
||||||
|
# earth
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 4, 0, 0 ]
|
||||||
|
- [ rotate-y, 2 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.25, 0.25, 0.25 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/earthmap-small.ppm
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.2
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.2, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 4
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.2, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between earth & mars
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.8, 0.8, 0.8 ]
|
||||||
|
- [ rotate-y, 1.7 ]
|
||||||
|
- [ translate, 0, -2.25, 0 ]
|
||||||
|
|
||||||
|
# mars
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 5, 0, 0 ]
|
||||||
|
- [ rotate-y, -2 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.25, 0.25, 0.25 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/mars-small.ppm
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.3
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.3, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 5
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.3, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between mars & jupiter
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -0.9 ]
|
||||||
|
- [ translate, 0, -2.35, 0 ]
|
||||||
|
|
||||||
|
# jupiter
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 6.5, 0, 0 ]
|
||||||
|
- [ rotate-y, -0.75 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.67, 0.67, 0.67 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/jupitermap-small.ppm
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.4
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.4, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 6.5
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.4, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between jupiter & saturn
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.95, 0.95, 0.95 ]
|
||||||
|
- [ rotate-y, -1.1 ]
|
||||||
|
- [ translate, 0, -2.45, 0 ]
|
||||||
|
|
||||||
|
# saturn
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 8, 0, 0 ]
|
||||||
|
- [ rotate-y, -2.5 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.5, 0.5, 0.5 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/saturnmap-small.ppm
|
||||||
|
# rings
|
||||||
|
- add: csg
|
||||||
|
operation: difference
|
||||||
|
transform:
|
||||||
|
- [ rotate-z, 0.2 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: rings
|
||||||
|
colors:
|
||||||
|
- [ 1, 1, 0.5 ]
|
||||||
|
- [ 1, 1, 0 ]
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.05, 1, 0.05 ]
|
||||||
|
left:
|
||||||
|
type: cylinder
|
||||||
|
min: -0.01
|
||||||
|
max: 0.01
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 1.2, 1, 1.2 ]
|
||||||
|
right:
|
||||||
|
type: cylinder
|
||||||
|
min: -0.02
|
||||||
|
max: 0.02
|
||||||
|
closed: true
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.75, 1, 0.75 ]
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.5
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.5, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 8
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.5, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between saturn & uranus
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.9, 0.9, 0.9 ]
|
||||||
|
- [ rotate-y, 1 ]
|
||||||
|
- [ translate, 0, -2.55, 0 ]
|
||||||
|
|
||||||
|
# uranus
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 9, 0, 0 ]
|
||||||
|
- [ rotate-y, -3 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.4, 0.4, 0.4 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/uranusmap-small.ppm
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.6
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.6, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 9
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.6, 0 ]
|
||||||
|
|
||||||
|
# mechanism: gear-plate between uranus & neptune
|
||||||
|
- add: GEAR
|
||||||
|
material: SILVER
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -1 ]
|
||||||
|
- [ translate, 0, -2.65, 0 ]
|
||||||
|
|
||||||
|
# neptune
|
||||||
|
- add: group
|
||||||
|
transform:
|
||||||
|
- [ translate, 10, 0, 0 ]
|
||||||
|
- [ rotate-y, -1.25 ]
|
||||||
|
children:
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.4, 0.4, 0.4 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/neptunemap-small.ppm
|
||||||
|
- add: group
|
||||||
|
material: GOLD
|
||||||
|
children:
|
||||||
|
- add: cylinder
|
||||||
|
min: -2.7
|
||||||
|
max: 0
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 0.025, 0.025 ]
|
||||||
|
- [ translate, 0, -2.7, 0 ]
|
||||||
|
- add: cylinder
|
||||||
|
min: 0
|
||||||
|
max: 10
|
||||||
|
transform:
|
||||||
|
- [ scale, 0.025, 1, 0.025 ]
|
||||||
|
- [ rotate-z, 1.5708 ]
|
||||||
|
- [ translate, 0, -2.7, 0 ]
|
||||||
|
|
||||||
|
# outer sphere as the surrounding environment
|
||||||
|
- add: sphere
|
||||||
|
transform:
|
||||||
|
- [ scale, 1000, 1000, 1000 ]
|
||||||
|
material:
|
||||||
|
pattern:
|
||||||
|
type: map
|
||||||
|
mapping: spherical
|
||||||
|
uv_pattern:
|
||||||
|
type: image
|
||||||
|
file: res/artist_workshop.ppm
|
||||||
|
transform:
|
||||||
|
- [ rotate-y, -2.7 ]
|
||||||
|
diffuse: 0
|
||||||
|
specular: 0
|
||||||
|
ambient: 1
|
||||||
@@ -1,16 +1,43 @@
|
|||||||
# To simplify testing, the app is build in two passes,
|
# To simplify testing, the app is build in two passes,
|
||||||
|
option(USE_OPENMP "Build using OpenMP" OFF)
|
||||||
|
|
||||||
|
if (USE_OPENMP)
|
||||||
|
find_package(OpenMP REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
# First most is build as a library
|
# First most is build as a library
|
||||||
add_library(rayonnement STATIC)
|
add_library(rayonnement STATIC)
|
||||||
|
|
||||||
set(RAY_HEADERS include/tuples.h include/math_helper.h include/colour.h include/canvas.h include/matrix.h)
|
file(GLOB RAY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/pattern/*.h
|
||||||
set(RAY_SOURCES tuples.cpp math_helper.cpp colour.cpp canvas.cpp matrix.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/uvpattern/*.h)
|
||||||
|
|
||||||
target_include_directories(rayonnement PUBLIC include)
|
file(GLOB RAY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/shapes/*.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/worldbuilder/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/worldoptimiser/*.cpp)
|
||||||
|
|
||||||
|
target_include_directories(rayonnement PUBLIC include pattern)
|
||||||
|
|
||||||
|
if (USE_LUA)
|
||||||
|
add_dependencies(rayonnement LuaCore)
|
||||||
|
target_link_libraries(rayonnement ${LUA_LIBRARIES})
|
||||||
|
target_include_directories(rayonnement PUBLIC ${LUA_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(rayonnement PUBLIC include ${LODEPNG_INCLUDE_FOLDER} ${NANOJPEG_INCLUDE_FOLDER})
|
||||||
target_sources(rayonnement PRIVATE ${RAY_HEADERS} ${RAY_SOURCES})
|
target_sources(rayonnement PRIVATE ${RAY_HEADERS} ${RAY_SOURCES})
|
||||||
target_link_libraries(rayonnement LodePNG)
|
target_link_libraries(rayonnement LodePNG NanoJPEG)
|
||||||
|
|
||||||
# Second we build the main executable
|
if (USE_OPENMP)
|
||||||
add_executable(dorayme main.cpp)
|
target_link_libraries(rayonnement OpenMP::OpenMP_CXX)
|
||||||
target_include_directories(rayonnement PUBLIC include ${LODEPNG_INCLUDE_FOLDER})
|
endif()
|
||||||
target_link_libraries(dorayme rayonnement)
|
|
||||||
|
|
||||||
|
# The main executable
|
||||||
|
#add_executable(dorayme main.cpp)
|
||||||
|
|
||||||
|
#add_dependencies(dorayme LuaCore)
|
||||||
|
#target_link_libraries(dorayme rayonnement ${LUA_LIBRARIES})
|
||||||
|
|
||||||
|
|
||||||
|
if (COVERALLS)
|
||||||
|
set(COVERAGE_SRCS ${RAY_HEADERS} ${RAY_SOURCES} ${COVERAGE_SRCS} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
102
source/camera.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Camera implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <matrix.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <camera.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
|
||||||
|
Camera::Camera(uint32_t hsize, uint32_t vsize, double fov) : verticalSize(vsize),
|
||||||
|
horizontalSize(hsize), fieldOfView(fov), focalDistance(1), apertureSize(0), rayCount(1)
|
||||||
|
{
|
||||||
|
double aspectRatio = (double)hsize / (double)vsize;
|
||||||
|
double halfView = tan(fov / 2.0) * this->focalDistance;
|
||||||
|
|
||||||
|
if (aspectRatio >= 1)
|
||||||
|
{
|
||||||
|
this->halfWidth = halfView;
|
||||||
|
this->halfHeight = halfView / aspectRatio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->halfWidth = halfView * aspectRatio;
|
||||||
|
this->halfHeight = halfView;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pixelSize = (this->halfWidth * 2) / this->horizontalSize;
|
||||||
|
|
||||||
|
this->setTransform(Matrix4().identity());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::setTransform(Matrix transform)
|
||||||
|
{
|
||||||
|
this->transformMatrix = transform;
|
||||||
|
this->inverseTransform = transform.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY, double horzOffset, double vertOffset)
|
||||||
|
{
|
||||||
|
double xOffset = ((double)pixelX + 0.5) * this->pixelSize;
|
||||||
|
double yOffset = ((double)pixelY + 0.5) * this->pixelSize;
|
||||||
|
|
||||||
|
double worldX = this->halfWidth - xOffset;
|
||||||
|
double worldY = this->halfHeight - yOffset;
|
||||||
|
|
||||||
|
Tuple pixel = this->inverseTransform * Point(worldX, worldY, -this->focalDistance);
|
||||||
|
Tuple origin = this->inverseTransform * Point(horzOffset, vertOffset, 0);
|
||||||
|
Tuple direction = (pixel - origin).normalise();
|
||||||
|
|
||||||
|
stats.addCastedRay();
|
||||||
|
return Ray(origin, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas Camera::render(World world, uint32_t depth)
|
||||||
|
{
|
||||||
|
uint32_t x, y;
|
||||||
|
Canvas image = Canvas(this->horizontalSize, this->verticalSize);
|
||||||
|
|
||||||
|
#pragma omp parallel default(shared) private(x, y) shared(image, stats)
|
||||||
|
{
|
||||||
|
#pragma omp for schedule(dynamic, 5)
|
||||||
|
for (y = 0 ; y < this->verticalSize ; y++)
|
||||||
|
{
|
||||||
|
for (x = 0 ; x < this->horizontalSize ; x++)
|
||||||
|
{
|
||||||
|
Tuple colour;
|
||||||
|
if (this->apertureSize > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0 ; i < this->rayCount ; i++)
|
||||||
|
{
|
||||||
|
double horz = frandclip(-this->apertureSize/2, this->apertureSize / 2);
|
||||||
|
double vert = frandclip(-this->apertureSize/2, this->apertureSize / 2);
|
||||||
|
Ray r = this->rayForPixel(x, y, horz, vert);
|
||||||
|
colour = colour + world.colourAt(r, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
colour = colour / this->rayCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ray r = this->rayForPixel(x, y);
|
||||||
|
colour = world.colourAt(r, depth);
|
||||||
|
}
|
||||||
|
stats.addPixel();
|
||||||
|
image.putPixel(x, y, colour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.printStats();
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
@@ -9,6 +9,16 @@
|
|||||||
|
|
||||||
#include <canvas.h>
|
#include <canvas.h>
|
||||||
#include <lodepng.h>
|
#include <lodepng.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* NanoJPEG is a bit interesting to include as a header */
|
||||||
|
extern "C" {
|
||||||
|
#define _NJ_INCLUDE_HEADER_ONLY
|
||||||
|
#include <nanojpeg.c>
|
||||||
|
#undef _NJ_INCLUDE_HEADER_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
#define BPP (24)
|
#define BPP (24)
|
||||||
#define BytePP (BPP / 8)
|
#define BytePP (BPP / 8)
|
||||||
@@ -22,6 +32,98 @@ Canvas::Canvas(uint32_t width, uint32_t height) : width(width), height(height)
|
|||||||
this->stride = BytePP * width;
|
this->stride = BytePP * width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Canvas::Canvas(const Canvas &b)
|
||||||
|
{
|
||||||
|
this->width = b.width;
|
||||||
|
this->height = b.height;
|
||||||
|
this->stride = b.stride;
|
||||||
|
this->bitmap = (uint8_t *)calloc(4, b.width * b.height);
|
||||||
|
memcpy(this->bitmap, b.bitmap, 4 * b.width * b.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas::Canvas(const Canvas *b)
|
||||||
|
{
|
||||||
|
this->width = b->width;
|
||||||
|
this->height = b->height;
|
||||||
|
this->stride = b->stride;
|
||||||
|
this->bitmap = (uint8_t *)calloc(4, b->width * b->height);
|
||||||
|
memcpy(this->bitmap, b->bitmap, 4 * b->width * b->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas::Canvas(const char *imgfile)
|
||||||
|
{
|
||||||
|
/* Try to determine the file type in a really lazy way */
|
||||||
|
const char *fileExt = strrchr(imgfile, '.');
|
||||||
|
|
||||||
|
this->bitmap = NULL;
|
||||||
|
|
||||||
|
if (fileExt == NULL)
|
||||||
|
{
|
||||||
|
printf("ERROR: Invalid file name '%s' - Can't determine the file format\n", imgfile);
|
||||||
|
}
|
||||||
|
else if (strncasecmp(fileExt, ".png", strlen(fileExt)) == 0)
|
||||||
|
{
|
||||||
|
uint32_t ret = lodepng_decode24_file(&this->bitmap, &this->width, &this->height, imgfile);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
printf("ERROR: %s\n", lodepng_error_text(ret));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( (strncasecmp(fileExt, ".jpg", strlen(fileExt)) == 0) || (strncasecmp(fileExt, ".jpeg", strlen(fileExt)) == 0) )
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *fileBuff;
|
||||||
|
size_t fileSize;
|
||||||
|
|
||||||
|
fp = fopen(imgfile, "rb");
|
||||||
|
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
fileSize = ftell(fp);
|
||||||
|
fileBuff = (char *)calloc(fileSize, 1);
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
fileSize = fread(fileBuff, 1, fileSize, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
njInit();
|
||||||
|
if (!njDecode(fileBuff, fileSize))
|
||||||
|
{
|
||||||
|
this->width = njGetWidth();
|
||||||
|
this->height = njGetHeight();
|
||||||
|
/* Need to do a local copy */
|
||||||
|
|
||||||
|
this->bitmap = (uint8_t *)calloc(1, njGetImageSize());
|
||||||
|
memcpy(this->bitmap, njGetImage(), njGetImageSize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ERROR: Error while decoding the file '%s'\n", imgfile);
|
||||||
|
}
|
||||||
|
free(fileBuff);
|
||||||
|
|
||||||
|
njDone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ERROR: Can't open/find the file '%s'.\n", imgfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ERROR: File extention '%s' is not a recognized one.\n", fileExt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->bitmap == NULL)
|
||||||
|
{
|
||||||
|
printf("ABORT: Opening image file '%s' failed\n", imgfile);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->stride = BytePP * width;
|
||||||
|
}
|
||||||
|
|
||||||
Canvas::~Canvas()
|
Canvas::~Canvas()
|
||||||
{
|
{
|
||||||
if (this->bitmap != nullptr)
|
if (this->bitmap != nullptr)
|
||||||
@@ -30,28 +132,23 @@ Canvas::~Canvas()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::put_pixel(uint32_t x, uint32_t y, Colour c)
|
void Canvas::putPixel(uint32_t x, uint32_t y, Tuple c)
|
||||||
{
|
{
|
||||||
uint32_t offset = y * this->stride + x * BytePP;
|
uint32_t offset = y * this->stride + x * BytePP;
|
||||||
this->bitmap[offset + 0] = MAX(MIN(c.red() * 255, 255), 0);
|
this->bitmap[offset + 0] = MAX(MIN(c.x * 255, 255), 0);
|
||||||
this->bitmap[offset + 1] = MAX(MIN(c.green() * 255, 255), 0);
|
this->bitmap[offset + 1] = MAX(MIN(c.y * 255, 255), 0);
|
||||||
this->bitmap[offset + 2] = MAX(MIN(c.blue() * 255, 255), 0);
|
this->bitmap[offset + 2] = MAX(MIN(c.z * 255, 255), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Colour Canvas::get_pixel(uint32_t x, uint32_t y)
|
Colour Canvas::getPixel(uint32_t x, uint32_t y)
|
||||||
{
|
{
|
||||||
uint32_t offset = y * this->stride + x * BytePP;
|
uint32_t offset = y * this->stride + x * BytePP;
|
||||||
return Colour(this->bitmap[offset + 0] / 255, this->bitmap[offset + 1] / 255, this->bitmap[offset + 2] / 255);
|
return Colour(this->bitmap[offset + 0] / 255.0, this->bitmap[offset + 1] / 255.0, this->bitmap[offset + 2] / 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::SaveAsPNG(const char *filename)
|
bool Canvas::SaveAsPNG(const char *filename)
|
||||||
{
|
{
|
||||||
uint32_t ret = lodepng_encode24_file(filename, this->bitmap, this->width, this->height);
|
uint32_t ret = lodepng_encode24_file(filename, this->bitmap, this->width, this->height);
|
||||||
|
|
||||||
if (ret > 0)
|
|
||||||
{
|
|
||||||
printf("lodepng_encode_file returned %d!\n", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret == 0;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
134
source/include/boundingbox.h
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Bounding box header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_BOUNDINGBOX_H
|
||||||
|
#define DORAYME_BOUNDINGBOX_H
|
||||||
|
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct BoundingBox
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool isReset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Tuple min;
|
||||||
|
Tuple max;
|
||||||
|
|
||||||
|
BoundingBox() : min(INFINITY, INFINITY, INFINITY, 1.0), max(-INFINITY, -INFINITY, -INFINITY, 1.0), isReset(true) { };
|
||||||
|
BoundingBox(Tuple min, Tuple max) : min(min), max(max), isReset(false) { };
|
||||||
|
|
||||||
|
void operator|(const BoundingBox &b) {
|
||||||
|
isReset = false;
|
||||||
|
|
||||||
|
if (this->min.x > b.min.x) { this->min.x = b.min.x; }
|
||||||
|
if (this->min.y > b.min.y) { this->min.y = b.min.y; }
|
||||||
|
if (this->min.z > b.min.z) { this->min.z = b.min.z; }
|
||||||
|
|
||||||
|
if (this->max.x < b.max.x) { this->max.x = b.max.x; }
|
||||||
|
if (this->max.y < b.max.y) { this->max.y = b.max.y; }
|
||||||
|
if (this->max.z < b.max.z) { this->max.z = b.max.z; }
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator|(const Tuple &b) {
|
||||||
|
isReset = false;
|
||||||
|
|
||||||
|
if (this->min.x > b.x) { this->min.x = b.x; }
|
||||||
|
if (this->min.y > b.y) { this->min.y = b.y; }
|
||||||
|
if (this->min.z > b.z) { this->min.z = b.z; }
|
||||||
|
|
||||||
|
if (this->max.x < b.x) { this->max.x = b.x; }
|
||||||
|
if (this->max.y < b.y) { this->max.y = b.y; }
|
||||||
|
if (this->max.z < b.z) { this->max.z = b.z; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool haveFiniteBounds() { return this->min.isRepresentable() && this->max.isRepresentable(); };
|
||||||
|
|
||||||
|
bool fitsIn(const BoundingBox &other) {
|
||||||
|
bool fits = true;
|
||||||
|
|
||||||
|
if (this->min.x > other.min.x) { fits = false; }
|
||||||
|
if (this->min.y > other.min.y) { fits = false; }
|
||||||
|
if (this->min.z > other.min.z) { fits = false; }
|
||||||
|
|
||||||
|
if (this->max.x < other.max.x) { fits = false; }
|
||||||
|
if (this->max.y < other.max.y) { fits = false; }
|
||||||
|
if (this->max.z < other.max.z) { fits = false; }
|
||||||
|
|
||||||
|
return fits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkAxis(double axeOrigin, double axeDirection, double xMin, double xMax, double *axeMin, double *axeMax)
|
||||||
|
{
|
||||||
|
double tMinNumerator = (xMin - axeOrigin);
|
||||||
|
double tMaxNumerator = (xMax - axeOrigin);
|
||||||
|
|
||||||
|
if (fabs(axeDirection) >= getEpsilon())
|
||||||
|
{
|
||||||
|
*axeMin = tMinNumerator / axeDirection;
|
||||||
|
*axeMax = tMaxNumerator / axeDirection;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*axeMin = tMinNumerator * INFINITY;
|
||||||
|
*axeMax = tMaxNumerator * INFINITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*axeMin > *axeMax)
|
||||||
|
{
|
||||||
|
double swap = *axeMax;
|
||||||
|
*axeMax = *axeMin;
|
||||||
|
*axeMin = swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
this->isReset = true;
|
||||||
|
min.x = min.y = min.z = INFINITY;
|
||||||
|
max.x = max.y = max.z = -INFINITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty() { return this->isReset; };
|
||||||
|
|
||||||
|
bool intesectMe(Ray r) {
|
||||||
|
|
||||||
|
double xtMin, xtMax, ytMin, ytMax, ztMin, ztMax;
|
||||||
|
double tMin, tMax;
|
||||||
|
|
||||||
|
this->checkAxis(r.origin.x, r.direction.x, this->min.x, this->max.x, &xtMin, &xtMax);
|
||||||
|
this->checkAxis(r.origin.y, r.direction.y, this->min.y, this->max.y, &ytMin, &ytMax);
|
||||||
|
this->checkAxis(r.origin.z, r.direction.z, this->min.z, this->max.z, &ztMin, &ztMax);
|
||||||
|
|
||||||
|
tMin = max3(xtMin, ytMin, ztMin);
|
||||||
|
tMax = min3(xtMax, ytMax, ztMax);
|
||||||
|
|
||||||
|
if (tMin <= tMax)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.addDiscardedIntersect();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
Tuple t = this->min;
|
||||||
|
fprintf(fp, "\"min\": { \"x\": %f, \"y\": %f, \"z\": %f}, \n",
|
||||||
|
t.x, t.y, t.z);
|
||||||
|
t = this->max;
|
||||||
|
fprintf(fp, "\"max\": { \"x\": %f, \"y\": %f, \"z\": %f}, \n",
|
||||||
|
t.x, t.y, t.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_BOUNDINGBOX_H */
|
||||||
47
source/include/camera.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Camera header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_CAMERA_H
|
||||||
|
#define DORAYME_CAMERA_H
|
||||||
|
|
||||||
|
#include <matrix.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <canvas.h>
|
||||||
|
#include <world.h>
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double halfWidth;
|
||||||
|
double halfHeight;
|
||||||
|
public:
|
||||||
|
double focalDistance;
|
||||||
|
double apertureSize;
|
||||||
|
uint32_t rayCount;
|
||||||
|
|
||||||
|
uint32_t verticalSize;
|
||||||
|
uint32_t horizontalSize;
|
||||||
|
double fieldOfView;
|
||||||
|
double pixelSize;
|
||||||
|
Matrix transformMatrix;
|
||||||
|
Matrix inverseTransform;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Camera(uint32_t hsize, uint32_t vsize, double fov);
|
||||||
|
void setFocal(double focal, double aperture, uint32_t rayCount) {
|
||||||
|
this->focalDistance = focal;
|
||||||
|
this->apertureSize = aperture;
|
||||||
|
this->rayCount = rayCount;
|
||||||
|
}
|
||||||
|
void setTransform(Matrix transform);
|
||||||
|
Ray rayForPixel(uint32_t pixelX, uint32_t pixelY, double horzOffset = 0, double vertOffset = 0);
|
||||||
|
Canvas render(World w, uint32_t depth = 5);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_CAMERA_H */
|
||||||
@@ -21,10 +21,14 @@ public:
|
|||||||
uint32_t width, height;
|
uint32_t width, height;
|
||||||
|
|
||||||
Canvas(uint32_t width, uint32_t height);
|
Canvas(uint32_t width, uint32_t height);
|
||||||
|
Canvas(const Canvas *c);
|
||||||
|
Canvas(const Canvas &c);
|
||||||
|
Canvas(const char *imgfile);
|
||||||
|
|
||||||
~Canvas();
|
~Canvas();
|
||||||
|
|
||||||
void put_pixel(uint32_t x, uint32_t y, Colour c);
|
void putPixel(uint32_t x, uint32_t y, Tuple c);
|
||||||
Colour get_pixel(uint32_t x, uint32_t y);
|
Colour getPixel(uint32_t x, uint32_t y);
|
||||||
|
|
||||||
bool SaveAsPNG(const char *filename);
|
bool SaveAsPNG(const char *filename);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#ifndef DORAYME_COLOUR_H
|
#ifndef DORAYME_COLOUR_H
|
||||||
#define DORAYME_COLOUR_H
|
#define DORAYME_COLOUR_H
|
||||||
|
|
||||||
#include <tuples.h>
|
#include <tuple.h>
|
||||||
|
|
||||||
class Colour : public Tuple
|
class Colour : public Tuple
|
||||||
{
|
{
|
||||||
|
|||||||
39
source/include/cone.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Cone header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_CONE_H
|
||||||
|
#define DORAYME_CONE_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Cone : public Shape {
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
bool checkCap(Ray r, double t, double y);
|
||||||
|
void intersectCaps(Ray r, Intersect &xs);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isClosed;
|
||||||
|
double minCap;
|
||||||
|
double maxCap;
|
||||||
|
|
||||||
|
Cone() : minCap(-INFINITY), maxCap(INFINITY), isClosed(false), Shape(Shape::CONE) { stats.addCone(); };
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
bool haveFiniteBounds() { return !(isinf(this->minCap) || isinf(this->maxCap)); };
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_CONE_H */
|
||||||
56
source/include/csg.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* CSG header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_CSG_H
|
||||||
|
#define DORAYME_CSG_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
|
||||||
|
class CSG : public Shape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum OperationType
|
||||||
|
{
|
||||||
|
UNION,
|
||||||
|
DIFFERENCE,
|
||||||
|
INTERSECTION
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Shape *left;
|
||||||
|
Shape *right;
|
||||||
|
OperationType operation;
|
||||||
|
BoundingBox bounds;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
|
||||||
|
bool intersectionAllowed(bool leftHit, bool inLeft, bool inRight);
|
||||||
|
|
||||||
|
void filterIntersections(Intersect &xs, Intersect &ret);
|
||||||
|
|
||||||
|
void updateBoundingBox();
|
||||||
|
BoundingBox getBounds();
|
||||||
|
|
||||||
|
public:
|
||||||
|
CSG(OperationType operation, Shape *left, Shape *right);
|
||||||
|
|
||||||
|
void intersect(Ray &r, Intersect &xs);
|
||||||
|
|
||||||
|
bool includes(Shape *b);
|
||||||
|
|
||||||
|
void updateTransform();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_CSG_H */
|
||||||
32
source/include/cube.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Cube header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_CUBE_H
|
||||||
|
#define DORAYME_CUBE_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Cube : public Shape {
|
||||||
|
protected:
|
||||||
|
void checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax);
|
||||||
|
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Cube() : Shape(Shape::CUBE) { stats.addCube(); };
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_CUBE_H */
|
||||||
41
source/include/cylinder.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Cylinder header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_CYLINDER_H
|
||||||
|
#define DORAYME_CYLINDER_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Cylinder : public Shape {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
bool checkCap(Ray r, double t);
|
||||||
|
void intersectCaps(Ray r, Intersect &xs);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isClosed;
|
||||||
|
double minCap;
|
||||||
|
double maxCap;
|
||||||
|
|
||||||
|
Cylinder() : minCap(-INFINITY), maxCap(INFINITY), isClosed(false), Shape(Shape::CYLINDER) { stats.addCylinder(); };
|
||||||
|
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
bool haveFiniteBounds() { return !(isinf(this->minCap) || isinf(this->maxCap)); };
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DORAYME_CYLINDER_H
|
||||||
69
source/include/group.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Group header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_GROUP_H
|
||||||
|
#define DORAYME_GROUP_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* TODO: Add a way to force(?) material from group to be applied on childs */
|
||||||
|
|
||||||
|
class Group : public Shape
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint32_t allocatedObjectCount;
|
||||||
|
Shape* *objectList;
|
||||||
|
uint32_t objectCount;
|
||||||
|
|
||||||
|
uint32_t allocatedUnboxableObjectCount;
|
||||||
|
Shape* *unboxableObjectList;
|
||||||
|
uint32_t unboxableObjectCount;
|
||||||
|
|
||||||
|
char name[32 + 1];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
BoundingBox bounds;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isEmpty();
|
||||||
|
|
||||||
|
void addObject(Shape *s);
|
||||||
|
void removeObject(Shape *s);
|
||||||
|
|
||||||
|
Shape *operator[](const int p) { return this->getObject(p); };
|
||||||
|
Shape *getObject(const int p) { return this->objectList[p]; };
|
||||||
|
Shape *getUnboxable(const int p) { return this->unboxableObjectList[p]; };
|
||||||
|
|
||||||
|
void intersect(Ray &r, Intersect &xs);
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
BoundingBox getBounds();
|
||||||
|
|
||||||
|
void updateBoundingBox();
|
||||||
|
void updateTransform();
|
||||||
|
|
||||||
|
bool includes(Shape *b);
|
||||||
|
|
||||||
|
uint32_t getObjectCount() { return this->objectCount; };
|
||||||
|
uint32_t getUnboxableCount() { return this->unboxableObjectCount; };
|
||||||
|
|
||||||
|
Group(const char *name = nullptr);
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
|
||||||
|
void setBounds(BoundingBox &bb) { this->bounds | bb; };
|
||||||
|
|
||||||
|
const char *getName() { return this->name; };
|
||||||
|
|
||||||
|
void dumpMe(FILE * fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_GROUP_H */
|
||||||
31
source/include/intersect.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Intersect header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_INTERSECT_H
|
||||||
|
#define DORAYME_INTERSECT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <intersection.h>
|
||||||
|
|
||||||
|
class Intersect
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Intersection **list;
|
||||||
|
uint32_t num;
|
||||||
|
uint32_t allocated;
|
||||||
|
public:
|
||||||
|
Intersect();
|
||||||
|
~Intersect();
|
||||||
|
void reset();
|
||||||
|
void add(Intersection i);
|
||||||
|
int count() { return this->num; };
|
||||||
|
Intersection operator[](const int p) { return *this->list[p]; }
|
||||||
|
Intersection hit();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_INTERSECT_H */
|
||||||
63
source/include/intersection.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Intersection header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_INTERSECTION_H
|
||||||
|
#define DORAYME_INTERSECTION_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <material.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
class Intersect;
|
||||||
|
|
||||||
|
struct Computation
|
||||||
|
{
|
||||||
|
Computation(Shape *object, double t, Tuple point, Tuple eyev, Tuple normalv, Tuple overHitP,
|
||||||
|
bool inside, Tuple reflectV = Vector(0, 0, 0), double n1 = 1.0, double n2 = 1.0,
|
||||||
|
Tuple underHitP = Point(0, 0, 0), Material *objMat = nullptr) :
|
||||||
|
object(object), t(t), hitPoint(point), eyeVector(eyev), normalVector(normalv), inside(inside),
|
||||||
|
overHitPoint(overHitP), underHitPoint(underHitP), reflectVector(reflectV), n1(n1), n2(n2), material(objMat) { };
|
||||||
|
|
||||||
|
double schlick();
|
||||||
|
|
||||||
|
Shape *object;
|
||||||
|
double t;
|
||||||
|
Tuple hitPoint;
|
||||||
|
Tuple overHitPoint;
|
||||||
|
Tuple underHitPoint;
|
||||||
|
Tuple eyeVector;
|
||||||
|
Tuple normalVector;
|
||||||
|
Tuple reflectVector;
|
||||||
|
|
||||||
|
Material *material;
|
||||||
|
|
||||||
|
double n1;
|
||||||
|
double n2;
|
||||||
|
|
||||||
|
bool inside;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Intersection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
double t;
|
||||||
|
Shape *object;
|
||||||
|
double u, v;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Intersection(double t, Shape *object, double u = NAN, double v = NAN) : t(t), object(object), u(u), v(v) { stats.addIntersection(); };
|
||||||
|
bool nothing() { return (this->object == nullptr); };
|
||||||
|
|
||||||
|
Computation prepareComputation(Ray r, Intersect *xs = nullptr);
|
||||||
|
|
||||||
|
bool operator==(const Intersection &b) const { return ((this->t == b.t) && (this->object == b.object)); };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_INTERSECTION_H */
|
||||||
67
source/include/light.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Light header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_LIGHT_H
|
||||||
|
#define DORAYME_LIGHT_H
|
||||||
|
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <colour.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <sequence.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class World;
|
||||||
|
|
||||||
|
enum LightType
|
||||||
|
{
|
||||||
|
POINT_LIGHT = 0,
|
||||||
|
AREA_LIGHT,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Light
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Colour intensity;
|
||||||
|
Tuple position;
|
||||||
|
LightType type;
|
||||||
|
|
||||||
|
/* For area light */
|
||||||
|
Tuple corner;
|
||||||
|
Tuple uVec;
|
||||||
|
Tuple vVec;
|
||||||
|
uint32_t samples;
|
||||||
|
uint32_t uSteps;
|
||||||
|
uint32_t vSteps;
|
||||||
|
bool jitter;
|
||||||
|
Sequence jitterBy;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Light(LightType type = POINT_LIGHT, Tuple position=Point(0, 0, 0),
|
||||||
|
Colour intensity=Colour(1, 1, 1)) : type(type), position(position), intensity(intensity)
|
||||||
|
{ stats.addLight(); };
|
||||||
|
Light(LightType type, Tuple corner, Tuple fullUVec, uint32_t uSteps, Tuple fullVVec, uint32_t vSteps,
|
||||||
|
Colour intensity, bool jitter = false): type(type), corner(corner), uVec(fullUVec / uSteps), uSteps(uSteps),
|
||||||
|
vVec(fullVVec / vSteps), vSteps(vSteps), intensity(intensity), jitter(jitter)
|
||||||
|
{
|
||||||
|
this->samples = this->vSteps * this->uSteps;
|
||||||
|
this->position = this->corner + ((fullUVec + fullVVec) / 2);
|
||||||
|
stats.addLight();
|
||||||
|
};
|
||||||
|
double intensityAt(World &w, Tuple point);
|
||||||
|
|
||||||
|
bool operator==(const Light &b) const { return this->intensity == b.intensity &&
|
||||||
|
this->position == b.position &&
|
||||||
|
this->type == b.type; };
|
||||||
|
|
||||||
|
Tuple pointOnLight(uint32_t u, uint32_t v);
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_LIGHT_H */
|
||||||
120
source/include/list.h
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* List header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_LIST_H
|
||||||
|
#define DORAYME_LIST_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
|
||||||
|
struct ChainList
|
||||||
|
{
|
||||||
|
Shape *shape;
|
||||||
|
ChainList *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class List
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ChainList *head;
|
||||||
|
ChainList *tail;
|
||||||
|
uint32_t count;
|
||||||
|
public:
|
||||||
|
List() : head(nullptr), tail(nullptr), count(0) { };
|
||||||
|
~List()
|
||||||
|
{
|
||||||
|
ChainList *p = this->head;
|
||||||
|
if (p == nullptr) { return; }
|
||||||
|
|
||||||
|
/* clear up the list */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ChainList *next = p->next;
|
||||||
|
free(p);
|
||||||
|
p = next;
|
||||||
|
}
|
||||||
|
while(p != nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape *last()
|
||||||
|
{
|
||||||
|
ChainList *p = this->tail;
|
||||||
|
if (p == nullptr) { return nullptr; }
|
||||||
|
return p->shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(Shape *s)
|
||||||
|
{
|
||||||
|
ChainList *p = this->head;
|
||||||
|
if (p == nullptr) { return; }
|
||||||
|
|
||||||
|
if ((p->next == nullptr) && (p->shape == s))
|
||||||
|
{
|
||||||
|
/* First element */
|
||||||
|
this->tail = nullptr;
|
||||||
|
free(this->head);
|
||||||
|
this->head = nullptr;
|
||||||
|
this->count = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(p->next != nullptr)
|
||||||
|
{
|
||||||
|
if (p->next->shape == s)
|
||||||
|
{
|
||||||
|
ChainList *found = p->next;
|
||||||
|
|
||||||
|
p->next = p->next->next;
|
||||||
|
|
||||||
|
free(found);
|
||||||
|
|
||||||
|
if (p->next == NULL) { this->tail = p; }
|
||||||
|
|
||||||
|
this->count --;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(Shape *s)
|
||||||
|
{
|
||||||
|
ChainList *theNew = (ChainList *)calloc(1, sizeof(ChainList));
|
||||||
|
|
||||||
|
theNew->shape = s;
|
||||||
|
|
||||||
|
ChainList *p = this->tail;
|
||||||
|
this->tail = theNew;
|
||||||
|
|
||||||
|
if (p != nullptr) { p->next = theNew; }
|
||||||
|
else { this->head = theNew; } /* If the tail is empty, it mean the list IS empty. */
|
||||||
|
|
||||||
|
this->count ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty()
|
||||||
|
{
|
||||||
|
return (this->count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doesInclude(Shape *s)
|
||||||
|
{
|
||||||
|
ChainList *p = this->head;
|
||||||
|
|
||||||
|
while(p != nullptr)
|
||||||
|
{
|
||||||
|
if (p->shape == s) { return true; }
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DORAYME_LIST_H
|
||||||
57
source/include/material.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Material header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_MATERIAL_H
|
||||||
|
#define DORAYME_MATERIAL_H
|
||||||
|
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <colour.h>
|
||||||
|
#include <pattern.h>
|
||||||
|
#include <light.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
|
||||||
|
class Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Colour colour;
|
||||||
|
double ambient;
|
||||||
|
double diffuse;
|
||||||
|
double specular;
|
||||||
|
double shininess;
|
||||||
|
double reflective;
|
||||||
|
double transparency;
|
||||||
|
double emissive;
|
||||||
|
double refractiveIndex;
|
||||||
|
|
||||||
|
Pattern *pattern;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Material() : colour(Colour(1, 1, 1)), ambient(0.1), diffuse(0.9), specular(0.9), shininess(200),
|
||||||
|
reflective(0.0), transparency(0.0), emissive(0), refractiveIndex(1.0), pattern(nullptr) {};
|
||||||
|
|
||||||
|
Colour lighting(Light light, Tuple point, Tuple eyeVector, Tuple normalVector, Shape *hitObject,
|
||||||
|
double lightIntensity = 1.0);
|
||||||
|
|
||||||
|
bool operator==(const Material &b) const { return double_equal(this->ambient, b.ambient) &&
|
||||||
|
double_equal(this->diffuse, b.diffuse) &&
|
||||||
|
double_equal(this->specular, b.specular) &&
|
||||||
|
double_equal(this->shininess, b.shininess) &&
|
||||||
|
double_equal(this->reflective, b.reflective) &&
|
||||||
|
double_equal(this->transparency, b.transparency) &&
|
||||||
|
double_equal(this->emissive, b.emissive) &&
|
||||||
|
double_equal(this->refractiveIndex, b.refractiveIndex) &&
|
||||||
|
(this->colour == b.colour); };
|
||||||
|
bool operator!=(const Material &b) const { return !(*this == b); };
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DORAYME_MATERIAL_H */
|
||||||
@@ -10,7 +10,23 @@
|
|||||||
#ifndef DORAYME_MATH_HELPER_H
|
#ifndef DORAYME_MATH_HELPER_H
|
||||||
#define DORAYME_MATH_HELPER_H
|
#define DORAYME_MATH_HELPER_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
void set_equal_precision(double v);
|
void set_equal_precision(double v);
|
||||||
|
double getEpsilon();
|
||||||
bool double_equal(double a, double b);
|
bool double_equal(double a, double b);
|
||||||
|
|
||||||
#endif //DORAYME_MATH_HELPER_H
|
double deg_to_rad(double deg);
|
||||||
|
|
||||||
|
double min3(double a, double b, double c);
|
||||||
|
double max3(double a, double b, double c);
|
||||||
|
|
||||||
|
double frand();
|
||||||
|
double frandclip(double min, double max);
|
||||||
|
|
||||||
|
static double modulo(double a, double b)
|
||||||
|
{
|
||||||
|
return a - floor(a/b) * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DORAYME_MATH_HELPER_H */
|
||||||
|
|||||||
@@ -9,7 +9,17 @@
|
|||||||
#ifndef DORAYME_MATRIX_H
|
#ifndef DORAYME_MATRIX_H
|
||||||
#define DORAYME_MATRIX_H
|
#define DORAYME_MATRIX_H
|
||||||
|
|
||||||
#include <tuples.h>
|
#include <tuple.h>
|
||||||
|
|
||||||
|
/* Some **** linux distro seems to define "minor" as a macro
|
||||||
|
* and wreak havoc.
|
||||||
|
* Let's make sure we are clean here
|
||||||
|
*/
|
||||||
|
#ifdef minor
|
||||||
|
#undef minor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FastGet4(_x, _y) (this->data[4 * (_x) + (_y)])
|
||||||
|
|
||||||
class Matrix
|
class Matrix
|
||||||
{
|
{
|
||||||
@@ -19,7 +29,7 @@ protected:
|
|||||||
int size;
|
int size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Matrix(int size);
|
Matrix(int size = 4);
|
||||||
Matrix(double values[], int size);
|
Matrix(double values[], int size);
|
||||||
|
|
||||||
double get(int x, int y) const { return this->data[this->size * x + y]; };
|
double get(int x, int y) const { return this->data[this->size * x + y]; };
|
||||||
@@ -38,7 +48,12 @@ public:
|
|||||||
bool isInvertible() { return this->determinant() != 0; }
|
bool isInvertible() { return this->determinant() != 0; }
|
||||||
|
|
||||||
Matrix operator*(const Matrix &b) const;
|
Matrix operator*(const Matrix &b) const;
|
||||||
Tuple operator*(const Tuple &b) const;
|
Tuple operator*(const Tuple &b) const {
|
||||||
|
return Tuple(b.x * FastGet4(0, 0) + b.y * FastGet4(0, 1) + b.z * FastGet4(0, 2) + b.w * FastGet4(0, 3),
|
||||||
|
b.x * FastGet4(1, 0) + b.y * FastGet4(1, 1) + b.z * FastGet4(1, 2) + b.w * FastGet4(1, 3),
|
||||||
|
b.x * FastGet4(2, 0) + b.y * FastGet4(2, 1) + b.z * FastGet4(2, 2) + b.w * FastGet4(2, 3),
|
||||||
|
b.x * FastGet4(3, 0) + b.y * FastGet4(3, 1) + b.z * FastGet4(3, 2) + b.w * FastGet4(3, 3));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Matrix4: public Matrix
|
class Matrix4: public Matrix
|
||||||
|
|||||||
80
source/include/objfile.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* OBJ File header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_OBJFILE_H
|
||||||
|
#define DORAYME_OBJFILE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <group.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
|
||||||
|
class OBJFile : public Shape
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Group *baseGroup;
|
||||||
|
|
||||||
|
Group *currentGroup;
|
||||||
|
|
||||||
|
uint32_t allocatedVertexCount;
|
||||||
|
Point* *vertexList;
|
||||||
|
uint32_t vertexCount;
|
||||||
|
|
||||||
|
uint32_t allocatedVertexNormalCount;
|
||||||
|
Vector* *vertexNormalList;
|
||||||
|
uint32_t vertexNormalCount;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* Some stats */
|
||||||
|
uint32_t ignoredLines;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void addGroup(Group *group);
|
||||||
|
void addVertex(Point *vertex);
|
||||||
|
void addVertexNormal(Vector *vertexNormal);
|
||||||
|
|
||||||
|
void parseLine(char *line, uint32_t currentLine);
|
||||||
|
int execLine(int argc, char *argv[], uint32_t currentLine);
|
||||||
|
BoundingBox bounds;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OBJFile();
|
||||||
|
OBJFile(const char *filepath);
|
||||||
|
|
||||||
|
~OBJFile();
|
||||||
|
|
||||||
|
int parseOBJFile(const char *content);
|
||||||
|
|
||||||
|
/* OBJ file expect the first vertice to be 1 and not 0 */
|
||||||
|
Point vertices(uint32_t i) { return *this->vertexList[i - 1]; };
|
||||||
|
Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; };
|
||||||
|
Group *groups(const char *groupName);
|
||||||
|
void intersect(Ray &r, Intersect &xs);
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
BoundingBox getBounds();
|
||||||
|
|
||||||
|
Shape *getBaseGroup() { return this->baseGroup; };
|
||||||
|
|
||||||
|
bool includes(Shape *b);
|
||||||
|
|
||||||
|
void updateBoundingBox();
|
||||||
|
void updateTransform();
|
||||||
|
|
||||||
|
void lock();
|
||||||
|
|
||||||
|
void dumpMe(FILE * fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OBJ_DEFAULT_GROUP "_DefaultObjGroup_"
|
||||||
|
|
||||||
|
#endif /* DORAYME_OBJFILE_H */
|
||||||
38
source/include/pattern.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_PATTERN_H
|
||||||
|
#define DORAYME_PATTERN_H
|
||||||
|
|
||||||
|
#include <colour.h>
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <matrix.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
|
||||||
|
class Pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Colour a;
|
||||||
|
Colour b;
|
||||||
|
|
||||||
|
Matrix transformMatrix;
|
||||||
|
Matrix inverseTransform;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Pattern(Colour a, Colour b);
|
||||||
|
|
||||||
|
virtual Colour patternAt(Tuple point) = 0;
|
||||||
|
virtual void dumpMe(FILE *fp);
|
||||||
|
|
||||||
|
void setTransform(Matrix transform);
|
||||||
|
Colour patternAtObject(Shape *object, Tuple point);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_PATTERN_H */
|
||||||
26
source/include/plane.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Plane header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_PLANE_H
|
||||||
|
#define DORAYME_PLANE_H
|
||||||
|
|
||||||
|
#include <renderstat.h>
|
||||||
|
|
||||||
|
class Plane : public Shape
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Plane() : Shape(Shape::PLANE) { stats.addPlane(); };
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
bool haveFiniteBounds() { return false; };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DORAYME_PLANE_H
|
||||||
26
source/include/ray.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Ray header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_RAY_H
|
||||||
|
#define DORAYME_RAY_H
|
||||||
|
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
|
||||||
|
class Ray
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Tuple direction;
|
||||||
|
Tuple origin;
|
||||||
|
|
||||||
|
Ray(Tuple origin, Tuple direction) : origin(origin), direction(direction) { stats.addRay(); };
|
||||||
|
|
||||||
|
Tuple position(double t) { return this->origin + this->direction * t; };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_RAY_H */
|
||||||
107
source/include/renderstat.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Render statistics header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_RENDERSTAT_H
|
||||||
|
#define DORAYME_RENDERSTAT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class RenderStats
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint64_t coneCount; /* Total number of cones */
|
||||||
|
uint64_t cylinderCount; /* Total number of cylinder */
|
||||||
|
uint64_t cubeCount; /* Total number of cubes */
|
||||||
|
uint64_t groupCount; /* Total number of groups */
|
||||||
|
uint64_t lightCount; /* Total number of light */
|
||||||
|
uint64_t planeCount; /* Total number of plane */
|
||||||
|
uint64_t sphereCount; /* Total number of sphere */
|
||||||
|
uint64_t triangleCount; /* Total number of triangle */
|
||||||
|
uint64_t smoothTriangleCount; /* Total number of smooth triangle */
|
||||||
|
uint64_t objfileCount; /* Total number of OBJ File */
|
||||||
|
uint64_t csgCount; /* Total number of CSG */
|
||||||
|
|
||||||
|
uint64_t pixelCount; /* Total number of rendered pixels */
|
||||||
|
uint64_t rayCount; /* Total number of rays object created */
|
||||||
|
uint64_t rayCasted; /* Total number of rays actually casted */
|
||||||
|
uint64_t lightRayEmitedCount; /* Total number of ray launched for light tests */
|
||||||
|
uint64_t reflectionRayCount; /* Total number of reflection ray launched */
|
||||||
|
uint64_t refractedRayCount; /* Total number of refracted ray launched */
|
||||||
|
uint64_t intersectCount; /* Total number of intersect object created */
|
||||||
|
uint64_t intersectionCount; /* Total number of intersection for all casted rays, including light and reflections */
|
||||||
|
uint64_t reallocCallCount; /* Total number of time realloc being called */
|
||||||
|
uint64_t mallocCallCount; /* Total number of time malloc/calloc being called */
|
||||||
|
uint64_t discardedIntersectCount; /* Number of time a bounding box check said "no need to test me" */
|
||||||
|
uint64_t maxDepthAttained; /* Report the lowest depth attained during ray recursion */
|
||||||
|
uint64_t maxIntersectOnARay; /* Biggest intersect done */
|
||||||
|
|
||||||
|
public:
|
||||||
|
RenderStats() : coneCount(0), cylinderCount(0), cubeCount(0), groupCount(0), lightCount(0), planeCount(0), sphereCount(0), triangleCount(0),
|
||||||
|
pixelCount(0), rayCount(0), lightRayEmitedCount(0), reflectionRayCount(0), refractedRayCount(0),
|
||||||
|
intersectCount(0), intersectionCount(0), reallocCallCount(0), mallocCallCount(0), smoothTriangleCount(0),
|
||||||
|
discardedIntersectCount(0), maxDepthAttained(UINT64_MAX), maxIntersectOnARay(0), objfileCount(0),
|
||||||
|
csgCount(0), rayCasted(0) {};
|
||||||
|
#ifdef RENDER_STATS
|
||||||
|
void addCone();
|
||||||
|
void addCylinder();
|
||||||
|
void addCube();
|
||||||
|
void addGroup();
|
||||||
|
void addLight();
|
||||||
|
void addPlane();
|
||||||
|
void addSphere();
|
||||||
|
void addCsg();
|
||||||
|
void addOBJFile();
|
||||||
|
void addTriangle();
|
||||||
|
void addSmoothTriangle();
|
||||||
|
void printStats();
|
||||||
|
void addPixel();
|
||||||
|
void addRay();
|
||||||
|
void addCastedRay();
|
||||||
|
void addLightRay();
|
||||||
|
void addReflectRay();
|
||||||
|
void addRefractRay();
|
||||||
|
void addIntersection();
|
||||||
|
void addDiscardedIntersect();
|
||||||
|
void setMaxDepth(uint32_t depth);
|
||||||
|
void addIntersect();
|
||||||
|
void addMalloc();
|
||||||
|
void addRealloc();
|
||||||
|
void setMaxIntersect(uint32_t count);
|
||||||
|
#else
|
||||||
|
static void addCone() {};
|
||||||
|
static void addCylinder() {};
|
||||||
|
static void addCube() {};
|
||||||
|
static void addGroup() {};
|
||||||
|
static void addLight() {};
|
||||||
|
static void addPlane() {};
|
||||||
|
static void addSphere() {};
|
||||||
|
static void addTriangle() {};
|
||||||
|
static void addSmoothTriangle() {};
|
||||||
|
static void printStats() {};
|
||||||
|
static void addPixel() {};
|
||||||
|
static void addRay() {};
|
||||||
|
static void addCastedRay() {};
|
||||||
|
static void addLightRay() {};
|
||||||
|
static void addReflectRay() {};
|
||||||
|
static void addRefractRay() {};
|
||||||
|
static void addIntersection() {};
|
||||||
|
static void addDiscardedIntersect() {};
|
||||||
|
static void setMaxDepth(uint32_t depth) {};
|
||||||
|
static void addIntersect() {};
|
||||||
|
static void addMalloc() {};
|
||||||
|
static void addRealloc() {};
|
||||||
|
static void setMaxIntersect(uint32_t count) {};
|
||||||
|
static void addOBJFile() {};
|
||||||
|
static void addCsg() {};
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern RenderStats stats;
|
||||||
|
|
||||||
|
#endif /* DORAYME_RENDERSTAT_H */
|
||||||
27
source/include/sequence.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Sequence header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_SEQUENCE_H
|
||||||
|
#define DORAYME_SEQUENCE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class Sequence
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double *list;
|
||||||
|
uint32_t listPos;
|
||||||
|
uint32_t listSize;
|
||||||
|
public:
|
||||||
|
Sequence();
|
||||||
|
Sequence(double *list, uint32_t listSize);
|
||||||
|
double next();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DORAYME_SEQUENCE_H */
|
||||||
111
source/include/shape.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Object header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_SHAPE_H
|
||||||
|
#define DORAYME_SHAPE_H
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <matrix.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
#include <material.h>
|
||||||
|
#include <boundingbox.h>
|
||||||
|
|
||||||
|
/* Base class for all object that can be presented in the world */
|
||||||
|
class Shape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ShapeType
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
SPHERE,
|
||||||
|
PLANE,
|
||||||
|
CUBE,
|
||||||
|
CYLINDER,
|
||||||
|
CONE,
|
||||||
|
GROUP,
|
||||||
|
TRIANGLE,
|
||||||
|
OBJFILE,
|
||||||
|
SMOOTHTRIANGLE,
|
||||||
|
CSG,
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ShapeType type;
|
||||||
|
Matrix localTransformMatrix;
|
||||||
|
bool locked;
|
||||||
|
uint64_t objectId;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void localIntersect(Ray r, Intersect &xs) = 0;
|
||||||
|
virtual Tuple localNormalAt(Tuple point, Intersection *hit) = 0;
|
||||||
|
|
||||||
|
static uint64_t newObjectId();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Matrix transformMatrix;
|
||||||
|
Matrix inverseTransform;
|
||||||
|
Matrix transposedInverseTransform;
|
||||||
|
|
||||||
|
Material material;
|
||||||
|
bool dropShadow;
|
||||||
|
Shape *parent;
|
||||||
|
bool materialSet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Shape(ShapeType = Shape::NONE);
|
||||||
|
|
||||||
|
ShapeType getType() { return this->type; };
|
||||||
|
|
||||||
|
virtual void intersect(Ray &r, Intersect &xs) { this->localIntersect(this->invTransform(r), xs); };
|
||||||
|
Tuple normalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
uint64_t getObjectId() { return this->objectId; };
|
||||||
|
void setObjectId(uint64_t oid) { this->objectId = oid; };
|
||||||
|
|
||||||
|
/* Bounding box points are always world value */
|
||||||
|
virtual BoundingBox getLocalBounds();
|
||||||
|
virtual BoundingBox getBounds();
|
||||||
|
virtual bool haveFiniteBounds() { return true; };
|
||||||
|
|
||||||
|
virtual void updateTransform();
|
||||||
|
|
||||||
|
virtual bool includes(Shape *b) { return this == b; };
|
||||||
|
|
||||||
|
virtual void dumpMe(FILE *fp);
|
||||||
|
|
||||||
|
/* When an object is locked, the matrix transformation and bounding box can't be updated. This is
|
||||||
|
* usefull to move object between group without changing the real hierarchy between them.
|
||||||
|
* It will also not change the parent member.
|
||||||
|
* This is supposed to be used only before a render is going to start so we can optimise the
|
||||||
|
* way the object are stored to prefer lots of un-needed intersections.
|
||||||
|
*/
|
||||||
|
virtual void lock() { this->locked = true; };
|
||||||
|
|
||||||
|
Tuple worldToObject(Tuple point) { return this->inverseTransform * point; };
|
||||||
|
Tuple objectToWorld(Tuple point) { return this->transformMatrix * point; };
|
||||||
|
Tuple normalToWorld(Tuple normalVector);
|
||||||
|
|
||||||
|
void setParent(Shape *parent) { if (!this->locked) { this->parent = parent; };};
|
||||||
|
|
||||||
|
void setTransform(Matrix transform);
|
||||||
|
void setMaterial(Material material) { this->material = material; this->materialSet = true; };
|
||||||
|
Material *getMaterial();
|
||||||
|
Ray transform(Ray &r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
|
||||||
|
Ray invTransform(Ray &r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); };
|
||||||
|
|
||||||
|
bool operator==(const Shape &b) const { return this->material == b.material &&
|
||||||
|
this->type == b.type &&
|
||||||
|
this->transformMatrix == b.transformMatrix; };
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_SHAPE_H */
|
||||||
30
source/include/smoothtriangle.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Smooth Triangle header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_SMOOTHTRIANGLE_H
|
||||||
|
#define DORAYME_SMOOTHTRIANGLE_H
|
||||||
|
|
||||||
|
#include <triangle.h>
|
||||||
|
|
||||||
|
class SmoothTriangle : public Triangle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector n1;
|
||||||
|
Vector n2;
|
||||||
|
Vector n3;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SmoothTriangle(Point p1, Point p2, Point p3, Vector n1, Vector n2, Vector n3);
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_SMOOTHTRIANGLE_H */
|
||||||
39
source/include/sphere.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Sphere header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_SPHERE_H
|
||||||
|
#define DORAYME_SPHERE_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Sphere : public Shape
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Sphere() : Shape(Shape::SPHERE) { stats.addSphere(); };
|
||||||
|
/* All sphere are at (0, 0, 0) and radius 1 in the object space */
|
||||||
|
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Mostly for test purposes */
|
||||||
|
class GlassSphere : public Sphere
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GlassSphere() : Sphere() { this->material.transparency = 1.0; this->material.refractiveIndex = 1.5; };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_SPHERE_H */
|
||||||
28
source/include/testshape.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Test shape header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_TESTSHAPE_H
|
||||||
|
#define DORAYME_TESTSHAPE_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <tuple.h>
|
||||||
|
|
||||||
|
class TestShape : public Shape
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ray localRay;
|
||||||
|
|
||||||
|
TestShape();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DORAYME_TESTSHAPE_H
|
||||||
26
source/include/transformation.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Transformation header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_TRANSFORMATION_H
|
||||||
|
#define DORAYME_TRANSFORMATION_H
|
||||||
|
|
||||||
|
#include <matrix.h>
|
||||||
|
|
||||||
|
Matrix translation(double x, double y, double z);
|
||||||
|
|
||||||
|
Matrix scaling(double x, double y, double z);
|
||||||
|
|
||||||
|
Matrix rotationX(double angle);
|
||||||
|
Matrix rotationY(double angle);
|
||||||
|
Matrix rotationZ(double angle);
|
||||||
|
|
||||||
|
Matrix shearing(double Xy, double Xx, double Yx, double Yz, double Zx, double Zy);
|
||||||
|
|
||||||
|
Matrix viewTransform(Tuple from, Tuple to, Tuple up);
|
||||||
|
|
||||||
|
#endif /* DORAYME_TRANSFORMATION_H */
|
||||||
34
source/include/triangle.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Triangle header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_TRIANGLE_H
|
||||||
|
#define DORAYME_TRIANGLE_H
|
||||||
|
|
||||||
|
#include <shape.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Triangle : public Shape
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Tuple p1, p2, p3;
|
||||||
|
Tuple e1, e2;
|
||||||
|
Tuple normal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Triangle(Point p1, Point p2, Point p3);
|
||||||
|
BoundingBox getLocalBounds();
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_TRIANGLE_H */
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
* Copyright (c) 2020 986-Studio.
|
* Copyright (c) 2020 986-Studio.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef DORAYME_TUPLES_H
|
#ifndef DORAYME_TUPLE_H
|
||||||
#define DORAYME_TUPLES_H
|
#define DORAYME_TUPLE_H
|
||||||
|
|
||||||
#include <math_helper.h>
|
#include <math_helper.h>
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ public:
|
|||||||
double x, y, z, w;
|
double x, y, z, w;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Tuple() : x(0), y(0), z(0), w(0.0) {};
|
||||||
Tuple(double x, double y, double z) : x(x), y(y), z(z), w(0.0) {};
|
Tuple(double x, double y, double z) : x(x), y(y), z(z), w(0.0) {};
|
||||||
Tuple(double x, double y, double z, double w) : x(x), y(y), z(z), w(w) {};
|
Tuple(double x, double y, double z, double w) : x(x), y(y), z(z), w(w) {};
|
||||||
bool isPoint() { return (this->w == 1.0); };
|
bool isPoint() { return (this->w == 1.0); };
|
||||||
@@ -26,6 +27,7 @@ public:
|
|||||||
double_equal(this->y, b.y) &&
|
double_equal(this->y, b.y) &&
|
||||||
double_equal(this->z, b.z) &&
|
double_equal(this->z, b.z) &&
|
||||||
double_equal(this->w, b.w); };
|
double_equal(this->w, b.w); };
|
||||||
|
bool operator!=(const Tuple &b) const { return !(*this == b); };
|
||||||
|
|
||||||
Tuple operator+(const Tuple &b) const { return Tuple(this->x + b.x, this->y + b.y,
|
Tuple operator+(const Tuple &b) const { return Tuple(this->x + b.x, this->y + b.y,
|
||||||
this->z + b.z, this->w + b.w); };
|
this->z + b.z, this->w + b.w); };
|
||||||
@@ -37,23 +39,38 @@ public:
|
|||||||
this->z * b, this->w * b); };
|
this->z * b, this->w * b); };
|
||||||
Tuple operator/(const double &b) const { return Tuple(this->x / b, this->y / b,
|
Tuple operator/(const double &b) const { return Tuple(this->x / b, this->y / b,
|
||||||
this->z / b, this->w / b); };
|
this->z / b, this->w / b); };
|
||||||
|
bool isRepresentable();
|
||||||
|
|
||||||
|
void set(double nX, double nY, double nZ) { this->x = nX; this->y = nY; this->z = nZ; };
|
||||||
double magnitude();
|
double magnitude();
|
||||||
Tuple normalise();
|
Tuple normalise();
|
||||||
double dot(const Tuple &b);
|
|
||||||
|
double dot(const Tuple &b) {
|
||||||
|
return this->x * b.x + this->y * b.y + this->z * b.z + this->w * b.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple cross(const Tuple &b) const {
|
||||||
|
return Tuple(this->y * b.z - this->z * b.y,
|
||||||
|
this->z * b.x - this->x * b.z,
|
||||||
|
this->x * b.y - this->y * b.x,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple reflect(const Tuple &normal);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Point: public Tuple
|
class Point: public Tuple
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Point() : Tuple(0, 0, 0, 1.0) {};
|
||||||
Point(double x, double y, double z) : Tuple(x, y, z, 1.0) {};
|
Point(double x, double y, double z) : Tuple(x, y, z, 1.0) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Vector: public Tuple
|
class Vector: public Tuple
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Vector() : Tuple(0, 0, 0, 0.0) {};
|
||||||
Vector(double x, double y, double z) : Tuple(x, y, z, 0.0) {};
|
Vector(double x, double y, double z) : Tuple(x, y, z, 0.0) {};
|
||||||
Vector cross(const Vector &b) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DORAYME_TUPLES_H */
|
#endif /* DORAYME_TUPLE_H */
|
||||||
28
source/include/uv_pattern.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* UV Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_UV_PATTERN_H
|
||||||
|
#define DORAYME_UV_PATTERN_H
|
||||||
|
|
||||||
|
#include <colour.h>
|
||||||
|
|
||||||
|
class UVPattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Colour a;
|
||||||
|
Colour b;
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
|
||||||
|
UVPattern(double width, double height, Colour a, Colour b) : a(a), b(b),
|
||||||
|
width(width), height(height) {};
|
||||||
|
|
||||||
|
virtual Colour uvPatternAt(double u, double v) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_UV_PATTERN_H */
|
||||||
73
source/include/world.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* World header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_WORLD_H
|
||||||
|
#define DORAYME_WORLD_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <light.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <group.h>
|
||||||
|
#include <worldoptimiser.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class World
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32_t lightCount;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t allocatedLightCount;
|
||||||
|
Light* *lightList;
|
||||||
|
|
||||||
|
Group worldGroup;
|
||||||
|
|
||||||
|
#ifdef ENABLE_LUA_SUPPORT
|
||||||
|
lua_State *L;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
World();
|
||||||
|
~World();
|
||||||
|
|
||||||
|
void addObject(Shape *s);
|
||||||
|
void addLight(Light *l);
|
||||||
|
|
||||||
|
/* Some debug things */
|
||||||
|
bool lightIsIn(Light &l);
|
||||||
|
bool objectIsIn(Shape &s);
|
||||||
|
|
||||||
|
Shape *getObject(int i) { return this->worldGroup[i]; };
|
||||||
|
Light *getLight(int i) { return this->lightList[i]; };
|
||||||
|
|
||||||
|
uint32_t getObjectCount() { return this->worldGroup.getObjectCount(); };
|
||||||
|
uint32_t getLightCount() { return this->lightCount; };
|
||||||
|
|
||||||
|
Tuple shadeHit(Computation comps, uint32_t depthCount = 4);
|
||||||
|
Tuple colourAt(Ray r, uint32_t depthCount = 4);
|
||||||
|
bool isShadowed(Tuple point, Tuple lightPosition);
|
||||||
|
|
||||||
|
Colour reflectColour(Computation comps, uint32_t depthCount = 4);
|
||||||
|
Colour refractedColour(Computation comps, uint32_t depthCount = 4);
|
||||||
|
|
||||||
|
void intersect(Ray &r, Intersect &xs);
|
||||||
|
|
||||||
|
void finalise(WorldOptimiser &opt);
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_WORLD_H */
|
||||||
53
source/include/worldbuilder.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Worldbuilder header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_WORLDBUILDER_H
|
||||||
|
#define DORAYME_WORLDBUILDER_H
|
||||||
|
|
||||||
|
#include <world.h>
|
||||||
|
#include <camera.h>
|
||||||
|
|
||||||
|
/* Let's keep a single header for now, will see later */
|
||||||
|
|
||||||
|
class DefaultWorld : public World
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DefaultWorld();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Not implemented yet */
|
||||||
|
class Hw3File : public World
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Matrix transformStack[50];
|
||||||
|
uint32_t transStackCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
double currentAmbient;
|
||||||
|
double currentShininess;
|
||||||
|
double currentSpecular;
|
||||||
|
double currentDiffuse;
|
||||||
|
double currentEmission;
|
||||||
|
double currentReflective;
|
||||||
|
double currentTransparency;
|
||||||
|
double currentRefIndex;
|
||||||
|
|
||||||
|
Colour currentColour;
|
||||||
|
Matrix cam;
|
||||||
|
double camFoV;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Matrix getTransformMatrix();
|
||||||
|
void popTransformMatrix();
|
||||||
|
void pushTransformMatrix();
|
||||||
|
void applyTransformMatrix(Matrix t);
|
||||||
|
|
||||||
|
Hw3File(const char *filename);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_WORLDBUILDER_H */
|
||||||
51
source/include/worldoptimiser.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* World optimiser header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_WORLDOPTIMISER_H
|
||||||
|
#define DORAYME_WORLDOPTIMISER_H
|
||||||
|
|
||||||
|
#include <group.h>
|
||||||
|
|
||||||
|
/* World Optimiser subclasses will created move objects around to try to optimise the raytrace of the world, to
|
||||||
|
* have as least as possible object to intersect per ray.
|
||||||
|
* This class is abstract to we can implement different type and change at runtime or build time
|
||||||
|
*/
|
||||||
|
class WorldOptimiser
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Group *root;
|
||||||
|
void moveInfiniteObjects(Shape *s = nullptr);
|
||||||
|
void moveAllObjects(Shape *s = nullptr);
|
||||||
|
public:
|
||||||
|
void setRoot(Group *root) { this->root = root; };
|
||||||
|
virtual void run() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NoWorldOptimisation : public WorldOptimiser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void run() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class BVHOptimisation : public WorldOptimiser
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void makeTree(Group *leaf, int depth = 0);
|
||||||
|
public:
|
||||||
|
void run();
|
||||||
|
};
|
||||||
|
|
||||||
|
class OctreeOptimisation : public WorldOptimiser
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void makeTree(Group *leaf, int depth = 0);
|
||||||
|
public:
|
||||||
|
void run();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_WORLDOPTIMISER_H */
|
||||||
105
source/intersect.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Intersect implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
#include <intersect.h>
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
|
||||||
|
#define MIN_ALLOC (2)
|
||||||
|
|
||||||
|
/* TODO: Memory allocation, even if using standard calloc/realloc have a huge impact on performances. need to find a way
|
||||||
|
* to reuse the intersect object without reallocating from scratch all the time. We use a lot of Intersect objects as
|
||||||
|
* there is at least 2 per ray (one for Ray intersect object, one object per light)
|
||||||
|
*/
|
||||||
|
|
||||||
|
Intersect::Intersect()
|
||||||
|
{
|
||||||
|
this->allocated = MIN_ALLOC;
|
||||||
|
this->list = (Intersection **)calloc(sizeof(Intersection *), MIN_ALLOC);
|
||||||
|
if (this->list != nullptr)
|
||||||
|
{
|
||||||
|
stats.addMalloc();
|
||||||
|
stats.addIntersect();
|
||||||
|
this->num = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ABORT: Allocation error [%s]!\n", __FUNCTION__);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Intersect::~Intersect()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < this->num; i++)
|
||||||
|
{
|
||||||
|
if (this->list[i] != nullptr)
|
||||||
|
{
|
||||||
|
delete this->list[i];
|
||||||
|
this->list[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Free stuff */
|
||||||
|
if (this->list != nullptr)
|
||||||
|
{
|
||||||
|
free(this->list);
|
||||||
|
this->list = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Intersect::reset()
|
||||||
|
{
|
||||||
|
this->num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Intersect::add(Intersection i)
|
||||||
|
{
|
||||||
|
Intersection *x;
|
||||||
|
int j, k;
|
||||||
|
|
||||||
|
if ((this->num + 1) > this->allocated)
|
||||||
|
{
|
||||||
|
this->allocated *= 2;
|
||||||
|
stats.addRealloc();
|
||||||
|
this->list = (Intersection **)realloc(this->list, sizeof(Intersection *) * this->allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->list[this->num++] = new Intersection(i.t, i.object, i.u, i.v);
|
||||||
|
|
||||||
|
stats.setMaxIntersect(this->num);
|
||||||
|
|
||||||
|
/* Now sort.. */
|
||||||
|
for(j = 1; j < (this->num); j++)
|
||||||
|
{
|
||||||
|
x = this->list[j];
|
||||||
|
k = j;
|
||||||
|
while( (k > 0) && (this->list[k - 1]->t) > x->t )
|
||||||
|
{
|
||||||
|
this->list[k] = this->list[k - 1];
|
||||||
|
k--;
|
||||||
|
}
|
||||||
|
this->list[k] = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Intersection Intersect::hit()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < this->num; i++)
|
||||||
|
{
|
||||||
|
if (this->list[i]->t >= 0)
|
||||||
|
return *this->list[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Intersection(0, nullptr);
|
||||||
|
}
|
||||||
123
source/intersection.cpp
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Intersection implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <intersection.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <list.h>
|
||||||
|
|
||||||
|
double Computation::schlick()
|
||||||
|
{
|
||||||
|
/* Find the cos of the angle betzeen the eye and normal vector */
|
||||||
|
double cos = this->eyeVector.dot(this->normalVector);
|
||||||
|
double r0;
|
||||||
|
/* Total internal reflection can only occur when n1 > n2 */
|
||||||
|
if (this->n1 > this->n2)
|
||||||
|
{
|
||||||
|
double n, sin2_t;
|
||||||
|
n = this->n1 / this->n2;
|
||||||
|
sin2_t = (n * n) * (1.0 - (cos * cos));
|
||||||
|
if (sin2_t > 1.0)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
/* Compute the cos of theta */
|
||||||
|
cos = sqrt(1.0 - sin2_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
r0 = ((this->n1 - this->n2) / (this->n1 + this->n2));
|
||||||
|
r0 = r0 * r0;
|
||||||
|
|
||||||
|
return r0 + (1 - r0) * ((1 - cos)*(1 - cos)*(1 - cos)*(1 - cos)*(1 - cos));
|
||||||
|
};
|
||||||
|
|
||||||
|
Computation Intersection::prepareComputation(Ray r, Intersect *xs)
|
||||||
|
{
|
||||||
|
double n1 = 1.0;
|
||||||
|
double n2 = 1.0;
|
||||||
|
|
||||||
|
Tuple hitP = r.position(this->t);
|
||||||
|
Tuple normalV;
|
||||||
|
|
||||||
|
if (xs != nullptr)
|
||||||
|
{
|
||||||
|
Intersection hit = xs->hit();
|
||||||
|
normalV = this->object->normalAt(hitP, &hit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
normalV = this->object->normalAt(hitP, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple eyeV = -r.direction;
|
||||||
|
bool inside = false;
|
||||||
|
|
||||||
|
if (normalV.dot(eyeV) < 0)
|
||||||
|
{
|
||||||
|
inside = true;
|
||||||
|
normalV = -normalV;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple overHitP = hitP + normalV * getEpsilon();
|
||||||
|
Tuple underHitP = hitP - normalV * getEpsilon();
|
||||||
|
Tuple reflectV = r.direction.reflect(normalV);
|
||||||
|
|
||||||
|
/* If the hit object is not transparent, there is no need to do that. I think .*/
|
||||||
|
if ((xs != nullptr) && (xs->hit().object->getMaterial()->transparency > 0))
|
||||||
|
{
|
||||||
|
List containers;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0 ; j < xs->count() ; j++)
|
||||||
|
{
|
||||||
|
Intersection i = ( *xs )[j];
|
||||||
|
if (*this == i)
|
||||||
|
{
|
||||||
|
if (!containers.isEmpty())
|
||||||
|
{
|
||||||
|
n1 = containers.last()->getMaterial()->refractiveIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containers.doesInclude(i.object))
|
||||||
|
{
|
||||||
|
containers.remove(i.object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
containers.append(i.object);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*this == i)
|
||||||
|
{
|
||||||
|
if (!containers.isEmpty())
|
||||||
|
{
|
||||||
|
n2 = containers.last()->getMaterial()->refractiveIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End the loop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Material *m = this->object->getMaterial();
|
||||||
|
|
||||||
|
return Computation(this->object,
|
||||||
|
this->t,
|
||||||
|
hitP,
|
||||||
|
eyeV,
|
||||||
|
normalV,
|
||||||
|
overHitP,
|
||||||
|
inside,
|
||||||
|
reflectV,
|
||||||
|
n1,
|
||||||
|
n2,
|
||||||
|
underHitP,
|
||||||
|
m);
|
||||||
|
}
|
||||||
@@ -8,10 +8,45 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_sin (lua_State *L) {
|
||||||
|
double d = luaL_checknumber(L, 1); /* get argument */
|
||||||
|
lua_pushnumber(L, sin(d)); /* push result */
|
||||||
|
return 1; /* number of results */
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
printf("Hello !\n");
|
char buff[256];
|
||||||
|
int error;
|
||||||
|
lua_State *L = luaL_newstate(); /* opens Lua */
|
||||||
|
luaL_openlibs(L); /* opens the basic library */
|
||||||
|
|
||||||
|
lua_pushcfunction(L, l_sin);
|
||||||
|
lua_setglobal(L, "mysin");
|
||||||
|
printf("[0]>");
|
||||||
|
|
||||||
|
while (fgets(buff, sizeof(buff), stdin) != NULL)
|
||||||
|
{
|
||||||
|
error = luaL_loadstring(L, buff) || lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1); /* pop error message from the stack */
|
||||||
|
}
|
||||||
|
printf("[%d]>", lua_gettop(L));
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_close(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math_helper.h>
|
#include <math_helper.h>
|
||||||
@@ -18,7 +19,58 @@ void set_equal_precision(double v)
|
|||||||
current_precision = v;
|
current_precision = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double getEpsilon()
|
||||||
|
{
|
||||||
|
return current_precision;
|
||||||
|
}
|
||||||
|
|
||||||
bool double_equal(double a, double b)
|
bool double_equal(double a, double b)
|
||||||
{
|
{
|
||||||
|
if (isinf(a) && isinf(b))
|
||||||
|
return true;
|
||||||
|
|
||||||
return fabs(a - b) < current_precision;
|
return fabs(a - b) < current_precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double deg_to_rad(double deg)
|
||||||
|
{
|
||||||
|
return deg * M_PI / 180.;
|
||||||
|
}
|
||||||
|
|
||||||
|
double min3(double a, double b, double c)
|
||||||
|
{
|
||||||
|
if (a <= b)
|
||||||
|
{
|
||||||
|
if (c < a) return c;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (b <= a)
|
||||||
|
{
|
||||||
|
if (c < b) return c;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double max3(double a, double b, double c)
|
||||||
|
{
|
||||||
|
if (a >= b)
|
||||||
|
{
|
||||||
|
if (c > a) return c;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (b >= a)
|
||||||
|
{
|
||||||
|
if (c > b) return c;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double frand()
|
||||||
|
{
|
||||||
|
return rand() / ((double) RAND_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
double frandclip(double min, double max)
|
||||||
|
{
|
||||||
|
return (frand() * (max - min)) + min;
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <matrix.h>
|
#include <matrix.h>
|
||||||
#include <tuples.h>
|
#include <tuple.h>
|
||||||
#include <math_helper.h>
|
#include <math_helper.h>
|
||||||
|
|
||||||
Matrix::Matrix(int width)
|
Matrix::Matrix(int width)
|
||||||
@@ -101,14 +101,18 @@ Matrix Matrix::operator*(const Matrix &b) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define FastGet4(_x, _y) (this->data[4 * (_x) + (_y)])
|
||||||
|
|
||||||
|
/* TODO: Check if we can optimise this function. It is called a lot */
|
||||||
|
/*
|
||||||
Tuple Matrix::operator*(const Tuple &b) const
|
Tuple Matrix::operator*(const Tuple &b) const
|
||||||
{
|
{
|
||||||
return Tuple(b.x * this->get(0, 0) + b.y * this->get(0, 1) + b.z * this->get(0, 2) + b.w * this->get(0, 3),
|
return Tuple(b.x * FastGet4(0, 0) + b.y * FastGet4(0, 1) + b.z * FastGet4(0, 2) + b.w * FastGet4(0, 3),
|
||||||
b.x * this->get(1, 0) + b.y * this->get(1, 1) + b.z * this->get(1, 2) + b.w * this->get(1, 3),
|
b.x * FastGet4(1, 0) + b.y * FastGet4(1, 1) + b.z * FastGet4(1, 2) + b.w * FastGet4(1, 3),
|
||||||
b.x * this->get(2, 0) + b.y * this->get(2, 1) + b.z * this->get(2, 2) + b.w * this->get(2, 3),
|
b.x * FastGet4(2, 0) + b.y * FastGet4(2, 1) + b.z * FastGet4(2, 2) + b.w * FastGet4(2, 3),
|
||||||
b.x * this->get(3, 0) + b.y * this->get(3, 1) + b.z * this->get(3, 2) + b.w * this->get(3, 3));
|
b.x * FastGet4(3, 0) + b.y * FastGet4(3, 1) + b.z * FastGet4(3, 2) + b.w * FastGet4(3, 3));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Matrix Matrix::identity()
|
Matrix Matrix::identity()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -123,6 +127,7 @@ Matrix Matrix::transpose()
|
|||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
Matrix ret = Matrix(this->size);
|
Matrix ret = Matrix(this->size);
|
||||||
|
|
||||||
for (y = 0 ; y < this->size ; y++)
|
for (y = 0 ; y < this->size ; y++)
|
||||||
{
|
{
|
||||||
for (x = 0 ; x < this->size ; x++)
|
for (x = 0 ; x < this->size ; x++)
|
||||||
@@ -138,6 +143,7 @@ Matrix Matrix::submatrix(int row, int column)
|
|||||||
int i, j;
|
int i, j;
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
Matrix ret = Matrix(this->size - 1);
|
Matrix ret = Matrix(this->size - 1);
|
||||||
|
|
||||||
for (i = 0 ; i < this->size ; i++)
|
for (i = 0 ; i < this->size ; i++)
|
||||||
{
|
{
|
||||||
if (i == row)
|
if (i == row)
|
||||||
|
|||||||
38
source/pattern.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Pattern implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
Pattern::Pattern(Colour a, Colour b): a(a), b(b)
|
||||||
|
{
|
||||||
|
this->transformMatrix = Matrix4().identity();
|
||||||
|
this->inverseTransform = this->transformMatrix.inverse();
|
||||||
|
};
|
||||||
|
|
||||||
|
Colour Pattern::patternAtObject(Shape *object, Tuple worldPoint)
|
||||||
|
{
|
||||||
|
Tuple objectPoint = object->worldToObject(worldPoint);
|
||||||
|
Tuple patternPoint = this->inverseTransform * objectPoint;
|
||||||
|
|
||||||
|
return this->patternAt(patternPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pattern::setTransform(Matrix transform)
|
||||||
|
{
|
||||||
|
this->transformMatrix = transform;
|
||||||
|
this->inverseTransform = transform.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pattern::dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"Colour A\": {\"red\": %f, \"green\": %f, \"blue\": %f},\n", this->a.x, this->a.y, this->a.z);
|
||||||
|
fprintf(fp, "\"Colour B\": {\"red\": %f, \"green\": %f, \"blue\": %f},\n", this->b.x, this->b.y, this->b.z);
|
||||||
|
}
|
||||||
33
source/pattern/checkerspattern.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Checkers Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_CHECKERSPATTERN_H
|
||||||
|
#define DORAYME_CHECKERSPATTERN_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class CheckersPattern : public Pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckersPattern(Colour a, Colour b) : Pattern(a, b) { };
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
double value = floor(point.x) + floor(point.y) + floor(point.z);
|
||||||
|
|
||||||
|
return (modulo(value, 2) == 0)?this->a:this->b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Checkers\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_CHECKERSPATTERN_H */
|
||||||
37
source/pattern/gradientpattern.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Gradient Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_GRADIENTPATTERN_H
|
||||||
|
#define DORAYME_GRADIENTPATTERN_H
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class GradientPattern : public Pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GradientPattern(Colour a, Colour b) : Pattern(a, b) { };
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
Tuple distance = this->b - this->a;
|
||||||
|
double fraction = point.x - floor(point.x);
|
||||||
|
|
||||||
|
Tuple ret = this->a + distance * fraction;
|
||||||
|
|
||||||
|
return Colour(ret.x, ret.y, ret.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Gradient\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_GRADIENTPATTERN_H */
|
||||||
107
source/pattern/luapattern.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Lua based Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_LUAPATTERN_H
|
||||||
|
#define DORAYME_LUAPATTERN_H
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef ENABLE_LUA_SUPPORT
|
||||||
|
#error Cannot use the Lua Pattern generator with no Lua support disabled!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <lua.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
class LuaPattern : public Pattern
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
lua_State *L;
|
||||||
|
char funcName[50];
|
||||||
|
|
||||||
|
public:
|
||||||
|
LuaPattern(Colour a, Colour b) : Pattern(a, b), L(nullptr) { };
|
||||||
|
|
||||||
|
void setLua(lua_State *L) {
|
||||||
|
this->L = L;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setLuaFunctionName(const char *name) {
|
||||||
|
strncpy(this->funcName, name, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
int isnum;
|
||||||
|
double r, g, b;
|
||||||
|
|
||||||
|
lua_getglobal(this->L, this->funcName);
|
||||||
|
lua_pushnumber(this->L, point.x);
|
||||||
|
lua_pushnumber(this->L, point.y);
|
||||||
|
lua_pushnumber(this->L, point.z);
|
||||||
|
|
||||||
|
lua_createtable(L, 3, 0);
|
||||||
|
lua_pushnumber(L, this->a.x);
|
||||||
|
lua_setfield(L, -2, "r");
|
||||||
|
lua_pushnumber(L, this->a.y);
|
||||||
|
lua_setfield(L, -2, "g");
|
||||||
|
lua_pushnumber(L, this->a.z);
|
||||||
|
lua_setfield(L, -2, "b");
|
||||||
|
|
||||||
|
lua_createtable(L, 3, 0);
|
||||||
|
lua_pushnumber(L, this->b.x);
|
||||||
|
lua_setfield(L, -2, "r");
|
||||||
|
lua_pushnumber(L, this->b.y);
|
||||||
|
lua_setfield(L, -2, "g");
|
||||||
|
lua_pushnumber(L, this->b.z);
|
||||||
|
lua_setfield(L, -2, "b");
|
||||||
|
|
||||||
|
if (lua_pcall(this->L, 5, 3, 0) != LUA_OK)
|
||||||
|
{
|
||||||
|
printf("Error running the Lua function '%s': %s\n", this->funcName,
|
||||||
|
lua_tostring(this->L, -1));
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = lua_tonumberx(this->L, -3, &isnum);
|
||||||
|
if (!isnum)
|
||||||
|
{
|
||||||
|
printf("Error: function '%s' must return numbers\n", this->funcName);
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
g = lua_tonumberx(this->L, -2, &isnum);
|
||||||
|
if (!isnum)
|
||||||
|
{
|
||||||
|
printf("Error: function '%s' must return numbers\n", this->funcName);
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
b = lua_tonumberx(this->L, -1, &isnum);
|
||||||
|
if (!isnum)
|
||||||
|
{
|
||||||
|
printf("Error: function '%s' must return numbers\n", this->funcName);
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(this->L, 1);
|
||||||
|
return Colour(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Lua\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_LUAPATTERN_H */
|
||||||
35
source/pattern/ringpattern.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Ring Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_RINGSUPPORT_H
|
||||||
|
#define DORAYME_RINGSUPPORT_H
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
|
||||||
|
class RingPattern : public Pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RingPattern(Colour a, Colour b) : Pattern(a, b) { };
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
double squared = (point.x * point.x) + (point.z * point.z);
|
||||||
|
|
||||||
|
double value = floor(sqrt(squared));
|
||||||
|
|
||||||
|
return (modulo(value, 2) == 0)?this->a:this->b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Ring\"\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DORAYME_RINGSUPPORT_H */
|
||||||
37
source/pattern/strippattern.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Strip Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DORAYME_STRIPPATTERN_H
|
||||||
|
#define DORAYME_STRIPPATTERN_H
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class StripPattern : public Pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StripPattern(Colour a, Colour b) : Pattern(a, b) { };
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
if (modulo(floor(point.x), 2) == 0)
|
||||||
|
{
|
||||||
|
return this->a;
|
||||||
|
}
|
||||||
|
return this->b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Strip\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_STRIPPATTERN_H */
|
||||||
32
source/pattern/testpattern.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Strip Pattern header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DORAYME_TESTPATTERN_H
|
||||||
|
#define DORAYME_TESTPATTERN_H
|
||||||
|
|
||||||
|
#include <pattern.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class TestPattern : public Pattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestPattern() : Pattern(Colour(0, 0, 0), Colour(1, 1, 1)) { };
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
return Colour(point.x, point.y, point.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"Test\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_TESTPATTERN_H */
|
||||||
198
source/pattern/texturemap.h
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Texture Map header
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DORAYME_TEXTUREMAP_H
|
||||||
|
#define DORAYME_TEXTUREMAP_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <uv_pattern.h>
|
||||||
|
#include <colour.h>
|
||||||
|
enum TextureMapType
|
||||||
|
{
|
||||||
|
SPHERICAL_MAP,
|
||||||
|
PLANAR_MAP,
|
||||||
|
CYLINDRICAL_MAP,
|
||||||
|
CUBIC_MAP
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureMap : public Pattern
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TextureMapType type;
|
||||||
|
UVPattern *pattern;
|
||||||
|
UVPattern *frontPat, *leftPat, *rightPat, *backPat, *upPat, *downPat;
|
||||||
|
public:
|
||||||
|
TextureMap(TextureMapType type, UVPattern *pattern) : Pattern(Colour(0, 0, 0), Colour(0, 0, 0)),
|
||||||
|
type(type), pattern(pattern) { };
|
||||||
|
|
||||||
|
static void sphericalMap(Tuple point, double &u, double &v) {
|
||||||
|
/* First compute the azimuthal angle
|
||||||
|
* -π < theta <= π
|
||||||
|
* angle increases clockwise as viewed from above,
|
||||||
|
* which is opposite of what we want, but we'll fix it later.
|
||||||
|
*/
|
||||||
|
double theta = atan2(point.x, point.z);
|
||||||
|
|
||||||
|
/* vec is the vector pointing from the sphere's origin (the world origin)
|
||||||
|
* to the point, which will also happen to be exactly equal to the sphere's
|
||||||
|
* radius.
|
||||||
|
*/
|
||||||
|
Tuple vec = Vector(point.x, point.y, point.z);
|
||||||
|
double radius = vec.magnitude();
|
||||||
|
|
||||||
|
/* Let's compute the polar angle
|
||||||
|
* 0 <= phi <= π
|
||||||
|
*/
|
||||||
|
double phi = acos(point.y / radius);
|
||||||
|
|
||||||
|
/* -0.5 < raw_u <= 0.5 */
|
||||||
|
double raw_u = theta / (2 * M_PI);
|
||||||
|
|
||||||
|
/* 0 <= u < 1
|
||||||
|
* here's also where we fix the direction of u. Subtract it from 1,
|
||||||
|
* so that it increases counterclockwise as viewed from above.
|
||||||
|
*/
|
||||||
|
u = 1 - (raw_u + 0.5);
|
||||||
|
|
||||||
|
/* We want v to be 0 at the south pole of the sphere,
|
||||||
|
* and 1 at the north pole, so we have to "flip it over"
|
||||||
|
* by subtracting it from 1.
|
||||||
|
*/
|
||||||
|
v = 1 - phi / M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void planarMap(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(point.x, 1.0);
|
||||||
|
v = modulo(point.z, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cylindricalMap(Tuple point, double &u, double &v) {
|
||||||
|
/* Let's get the azimuthal angle, same as with the spherical mapping */
|
||||||
|
double theta = atan2(point.x , point.z);
|
||||||
|
double raw_u = theta / (2 * M_PI);
|
||||||
|
|
||||||
|
u = 1 - (raw_u + 0.5);
|
||||||
|
v = modulo(point.y, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CubeFaces {
|
||||||
|
CUBE_LEFT,
|
||||||
|
CUBE_RIGHT,
|
||||||
|
CUBE_FRONT,
|
||||||
|
CUBE_BACK,
|
||||||
|
CUBE_UP,
|
||||||
|
CUBE_DOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static CubeFaces faceFromPoint(Tuple point) {
|
||||||
|
double abs_x = fabs(point.x);
|
||||||
|
double abs_y = fabs(point.y);
|
||||||
|
double abs_z = fabs(point.z);
|
||||||
|
|
||||||
|
double coord = max3(abs_x, abs_y, abs_z);
|
||||||
|
|
||||||
|
if (coord == point.x) { return CUBE_RIGHT; }
|
||||||
|
if (coord == -point.x) { return CUBE_LEFT; }
|
||||||
|
if (coord == point.y) { return CUBE_UP; }
|
||||||
|
if (coord == -point.y) { return CUBE_DOWN; }
|
||||||
|
if (coord == point.z) { return CUBE_FRONT; }
|
||||||
|
|
||||||
|
return CUBE_BACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cubeUBFront(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(point.x + 1, 2.0) / 2.0;
|
||||||
|
v = modulo(point.y + 1, 2.0) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cubeUBBack(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(1 - point.x, 2.0) / 2.0;
|
||||||
|
v = modulo(point.y + 1, 2.0) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cubeUBLeft(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(point.z + 1, 2.0) / 2.0;
|
||||||
|
v = modulo(point.y + 1, 2.0) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cubeUBRight(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(1 - point.z, 2.0) / 2.0;
|
||||||
|
v = modulo(point.y + 1, 2.0) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cubeUBUp(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(point.x + 1, 2.0) / 2.0;
|
||||||
|
v = modulo(1 - point.z, 2.0) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cubeUBDown(Tuple point, double &u, double &v) {
|
||||||
|
u = modulo(point.x + 1, 2.0) / 2.0;
|
||||||
|
v = modulo(point.z + 1, 2.0) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCubePattern(UVPattern *front, UVPattern *left, UVPattern *right,
|
||||||
|
UVPattern *back, UVPattern *up, UVPattern *down)
|
||||||
|
{
|
||||||
|
this->frontPat = front;
|
||||||
|
this->leftPat = left;
|
||||||
|
this->rightPat = right;
|
||||||
|
this->backPat = back;
|
||||||
|
this->upPat = up;
|
||||||
|
this->downPat = down;
|
||||||
|
}
|
||||||
|
|
||||||
|
Colour patternAt(Tuple point)
|
||||||
|
{
|
||||||
|
double u,v;
|
||||||
|
if (this->type == CUBIC_MAP)
|
||||||
|
{
|
||||||
|
CubeFaces face = TextureMap::faceFromPoint(point);
|
||||||
|
UVPattern *facePat;
|
||||||
|
switch(face)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case CUBE_LEFT: facePat = this->leftPat; TextureMap::cubeUBLeft(point, u, v); break;
|
||||||
|
case CUBE_RIGHT: facePat = this->rightPat; TextureMap::cubeUBRight(point, u, v); break;
|
||||||
|
case CUBE_FRONT: facePat = this->frontPat; TextureMap::cubeUBFront(point, u, v); break;
|
||||||
|
case CUBE_BACK: facePat = this->backPat; TextureMap::cubeUBBack(point, u, v); break;
|
||||||
|
case CUBE_UP: facePat = this->upPat; TextureMap::cubeUBUp(point, u, v); break;
|
||||||
|
case CUBE_DOWN: facePat = this->downPat; TextureMap::cubeUBDown(point, u, v); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return facePat->uvPatternAt(u, v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (this->type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case SPHERICAL_MAP:
|
||||||
|
this->sphericalMap(point, u, v);
|
||||||
|
break;
|
||||||
|
case PLANAR_MAP:
|
||||||
|
this->planarMap(point, u, v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CYLINDRICAL_MAP:
|
||||||
|
this->cylindricalMap(point, u, v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->pattern->uvPatternAt(u, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpMe(FILE *fp) {
|
||||||
|
fprintf(fp, "\"Type\": \"TextureMap\",\n");
|
||||||
|
Pattern::dumpMe(fp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DORAYME_TEXTUREMAP_H */
|
||||||
202
source/renderstat.cpp
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Render statistics implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
RenderStats stats;
|
||||||
|
|
||||||
|
#ifdef RENDER_STATS
|
||||||
|
|
||||||
|
void RenderStats::addCone()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->coneCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addCylinder()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->cylinderCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addCube()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->cubeCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addGroup()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->groupCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addLight()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->lightCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addPlane()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->planeCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addSphere()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->sphereCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addTriangle()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->triangleCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addSmoothTriangle()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->smoothTriangleCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addOBJFile()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->objfileCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addPixel()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->pixelCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addRay()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->rayCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addCastedRay()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->rayCasted++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addLightRay()
|
||||||
|
{
|
||||||
|
this->addCastedRay();
|
||||||
|
|
||||||
|
#pragma omp atomic
|
||||||
|
this->lightRayEmitedCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addReflectRay()
|
||||||
|
{
|
||||||
|
this->addCastedRay();
|
||||||
|
|
||||||
|
#pragma omp atomic
|
||||||
|
this->reflectionRayCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addRefractRay()
|
||||||
|
{
|
||||||
|
this->addCastedRay();
|
||||||
|
|
||||||
|
#pragma omp atomic
|
||||||
|
this->refractedRayCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addIntersect()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->intersectCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addIntersection()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->intersectionCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addMalloc()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->mallocCallCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addRealloc()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->reallocCallCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addDiscardedIntersect()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->discardedIntersectCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::addCsg()
|
||||||
|
{
|
||||||
|
#pragma omp atomic
|
||||||
|
this->csgCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void RenderStats::setMaxDepth(uint32_t depth)
|
||||||
|
{
|
||||||
|
if (this->maxDepthAttained > depth)
|
||||||
|
{
|
||||||
|
this->maxDepthAttained = depth;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::setMaxIntersect(uint32_t count)
|
||||||
|
{
|
||||||
|
if (this->maxIntersectOnARay < count)
|
||||||
|
{
|
||||||
|
this->maxIntersectOnARay = count;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderStats::printStats()
|
||||||
|
{
|
||||||
|
printf("Rendering statistics:\n");
|
||||||
|
printf("Cones : %lld\n", this->coneCount);
|
||||||
|
printf("Cubes : %lld\n", this->cubeCount);
|
||||||
|
printf("Cylinders : %lld\n", this->cylinderCount);
|
||||||
|
printf("Groups : %lld\n", this->groupCount);
|
||||||
|
printf("Lights : %lld\n", this->lightCount);
|
||||||
|
printf("Planes : %lld\n", this->planeCount);
|
||||||
|
printf("Spheres : %lld\n", this->sphereCount);
|
||||||
|
printf("Triangles : %lld\n", this->triangleCount);
|
||||||
|
printf("Smooth Triangles : %lld\n", this->smoothTriangleCount);
|
||||||
|
printf("OBJ File : %lld\n", this->objfileCount);
|
||||||
|
printf("CSG : %lld\n", this->csgCount);
|
||||||
|
printf("==================================================\n");
|
||||||
|
printf("Pixel rendered : %lld\n", this->pixelCount);
|
||||||
|
printf("Ray created : %lld\n", this->rayCount);
|
||||||
|
printf("Ray casted : %lld\n", this->rayCasted);
|
||||||
|
printf("Light Ray casted : %lld\n", this->lightRayEmitedCount);
|
||||||
|
printf("Reflection ray casted : %lld\n", this->reflectionRayCount);
|
||||||
|
printf("Refraction ray casted : %lld\n", this->refractedRayCount);
|
||||||
|
printf("Intersect object created: %lld\n", this->intersectCount);
|
||||||
|
printf("Intersection created : %lld\n", this->intersectionCount);
|
||||||
|
printf("Malloc called : %lld\n", this->mallocCallCount);
|
||||||
|
printf("Realloc called : %lld\n", this->reallocCallCount);
|
||||||
|
printf("Bounding box missed : %lld\n", this->discardedIntersectCount);
|
||||||
|
printf("Min depth attained : %lld\n", this->maxDepthAttained);
|
||||||
|
printf("Max intersect count : %lld\n", this->maxIntersectOnARay);
|
||||||
|
printf("==================================================\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
33
source/sequence.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Sequence implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <sequence.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
|
||||||
|
Sequence::Sequence() : list(nullptr), listPos(0), listSize(0) {
|
||||||
|
/* Need to bootstrap rand here */
|
||||||
|
srand(time(NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
Sequence::Sequence(double *list, uint32_t listSize) : list(list), listPos(0), listSize(listSize) { };
|
||||||
|
|
||||||
|
double Sequence::next() {
|
||||||
|
if (this->listSize == 0)
|
||||||
|
{
|
||||||
|
return frand();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t pos = this->listPos;
|
||||||
|
this->listPos = (this->listPos + 1) % this->listSize;
|
||||||
|
return this->list[pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
146
source/shapes/cone.cpp
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Cone implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <cone.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
|
||||||
|
bool Cone::checkCap(Ray r, double t, double y)
|
||||||
|
{
|
||||||
|
/* Helping function to reduce duplication.
|
||||||
|
* Checks to see if the intersection ot t is within a radius
|
||||||
|
* of 1 (the radius of our Cone from the y axis
|
||||||
|
*/
|
||||||
|
double x = r.origin.x + t * r.direction.x;
|
||||||
|
double z = r.origin.z + t * r.direction.z;
|
||||||
|
return (x * x + z * z) <= fabs(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cone::intersectCaps(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
/* Caps only mattter is the Cone is closed, and might possibly be
|
||||||
|
* intersected by the ray
|
||||||
|
*/
|
||||||
|
if ((this->isClosed) && (fabs(r.direction.y) > getEpsilon()))
|
||||||
|
{
|
||||||
|
double t;
|
||||||
|
/* Check for an intersection with the lower end cap by intersecting
|
||||||
|
* the ray with the plan at y = this->minCap
|
||||||
|
*/
|
||||||
|
t = (this->minCap - r.origin.y) / r.direction.y;
|
||||||
|
if (this->checkCap(r, t, this->minCap))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for an intersection with the upper end cap by intersecting
|
||||||
|
* the ray with the plan at y = this->maxCap
|
||||||
|
*/
|
||||||
|
t = (this->maxCap - r.origin.y) / r.direction.y;
|
||||||
|
if (this->checkCap(r, t, this->maxCap))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cone::localIntersect(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
double A = (r.direction.x * r.direction.x) -
|
||||||
|
(r.direction.y * r.direction.y) +
|
||||||
|
(r.direction.z * r.direction.z);
|
||||||
|
|
||||||
|
double B = (2 * r.origin.x * r.direction.x) -
|
||||||
|
(2 * r.origin.y * r.direction.y) +
|
||||||
|
(2 * r.origin.z * r.direction.z);
|
||||||
|
|
||||||
|
double C = (r.origin.x * r.origin.x) -
|
||||||
|
(r.origin.y * r.origin.y) +
|
||||||
|
(r.origin.z * r.origin.z);
|
||||||
|
|
||||||
|
if ((fabs(A) <= getEpsilon()) && (fabs(B) >= getEpsilon()))
|
||||||
|
{
|
||||||
|
double t = -C / (2*B);
|
||||||
|
xs.add(Intersection(t, this));
|
||||||
|
}
|
||||||
|
else if (fabs(A) >= getEpsilon())
|
||||||
|
{
|
||||||
|
double disc = (B * B) - 4 * A * C;
|
||||||
|
if (disc >= 0)
|
||||||
|
{
|
||||||
|
double t0 = (-B - sqrt(disc)) / (2 * A);
|
||||||
|
double t1 = (-B + sqrt(disc)) / (2 * A);
|
||||||
|
|
||||||
|
double y0 = r.origin.y + t0 * r.direction.y;
|
||||||
|
if ((this->minCap < y0) && (y0 < this->maxCap))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t0, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
double y1 = r.origin.y + t1 * r.direction.y;
|
||||||
|
if ((this->minCap < y1) && (y1 < this->maxCap))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t1, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->intersectCaps(r, xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple Cone::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
{
|
||||||
|
/* Compute the square of the distance from the Y axis */
|
||||||
|
double dist = point.x * point.x + point.z * point.z;
|
||||||
|
|
||||||
|
if ((dist < 1) && (point.y >= (this->maxCap - getEpsilon())))
|
||||||
|
{
|
||||||
|
return Vector(0, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dist < 1) && (point.y <= this->minCap + getEpsilon()))
|
||||||
|
{
|
||||||
|
return Vector(0, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double y = sqrt(point.x * point.x + point.z * point.z);
|
||||||
|
if (point.y > 0)
|
||||||
|
{
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
|
return Vector(point.x, y, point.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox Cone::getLocalBounds()
|
||||||
|
{
|
||||||
|
BoundingBox ret;
|
||||||
|
|
||||||
|
double a = fabs(this->minCap);
|
||||||
|
double b = fabs(this->maxCap);
|
||||||
|
double limit = (a > b)?a:b;
|
||||||
|
|
||||||
|
ret | Point(-limit, this->minCap, -limit);
|
||||||
|
ret | Point(limit, this->maxCap, limit);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cone::dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"Type\": \"Cylinder\",\n");
|
||||||
|
Tuple t = this->transformMatrix * Point(0, 0, 0);
|
||||||
|
fprintf(fp, "\"pseudocenter\": { \"x\": %f, \"y\": %f, \"z\": %f}, \n",
|
||||||
|
t.x, t.y, t.z);
|
||||||
|
t = this->transformMatrix * Point(0, this->minCap, 0);
|
||||||
|
fprintf(fp, "\"min\": %f, \n", t.y);
|
||||||
|
t = this->transformMatrix * Point(1, this->maxCap, 1);
|
||||||
|
fprintf(fp, "\"max\": %f, \n", t.y);
|
||||||
|
Shape::dumpMe(fp);
|
||||||
|
}
|
||||||
146
source/shapes/csg.cpp
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Constructive Solid Geometry (CSG) implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <csg.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
|
||||||
|
|
||||||
|
CSG::CSG(OperationType operation, Shape *left, Shape *right) : Shape(Shape::CSG), operation(operation), left(left), right(right)
|
||||||
|
{
|
||||||
|
stats.addCsg();
|
||||||
|
|
||||||
|
this->left->setParent(this);
|
||||||
|
this->right->setParent(this);
|
||||||
|
|
||||||
|
this->bounds | this->left->getBounds();
|
||||||
|
this->bounds | this->right->getBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSG::localIntersect(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
this->intersect(r, xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSG::intersect(Ray &r, Intersect &xs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Intersect tmp = Intersect();
|
||||||
|
|
||||||
|
if (this->bounds.intesectMe(r))
|
||||||
|
{
|
||||||
|
this->left->intersect(r, tmp);
|
||||||
|
this->right->intersect(r, tmp);
|
||||||
|
|
||||||
|
this->filterIntersections(tmp, xs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple CSG::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
{
|
||||||
|
return Vector(1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox CSG::getLocalBounds()
|
||||||
|
{
|
||||||
|
return this->bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox CSG::getBounds()
|
||||||
|
{
|
||||||
|
if (this->bounds.isEmpty()) { this->updateBoundingBox(); }
|
||||||
|
return this->bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSG::updateBoundingBox()
|
||||||
|
{
|
||||||
|
this->bounds.reset();
|
||||||
|
|
||||||
|
this->bounds | this->left->getBounds();
|
||||||
|
this->bounds | this->right->getBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSG::updateTransform()
|
||||||
|
{
|
||||||
|
Shape::updateTransform();
|
||||||
|
|
||||||
|
this->left->updateTransform();
|
||||||
|
this->right->updateTransform();
|
||||||
|
|
||||||
|
/* Once the full stack being notified of the changes, let's update the
|
||||||
|
* bounding box
|
||||||
|
*/
|
||||||
|
this->updateBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSG::includes(Shape *b)
|
||||||
|
{
|
||||||
|
if (this->left->includes(b)) { return true; }
|
||||||
|
if (this->right->includes(b)) { return true; }
|
||||||
|
if (this == b) { return true; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSG::intersectionAllowed(bool leftHit, bool inLeft, bool inRight)
|
||||||
|
{
|
||||||
|
switch(this->operation)
|
||||||
|
{
|
||||||
|
case CSG::UNION: return (leftHit && !inRight) || (!leftHit && !inLeft);
|
||||||
|
case CSG::INTERSECTION: return (!leftHit && inLeft) || (leftHit && inRight);
|
||||||
|
case CSG::DIFFERENCE: return (leftHit && !inRight) || (!leftHit && inLeft);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSG::filterIntersections(Intersect &xs, Intersect &ret)
|
||||||
|
{
|
||||||
|
bool inl = false;
|
||||||
|
bool inr = false;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < xs.count(); i++)
|
||||||
|
{
|
||||||
|
bool lhit = this->left->includes(xs[i].object);
|
||||||
|
|
||||||
|
if (this->intersectionAllowed(lhit, inl, inr))
|
||||||
|
{
|
||||||
|
ret.add(xs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lhit)
|
||||||
|
{
|
||||||
|
inl = !inl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inr = !inr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSG::lock()
|
||||||
|
{
|
||||||
|
Shape::lock();
|
||||||
|
if(this->left)
|
||||||
|
{
|
||||||
|
this->left->lock();
|
||||||
|
}
|
||||||
|
if(this->right)
|
||||||
|
{
|
||||||
|
this->right->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSG::dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
84
source/shapes/cube.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Cube implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <cube.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
|
||||||
|
void Cube::checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax)
|
||||||
|
{
|
||||||
|
double tMinNumerator = (-1 - axeOrigin);
|
||||||
|
double tMaxNumerator = (1 - axeOrigin);
|
||||||
|
|
||||||
|
if (fabs(axeDirection) >= getEpsilon())
|
||||||
|
{
|
||||||
|
*axeMin = tMinNumerator / axeDirection;
|
||||||
|
*axeMax = tMaxNumerator / axeDirection;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*axeMin = tMinNumerator * INFINITY;
|
||||||
|
*axeMax = tMaxNumerator * INFINITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*axeMin > *axeMax)
|
||||||
|
{
|
||||||
|
double swap = *axeMax;
|
||||||
|
*axeMax = *axeMin;
|
||||||
|
*axeMin = swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cube::localIntersect(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
double xtMin, xtMax, ytMin, ytMax, ztMin, ztMax;
|
||||||
|
double tMin, tMax;
|
||||||
|
|
||||||
|
this->checkAxis(r.origin.x, r.direction.x, &xtMin, &xtMax);
|
||||||
|
this->checkAxis(r.origin.y, r.direction.y, &ytMin, &ytMax);
|
||||||
|
this->checkAxis(r.origin.z, r.direction.z, &ztMin, &ztMax);
|
||||||
|
|
||||||
|
tMin = max3(xtMin, ytMin, ztMin);
|
||||||
|
tMax = min3(xtMax, ytMax, ztMax);
|
||||||
|
|
||||||
|
if (tMin <= tMax)
|
||||||
|
{
|
||||||
|
xs.add(Intersection(tMin, this));
|
||||||
|
xs.add(Intersection(tMax, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple Cube::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
{
|
||||||
|
double maxC = max3(fabs(point.x), fabs(point.y), fabs(point.z));
|
||||||
|
|
||||||
|
if (maxC == fabs(point.x))
|
||||||
|
{
|
||||||
|
return Vector(point.x, 0, 0);
|
||||||
|
}
|
||||||
|
else if (maxC == fabs(point.y))
|
||||||
|
{
|
||||||
|
return Vector(0, point.y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Vector(0, 0, point.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cube::dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"Type\": \"Cube\",\n");
|
||||||
|
Tuple t = this->transformMatrix * Point(0, 0, 0);
|
||||||
|
fprintf(fp, "\"center\": { \"x\": %f, \"y\": %f, \"z\": %f}, \n",
|
||||||
|
t.x, t.y, t.z);
|
||||||
|
t = this->transformMatrix * Point(1, 1, 1);
|
||||||
|
fprintf(fp, "\"corner\": { \"x\": %f, \"y\": %f, \"z\": %f}, \n",
|
||||||
|
t.x, t.y, t.z);
|
||||||
|
Shape::dumpMe(fp);
|
||||||
|
}
|
||||||
128
source/shapes/cylinder.cpp
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Cylinder implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <shape.h>
|
||||||
|
#include <cylinder.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
|
||||||
|
bool Cylinder::checkCap(Ray r, double t)
|
||||||
|
{
|
||||||
|
/* Helping function to reduce duplication.
|
||||||
|
* Checks to see if the intersection ot t is within a radius
|
||||||
|
* of 1 (the radius of our cylinder from the y axis
|
||||||
|
*/
|
||||||
|
double x = r.origin.x + t * r.direction.x;
|
||||||
|
double z = r.origin.z + t * r.direction.z;
|
||||||
|
return (x * x + z * z) <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cylinder::intersectCaps(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
/* Caps only matter if the cylinder is closed, and might possibly be
|
||||||
|
* intersected by the ray
|
||||||
|
*/
|
||||||
|
if ((this->isClosed) && (fabs(r.direction.y) > getEpsilon()))
|
||||||
|
{
|
||||||
|
double t;
|
||||||
|
/* Check for an intersection with the lower end cap by intersecting
|
||||||
|
* the ray with the plan at y = this->minCap
|
||||||
|
*/
|
||||||
|
t = (this->minCap - r.origin.y) / r.direction.y;
|
||||||
|
if (this->checkCap(r, t))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for an intersection with the upper end cap by intersecting
|
||||||
|
* the ray with the plan at y = this->maxCap
|
||||||
|
*/
|
||||||
|
t = (this->maxCap - r.origin.y) / r.direction.y;
|
||||||
|
if (this->checkCap(r, t))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cylinder::localIntersect(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
double A = r.direction.x * r.direction.x + r.direction.z * r.direction.z;
|
||||||
|
|
||||||
|
/* Ray is parallel to the Y axis */
|
||||||
|
if (A >= getEpsilon())
|
||||||
|
{
|
||||||
|
double B = 2 * r.origin.x * r.direction.x +
|
||||||
|
2 * r.origin.z * r.direction.z;
|
||||||
|
double C = r.origin.x * r.origin.x + r.origin.z * r.origin.z - 1;
|
||||||
|
|
||||||
|
double disc = B * B - 4 * A * C;
|
||||||
|
|
||||||
|
if (disc >= 0)
|
||||||
|
{
|
||||||
|
double t0 = (-B - sqrt(disc)) / (2 * A);
|
||||||
|
double t1 = (-B + sqrt(disc)) / (2 * A);
|
||||||
|
|
||||||
|
double y0 = r.origin.y + t0 * r.direction.y;
|
||||||
|
if ((this->minCap < y0) && (y0 < this->maxCap))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t0, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
double y1 = r.origin.y + t1 * r.direction.y;
|
||||||
|
if ((this->minCap < y1) && (y1 < this->maxCap))
|
||||||
|
{
|
||||||
|
xs.add(Intersection(t1, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->intersectCaps(r, xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple Cylinder::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
{
|
||||||
|
/* Compute the square of the distance from the Y axis */
|
||||||
|
double dist = point.x * point.x + point.z * point.z;
|
||||||
|
|
||||||
|
if ((dist < 1) && (point.y >= (this->maxCap - getEpsilon())))
|
||||||
|
{
|
||||||
|
return Vector(0, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dist < 1) && (point.y <= this->minCap + getEpsilon()))
|
||||||
|
{
|
||||||
|
return Vector(0, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Vector(point.x, 0, point.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox Cylinder::getLocalBounds()
|
||||||
|
{
|
||||||
|
BoundingBox ret;
|
||||||
|
|
||||||
|
ret | Point(-1, this->minCap, -1);
|
||||||
|
ret | Point(1, this->maxCap, 1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cylinder::dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"Type\": \"Cylinder\",\n");
|
||||||
|
Tuple t = this->transformMatrix * Point(0, 0, 0);
|
||||||
|
fprintf(fp, "\"pseudocenter\": { \"x\": %f, \"y\": %f, \"z\": %f}, \n",
|
||||||
|
t.x, t.y, t.z);
|
||||||
|
t = this->transformMatrix * Point(0, this->minCap, 0);
|
||||||
|
fprintf(fp, "\"min\": %f, \n", t.y);
|
||||||
|
t = this->transformMatrix * Point(1, this->maxCap, 1);
|
||||||
|
fprintf(fp, "\"max\": %f, \n", t.y);
|
||||||
|
Shape::dumpMe(fp);
|
||||||
|
}
|
||||||
279
source/shapes/group.cpp
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
/*
|
||||||
|
* DoRayMe - a quick and dirty Raytracer
|
||||||
|
* Group implementation
|
||||||
|
*
|
||||||
|
* Created by Manoël Trapier
|
||||||
|
* Copyright (c) 2020 986-Studio.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <tuple.h>
|
||||||
|
#include <ray.h>
|
||||||
|
#include <group.h>
|
||||||
|
#include <math_helper.h>
|
||||||
|
#include <renderstat.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MIN_ALLOC (2)
|
||||||
|
|
||||||
|
Group::Group(const char *name) : Shape(Shape::GROUP)
|
||||||
|
{
|
||||||
|
stats.addGroup();
|
||||||
|
this->allocatedObjectCount = MIN_ALLOC;
|
||||||
|
this->objectList = (Shape **)calloc(sizeof(Shape **), MIN_ALLOC);
|
||||||
|
this->objectCount = 0;
|
||||||
|
|
||||||
|
this->allocatedUnboxableObjectCount = MIN_ALLOC;
|
||||||
|
this->unboxableObjectList = (Shape **)calloc(sizeof(Shape **), MIN_ALLOC);
|
||||||
|
this->unboxableObjectCount = 0;
|
||||||
|
|
||||||
|
if (name != nullptr)
|
||||||
|
{
|
||||||
|
strncpy(this->name, name, 32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(this->name, "untitled", 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::intersect(Ray &r, Intersect &xs)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
if (this->bounds.intesectMe(r))
|
||||||
|
{
|
||||||
|
for (i = 0 ; i < this->objectCount ; i++)
|
||||||
|
{
|
||||||
|
this->objectList[i]->intersect(r, xs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are force to do them all the time */
|
||||||
|
if (this->unboxableObjectCount > 0)
|
||||||
|
{
|
||||||
|
for(i = 0; i < this->unboxableObjectCount; i++)
|
||||||
|
{
|
||||||
|
this->unboxableObjectList[i]->intersect(r, xs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Group::includes(Shape *b)
|
||||||
|
{
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0 ; i < this->objectCount ; i++)
|
||||||
|
{
|
||||||
|
if (this->objectList[i] == b)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->unboxableObjectCount > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < this->unboxableObjectCount; i++)
|
||||||
|
{
|
||||||
|
if (this->unboxableObjectList[i] == b)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::localIntersect(Ray r, Intersect &xs)
|
||||||
|
{
|
||||||
|
this->intersect(r, xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple Group::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
{
|
||||||
|
return Vector(1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ONLY INSERT SHAPES THAT ARE NOT GOING TO CHANGE ELSE..! */
|
||||||
|
void Group::addObject(Shape *s)
|
||||||
|
{
|
||||||
|
if (s->haveFiniteBounds())
|
||||||
|
{
|
||||||
|
if ((this->objectCount + 1) > this->allocatedObjectCount)
|
||||||
|
{
|
||||||
|
this->allocatedObjectCount *= 2;
|
||||||
|
this->objectList = (Shape **)realloc(this->objectList, sizeof(Shape **) * this->allocatedObjectCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->setParent(this);
|
||||||
|
s->updateTransform();
|
||||||
|
|
||||||
|
this->objectList[this->objectCount++] = s;
|
||||||
|
|
||||||
|
this->bounds | s->getBounds();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((this->unboxableObjectCount + 1) > this->allocatedUnboxableObjectCount)
|
||||||
|
{
|
||||||
|
this->allocatedUnboxableObjectCount *= 2;
|
||||||
|
this->unboxableObjectList = (Shape **)realloc(this->unboxableObjectList, sizeof(Shape **) * this->allocatedUnboxableObjectCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->setParent(this);
|
||||||
|
s->updateTransform();
|
||||||
|
|
||||||
|
this->unboxableObjectList[this->unboxableObjectCount++] = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::removeObject(Shape *s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (s->haveFiniteBounds())
|
||||||
|
{
|
||||||
|
for (i = 0; i < this->objectCount; i++)
|
||||||
|
{
|
||||||
|
if (this->objectList[i] == s)
|
||||||
|
{
|
||||||
|
this->objectCount --;
|
||||||
|
this->objectList[i] = this->objectList[this->objectCount];
|
||||||
|
this->objectList[this->objectCount] = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < this->unboxableObjectCount; i++)
|
||||||
|
{
|
||||||
|
if (this->unboxableObjectList[i] == s)
|
||||||
|
{
|
||||||
|
this->unboxableObjectCount --;
|
||||||
|
this->unboxableObjectList[i] = this->unboxableObjectList[this->unboxableObjectCount];
|
||||||
|
this->unboxableObjectList[this->unboxableObjectCount] = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Group::isEmpty()
|
||||||
|
{
|
||||||
|
return (this->objectCount == 0) && (this->unboxableObjectCount == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox Group::getLocalBounds()
|
||||||
|
{
|
||||||
|
return this->bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox Group::getBounds()
|
||||||
|
{
|
||||||
|
if (this->bounds.isEmpty()) { this->updateBoundingBox(); }
|
||||||
|
return this->bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::updateBoundingBox()
|
||||||
|
{
|
||||||
|
this->bounds.reset();
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < this->objectCount; i++)
|
||||||
|
{
|
||||||
|
if (this->objectList[i]->haveFiniteBounds())
|
||||||
|
{
|
||||||
|
BoundingBox objB = this->objectList[i]->getBounds();
|
||||||
|
this->bounds | objB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::updateTransform()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Shape::updateTransform();
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
for (i = 0 ; i < this->objectCount ; i++)
|
||||||
|
{
|
||||||
|
this->objectList[i]->updateTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->unboxableObjectCount > 0)
|
||||||
|
{
|
||||||
|
for(i = 0; i < this->unboxableObjectCount; i++)
|
||||||
|
{
|
||||||
|
this->unboxableObjectList[i]->updateTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Once the full stack being notified of the changes, let's update the
|
||||||
|
* bounding box
|
||||||
|
*/
|
||||||
|
this->updateBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::dumpMe(FILE *fp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
fprintf(fp, "\"Type\": \"Group\",\n");
|
||||||
|
fprintf(fp, "\"Name\": \"%s\",\n", this->name);
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"Objects\": {\n");
|
||||||
|
for(i = 0; i < this->objectCount; i++)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"%d\": {\n", i);
|
||||||
|
this->objectList[i]->dumpMe(fp);
|
||||||
|
fprintf(fp, "},\n");
|
||||||
|
}
|
||||||
|
fprintf(fp, "},\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->unboxableObjectCount > 0)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"UnboxableObjects\": {\n");
|
||||||
|
for(i = 0; i < this->objectCount; i++)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\"%d\": {\n", i);
|
||||||
|
this->objectList[i]->dumpMe(fp);
|
||||||
|
fprintf(fp, "},\n");
|
||||||
|
}
|
||||||
|
fprintf(fp, "},\n");
|
||||||
|
}
|
||||||
|
Shape::dumpMe(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::lock()
|
||||||
|
{
|
||||||
|
Shape::lock();
|
||||||
|
|
||||||
|
/* Now notify included object they have to lock */
|
||||||
|
int i;
|
||||||
|
if (this->objectCount > 0)
|
||||||
|
{
|
||||||
|
for (i = 0 ; i < this->objectCount ; i++)
|
||||||
|
{
|
||||||
|
this->objectList[i]->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->unboxableObjectCount > 0)
|
||||||
|
{
|
||||||
|
for(i = 0; i < this->unboxableObjectCount; i++)
|
||||||
|
{
|
||||||
|
this->unboxableObjectList[i]->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||