├── Build
├── Linux
│ └── build.sh
└── Windows
│ ├── EULA.txt
│ ├── InstallerReadme.txt
│ ├── License.txt
│ ├── Microsoft.VC80.CRT.manifest
│ ├── Microsoft.VC80.CRT
│ ├── Microsoft.VC80.CRT.manifest
│ ├── msvcm80.dll
│ ├── msvcp80.dll
│ └── msvcr80.dll
│ ├── Microsoft.VC90.CRT
│ ├── Microsoft.VC90.CRT.manifest
│ ├── msvcm90.dll
│ ├── msvcp90.dll
│ └── msvcr90.dll
│ ├── ReadMe.txt
│ ├── copyWin32Files.bat
│ └── installer2.iss
├── BuildProcedure.txt
├── Examples
├── Arc Sphere.es
├── Ball.es
├── BinaryKite.es
├── City of Glass.es
├── Default.es
├── Frame In Frame.es
├── Grinder.es
├── Konstrukt.es
├── Menger.es
├── MeshTest.es
├── Moduli Creatures.es
├── Mondrian.es
├── Nabla.es
├── NablaSystem.es
├── NineWorthies.es
├── Nouveau.es
├── Nouveau2.es
├── Nouveau3.es
├── Octopod II.es
├── Pure Structure.es
├── Reflection.es
├── RoundTree.es
├── SpiralTree2D.es
├── Synctor.es
├── Thingy.es
├── Torus2.es
├── Torus3.es
├── Trees 3d.es
└── Tutorials
│ ├── Blend.es
│ ├── CSG test.es
│ ├── JavaScript - Movie.es
│ ├── NouveauMovie.es
│ ├── Preprocessor.es
│ ├── PreprocessorGUI.es
│ ├── Primitives.es
│ ├── RandomColor.es
│ ├── Raytracer - Light.es
│ └── TriangleComposites.es
├── LICENSE.GPL3
├── LICENSE.LGPL
├── LICENSE.README
├── Main.cpp
├── Misc
├── Blender_Importer_2.py
├── Blender_Importer_2.rendertemplate
├── SunFlow-Monochrome.rendertemplate
├── Sunflow-Colored.rendertemplate
├── Sunflow-Meta-Neon22.rendertemplate
├── Sunflow-Textured.rendertemplate
├── Sunflow-Ultimate-Groovelock.rendertemplate
├── Sunflow-Ward.rendertemplate
├── about.html
├── appleseed.rendertemplate
├── cube.obj
├── icon.jpg
├── povray.rendertemplate
├── povray2.rendertemplate
├── renderman.rendertemplate
├── sphere.obj
└── splash.png
├── StructureSynth.ico
├── StructureSynth.qrc
├── StructureSynth.sln
├── StructureSynth.vcproj
├── StructureSynth
├── GUI
│ ├── MainWindow.cpp
│ ├── MainWindow.h
│ ├── TemplateExportDialog.cpp
│ ├── TemplateExportDialog.h
│ ├── VariableEditor.cpp
│ └── VariableEditor.h
├── JavaScriptSupport
│ ├── Debug.cpp
│ ├── Debug.h
│ ├── JavaScriptBuilder.cpp
│ ├── JavaScriptBuilder.h
│ ├── JavaScriptParser.cpp
│ └── JavaScriptParser.h
├── Model
│ ├── Action.cpp
│ ├── Action.h
│ ├── AmbiguousRule.cpp
│ ├── AmbiguousRule.h
│ ├── Builder.cpp
│ ├── Builder.h
│ ├── ColorPool.cpp
│ ├── ColorPool.h
│ ├── CustomRule.cpp
│ ├── CustomRule.h
│ ├── ExecutionStack.cpp
│ ├── ExecutionStack.h
│ ├── PrimitiveClass.cpp
│ ├── PrimitiveClass.h
│ ├── PrimitiveRule.cpp
│ ├── PrimitiveRule.h
│ ├── RandomStreams.cpp
│ ├── RandomStreams.h
│ ├── Rendering
│ │ ├── ObjRenderer.cpp
│ │ ├── ObjRenderer.h
│ │ ├── OpenGLRenderer.cpp
│ │ ├── OpenGLRenderer.h
│ │ ├── Renderer.cpp
│ │ ├── Renderer.h
│ │ ├── TemplateRenderer.cpp
│ │ └── TemplateRenderer.h
│ ├── Rule.cpp
│ ├── Rule.h
│ ├── RuleRef.cpp
│ ├── RuleRef.h
│ ├── RuleSet.cpp
│ ├── RuleSet.h
│ ├── State.cpp
│ ├── State.h
│ ├── Transformation.cpp
│ ├── Transformation.h
│ ├── TransformationLoop.cpp
│ └── TransformationLoop.h
└── Parser
│ ├── EisenParser.cpp
│ ├── EisenParser.h
│ ├── Preprocessor.cpp
│ ├── Preprocessor.h
│ ├── Tokenizer.cpp
│ └── Tokenizer.h
├── StructureSynthDoc.ico
├── SyntopiaCore
├── Exceptions
│ └── Exception.h
├── GLEngine
│ ├── Box.cpp
│ ├── Box.h
│ ├── Dot.cpp
│ ├── Dot.h
│ ├── EngineWidget.cpp
│ ├── EngineWidget.h
│ ├── Grid.cpp
│ ├── Grid.h
│ ├── Line.cpp
│ ├── Line.h
│ ├── Mesh.cpp
│ ├── Mesh.h
│ ├── Object3D.cpp
│ ├── Object3D.h
│ ├── RaytraceTriangle.cpp
│ ├── RaytraceTriangle.h
│ ├── Raytracer
│ │ ├── AtomicCounter.cpp
│ │ ├── AtomicCounter.h
│ │ ├── ProgressiveOutput.h
│ │ ├── RayTracer.cpp
│ │ ├── RayTracer.h
│ │ ├── RenderThread.cpp
│ │ ├── RenderThread.h
│ │ ├── Sampler.cpp
│ │ ├── Sampler.h
│ │ ├── VoxelStepper.cpp
│ │ └── VoxelStepper.h
│ ├── Sphere.cpp
│ ├── Sphere.h
│ ├── Triangle.cpp
│ └── Triangle.h
├── Logging
│ ├── ListWidgetLogger.cpp
│ ├── ListWidgetLogger.h
│ ├── Logging.cpp
│ └── Logging.h
├── Math
│ ├── Matrix4.cpp
│ ├── Matrix4.h
│ ├── Random.cpp
│ ├── Random.h
│ ├── Vector3.cpp
│ └── Vector3.h
└── Misc
│ ├── ColorUtils.cpp
│ ├── ColorUtils.h
│ ├── MiniParser.cpp
│ ├── MiniParser.h
│ ├── Persistence.cpp
│ ├── Persistence.h
│ ├── Version.cpp
│ └── Version.h
├── ThirdPartyCode
└── MersenneTwister
│ └── MersenneTwister.h
├── bugs.txt
├── changelog.txt
├── images
├── agt_internet.png
├── copy.png
├── cut.png
├── documentinfo.png
├── exit.png
├── fileclose.png
├── fileicons
│ ├── Structure Synth.icns
│ ├── Structure Synth.ico
│ ├── StructureSynth-16.png
│ ├── StructureSynth-256.png
│ ├── StructureSynthDoc-256.png
│ ├── StructureSynthDoc.icns
│ ├── StructureSynthDoc.ico
│ ├── icon.pdn
│ └── icon2.pdn
├── filesaveas.png
├── folder.png
├── mail_new.png
├── new.png
├── open.png
├── paste.png
├── render.png
├── save.png
├── saveas.png
└── structuresynth.png
├── notes.txt
├── resource.h
├── roadmap.txt
├── structure-synth.desktop
└── structuresynth.rc
/Build/Linux/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ../..
4 | qmake-qt4 -project -after "CONFIG+=opengl" -after "QT+=xml opengl script"
5 | qmake-qt4
6 | make
7 |
8 | cd Build/Linux
9 |
10 | mkdir "Structure Synth"
11 | mkdir "Structure Synth/Examples"
12 | mkdir "Structure Synth/Misc"
13 | cp ../../trunk "Structure Synth/structuresynth"
14 | cp ../../LICENSE* "Structure Synth"
15 | cp -r ../../Examples/* "Structure Synth/Examples"
16 | cp -r ../../Misc/* "Structure Synth/Misc"
17 |
18 | cd "Structure Synth"
19 | rm -rf `find . -type d -name .svn`
20 | cd ..
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Build/Windows/EULA.txt:
--------------------------------------------------------------------------------
1 | END USER LICENSE AGREEMENT.
2 |
3 | Version 1.1.
4 |
5 | This software is provided with NO WARRANTY.
6 |
7 | That's right: not even if the software is loaded with viruses or crashes your hard-drive, can the author be held responsible. I would never intentionally include malware in the distribution, but I do not control the servers hosting the software, and will not make any guarantees.
8 |
9 | If you do not like this, do not run the software.
10 |
11 | If you are okay with this, feel free to run the software on any number of computers and use it any way you want to.
12 |
13 | If you do modify or redistribute this software make sure you respect the included GPL license (license.txt).
14 |
15 | If you found that this EULA did not exactly ease your mind and you are worried about running this software, here is a few general suggestions:
16 | (1) Run the software in a sandboxed environment. (VM-Ware Player provides excellent and free virtualization)
17 | (2) Do not run as administrator, but as a non-privileged user.
18 | (3) Compile the sources yourself.
19 | (4) Check the MD5/SHA1 checksums to see if the files have been tampered with.
20 | (5) Search Google to see if anyone has experienced problems with the software.
21 |
--------------------------------------------------------------------------------
/Build/Windows/InstallerReadme.txt:
--------------------------------------------------------------------------------
1 | Notice:
2 |
3 | If you install Structure Synth into the 'Program Files' folder, you will most likely not have privileges to modify the examples and export templates.
4 |
5 | Consider installing into a non-protected directory, e.g. "c:\structure synth"
6 |
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC80.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC80.CRT/msvcm80.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Build/Windows/Microsoft.VC80.CRT/msvcm80.dll
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC80.CRT/msvcp80.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Build/Windows/Microsoft.VC80.CRT/msvcp80.dll
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC80.CRT/msvcr80.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Build/Windows/Microsoft.VC80.CRT/msvcr80.dll
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC90.CRT/msvcm90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Build/Windows/Microsoft.VC90.CRT/msvcm90.dll
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC90.CRT/msvcp90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Build/Windows/Microsoft.VC90.CRT/msvcp90.dll
--------------------------------------------------------------------------------
/Build/Windows/Microsoft.VC90.CRT/msvcr90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Build/Windows/Microsoft.VC90.CRT/msvcr90.dll
--------------------------------------------------------------------------------
/Build/Windows/ReadMe.txt:
--------------------------------------------------------------------------------
1 | If the executable complains about missing libraries such as msvcr90.dll, msvcp90.dll or msvcm90.dll, you will need to install the
2 | Microsoft Visual C++ C Runtime Libraries:
3 |
4 | Microsoft Visual C++ 2008 Redistributable Package (x86):
5 | http://www.microsoft.com/downloads/details.aspx?FamilyID=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF&displaylang=en
--------------------------------------------------------------------------------
/Build/Windows/copyWin32Files.bat:
--------------------------------------------------------------------------------
1 | rmdir /S "Structure Synth"
2 | mkdir "Structure Synth"
3 | xcopy ..\..\Examples\*.* "Structure Synth"\Examples\ /E
4 | rmdir /S "Structure Synth"\Examples\DontDeploy
5 | xcopy ..\..\Misc\*.* "Structure Synth"\Misc\ /E
6 | xcopy Microsoft.VC90.CRT\*.* "Structure Synth"\Microsoft.VC90.CRT\ /E
7 | copy ..\..\Release\structuresynth.exe "Structure Synth"\
8 | copy %QT4DIR%\bin\QtOpenGl4.dll "Structure Synth"\
9 | copy %QT4DIR%\bin\QtGUI4.dll "Structure Synth"\
10 | copy %QT4DIR%\bin\QtCore4.dll "Structure Synth"\
11 | copy %QT4DIR%\bin\QtXml4.dll "Structure Synth"\
12 | copy %QT4DIR%\bin\QtScript4.dll "Structure Synth"\
13 | rem copy *.manifest "Structure Synth"\
14 | copy EULA.txt "Structure Synth"\
15 | copy License.txt "Structure Synth"\
16 | copy ReadMe.txt "Structure Synth"\
17 | @rem copy C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700\msvcr80.dll "Structure Synth"\
18 | @rem copy C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700\msvcp80.dll "Structure Synth"\
19 | pause
20 |
21 |
--------------------------------------------------------------------------------
/Build/Windows/installer2.iss:
--------------------------------------------------------------------------------
1 | ; Script generated by the Inno Setup Script Wizard.
2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
3 |
4 | [Setup]
5 | ; NOTE: The value of AppId uniquely identifies this application.
6 | ; Do not use the same AppId value in installers for other applications.
7 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
8 | AppId={{E4CDF523-5418-47F2-8C82-3AA9688270BE}
9 | AppName=Structure Synth
10 | AppVersion=1.5
11 | ;AppVerName=Structure Synth 1.5
12 | AppPublisher=Syntopia
13 | AppPublisherURL=http://structuresynth.sourceforge.net/
14 | AppSupportURL=http://structuresynth.sourceforge.net/
15 | AppUpdatesURL=http://structuresynth.sourceforge.net/
16 | DefaultDirName={pf}\Structure Synth
17 | DefaultGroupName=Structure Synth
18 | AllowNoIcons=yes
19 | LicenseFile=F:\Structure Synth\trunk\Build\Windows\Structure Synth\EULA.txt
20 | InfoBeforeFile=F:\Structure Synth\trunk\Build\Windows\InstallerReadme.txt
21 | OutputBaseFilename=StructureSynth-Windows_Binary-v1.5.0
22 | Compression=lzma
23 | SolidCompression=yes
24 |
25 | [Registry]
26 | Root: HKCR; Subkey: "StructureSynth.Document"; ValueType: string; ValueName: ""; ValueData: "StructureSynth EisenScript File"; Flags: uninsdeletekey; Tasks: associate1
27 | Root: HKCR; Subkey: "StructureSynth.Document\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\StructureSynth.exe,1"; Tasks: associate1
28 | Root: HKCR; Subkey: "StructureSynth.Document\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\StructureSynth.exe"" ""%1"""; Tasks: associate1
29 | Root: HKCR; Subkey: ".es"; ValueType: string; ValueName: ""; ValueData: "StructureSynth.Document"; Flags: uninsdeletevalue; Tasks: associate1
30 |
31 |
32 | [Languages]
33 | Name: "english"; MessagesFile: "compiler:Default.isl"
34 |
35 | [Tasks]
36 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
37 | Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
38 | Name: associate1; Description: "Associate EisenScript (.es) files with Structure Synth"; GroupDescription: "File Associations:"
39 |
40 | [Files]
41 | Source: "F:\Structure Synth\trunk\Build\Windows\Structure Synth\StructureSynth.exe"; DestDir: "{app}"; Flags: ignoreversion
42 | Source: "F:\Structure Synth\trunk\Build\Windows\Structure Synth\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
43 | ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
44 |
45 | [Icons]
46 | Name: "{group}\Structure Synth"; Filename: "{app}\StructureSynth.exe"
47 | Name: "{group}\{cm:ProgramOnTheWeb,Structure Synth}"; Filename: "http://structuresynth.sourceforge.net/"
48 | Name: "{group}\{cm:UninstallProgram,Structure Synth}"; Filename: "{uninstallexe}"
49 | Name: "{commondesktop}\Structure Synth"; Filename: "{app}\StructureSynth.exe"; Tasks: desktopicon
50 | Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Structure Synth"; Filename: "{app}\StructureSynth.exe"; Tasks: quicklaunchicon
51 |
52 | [Run]
53 | Filename: "{app}\StructureSynth.exe"; Description: "{cm:LaunchProgram,Structure Synth}"; Flags: nowait postinstall skipifsilent
54 |
55 |
--------------------------------------------------------------------------------
/BuildProcedure.txt:
--------------------------------------------------------------------------------
1 | Build Procedure:
2 |
3 | - Update Version object in MainWindow.cpp
4 | -
5 |
6 | Windows:
7 | - Change to 'Release'. Build in VS 2008.
8 | - Check dependencies in Process Explorer - update Build\Windows\copyWin32Files.bat to reflect this.
9 | - Run copyWin32Files.bat
10 | - Zip the content of 'Structure Synth' and name the files after the following template: "StructureSynth-Windows_Binary_v0.8.0.zip"
11 | - Run the Inno Setup installer.
12 | - Make an 'export' of the Trunk SVN directory (e.g. right-mouse-button-drag the directory to a new location, and use the context menu) into a directory named 'Structure Synth Source Code' and zip the contents into an archive named "StructureSynth-Source-v0.8.0.zip".
13 | - Log onto SourceForge choose 'Admin | File Releases'. Choose 'Structure Synth | Add Release'. Choose a suitable name: "Version 0.8.0 (Exonautica)"
14 |
15 | - Update the SourceForge web pages.
16 | - Send out SourceForge news.
17 | - Mention on Syntopia Blog.
18 |
19 |
20 |
21 |
22 | Template for SourceForge news updates:
23 |
24 | Structure Synth 0.9.0 ("Glasnost") Released
25 | -------------------------------------------
26 |
27 | Binaries for Windows XP and Vista. Source for Linux and Mac.
28 | (Mac binaries will be available shortly)
29 |
30 | New features:
31 | - Template renderers: camera export is now working.
32 | - Implemented a 'Triangle' primitive. E.g.: 'Triangle[0,0,0;1,0,0;0.5,0.5,0.5]' is now a valid primitive.
33 | - Added support for '#define varname value' preprocessor substitutions (useful for declaring constant variables).
34 |
35 | Minor changes and bug fixes:
36 | - Added 'FastRotate' button (draws a subset while rotating/translating the view).
37 | - Template Renderer: Missing primitives no longer cancels the renderer, but only warns.
38 | - OpenGL renderer now turns off GLWidget when rendering (makes build phase faster).
39 | - Fixed CR+CR+LF export bug.
40 | - Enabled the Cut,Paste,Copy main menu
41 | - Removed an extensive memory leak (leaked 16 bytes per created state).
42 | - When resizing the OpenGL window, width/height/aspect ratio is shown.
43 | - Corrected some syntax highlighter bugs
44 | - Fixed a bug when going into full screen mode (not all chrome was hidden)
45 |
46 | Download instructions at:
47 | http://structuresynth.sourceforge.net/download.php
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Examples/Arc Sphere.es:
--------------------------------------------------------------------------------
1 | // Arc Sphere.es
2 | // Inspired by Marius Watz spheres:
3 | // http://www.flickr.com/photos/watz/363931023/
4 |
5 | set maxobjects 10400
6 | set background #454
7 |
8 | // Camera settings. Place these before first rule call.
9 | set translation [-3.33009 0.0259899 -20]
10 | set rotation [0.147791 -0.237766 -0.960012 -0.822766 -0.568209 0.014066 -0.548833 0.787786 -0.279602]
11 | set pivot [0 0 0]
12 | set scale 0.18957
13 |
14 | 7 * { s 0.9 z -2 y 0.5 } 1 * { color #5a5 s 0.92 rz 0 } r1
15 | 7 * { s 0.9 z -2 y 0.5 } 1 * { color #aaa s 0.87 rz 0 } r1
16 | 7 * { s 0.9 z -2 y 0.5 } 1 * { color #fff } r1
17 |
18 | rule r1 w 40 {
19 | ubox
20 | dbox
21 | { x 1 ry 3 } r1
22 | }
23 |
24 | rule r1 w 14 { r2 }
25 |
26 | rule r2 w 10 {
27 | { x 1 ry 3 } r2
28 | }
29 |
30 | rule r2 { r1 }
31 |
32 | rule dbox w 8 maxdepth 15 {
33 | { y -1 rx 2.9 } dbox
34 | sbox
35 | }
36 |
37 | rule dbox { }
38 |
39 | rule ubox w 8 maxdepth 15 {
40 | { y 1 rx -2.9 } ubox
41 | sbox
42 | }
43 |
44 | rule ubox { }
45 |
46 | rule sbox {
47 | { s 1.2 1.2 0.6 ry 5 } box
48 | }
--------------------------------------------------------------------------------
/Examples/Ball.es:
--------------------------------------------------------------------------------
1 | set maxdepth 2000
2 | { a 0.9 hue 30 } R1
3 |
4 | rule R1 w 10 {
5 | { x 1 rz 3 ry 5 } R1
6 | { s 1 1 0.1 sat 0.9 } box
7 | }
8 |
9 | rule R1 w 10 {
10 | { x 1 rz -3 ry 5 } R1
11 | { s 1 1 0.1 } box
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/Examples/BinaryKite.es:
--------------------------------------------------------------------------------
1 | set maxobjects 16000
2 | 10 * { y 1 } 10 * { z 1 } 1 * { a 0.8 sat 0.9 } r1
3 | set background #fff
4 |
5 |
6 | rule r1 {
7 | { x 1 ry 4 } r1
8 | xbox
9 | }
10 |
11 | rule r1 {
12 | { x 1 ry -4 } r1
13 | xbox
14 | }
15 |
16 | rule r1 {
17 | { x 1 rz -8 s 0.95 } r1
18 | xbox
19 | }
20 |
21 | rule r1 {
22 | { x 1 rz 8 s 0.95 } r1
23 | xbox
24 | }
25 |
26 |
27 |
28 | rule r2 maxdepth 36 {
29 | { ry 1 ry -13 x 1.2 b 0.99 h 12 } r2
30 | xbox
31 | }
32 |
33 | rule xbox {
34 | { s 1.1 color #000 } grid
35 | { b 0.7 color #000 } box
36 | }
37 |
38 | rule xbox {
39 | { s 1.1 color #000 } grid
40 | { b 0.7 color #fff } box
41 | }
42 |
--------------------------------------------------------------------------------
/Examples/City of Glass.es:
--------------------------------------------------------------------------------
1 | set maxobjects 117600
2 | { a 0.4 sat 0.5 } grinder
3 |
4 | rule grinder {
5 | 36 * { ry 10 z 1.2 b 0.99 h 2 } arm
6 | }
7 |
8 | rule arm {
9 | xbox
10 | { rz -1 rx 3 z 0.22 x 0.3 ry 10 s 0.998 x 0.5 sat 0.9995 hue 0.05 } arm
11 | }
12 |
13 | rule arm {
14 | xbox
15 | { rz 1 rx 3 z 0.22 x 0.3 ry 10 s 0.99 x -0.5 sat 0.9995 hue 0.15 } arm
16 | }
17 |
18 | rule xbox {
19 | box
20 | }
21 |
22 | rule xbox {
23 | { s 0.9 } grid
24 | { b 0.7 } box
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/Default.es:
--------------------------------------------------------------------------------
1 | // ------ Camera settings.
2 | set translation [0 -0.367113 -20]
3 | set rotation [0.963994 0.0575931 -0.259613 0.0514549 0.917418 0.394584 0.260899 -0.393735 0.881422]
4 | set pivot [0 0 0]
5 | set scale 0.408795
6 |
7 | // ------ The actual EisenScript
8 | set background #fff
9 | set maxdepth 400
10 |
11 | r0
12 |
13 | rule r0 {
14 | 3 * { rz 120 } R1
15 | 3 * { rz 120 } R2
16 | }
17 |
18 | rule R1 {
19 | { x 1.3 rx 1.57 rz 6 ry 3 s 0.99 hue 0.4 sat 0.99 } R1
20 | { s 4 } sphere::shiny
21 | }
22 |
23 | rule R2 {
24 | { x -1.3 rz 6 ry 3 s 0.99 hue 0.4 sat 0.99 } R2
25 | { s 4 } sphere
26 | }
27 |
28 | // ----- Settings for internal raytracer
29 |
30 | set raytracer::shadows false
31 |
32 | // the number of samples controls the quality
33 | // '6' means 6x6 samples per pixels, and is the default.
34 | set raytracer::samples 6
35 |
36 | // dof is depth-of-field.
37 | // Use 'Edit | Show 3D Object Information' to find the correct plane
38 | // comment the line below to disable this.
39 | set raytracer::dof [0.23,0.07]
40 |
41 | // Set materials either globally,
42 | // or for a selected tag (e.g. 'shiny')
43 | set raytracer::shiny::reflection 0.3
44 | set raytracer::phong [0.5,0.6,0.2]
45 |
--------------------------------------------------------------------------------
/Examples/Frame In Frame.es:
--------------------------------------------------------------------------------
1 | { hue 20 sat 0.8 } r2
2 |
3 | rule r2 maxdepth 20 {
4 | { s 0.75 rz 10 b 0.9 } r2
5 | frame
6 | }
7 |
8 | rule frame {
9 | { s 0.1 1.1 0.1 x 5 z 5 } box
10 | { s 0.1 1.1 0.1 x 5 z -5 } box
11 | { s 0.1 1.1 0.1 x -5 z 5 } box
12 | { s 0.1 1.1 0.1 x -5 z -5 } box
13 |
14 | { s 1 0.1 0.1 y 5 z 5 } box
15 | { s 1 0.1 0.1 y 5 z -5 } box
16 | { s 1 0.1 0.1 y -5 z 5 } box
17 | { s 1 0.1 0.1 y -5 z -5 } box
18 |
19 | { s 0.1 0.1 1 y 5 x 5 } box
20 | { s 0.1 0.1 1 y 5 x -5 } box
21 | { s 0.1 0.1 1 y -5 x 5 } box
22 | { s 0.1 0.1 1 y -5 x -5 } box
23 | }
--------------------------------------------------------------------------------
/Examples/Grinder.es:
--------------------------------------------------------------------------------
1 | // Grinder.es
2 |
3 | set maxobjects 117600
4 | grinder
5 |
6 | rule grinder {
7 | 36 * { ry 10 z 1.2 b 0.99 } 1 * { ry 34 rx 34 } arm
8 | }
9 |
10 | rule arm {
11 | xbox
12 | { rz 2 rx 3 z 0.22 x 0.3 ry 10 s 0.999 x 0.5 sat 0.9995 hue 0.05 } arm
13 | }
14 |
15 | rule arm {
16 | xbox
17 | { rz 2 rx 3 z 0.22 x 0.3 ry 10 s 0.99 x 0.5 sat 0.9995 hue 0.15 } arm
18 | }
19 |
20 | rule xbox {
21 | { b 0.7 } box
22 | }
23 |
--------------------------------------------------------------------------------
/Examples/Konstrukt.es:
--------------------------------------------------------------------------------
1 | set background #000
2 | #define _md 400
3 | #define _rz 0
4 | #define _zoom 1
5 |
6 | set maxdepth _md
7 |
8 | { rz _rz s _zoom } r0
9 |
10 | rule r0 {
11 | 3 * { rz 120 } R1
12 | 3 * { rz 120 } R2
13 | }
14 |
15 | rule R1 {
16 | { x -1.3 rz 1.57 rz 6 ry 13 s 0.99 hue 1 sat 0.99 } R1
17 | { s 4 color black } box
18 | }
19 |
20 | rule R2 {
21 | { x -1.3 rz 6 ry 13 s 0.99 hue 1 sat 0.99 } R2
22 | { s 4 a 1 color white } box
23 | }
--------------------------------------------------------------------------------
/Examples/Menger.es:
--------------------------------------------------------------------------------
1 | R1
2 |
3 | rule R1 maxdepth 3 > c2 {
4 | { s 1/3 x -1 y -1 } R1
5 | { s 1/3 x -1 y -1 z -1 } R1
6 | { s 1/3 x -1 y -1 z +1 } R1
7 | { s 1/3 x 1 y -1 } R1
8 | { s 1/3 x 1 y -1 z -1 } R1
9 | { s 1/3 x 1 y -1 z +1 } R1
10 | { s 1/3 y -1 z -1 } R1
11 | { s 1/3 y -1 z +1 } R1
12 | { s 1/3 x -1 y 1 } R1
13 | { s 1/3 x -1 y 1 z -1 } R1
14 | { s 1/3 x -1 y 1 z +1 } R1
15 | { s 1/3 x 1 y 1 } R1
16 | { s 1/3 x 1 y 1 z -1 } R1
17 | { s 1/3 x 1 y 1 z +1 } R1
18 | { s 1/3 y 1 z -1 } R1
19 | { s 1/3 y 1 z +1 } R1
20 | { s 1/3 x -1 z -1 } R1
21 | { s 1/3 x -1 z +1 } R1
22 | { s 1/3 x 1 z -1 } R1
23 | { s 1/3 x 1 z +1 } R1
24 | }
25 |
26 | rule c2 {
27 | box
28 | }
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Examples/MeshTest.es:
--------------------------------------------------------------------------------
1 | set maxobjects 52222
2 | set background #a00
3 | R1
4 | { x 3 s 0.9 } R1
5 | { y 3 s 0.7 } R1
6 | { y -3 s 0.6 } R1
7 | { x -3 s 0.5 } R1
8 |
9 | // Camera settings. Place these before first rule call.
10 | set translation [-2.59764 -5.03937 -20]
11 | set rotation [0.946021 0.279788 0.163595 -0.166082 -0.0149648 0.985998 0.278318 -0.959945 0.0323107]
12 | set pivot [0 0 0]
13 | set scale 1.1874
14 |
15 |
16 | rule R1 maxdepth 30 > endrule {
17 | { z 1 ry 6 s 0.91 hue 5 y 0.01 } R1
18 | mesh
19 | }
20 |
21 | rule R1 w 0.2 {
22 | { z 1 ry 6 s 0.99 hue 1 } R1
23 | { rz 90 } R1
24 | mesh
25 | }
26 |
27 | rule endrule {
28 | { s 3 } sphere
29 | }
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Examples/Moduli Creatures.es:
--------------------------------------------------------------------------------
1 | // Moduli Creatures. Syntopia 2010.
2 | // This one works best when raytraced in e.g. Sunflow.
3 |
4 | // Camera settings. Place these before first rule call.
5 | set translation [-8.07939 -6.42262 -20]
6 | set rotation [-0.608586 0.78168 -0.136359 0.78734 0.616241 0.0185897 0.0985613 -0.0960483 -0.99048]
7 | set pivot [0 0 0]
8 | set scale 0.625595
9 |
10 | set background grey
11 | 50 * { x 1 rz 5 s 0.99 color red } 20 * { y 1 rz 3 hue 1 } d
12 |
13 | rule d md 30 {
14 | { z 1 rx 5 } d
15 | { s 0.01 1 1.2 sat 0.4 } box
16 | }
17 |
18 | rule d w 0.1 {
19 | e
20 | }
21 |
22 | rule e md 5 {
23 | { z 1 rx 5 } e
24 | { s 0.01 1 1.2 sat 0.4 } box
25 | }
--------------------------------------------------------------------------------
/Examples/Mondrian.es:
--------------------------------------------------------------------------------
1 | // Mondrian Cube.
2 |
3 | mondrian
4 |
5 | rule mondrian {
6 | // The six faces of the cube
7 | a2
8 | { x -0.5 z -0.5 ry 90 } a2
9 | { x +0.5 z -0.5 ry 90 } a2
10 | { z -1 } a2
11 | { y +0.5 z -0.5 rx 90 } a2
12 | { y -0.5 z -0.5 rx 90 } a2
13 | }
14 |
15 | rule a2 w 2 maxdepth 2 > d {
16 | // Split into two halves in x direction
17 | { s 0.333 1 1 x -1 } a2
18 | { s 0.666 1 1 x 0.26 } a2
19 | }
20 |
21 | rule a2 w 2 maxdepth 2 > d {
22 | // Split into two halves in y direction
23 | { s 1 0.333 1 y -1 } a2
24 | { s 1 0.666 1 y 0.26 } a2
25 | }
26 |
27 |
28 | rule a2 { d }
29 |
30 | // This rule chooses a random color.
31 | rule d { { s 1 1 0.02 color #F00 } square }
32 | rule d { { s 1 1 0.02 color #0404A2 } square }
33 | rule d { { s 1 1 0.02 color #FFFE33 } square }
34 | rule d w 2 { { s 1 1 0.02 color #FFF } square }
35 |
36 | // Draws a framed square
37 | rule square {
38 | { s 0.95 0.95 1 } box
39 | { s 0.05 1 1 b 0 x -10 } box
40 | { s 0.05 1 1 b 0 x 10 } box
41 | { s 1.05 0.05 1 b 0 y -10 } box
42 | { s 1.05 0.05 1 b 0 y 10 } box
43 | }
--------------------------------------------------------------------------------
/Examples/Nabla.es:
--------------------------------------------------------------------------------
1 | set maxdepth 30
2 |
3 | { ry -90 color white } R1
4 | {rx -90 color white } R1
5 | { x 30 y 30 z -3 s 900 900 1 color white } box
6 |
7 | Rule R1 {
8 | dbox
9 | { z 0.6 rx 5 } R1
10 | }
11 |
12 | Rule R1 {
13 | dbox
14 | { z 0.6 rx -5 } R1
15 | }
16 |
17 | Rule R1 {
18 | dbox
19 | { z 0.6 rz 5 } R1
20 | }
21 |
22 | Rule R1 {
23 | dbox
24 | { z 0.6 rz -5 } R1
25 | }
26 |
27 | Rule R1 weight 0.01 {
28 |
29 | }
30 |
31 | Rule dbox {
32 | { s 1.5 1.6 0.5 } box
33 | }
34 |
35 | Rule dbox weight 0.5 {
36 | { ry 90 s 0.5 } R1
37 | }
38 |
39 | Rule dbox weight 0.5 {
40 | { rx 90 s 0.5 } R1
41 | }
--------------------------------------------------------------------------------
/Examples/NablaSystem.es:
--------------------------------------------------------------------------------
1 | // 10, 20 , 21, 23, 33 , 104, 106, 118, 119, 127, 128, 133, 136, 138, 139
2 | //1, 66,69,70,73, 79
3 |
4 | set maxdepth 30
5 |
6 | { ry -90 b 0.2 } R1
7 |
8 | // Floor box
9 | //{ x 30 y 30 z -3 s 900 900 1 color red } box
10 |
11 | Rule R1 {
12 | dbox
13 | set seed initial
14 | { z 0.6 rx 5 } R1
15 | }
16 |
17 | Rule R1 {
18 | dbox
19 | { z 0.5 rx -90 } R1
20 | }
21 |
22 | Rule R1 {
23 | dbox
24 | { z 0.6 rz 90 } R1
25 | }
26 |
27 | Rule R1 {
28 | dbox
29 | { z 0.6 rz -90 } R1
30 | }
31 |
32 | Rule R1 weight 0.01 {
33 |
34 | }
35 |
36 | Rule dbox {
37 | { color random s 2 2 0.5 } box
38 | }
39 |
40 | Rule dbox weight 0.5 {
41 | { ry 90 s 0.5 1 1 } R1
42 | }
43 |
44 | Rule dbox weight 0.5 {
45 | { rx 90 s 0.5 2 1 } R1
46 | }
--------------------------------------------------------------------------------
/Examples/NineWorthies.es:
--------------------------------------------------------------------------------
1 | /// The Nine Worthies
2 | /// Syntopia 2009
3 |
4 | set maxobjects 52200
5 | set maxdepth 3000
6 | set background #232
7 | 9 * { x 5 } 1 * { b 0.4 color #0a0 color white } r1
8 | // { s 1000 1000 1 color white } box
9 |
10 | // Camera settings. Place these before first rule call.
11 | set translation [-4.50383 -2.80381 -20]
12 | set rotation [0.993991 0.0947988 -0.0545559 0.0140638 0.383866 0.923278 0.108471 -0.918504 0.380229]
13 | set pivot [0 0 0]
14 | set scale 0.209524
15 |
16 | rule r1 w 10 {
17 | { rz 15 h 1 y 1 h 4 z 0.01 s 0.999 } r1
18 | r2
19 | }
20 |
21 | rule r1 w 0.1 {
22 | { rx 10 z 1 s 0.99 } r1
23 | r2
24 | }
25 |
26 | rule r2 {
27 | box
28 | { s 1.1 0.2 0.2 color orange } box
29 | grid
30 | }
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Examples/Nouveau.es:
--------------------------------------------------------------------------------
1 | #define shrink s 0.996
2 |
3 | set seed 9
4 | // Camera settings. Place these before first rule call.
5 | set translation [-2.66914 -1.23905 -20]
6 | set rotation [0.707436 -0.702911 -0.0738339 0.542177 0.472696 0.694696 -0.453408 -0.531484 0.715504]
7 | set pivot [0 0 0]
8 | set scale 0.953754
9 |
10 | set raytracer::dof [0.245,0.09]
11 |
12 | set maxdepth 1000
13 | set background #fff
14 | 16 * { rz 20 color white } hbox
15 |
16 | rule hbox { r}
17 | rule r { forward }
18 | rule r { turn }
19 | rule r { turn2 }
20 | rule r { turn4 }
21 | rule r { turn3 }
22 | //rule r { turn5 }
23 | //rule r { turn6 }
24 |
25 | rule forward md 90 > r {
26 | dbox
27 | { rz 2 x 0.1 shrink } forward
28 | }
29 |
30 | rule turn md 90 > r {
31 | dbox
32 | { rz 2 x 0.1 shrink } turn
33 | }
34 |
35 | rule turn2 md 90 > r {
36 | dbox
37 | { rz -2 x 0.1 shrink } turn2
38 | }
39 |
40 | rule turn3 md 90 > r {
41 | dbox
42 | { ry -2 x 0.1 shrink } turn3
43 | }
44 |
45 | rule turn4 md 90 > r {
46 | dbox
47 | { ry -2 x 0.1 shrink } turn4
48 | }
49 |
50 | rule turn5 md 90 > r {
51 | dbox
52 | { rx -2 x 0.1 shrink } turn5
53 | }
54 |
55 | rule turn6 md 90 > r {
56 | dbox
57 | { rx -2 x 0.1 shrink } turn6
58 | }
59 |
60 | rule dbox {
61 | { s 0.2 1 1 } box
62 | }
--------------------------------------------------------------------------------
/Examples/Nouveau2.es:
--------------------------------------------------------------------------------
1 | // Nouveau system variant.
2 |
3 | #define shrink s 0.999
4 |
5 | set maxdepth 1000
6 | set background #888
7 | 6 * { rz 60 color white } hbox
8 | //{ s 80 80 0.1 color white } box
9 | //set raytracer::light [0,0,-20]
10 |
11 | rule hbox { set seed initial r}
12 | rule r { { rx 90 } forward }
13 | rule r { { rx -90 }forward }
14 | rule r { forward }
15 | rule r { forward }
16 | rule r { turn }
17 | rule r { turn2 }
18 |
19 | rule forward md 90 > r {
20 | dbox
21 | { rz 2 x 0.1 shrink } forward
22 | }
23 |
24 | rule turn md 90 > r {
25 | dbox
26 | { rz 2 x 0.1 shrink } turn
27 | }
28 |
29 | rule turn2 md 90 > r {
30 | dbox
31 | { rz -2 x 0.1 shrink } turn2
32 | }
33 |
34 | rule turn3 md 90 > r {
35 | dbox
36 | { ry -2 x 0.1 shrink } turn3
37 | }
38 |
39 | rule turn4 md 90 > r {
40 | dbox
41 | { ry -2 x 0.1 shrink } turn4
42 | }
43 |
44 | rule turn5 md 90 > r {
45 | dbox
46 | { rx -2 x 0.1 shrink } turn5
47 | }
48 |
49 | rule turn6 md 90 > r {
50 | dbox
51 | { rx -2 x 0.1 shrink } turn6
52 | }
53 |
54 | rule dbox {
55 | { s 0.2 1 1 } box
56 | { rx 10 s 0.2 1 1 color black } box
57 | }
--------------------------------------------------------------------------------
/Examples/Nouveau3.es:
--------------------------------------------------------------------------------
1 | // Nouveau variant (Rounded tubes)
2 |
3 | #define shrink s 0.996
4 |
5 |
6 | set maxdepth 1000
7 | set background #fff
8 | 10 * { x 0 color white ry 10 } 2 * { rz 180 } hbox
9 |
10 | rule hbox { r}
11 | rule r { forward }
12 | rule r { turn }
13 | rule r { turn2 }
14 | rule r { turn4 }
15 | rule r { turn3 }
16 | rule r { turn5 }
17 | rule r { turn6 }
18 |
19 | rule forward md 90 > r {
20 | dbox
21 | { rz 2 x 0.1 shrink } forward
22 | }
23 |
24 | rule turn md 90 > r {
25 | dbox
26 | { rz 2 x 0.1 shrink } turn
27 | }
28 |
29 | rule turn2 md 90 > r {
30 | dbox
31 | { rz -2 x 0.1 shrink } turn2
32 | }
33 |
34 | rule turn3 md 90 > r {
35 | dbox
36 | { ry -2 x 0.1 shrink } turn3
37 | }
38 |
39 | rule turn4 md 90 > r {
40 | dbox
41 | { ry -2 x 0.1 shrink } turn4
42 | }
43 |
44 | rule turn5 md 90 > r {
45 | dbox
46 | { ry -2 x 0.1 shrink } turn5
47 | }
48 |
49 | rule turn6 md 90 > r {
50 | dbox
51 | { ry -2 x 0.1 shrink } turn6
52 | }
53 |
54 | rule dbox {
55 | { s 0.2 1 1 } sphere
56 | }
--------------------------------------------------------------------------------
/Examples/Octopod II.es:
--------------------------------------------------------------------------------
1 | set maxdepth 100
2 |
3 | 10 * { ry 36 sat 0.9 } 30 * { ry 10 } 1 * { h 30 b 0.8 sat 0.8 a 0.3 } r1
4 |
5 | rule r1 w 20 {
6 | { s 0.9 rz 5 h 5 rx 5 x 1 } r1
7 | { s 1 0.2 0.5 } box
8 | }
9 |
10 | rule r1 w 20 {
11 | { s 0.99 rz -5 h 5 rx -5 x 1 } r1
12 | { s 1 0.2 0.5 } box
13 | }
14 |
15 | rule r1 {
16 | }
--------------------------------------------------------------------------------
/Examples/Pure Structure.es:
--------------------------------------------------------------------------------
1 | #define shrink s 0.996
2 |
3 | set maxdepth 1000
4 | set background white
5 | set syncrandom true
6 |
7 | //set colorpool image:001.jpg
8 |
9 | set colorpool list:white,white,white,orange
10 | set minsize 0.5
11 |
12 | 5 * { x 2 } 1 * { s 0.2 0.2 1 } s2
13 |
14 | rule s2 md 25 {
15 | { z 1 } s2
16 | start
17 | }
18 |
19 |
20 |
21 | rule start { 6 * { rz 60 } hbox }
22 |
23 | rule hbox md 10 { r }
24 |
25 | rule r {
26 | set seed initial
27 | forward
28 | }
29 |
30 | rule r { turn }
31 | rule r { turn2 }
32 |
33 | rule forward md 90 > r {
34 | dbox
35 | { rz 2 x 0.1 shrink } forward
36 | }
37 |
38 | rule turn md 90 > r {
39 | dbox
40 | { rz 2 x 0.1 shrink } turn
41 | }
42 |
43 | rule turn2 md 90 > r {
44 | dbox
45 | { rz -2 x 0.1 shrink } turn2
46 | }
47 |
48 | rule turn3 md 90 > r {
49 | dbox
50 | { ry -2 x 0.1 shrink } turn3
51 | }
52 |
53 | rule turn4 md 90 > r {
54 | dbox
55 | { ry -2 x 0.1 shrink } turn4
56 | }
57 |
58 | rule turn5 md 90 > r {
59 | dbox
60 | { rx -2 x 0.1 shrink } turn5
61 | }
62 |
63 | rule turn6 md 90 > r {
64 | dbox
65 | { rx -2 x 0.1 shrink } turn6
66 | }
67 |
68 | rule dbox {
69 | { s 0.2 1 1 color random } box
70 | }
--------------------------------------------------------------------------------
/Examples/Reflection.es:
--------------------------------------------------------------------------------
1 | // Reflection.es
2 |
3 | set raytracer::shadows false
4 | set raytracer::reflection 0.2
5 | set raytracer::phong [0.5,0.4,0.2]
6 | set raytracer::max-depth 5
7 | set background #fff
8 | set maxdepth 400
9 | 2 * { rx 38 color white } R1
10 |
11 | rule R1 {
12 | { x 1.3 rz 6 ry 3 s 0.99 hue 1 sat 0.99 blend red 0.02 } R1
13 | { s 6 a 1 } sphere
14 | { s 7 hue 120 a 0.2 } sphere
15 | }
16 |
17 | rule R2 {
18 | { x -1.3 rz 6 ry 3 s 0.99 hue 1 sat 0.99 blend red 0.02 } R2
19 | { s 6 a 1 } sphere
20 | { s 7 hue 120 a 0.2 } sphere
21 | }
--------------------------------------------------------------------------------
/Examples/RoundTree.es:
--------------------------------------------------------------------------------
1 | set maxdepth 400
2 | 1 * { ry 90 x 6 } 10 * { rx 36 color white } R1
3 | { s 200 200 0.1 color white } box
4 |
5 | rule R1 {
6 | { x 1 rz -4 ry 6 s 0.99 } R1
7 | { s 2 } sphere
8 | }
9 |
10 | rule R1 {
11 | { x 1 rz 4 ry 6 s 0.99 } R1
12 | { s 2 } sphere
13 | }
14 |
--------------------------------------------------------------------------------
/Examples/SpiralTree2D.es:
--------------------------------------------------------------------------------
1 | set maxdepth 600
2 | { h 30 sat 0.7 } spiral
3 | { ry 180 h 30 sat 0.7 } spiral
4 |
5 | rule spiral w 100 {
6 | box
7 | { y 0.4 rx 1 s 0.995 b 0.995 } spiral
8 | }
9 |
10 | rule spiral w 1 {
11 | spiral
12 | { ry 180 h 3 } spiral
13 | }
14 |
--------------------------------------------------------------------------------
/Examples/Synctor.es:
--------------------------------------------------------------------------------
1 | set maxdepth 600
2 |
3 | set background #f94
4 |
5 | { sat 0.7 color green } start
6 |
7 | rule spiral w 100 {
8 | box
9 | { y 0.4 rx 5 hue 1 s 0.995 b 0.999 } spiral
10 | }
11 |
12 | rule spiral w 100 {
13 | box
14 | { y 0.4 rx 5 hue -1 rz -5 s 0.995 b 0.999 } spiral
15 | }
16 |
17 | rule spiral w 100 {
18 | box
19 | { y 0.4 rx 5 hue 0 rz 5 s 0.995 b 0.995 } spiral
20 | }
21 |
22 | rule spiral w 3 {
23 | start
24 | }
25 |
26 | rule start {
27 | set seed initial
28 | { rx 15 } spiral
29 | { ry 180 h 3 } spiral
30 | }
--------------------------------------------------------------------------------
/Examples/Thingy.es:
--------------------------------------------------------------------------------
1 | #define steps 30
2 | set minsize 0.01
3 | set background white
4 |
5 | 10 * { s 0.8 rx 36 ry 10 } steps * { h 1 rz 360/steps } 1 * { x 10 rz 180} dspawn
6 |
7 | rule dspawn {
8 | spawn
9 | m
10 | }
11 |
12 | rule m {
13 | }
14 |
15 | rule spawn {
16 | set seed initial
17 | dbox
18 | }
19 |
20 | rule dbox {
21 | { x 0.1 s 0.99 sat 0.99 } dbox
22 | box
23 | }
24 |
25 | rule dbox {
26 | { x 0.1 s 0.99 ry 1 } dbox
27 | box
28 | }
29 |
30 | rule dbox {
31 | { x 0.1 s 0.99 ry -1 } dbox
32 | box
33 | }
34 |
35 | rule dbox {
36 | { x 0.1 s 0.99 ry 1 } dbox
37 | box
38 | }
39 |
40 | rule dbox {
41 | { x 0.1 s 0.99 rz -3 } dbox
42 | box
43 | }
--------------------------------------------------------------------------------
/Examples/Torus2.es:
--------------------------------------------------------------------------------
1 | set maxobjects 160000
2 | { a 0.3 sat 0.5 } grinder
3 |
4 | set background #fff
5 | rule grinder {
6 | 36 * { rz 10 y 0.1 } 36 * { ry 10 z 1.2 b 0.99 h 12 } xbox
7 | }
8 |
9 | rule xbox {
10 | { s 1.1 } frame
11 | { b 0.7 color #eee a 0.2 } box
12 | }
13 |
14 | rule xbox {
15 | { s 1.1 } frame
16 | { b 0.7 color #fff a 0.3 } box
17 | }
18 |
19 | #define _f3 10
20 | #define _f1 0.05
21 | #define _f2 1.05
22 |
23 | rule frame {
24 | { s _f1 _f2 _f1 x _f3 z _f3 } box
25 | {s _f1 _f2 _f1 x _f3 z -_f3 } box
26 | { s _f1 _f2 _f1 x -_f3 z _f3} box
27 | {s _f1 _f2 _f1 x -_f3 z -_f3} box
28 |
29 |
30 | { s _f2 _f1 _f1 y _f3 z _f3 } box
31 | { s _f2 _f1 _f1 y _f3 z -_f3 } box
32 | { s _f2 _f1 _f1 y -_f3 z _f3 } box
33 | { s _f2 _f1 _f1 y -_f3 z -_f3 } box
34 |
35 | { s _f1 _f1 _f2 y _f3 x _f3 } box
36 | { s _f1 _f1 _f2 y _f3 x -_f3 } box
37 | { s _f1 _f1 _f2 y -_f3 x _f3 } box
38 | { s _f1 _f1 _f2 y -_f3 x -_f3} box
39 |
40 | }
--------------------------------------------------------------------------------
/Examples/Torus3.es:
--------------------------------------------------------------------------------
1 | set maxobjects 160000
2 | { a 1.0 sat 0.5 } grinder
3 | set background #fff
4 |
5 | rule grinder {
6 | 36 * { rz 5 rz 2 y 0.1 } 36 * { ry 10 rz 3 z 1.2 b 0.99 h 12 } xbox
7 | }
8 |
9 | rule xbox {
10 | { s 1.1 } frame
11 | { b 0.7 color #eee a 1.0 } box
12 | }
13 |
14 | rule xbox {
15 | { s 1.1 } frame
16 | { b 0.7 color #fff a 1.0 } box
17 | }
18 |
19 | #define _f3 10
20 | #define _f1 0.05
21 | #define _f2 1.05
22 |
23 | rule frame {
24 | { s _f1 _f2 _f1 x _f3 z _f3 } box
25 | {s _f1 _f2 _f1 x _f3 z -_f3 } box
26 | { s _f1 _f2 _f1 x -_f3 z _f3} box
27 | {s _f1 _f2 _f1 x -_f3 z -_f3} box
28 |
29 |
30 | { s _f2 _f1 _f1 y _f3 z _f3 } box
31 | { s _f2 _f1 _f1 y _f3 z -_f3 } box
32 | { s _f2 _f1 _f1 y -_f3 z _f3 } box
33 | { s _f2 _f1 _f1 y -_f3 z -_f3 } box
34 |
35 | { s _f1 _f1 _f2 y _f3 x _f3 } box
36 | { s _f1 _f1 _f2 y _f3 x -_f3 } box
37 | { s _f1 _f1 _f2 y -_f3 x _f3 } box
38 | { s _f1 _f1 _f2 y -_f3 x -_f3} box
39 |
40 | }
--------------------------------------------------------------------------------
/Examples/Trees 3d.es:
--------------------------------------------------------------------------------
1 |
2 | set background white
3 |
4 | { h 30 sat 0.7 } seed
5 | { ry 180 h 30 sat 0.7 } seed
6 |
7 | rule seed weight 100 {
8 | box
9 | { y 0.4 rx 1 s 0.995 b 0.995 } seed
10 | }
11 |
12 | rule seed weight 100 {
13 | box
14 | { y 0.4 rx 1 ry 1 s 0.995 b 0.995 } seed
15 | }
16 |
17 | rule seed weight 100 {
18 | box
19 | { y 0.4 rx 1 rz -1 s 0.995 b 0.995 } seed
20 | }
21 |
22 | rule seed weight 6 {
23 | { rx 15 } seed
24 | { ry 180 h 3 } seed
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/Tutorials/Blend.es:
--------------------------------------------------------------------------------
1 | // Demonstration of Blend
2 | //
3 | // The blend operator blends the current color
4 | // with the specified color.
5 | //
6 | // Notice that colors are blended in HSV space,
7 | // explaining why blending from red to blue will
8 | // go through green and yellow.
9 |
10 |
11 | set maxdepth 400
12 | R1
13 | R2
14 |
15 | rule R1 {
16 | { x 1 rz 6 ry 6 s 0.99 blend blue 0.04 } R1
17 | { s 2 } sphere
18 | }
19 |
20 | rule R2 {
21 | { x -1 rz 6 ry 6 s 0.99 blend green 0.04 } R2
22 | { s 2 } sphere
23 | }
--------------------------------------------------------------------------------
/Examples/Tutorials/CSG test.es:
--------------------------------------------------------------------------------
1 | // Example of a CSG (Constructive Solid Geometry) system
2 | // Should be used with a PovRay template.
3 | //
4 | // See:
5 | // http://www.flickr.com/photos/syntopia/3644799200/
6 | // for more information.
7 | set maxdepth 17
8 | set recursion depth
9 |
10 | template::intersection-begin
11 | { y 0.5 s 5 1 1 color white } box
12 | template::union-begin
13 | r1
14 | template::union-end
15 | template::intersection-end
16 |
17 | rule r1 md 17 {
18 | template::difference-begin
19 | sphere
20 | { s 0.99 x -0.1 } sphere
21 | template::difference-end
22 | 1 * { s 0.95 x -0.1 } 1 * { s 0.95 x -0.1 } r1
23 | }
24 |
25 | rule r1 md 17 {
26 | template::difference-begin
27 | sphere
28 | { s 0.99 x -0.1 } sphere
29 | template::difference-end
30 | 1 * { s 0.95 x -0.1 } 1 * { s 0.95 x -0.1 } r1
31 | }
--------------------------------------------------------------------------------
/Examples/Tutorials/JavaScript - Movie.es:
--------------------------------------------------------------------------------
1 | #javascript
2 |
3 | function pad(number) {
4 | number = number + ''; // convert to string
5 | while (number.length < 4) {
6 | number = "0" + number;
7 | }
8 | return number;
9 | }
10 |
11 |
12 | Builder.load("NouveauMovie.es");
13 | max =1000 ;
14 | for (i = 0; i <= max; i+=1) {
15 | c = i/max;
16 |
17 | Builder.reset();
18 | Builder.setSize(0,100);
19 | Builder.define("_rz",c*360);
20 | Builder.define("_md",20+c*3000);
21 | Builder.define("_dofa",0.2+ 0.1*Math.sin(c*3.1415*2));
22 |
23 | Builder.build();
24 |
25 | // ---- Sunflow raytrace -----
26 | /*
27 | name = "f:/Test/out" + pad(i);
28 | Builder.templateRenderToFile("Sunflow-Colored.rendertemplate", name + ".sc",true);
29 | Builder.execute('"C:/Program Files/Java/jdk1.6.0_21/bin/java"', '-Xmx1G -server -jar "%SUNFLOW%/sunflow.jar" ' + name + ".sc -nogui -o " + name + ".png", true);
30 | */
31 |
32 | // ---- Internal raytrace ------
33 | Builder.raytraceToFile("N" + pad(i) + ".png",true);
34 | }
35 |
--------------------------------------------------------------------------------
/Examples/Tutorials/NouveauMovie.es:
--------------------------------------------------------------------------------
1 | // This system is meant to used
2 | // by the 'JavaScript - Movie.es' example.
3 |
4 | #define shrink s 0.996
5 | #define _rz 0
6 | #define _dofa 0.245
7 | #define _dofb 0.09
8 | #define _md 1000
9 | set seed 14
10 |
11 | // Camera settings. Place these before first rule call.
12 | set translation [-1.54217 -1.76221 -20]
13 | set rotation [0.530172 -0.847845 -0.00877037 0.100004 0.0522555 0.993614 -0.841972 -0.527663 0.112492]
14 | set pivot [0 0 0]
15 | set scale 1.13904
16 |
17 | set raytracer::dof [_dofa,_dofb]
18 |
19 | set maxdepth _md
20 | set background #fff
21 | 1 * { rz _rz } 16 * { rz 20 color white } hbox
22 |
23 | rule hbox { r}
24 | rule r { forward }
25 | rule r { turn }
26 | rule r { turn2 }
27 | rule r { turn4 }
28 | rule r { turn3 }
29 | //rule r { turn5 }
30 | //rule r { turn6 }
31 |
32 | rule forward md 90 > r {
33 | dbox
34 | { rz 2 x 0.1 shrink } forward
35 | }
36 |
37 | rule turn md 90 > r {
38 | dbox
39 | { rz 2 x 0.1 shrink } turn
40 | }
41 |
42 | rule turn2 md 90 > r {
43 | dbox
44 | { rz -2 x 0.1 shrink } turn2
45 | }
46 |
47 | rule turn3 md 90 > r {
48 | dbox
49 | { ry -2 x 0.1 shrink } turn3
50 | }
51 |
52 | rule turn4 md 90 > r {
53 | dbox
54 | { ry -2 x 0.1 shrink } turn4
55 | }
56 |
57 | rule turn5 md 90 > r {
58 | dbox
59 | { rx -2 x 0.1 shrink } turn5
60 | }
61 |
62 | rule turn6 md 90 > r {
63 | dbox
64 | { rx -2 x 0.1 shrink } turn6
65 | }
66 |
67 | rule dbox {
68 | { s 0.2 1 1 } box
69 | }
--------------------------------------------------------------------------------
/Examples/Tutorials/Preprocessor.es:
--------------------------------------------------------------------------------
1 | /*
2 | An example of using preprocessor defines.
3 |
4 | A preprocessor '#define' makes it easier
5 | to explore parameter settings that are used
6 | multiple times in the script.
7 | */
8 |
9 | #define sizeStep 0.98
10 | #define angle 6
11 |
12 | set maxdepth 100
13 | set background black
14 |
15 | 18 * { rx 10 x 0.2 sat 0.95 } R
16 |
17 |
18 | rule R { R1 }
19 |
20 | rule R1 {
21 | { x 0.6 rz angle ry angle s sizeStep hue 1 a 0.99 } R1
22 | { s 1 1 0.1 } sbox
23 | }
24 |
25 | rule R2 {
26 | { x -0.6 rz angle ry angle s sizeStep hue 1 sat 1 a 0.99 } R2
27 | { s 1 1 0.1 } sbox
28 | }
29 |
30 | rule sbox {
31 | { color black } grid
32 | { b 0.8 hue 67 } box
33 | }
34 |
--------------------------------------------------------------------------------
/Examples/Tutorials/PreprocessorGUI.es:
--------------------------------------------------------------------------------
1 | /*
2 | An example of using GUI preprocessor defines.
3 |
4 | The "float" suffix makes it possible to control variables via sliders.
5 | The 'int' suffix is identical to the above, but only accepts natural numbers.
6 | */
7 |
8 | #define sizeStep 0.94 (float:0-1)
9 | #define angle1 20 (float:0-90)
10 | #define angle2 6 (float:0-90)
11 | #define iterations 6 (int:1-90)
12 |
13 |
14 | set maxdepth 100
15 | set background black
16 |
17 | iterations * { rx 10 x 0.2 sat 0.95 } R
18 |
19 |
20 | rule R {
21 | set seed initial
22 | R1
23 | }
24 |
25 | rule R1 {
26 | { x 0.6 rz 0 ry angle1 s sizeStep hue 1 a 0.99 } R1
27 | { s 1 1 0.1 color green } sbox
28 | }
29 |
30 | rule R1 {
31 | { x 0.6 rz angle2 ry 0 s sizeStep hue 1 a 0.99 } R1
32 | { s 1 1 0.1 color red } sbox
33 | }
34 |
35 | rule sbox {
36 | { color black } grid
37 | { b 0.8 hue 67 } box
38 | }
39 |
--------------------------------------------------------------------------------
/Examples/Tutorials/Primitives.es:
--------------------------------------------------------------------------------
1 | /*
2 | This is just a simple demonstration
3 | of the various primitives in Structure Synth.
4 | */
5 |
6 | set maxdepth 20
7 | set background white
8 |
9 | // Camera settings. Place these before first rule call.
10 | set translation [4.6096 -1.3831 -20]
11 | set rotation [-0.923481 0.370221 -0.100283 -0.119863 -0.0301876 0.992333 0.364361 0.928431 0.0722537]
12 | set pivot [0 0 0]
13 | set scale 0.38721
14 |
15 | R6
16 | { x 4 } R2
17 | { x 8 } R3
18 | { x 12 } R4
19 | { x 16 } R5
20 | { x 20 } R1
21 |
22 | rule R1 maxdepth 8 {
23 | { z 1 rz 0 rx 10 s 1.2 h 20 } R1
24 | sphere
25 | }
26 |
27 |
28 | rule R2 maxdepth 8 {
29 | { z 1 rz 0 rx 10 s 1.2 h 20 } R2
30 | box
31 | }
32 |
33 | rule R3 maxdepth 8 {
34 | { z 1 rz 0 rx 10 s 1.2 h 20 } R3
35 | dot
36 | }
37 |
38 | rule R4 maxdepth 8 {
39 | { z 1 rz 0 rx 10 s 1.2 h 20 } R4
40 | line
41 | }
42 |
43 | rule R5 maxdepth 8 {
44 | { z 1 rz 0 rx 10 s 1.2 h 20 } R5
45 | grid
46 | }
47 |
48 | rule R6 maxdepth 8 {
49 | { z 1 rz 0 rx 10 s 1.2 h 20 } R6
50 | mesh
51 | }
--------------------------------------------------------------------------------
/Examples/Tutorials/RandomColor.es:
--------------------------------------------------------------------------------
1 | /*
2 | A demonstration of random colors in Structure Synth
3 |
4 | Use the 'color random' to select a random color.
5 |
6 | There a different schemes for creating random colors:
7 |
8 | 'randomhue' - HSV color with random hue, max brigthness and saturation.
9 | 'randomrgb' - random R,G,B.
10 | 'greyscale' - random R=G=B.
11 | 'image' - samples a random pixel from the specified image
12 | the image must be located relative to the current path
13 | (look at error message to see where Structure Synth tries to find the file.)
14 | 'list:xxx' - chooses a random color from the list.
15 |
16 | */
17 |
18 | //set colorpool randomhue
19 | //set colorpool randomrgb
20 | //set colorpool greyscale
21 | //set colorpool image:001.jpg
22 | set colorpool list:red,orange,yellow,white,white
23 |
24 |
25 | face
26 | { rx 90 } face
27 | { ry -90 } face
28 |
29 | rule face {
30 | 10 * { x 1 } 10 * { y 1 } 1 * { x -1 y -1 } mybox
31 | }
32 |
33 | rule mybox {
34 | { rz 5 ry 5 s 1 1 0.1 color random } box
35 | }
36 |
37 | rule mybox {
38 | { rz 5 ry -5 s 1 1 0.1 color random } box
39 | }
40 |
41 | rule mybox {
42 | { rz 5 rx -5 s 1 1 0.1 color random } box
43 | }
--------------------------------------------------------------------------------
/Examples/Tutorials/Raytracer - Light.es:
--------------------------------------------------------------------------------
1 | // Use the light command to control the lightning
2 | // Only one light source is possible, and it controls
3 | // both hard shadows and specular and diffuse lightning.
4 | set raytracer::light [0,0,5]
5 |
6 | // Camera settings. Place these before first rule call.
7 | set translation [-0.0593143 0.0238477 -20]
8 | set rotation [-0.00666739 0.999819 0.0178465 -0.999778 -0.00630773 -0.0201334 -0.0200167 -0.0179761 0.999636]
9 | set pivot [0 0 0]
10 | set scale 0.379953
11 |
12 | 1 * { x 2.5 } 20 * { rz 18 y 1 } 1 * { z 1 s 0.2 0.2 2 color white } box
13 | 1 * { x 5 } 20 * { rz 18 y 2 } 1 * { z 1 s 0.2 0.2 2 color white } box
14 | 1 * { x 7.5 } 20 * { rz 18 y 3 } 1 * { z 1 s 0.2 0.2 2 color white } box
15 | { s 50 50 0.1 color white } box
--------------------------------------------------------------------------------
/Examples/Tutorials/TriangleComposites.es:
--------------------------------------------------------------------------------
1 | // This example shows how to build
2 | // custom primitives from individual polygons.
3 | // Note that the Triangle primitives are NOT supported
4 | // by most of the templates.
5 |
6 | 5 * { x 2 } 5 * { y 2 hue 20 } house
7 |
8 | rule house {
9 | { color black s 1.01 } grid
10 | box
11 | { z 1 sat 0.4 } pyramid
12 | }
13 |
14 | rule house {
15 | { color black s 1.01 } grid
16 | box
17 | { z 1 } bar
18 | }
19 |
20 | rule pyramid {
21 | triangle[0,0,0;1,0,0;0.5,0.5,0.5]
22 | triangle[1,0,0;1,1,0;0.5,0.5,0.5]
23 | triangle[1,1,0;0,1,0;0.5,0.5,0.5]
24 | triangle[0,1,0;0,0,0;0.5,0.5,0.5]
25 | }
26 |
27 | rule bar {
28 | triangle[0,0,0;1,0,0;0.5,0,0.5]
29 | triangle[1,0,0;1,1,0;0.5,0,0.5]
30 | triangle[0.5,0,0.5;1,1,0;0.5,1,0.5]
31 | triangle[0,1,0;0.5,1,0.5;1,1,0]
32 | triangle[0,0,0;0.5,0,0.5;0,1,0]
33 | triangle[0.5,0,0.5;0.5,1,0.5;0,1,0]
34 | }
--------------------------------------------------------------------------------
/LICENSE.README:
--------------------------------------------------------------------------------
1 | This software is licensed under either LGPL 2.1 ("LICENSE.LGPL") or GPL 3 ("LICENSE.GPL3").
2 |
3 | The choice of license is determined and inherited from the version of Qt used.
4 | See: http://www.qtsoftware.com/products/licensing for more info.
5 |
--------------------------------------------------------------------------------
/Main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "StructureSynth/GUI/MainWindow.h"
4 |
5 | // Needed for unicode commandline below.
6 | #ifdef Q_WS_WIN
7 | #define WIN32_LEAN_AND_MEAN
8 | #include "windows.h"
9 | #endif
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | Q_INIT_RESOURCE(StructureSynth);
14 | //QApplication::setStyle("cleanlooks");
15 | QApplication app(argc, argv);
16 |
17 | QCoreApplication::setOrganizationName("Syntopia Software");
18 | QCoreApplication::setApplicationName("Structure Synth");
19 |
20 | QPixmap pixmap(QDir(StructureSynth::GUI::MainWindow::getMiscDir()).absoluteFilePath("splash.png"));
21 | QSplashScreen splash(pixmap, Qt::WindowStaysOnTopHint);
22 | splash.setMask(pixmap.mask());
23 | splash.show();
24 | qApp->processEvents();
25 |
26 | // We will parse for filenames.
27 | // On Windows 'argv*' is not of much use, since it fails for Unicode paths.
28 | // We will fetch the unicode strings...
29 | QStringList args;
30 |
31 | #ifdef Q_WS_WIN
32 | // On Windows we call this Win32 call...
33 | int nArgs = 0;
34 | LPWSTR* wargv = CommandLineToArgvW(GetCommandLineW(), &nArgs);
35 | for (int i = 0; i < nArgs; i++) { args.append(QString::fromUtf16((const ushort *)wargv[i])); }
36 | #else
37 | // Other platforms must implement their unicode parsing here...
38 | // I believe Linux and Unix will store UTF8 in the argv array.
39 | for (int i = 0; i < argc; i++) {
40 | args.append(QString::fromUtf8(argv[i]));
41 | }
42 | #endif
43 |
44 | StructureSynth::GUI::MainWindow *mainWin;
45 | if (args.size() <= 1) {
46 | mainWin = new StructureSynth::GUI::MainWindow();
47 | } else {
48 | // We ignore more then one argument
49 | mainWin = new StructureSynth::GUI::MainWindow(args[1]);
50 | }
51 | mainWin->show();
52 | splash.show();
53 | return app.exec();
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/Misc/Blender_Importer_2.rendertemplate:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | This is an exporter that can be used together with the Blender_Importer_2.py script.
7 | Author: David Bucciarelli, modded by SourceZuka.
8 | (I added the above info, please correct me if I'm wrong - Mikael/Syntopia)
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Misc/SunFlow-Monochrome.rendertemplate:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | This is a simple monochrome export template for Sunflow.
7 | All objects colors will be white, except the background color, which may be changed.
8 |
9 | Template by Syntopia.
10 |
11 |
12 |
105 |
106 |
107 |
108 |
111 |
112 |
113 |
114 |
122 |
123 |
124 |
125 |
133 |
134 |
--------------------------------------------------------------------------------
/Misc/Sunflow-Colored.rendertemplate:
--------------------------------------------------------------------------------
1 |
2 |
3 | A simple Sunflow render template, using one shader for each object.
4 | The template uses ambient occlusion lightning, which means there is no need to worry about setting up light sources.
5 |
6 | This template is a good choice for trying out Sunflow.
7 |
8 | Original template by Syntopia.
9 | The Sunflow coloring was added by Tom Beddard ('subblue')
10 |
11 |
94 |
97 |
114 |
128 |
129 |
--------------------------------------------------------------------------------
/Misc/Sunflow-Ward.rendertemplate:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | This is an example of a render template, using one Ward shader for each object.
7 |
8 | Template by Syntopia.
9 |
10 |
11 |
108 |
109 |
110 |
111 |
114 |
115 |
116 |
117 |
133 |
134 |
135 |
136 |
154 |
155 |
--------------------------------------------------------------------------------
/Misc/about.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Misc/about.html
--------------------------------------------------------------------------------
/Misc/appleseed.rendertemplate:
--------------------------------------------------------------------------------
1 |
2 |
3 | A template for the appleseed renderer (http://appleseedhq.net/).
4 |
5 | Renders using ambient occlusion.
6 |
7 | Version 1.0.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | {CamColumnMatrix}
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
37 | ]]>
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
51 |
52 |
53 |
54 |
55 |
56 | ]]>
57 |
58 |
59 |
60 |
61 |
62 | {columnmatrix}
63 |
64 |
65 |
66 | ]]>
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | ]]>
78 |
79 |
80 |
--------------------------------------------------------------------------------
/Misc/cube.obj:
--------------------------------------------------------------------------------
1 | # Exported from Wings 3D 1.3.0.1
2 | mtllib cube.mtl
3 | o cube
4 | #8 vertices, 6 faces
5 | v -0.50000000 0.0000000e+0 -0.50000000
6 | v 0.50000000 0.0000000e+0 -0.50000000
7 | v -0.50000000 1.00000000 -0.50000000
8 | v 0.50000000 1.00000000 -0.50000000
9 | v -0.50000000 0.0000000e+0 0.50000000
10 | v 0.50000000 0.0000000e+0 0.50000000
11 | v -0.50000000 1.00000000 0.50000000
12 | v 0.50000000 1.00000000 0.50000000
13 | vt 4.9500000e-3 4.9500000e-3
14 | vt 4.9500000e-3 0.99504900
15 | vt 0.99504900 4.9500000e-3
16 | vt 0.99504900 0.99504900
17 | vn 0.0000000e+0 0.0000000e+0 -1.00000000
18 | vn 0.0000000e+0 -1.00000000 0.0000000e+0
19 | vn -1.00000000 0.0000000e+0 0.0000000e+0
20 | vn 0.0000000e+0 0.0000000e+0 -1.00000000
21 | vn 0.0000000e+0 -1.00000000 0.0000000e+0
22 | vn 1.00000000 0.0000000e+0 0.0000000e+0
23 | vn 0.0000000e+0 0.0000000e+0 -1.00000000
24 | vn 0.0000000e+0 1.00000000 0.0000000e+0
25 | vn -1.00000000 0.0000000e+0 0.0000000e+0
26 | vn 0.0000000e+0 0.0000000e+0 -1.00000000
27 | vn 1.00000000 0.0000000e+0 0.0000000e+0
28 | vn 0.0000000e+0 1.00000000 0.0000000e+0
29 | vn 0.0000000e+0 0.0000000e+0 1.00000000
30 | vn 0.0000000e+0 -1.00000000 0.0000000e+0
31 | vn -1.00000000 0.0000000e+0 0.0000000e+0
32 | vn 0.0000000e+0 0.0000000e+0 1.00000000
33 | vn 0.0000000e+0 -1.00000000 0.0000000e+0
34 | vn 1.00000000 0.0000000e+0 0.0000000e+0
35 | vn 0.0000000e+0 0.0000000e+0 1.00000000
36 | vn 0.0000000e+0 1.00000000 0.0000000e+0
37 | vn -1.00000000 0.0000000e+0 0.0000000e+0
38 | vn 0.0000000e+0 0.0000000e+0 1.00000000
39 | vn 1.00000000 0.0000000e+0 0.0000000e+0
40 | vn 0.0000000e+0 1.00000000 0.0000000e+0
41 | g cube
42 | usemtl Default
43 | s 1
44 | f 1/2/1 3/2/7 4/4/10 2/4/4
45 | f 6/3/16 8/3/22 7/1/19 5/1/13
46 | s 2
47 | f 1/2/3 5/1/15 7/1/21 3/2/9
48 | f 4/4/11 8/3/23 6/3/18 2/4/6
49 | s 3
50 | f 2/4/5 6/3/17 5/1/14 1/2/2
51 | f 3/2/8 7/1/20 8/3/24 4/4/12
52 |
--------------------------------------------------------------------------------
/Misc/icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Misc/icon.jpg
--------------------------------------------------------------------------------
/Misc/povray.rendertemplate:
--------------------------------------------------------------------------------
1 |
2 |
3 | A rough POV-Ray export template.
4 | Notice that the camera position is not handled correctly in all cases yet.
5 |
6 | Template by Syntopia.
7 |
8 |
15 | }
16 |
17 | // Finish and normal
18 | #declare DEFFIN = finish { ambient 0.1 diffuse 0.5 specular 0.5 };
19 | #declare DEFNOR = normal { dents 0 scale 0.01 };
20 |
21 | // Background
22 | plane {
23 | z, 100.0
24 | texture {
25 | pigment { color rgb <0.0,0.0,0.0> }
26 | finish { ambient 1 }
27 | }
28 | hollow
29 | }
30 |
31 | // Camera
32 | camera {
33 | location <{CamPosX},{CamPosY},{CamPosZ}>
34 | look_at <{CamTargetX},{CamTargetY},{CamTargetZ}>
35 | direction <{CamDirX},{CamDirY},{CamDirZ}>
36 | right <{CamRightX}*{aspect},{CamRightY}*{aspect},{CamRightZ}*{aspect}>
37 | up <{CamUpX},{CamUpY},{CamUpZ}>
38 | angle 60
39 | }
40 |
41 | // Lights
42 | light_source { <500,500,-1000> rgb <1,1,1> shadowless }
43 | light_source { <-500,-500,-1000> rgb <1,1,1> shadowless }
44 | light_source { <-500,500,1000> rgb <1,1,1> shadowless }
45 | ]]>
46 |
51 | , <1, 1, 1> }
54 | matrix < {povmatrix} >
55 | texture { pigment { color rgbt <{r},{g},{b},{oneminusalpha}> } finish { DEFFIN } normal { DEFNOR } }
56 | }
57 | ]]>
58 | , {rad} }
61 | texture { pigment { color rgbt <{r},{g},{b},{oneminusalpha}> } finish { DEFFIN } normal { DEFNOR } }
62 | }
63 | ]]>
64 |
65 | intersection {
66 |
67 |
68 | }
69 |
70 |
71 | union {
72 |
73 |
74 | }
75 |
76 |
77 | difference {
78 |
79 |
80 | }
81 |
82 |
83 |
--------------------------------------------------------------------------------
/Misc/povray2.rendertemplate:
--------------------------------------------------------------------------------
1 |
2 |
3 | A rough POV-Ray export template.
4 | Notice that the camera position is not handled correctly in all cases yet.
5 |
6 | Template by Syntopia.
7 |
8 |
15 | }
16 |
17 | #default {
18 | texture {
19 | pigment { color rgb 1 }
20 | finish { ambient 0.1 diffuse 0.5 specular 0.5 }
21 | normal { dents 0 scale 0.01 }
22 | }
23 | }
24 |
25 | // Background
26 | plane {
27 | z, 100.0
28 | texture {
29 | pigment { color rgb <0.0,0.0,0.0> }
30 | finish { ambient 1 }
31 | }
32 | hollow
33 | }
34 |
35 | // Camera
36 | camera {
37 | location <{CamPosX},{CamPosY},{CamPosZ}>
38 | right <{CamRightX}*{aspect},{CamRightY}*{aspect},{CamRightZ}*{aspect}>
39 | up <{CamUpX},{CamUpY},{CamUpZ}>
40 | look_at <{CamTargetX},{CamTargetY},{CamTargetZ}>
41 |
42 | }
43 |
44 | // Lights
45 | light_source { <500,500,-1000> rgb <1,1,1> }
46 | light_source { <-500,-500,-1000> rgb <1,1,1> }
47 | light_source { <-500,500,1000> rgb <1,1,1> }
48 | ]]>
49 |
54 | , <1, 1, 1> }
57 | matrix < {povmatrix} >
58 | texture { pigment { color rgbt <{r},{g},{b},{oneminusalpha}> } }
59 | }
60 | ]]>
61 | , {rad} }
64 | texture { pigment { color rgbt <{r},{g},{b},{oneminusalpha}> } }
65 | }
66 | ]]>
67 |
68 | intersection {
69 |
70 |
71 | }
72 |
73 |
74 | union {
75 |
76 |
77 | }
78 |
79 |
80 | difference {
81 |
82 |
83 | }
84 |
85 |
86 |
--------------------------------------------------------------------------------
/Misc/renderman.rendertemplate:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Structure Synth export template for Renderman compliant renderers.
5 |
6 | This template is created by Tom Beddard ('subblue')
7 |
8 | # Open-source renderman solutions
9 | # Aqsis: http://www.aqsis.org/
10 | # Pixie: http://www.renderpixie.com/
11 | # Lots more info from the Renderman Repository:
12 | # http://www.renderman.org/RMR/
13 |
14 |
15 |
46 |
47 |
48 |
49 |
52 |
53 |
54 |
55 |
63 |
64 |
65 |
66 |
74 |
75 |
76 |
77 |
85 |
86 |
--------------------------------------------------------------------------------
/Misc/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/Misc/splash.png
--------------------------------------------------------------------------------
/StructureSynth.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/StructureSynth.ico
--------------------------------------------------------------------------------
/StructureSynth.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/copy.png
4 | images/cut.png
5 | images/new.png
6 | images/open.png
7 | images/paste.png
8 | images/save.png
9 | images/filesaveas.png
10 | images/folder.png
11 | images/mail_new.png
12 | images/render.png
13 | images/agt_internet.png
14 | images/exit.png
15 | images/fileclose.png
16 | images/documentinfo.png
17 | images/structuresynth.png
18 |
19 |
20 |
--------------------------------------------------------------------------------
/StructureSynth.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual C++ Express 2008
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StructureSynth", "StructureSynth.vcproj", "{D41D8CD9-8F00-3204-A980-0998ECF8427E}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {D41D8CD9-8F00-3204-A980-0998ECF8427E}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {D41D8CD9-8F00-3204-A980-0998ECF8427E}.Debug|Win32.Build.0 = Debug|Win32
14 | {D41D8CD9-8F00-3204-A980-0998ECF8427E}.Release|Win32.ActiveCfg = Release|Win32
15 | {D41D8CD9-8F00-3204-A980-0998ECF8427E}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/StructureSynth/GUI/TemplateExportDialog.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "../Model/Rendering/TemplateRenderer.h"
31 |
32 | namespace StructureSynth {
33 | namespace GUI {
34 |
35 |
36 | class MainWindow; // Forward declaration.
37 |
38 | /// The Variable Editor window.
39 | class TemplateExportDialog : public QDialog {
40 | Q_OBJECT
41 | public:
42 | TemplateExportDialog(MainWindow* parent, QStringList primitives);
43 | ~TemplateExportDialog();
44 |
45 |
46 | void setTemplatePath(QString templatePath);
47 | void setDefaultSize(int width, int height);
48 | void changeFileNameExtension(QString extension);
49 |
50 |
51 | public slots:
52 | void multiplySize(double d);
53 | void halfSize();
54 | void doubleSize();
55 | void defaultSize();
56 | void accept();
57 | void reject();
58 | void templateChanged(const QString &);
59 | void saveModifications();
60 | void undo();
61 | void textChanged();
62 | void tabChanged(int i);
63 |
64 |
65 | void lockAspectChanged();
66 | void heightChanged(int);
67 | void widthChanged(int);
68 | void selectFileName();
69 | void uniqueToggled(bool);
70 | void updateUniqueFileName(const QString &);
71 |
72 |
73 | void fileRadioButtonToggled(bool);
74 | void changeTemplatePath();
75 |
76 | protected:
77 | void retranslateUi();
78 |
79 | void setupUi();
80 |
81 | private:
82 | void setAspectLabel(double ratio) ;
83 | Model::Rendering::Template currentTemplate;
84 |
85 | QStringList primitives;
86 | QString path;
87 | QVBoxLayout *verticalLayout;
88 | QHBoxLayout *horizontalLayout;
89 | QLabel *label;
90 | QComboBox *templateComboBox;
91 | QPushButton *templatePathButton;
92 | QTabWidget *tabWidget;
93 | QWidget *settingstab;
94 | QVBoxLayout *verticalLayout_3;
95 | QLabel *descriptionLabel;
96 | QTextBrowser *descriptionTextBrowser;
97 | QLabel *primitivesLabel;
98 | QTableWidget *primitivesTableWidget;
99 | QGroupBox *templateOutputGroupBox;
100 | QVBoxLayout *verticalLayout_2;
101 | QHBoxLayout *horizontalLayout_2;
102 | QRadioButton *fileRadioButton;
103 | QLineEdit *fileNameLineEdit;
104 | QPushButton *filePushButton;
105 | QHBoxLayout *horizontalLayout_3;
106 | QSpacerItem *horizontalSpacer;
107 | QCheckBox *uniqueCheckBox;
108 | QCheckBox *autoSaveCheckBox;
109 | QRadioButton *clipboardRadioButton;
110 | QGroupBox *postProcessingGroupBox;
111 | QVBoxLayout *verticalLayout_4;
112 | QCheckBox *runAfterCheckBox;
113 | QHBoxLayout *horizontalLayout_4;
114 | QSpacerItem *horizontalSpacer_2;
115 | QLineEdit *afterCommandLineEdit;
116 | QWidget *advancedTab;
117 | QVBoxLayout *verticalLayout_5;
118 | QHBoxLayout *horizontalLayout_5;
119 | QLabel *label_4;
120 | QSpinBox *widthSpinBox;
121 | double aspectRatio;
122 | QLabel *label_5;
123 | QSpinBox *heightSpinBox;
124 | QFrame *line;
125 | QCheckBox *lockAspectRatioCheckBox;
126 | QSpacerItem *horizontalSpacer_4;
127 | QLabel *modifyTemplateLabel;
128 | QTextEdit *templateTextEdit;
129 | QHBoxLayout *horizontalLayout_6;
130 | QSpacerItem *horizontalSpacer_3;
131 | QPushButton *saveModificationsButton;
132 | QPushButton *undoButton;
133 | QCheckBox * modifyOutputCheckBox;
134 | QDialogButtonBox *buttonBox;
135 | QString modifiedTemplate;
136 | MainWindow* mainWindow;
137 | QString uniqueFileName;
138 | int screenWidth;
139 | int screenHeight;
140 | };
141 |
142 |
143 | }
144 | }
145 |
146 |
--------------------------------------------------------------------------------
/StructureSynth/GUI/VariableEditor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "../Parser/Preprocessor.h"
11 |
12 | /// Classes for the GUI Editor for the preprocessor constant variables.
13 | /// E.g. the line: #define angle 45 (float:0.0-360.0)
14 | /// will make a simple editor widget appear.
15 | namespace StructureSynth {
16 | namespace GUI {
17 |
18 | class VariableWidget; // Forward decl...
19 |
20 | /// The Variable Editor window.
21 | class VariableEditor : public QWidget {
22 | public:
23 | VariableEditor(QWidget* parent);
24 |
25 | QString updateFromPreprocessor(Parser::Preprocessor* pp, QString in, bool* showGUI);
26 |
27 | private:
28 |
29 | QSpacerItem* spacer;
30 | QVector variables;
31 | QVBoxLayout* layout;
32 | };
33 |
34 | // A helper class (combined float slider+spinner)
35 | class ComboSlider : public QWidget {
36 | Q_OBJECT
37 | public:
38 | ComboSlider(QWidget* parent, double defaultValue, double minimum, double maximum)
39 | : QWidget(parent), defaultValue(defaultValue), minimum(minimum), maximum(maximum){
40 | setLayout(new QHBoxLayout());
41 | slider = new QSlider(Qt::Horizontal,this);
42 | slider->setRange(0,1000);
43 | double val = (defaultValue-minimum)/(maximum-minimum);
44 | slider->setValue(val*1000);
45 | spinner = new QDoubleSpinBox(this);
46 | spinner->setMaximum(maximum);
47 | spinner->setMinimum(minimum);
48 | spinner->setValue(defaultValue);
49 | layout()->addWidget(slider);
50 | layout()->addWidget(spinner);
51 | connect(spinner, SIGNAL(valueChanged(double)), this, SLOT(spinnerChanged(double)));
52 | connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int)));
53 | }
54 |
55 | double getValue() { return spinner->value(); }
56 |
57 | protected slots:
58 | void spinnerChanged(double) {
59 | double val = (spinner->value()-minimum)/(maximum-minimum);
60 | slider->setValue(val*1000);
61 | }
62 |
63 | void sliderChanged(int) {
64 | double val = (slider->value()/1000.0)*(maximum-minimum)+minimum;
65 | spinner->setValue(val);
66 | }
67 |
68 | private:
69 |
70 | QSlider* slider;
71 | QDoubleSpinBox* spinner;
72 | double defaultValue;
73 | double minimum;
74 | double maximum;
75 | };
76 |
77 | // A helper class (combined int slider+spinner)
78 | class IntComboSlider : public QWidget {
79 | Q_OBJECT
80 | public:
81 | IntComboSlider(QWidget* parent, int defaultValue, int minimum, int maximum)
82 | : QWidget(parent), defaultValue(defaultValue), minimum(minimum), maximum(maximum){
83 | setLayout(new QHBoxLayout());
84 | slider = new QSlider(Qt::Horizontal,this);
85 | slider->setRange(minimum,maximum);
86 | slider->setValue(defaultValue);
87 | spinner = new QSpinBox(this);
88 | spinner->setMaximum(maximum);
89 | spinner->setMinimum(minimum);
90 | spinner->setValue(defaultValue);
91 | layout()->addWidget(slider);
92 | layout()->addWidget(spinner);
93 | connect(spinner, SIGNAL(valueChanged(int)), this, SLOT(spinnerChanged(int)));
94 | connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int)));
95 | }
96 |
97 | int getValue() { return spinner->value(); }
98 |
99 | protected slots:
100 | void spinnerChanged(int) {
101 | int val = spinner->value();
102 | slider->setValue(val);
103 | }
104 |
105 | void sliderChanged(int) {
106 | double val = slider->value();
107 | spinner->setValue(val);
108 | }
109 |
110 | private:
111 |
112 | QSlider* slider;
113 | QSpinBox* spinner;
114 | int defaultValue;
115 | int minimum;
116 | int maximum;
117 | };
118 |
119 | }
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/StructureSynth/JavaScriptSupport/Debug.cpp:
--------------------------------------------------------------------------------
1 | #if defined(_MSC_VER)
2 | // disable warning "'QtConcurrent::BlockSizeManager' : assignment operator could not be generated"
3 | #pragma warning( disable : 4512 )
4 | #endif
5 |
6 | #include "Debug.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include "SyntopiaCore/Logging/Logging.h"
15 | #include "../../SyntopiaCore/Exceptions/Exception.h"
16 | #include "../../SyntopiaCore/GLEngine/Sphere.h"
17 |
18 | using namespace SyntopiaCore::Logging;
19 | using namespace SyntopiaCore::Exceptions;
20 |
21 |
22 | namespace StructureSynth {
23 | namespace JavaScriptSupport {
24 |
25 | namespace {
26 | // Dont know why Qt has chosen to make 'sleep' protected.
27 | class MyThread : public QThread {
28 | public:
29 | static void sleep(unsigned long msecs) { msleep(msecs); }
30 | };
31 |
32 |
33 | };
34 |
35 | Debug::Debug(QStatusBar* statusBar) : statusBar(statusBar) {
36 | progress = 0;
37 | }
38 |
39 | Debug::~Debug() {
40 | }
41 |
42 | void Debug::Info(QString input) {
43 | INFO(input);
44 | }
45 |
46 | void Debug::Message(QString input) {
47 | QMessageBox::information(0, "JavaScript Message", input);
48 | }
49 |
50 | void Debug::ShowProgress(QString caption) {
51 | delete(progress);
52 | progress = new QProgressDialog(caption, "Cancel", 0, 1000, 0);
53 | progress->setWindowModality(Qt::WindowModal);
54 | progress->show();
55 |
56 | }
57 |
58 | void Debug::SetProgress(double percentage) {
59 | if (progress) progress->setValue(percentage*1000.0);
60 | qApp->processEvents();
61 | }
62 |
63 | void Debug::HideProgress() {
64 | delete(progress);
65 | progress = 0;
66 | }
67 |
68 | void Debug::Sleep(int ms) {
69 | MyThread::sleep(ms);
70 | }
71 |
72 |
73 | void Debug::waitForMouseButton() {
74 | while (true) {
75 |
76 | statusBar->showMessage("Left Mousebutton to continue, right to quit.", 4000);
77 | if (QApplication::mouseButtons() == Qt::LeftButton) {
78 | //statusBar->showMessage("");
79 |
80 | break;
81 | } else if (QApplication::mouseButtons() == Qt::RightButton) {
82 | //statusBar->showMessage("");
83 | throw Exception("");
84 | break;
85 | }
86 | qApp->processEvents();
87 | //QThread::msleep(100);
88 |
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/StructureSynth/JavaScriptSupport/Debug.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "../../SyntopiaCore/Math/Vector3.h"
8 | #include "../../SyntopiaCore/GLEngine/EngineWidget.h"
9 | #include "../GUI/MainWindow.h"
10 |
11 | namespace StructureSynth {
12 | namespace JavaScriptSupport {
13 |
14 | /// Write info to console (available as a Global object field in the JavaScript environment).
15 | class Debug : public QObject {
16 | Q_OBJECT
17 |
18 | public:
19 | Debug(QStatusBar* statusBar);
20 | ~Debug();
21 |
22 | public slots:
23 | void Info(QString input);
24 | void Message(QString input);
25 | void ShowProgress(QString caption);
26 | void SetProgress(double percentage); // between 0 and 1
27 | void HideProgress();
28 | void Sleep(int ms);
29 | void waitForMouseButton();
30 |
31 | private:
32 | QProgressDialog* progress;
33 | QStatusBar* statusBar;
34 | };
35 |
36 |
37 | }
38 | }
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/StructureSynth/JavaScriptSupport/JavaScriptParser.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include "../GUI/MainWindow.h"
6 |
7 |
8 | namespace StructureSynth {
9 | namespace JavaScriptSupport {
10 |
11 | /// Responsible for setting up the JavaScript environment and parsing
12 | class JavaScriptParser {
13 | public:
14 | JavaScriptParser(StructureSynth::GUI::MainWindow* mainWindow, QStatusBar* statusBar);
15 | ~JavaScriptParser();
16 |
17 | void parse(QString input, QString dir);
18 | private:
19 | StructureSynth::GUI::MainWindow* mainWindow;
20 | QStatusBar* statusBar;
21 | };
22 |
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Action.cpp:
--------------------------------------------------------------------------------
1 | #include "Action.h"
2 | #include "ExecutionStack.h"
3 | #include "Builder.h"
4 |
5 | #include "../../SyntopiaCore/Logging/Logging.h"
6 |
7 | using namespace SyntopiaCore::Logging;
8 |
9 | namespace StructureSynth {
10 | namespace Model {
11 | void Action::apply(Builder* b, const Rule* callingRule, int ruleDepth) const {
12 | bool rememberPreviousMatrix = true; // at some point we might make this optional -> only needed for grid meshes...
13 |
14 | if (set != 0) {
15 | b->setCommand(set->key, set->value);
16 | return;
17 | }
18 |
19 | State s = b->getState();
20 |
21 |
22 | QList counters;
23 | for (int i = 0; i < loops.size(); i++) counters.append(1);
24 |
25 | if (counters.size() == 0) {
26 | if (callingRule) {
27 | s.maxDepths[callingRule] = ruleDepth;
28 | }
29 | b->getNextStack().append(RuleState(rule->rule(), s));
30 | return;
31 | }
32 |
33 | bool done = false;
34 | while (!done) {
35 |
36 | // create state
37 | State s0 = s;
38 | if (rememberPreviousMatrix) {
39 | // Copy the old matrix...
40 | s0.setPreviousState(s.matrix, s.hsv, s.alpha);
41 | }
42 | for (int i = 0; i < counters.size(); i++) {
43 | for (int j = 0; j < counters[i]; j++) {
44 | s0 = loops[i].transformation.apply(s0, b->getColorPool());
45 | }
46 | }
47 | if (callingRule) {
48 | s0.maxDepths[callingRule] = ruleDepth;
49 | }
50 | b->getNextStack().append(RuleState(rule->rule(), s0));
51 |
52 | // increase lowest counter...
53 | counters[0]++;
54 | for (int i = 0; i < counters.size(); i++) {
55 | if (counters[i] > loops[i].repetitions) {
56 | if (i == counters.size()-1) {
57 | done = true;
58 | } else {
59 | counters[i] = 1;
60 | counters[i+1]++;
61 | }
62 | }
63 | }
64 |
65 | }
66 | }
67 |
68 | Action::Action(QString key, QString value) {
69 | set = new SetAction();
70 | set->key = key;
71 | set->value = value;
72 | rule = 0;
73 | }
74 |
75 | Action::~Action() {
76 | // TODO: Handle leaks (Actions are treated as value types, and hence rule,set ptrs are duped)
77 | //delete(rule);
78 | //delete(set);
79 | }
80 |
81 |
82 | void Action::addTransformationLoop(TransformationLoop tl) {
83 | loops.append(tl);
84 | }
85 |
86 | void Action::setRule(QString ruleName) {
87 | rule = new RuleRef(ruleName);
88 | set = 0;
89 | }
90 |
91 | Action::Action(Transformation t, QString ruleName) {
92 | loops.append(TransformationLoop(1, t));
93 | rule = new RuleRef(ruleName);
94 | set = 0;
95 | }
96 |
97 | Action::Action(QString ruleName) {
98 | rule = new RuleRef(ruleName);
99 | set = 0;
100 | }
101 |
102 | }
103 | }
104 |
105 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Action.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "RuleRef.h"
4 | #include "TransformationLoop.h"
5 |
6 | namespace StructureSynth {
7 | namespace Model {
8 |
9 | struct SetAction {
10 | QString key;
11 | QString value;
12 | };
13 |
14 | /// An actions is a number of loops, that is applied to a rule.
15 | ///
16 | /// Rules with only one transformation, e.g.:
17 | /// { x 1 } R1
18 | /// are represented as a loop transformation with one repetitions.
19 | class Action {
20 | public:
21 | Action(Transformation t, QString ruleName);
22 | Action(QString ruleName);
23 | Action(QString key, QString value);
24 | Action() { rule = 0; set = 0; }
25 |
26 | void addTransformationLoop(TransformationLoop tl);
27 | void setRule(QString rule);
28 |
29 | ~Action();
30 |
31 | /// If 'callingRule' != 0 the new states generated will be set with
32 | /// a depth equal to 'ruleDepth'
33 | void apply(Builder* b, const Rule* callingRule, int ruleDepth) const;
34 | RuleRef* getRuleRef() const { return rule; }
35 |
36 | private:
37 | QList loops;
38 | RuleRef* rule; // The rule that will be called after all transformations.
39 | SetAction* set;
40 | };
41 |
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/StructureSynth/Model/AmbiguousRule.cpp:
--------------------------------------------------------------------------------
1 | #include "AmbiguousRule.h"
2 |
3 | #include "Builder.h"
4 | #include "RandomStreams.h"
5 |
6 | #include "../../SyntopiaCore/Logging/Logging.h"
7 |
8 | using namespace SyntopiaCore::Logging;
9 |
10 |
11 | namespace StructureSynth {
12 | namespace Model {
13 |
14 | QList AmbiguousRule::getRuleRefs() const {
15 | QList list;
16 | for (int i = 0; i < rules.size(); i++) {
17 | for (int j = 0; j < rules[i]->getRuleRefs().size(); j++) {
18 | list.append(rules[i]->getRuleRefs()[j]);
19 | }
20 | }
21 | return list;
22 | }
23 |
24 | void AmbiguousRule::apply(Builder* builder) const {
25 | // Calc sum of weigths
26 | double totalWeight = 0;
27 | for (int i = 0; i < rules.size(); i++) {
28 | totalWeight += rules[i]->getWeight();
29 | }
30 |
31 |
32 | double random = totalWeight*RandomStreams::Geometry()->getDouble();
33 |
34 |
35 | // Choose a random rule according to weights
36 | double accWeight = 0;
37 | for (int i = 0; i < rules.size(); i++) {
38 | accWeight += rules[i]->getWeight();
39 | if (random <= accWeight) {
40 | rules[i]->apply(builder);
41 | return;
42 | }
43 | }
44 | rules[rules.size()-1]->apply(builder);
45 |
46 | WARNING("Assertion failed: in AmbiguousRule::apply");
47 |
48 | };
49 |
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/StructureSynth/Model/AmbiguousRule.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rule.h"
4 | #include "CustomRule.h"
5 |
6 | namespace StructureSynth {
7 | namespace Model {
8 |
9 |
10 | /// If several definitions for the same rule exists,
11 | /// an Ambiguous Rule is created which contains the multiple definitions.
12 | ///
13 | /// When the rule is executed, a random rule is chosen from the multiple definitions,
14 | /// taking their weights into account.
15 | class AmbiguousRule : public Rule {
16 | public:
17 | AmbiguousRule(QString name) : Rule(name) {};
18 |
19 | virtual void apply(Builder* builder) const;
20 |
21 | /// Returns a list over rules that this rule references.
22 | virtual QList getRuleRefs() const;
23 |
24 | QList getRules() { return rules; };
25 |
26 | void appendRule(CustomRule* r) { rules.append(r); }
27 |
28 | virtual void setMaxDepth(int maxDepth) { for (int i = 0; i < rules.size(); i++) rules[i]->setMaxDepth(maxDepth); }
29 |
30 | private:
31 | QList rules;
32 | };
33 |
34 |
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Builder.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include "Rendering/Renderer.h"
6 | #include "RuleSet.h"
7 | #include "State.h"
8 | #include "ColorPool.h"
9 | #include "ExecutionStack.h"
10 |
11 | #include "../../SyntopiaCore/Math/Matrix4.h"
12 | #include "../../SyntopiaCore/GLEngine/EngineWidget.h"
13 |
14 |
15 | namespace StructureSynth {
16 | namespace Model {
17 |
18 |
19 | using namespace SyntopiaCore;
20 |
21 | /// A Builder executes the rule set on a Renderer object
22 | class Builder {
23 | public:
24 | Builder(Rendering::Renderer* renderTarget, RuleSet* ruleSet, bool verbose);
25 | ~Builder();
26 | void build();
27 |
28 | void setCommand(QString command, QString param);
29 | ExecutionStack& getNextStack();
30 | State& getState() { return state; };
31 | Rendering::Renderer* getRenderer() { return renderTarget; };
32 | void increaseObjectCount() { objects++; };
33 |
34 | // True, if the random seed was changed by the builder (by 'set seed ')
35 | bool seedChanged() { return hasSeedChanged; }
36 | int getNewSeed() { return newSeed; }
37 | ColorPool* getColorPool() { return colorPool; }
38 | QVector getRaytracerCommands() { return raytracerCommands; };
39 | bool wasCancelled() { return userCancelled; }
40 |
41 | private:
42 | void recurseBreadthFirst(QProgressDialog& progressDialog, int& maxTerminated, int& minTerminated, int& generationCounter);
43 | void recurseDepthFirst(QProgressDialog& progressDialog, int& maxTerminated, int& minTerminated, int& generationCounter);
44 |
45 | State state;
46 |
47 | bool userCancelled;
48 |
49 | ExecutionStack stack;
50 | ExecutionStack nextStack;
51 | Rendering::Renderer* renderTarget;
52 | RuleSet* ruleSet;
53 | bool verbose;
54 | int maxGenerations;
55 | int maxObjects;
56 | int objects;
57 | int newSeed;
58 | bool hasSeedChanged;
59 | float minDim;
60 | float maxDim;
61 | bool syncRandom;
62 | int initialSeed;
63 | State* currentState;
64 | ColorPool* colorPool;
65 | QVector raytracerCommands;
66 | };
67 |
68 |
69 |
70 |
71 | }
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/StructureSynth/Model/ColorPool.cpp:
--------------------------------------------------------------------------------
1 | #include "ColorPool.h"
2 |
3 | #include "../../SyntopiaCore/Logging/Logging.h"
4 | #include "../../SyntopiaCore/Exceptions/Exception.h"
5 | #include "Builder.h"
6 | #include "RandomStreams.h"
7 |
8 |
9 | #include
10 | #include
11 |
12 |
13 | using namespace SyntopiaCore::Logging;
14 | using namespace SyntopiaCore::Exceptions;
15 |
16 | namespace StructureSynth {
17 | namespace Model {
18 |
19 | ColorPool::ColorPool(QString initString) {
20 | initString = initString.toLower();
21 | picture = 0;
22 |
23 | if (initString == "randomhue") {
24 | type = RandomHue;
25 | } else if (initString == "greyscale" || initString == "grayscale" ) {
26 | type = GreyScale;
27 | } else if (initString == "randomrgb") {
28 | type = RandomRGB;
29 | } else if (initString.startsWith("image:")) {
30 | initString = initString.remove("image:");
31 | type = Picture;
32 |
33 | if (!QFile::exists(initString)) {
34 | throw Exception(QString("Could not open file: %1").arg(QFileInfo(initString).absoluteFilePath()));
35 | }
36 |
37 | picture = new QImage(initString);
38 | if (picture->isNull()) {
39 | throw Exception(QString("Could not parse image file: %1").arg(QFileInfo(initString).absoluteFilePath()));
40 | }
41 |
42 | } else if (initString.startsWith("list:")) {
43 | initString = initString.remove("list:");
44 | QStringList l = initString.split(",");
45 | for (int i = 0; i < l.count(); i++) {
46 | QColor c(l[i]);
47 | if (!c.isValid()) {
48 | throw Exception(QString("Could not parse color in colorlist: %1").arg(initString));
49 | }
50 | colorList.append(c);
51 | }
52 | type = ColorList;
53 | } else {
54 | throw Exception(QString("Could not understand the color pool: %1. Try: RandomHue, RandomRGB, GrayScale, Image:test.png, List:#234,Red,Blue").arg(initString));
55 | }
56 | }
57 |
58 | ColorPool::~ColorPool() {
59 | delete picture;
60 | }
61 |
62 | QColor ColorPool::drawColor() {
63 | if (type == RandomHue) {
64 | return QColor::fromHsv(RandomStreams::Color()->getInt(359),255,255);
65 | } else if (type == GreyScale) {
66 | int r = RandomStreams::Color()->getInt(255);
67 | return QColor(r,r,r).toHsv();
68 | } else if (type == RandomRGB) {
69 | // We can only pull one random number, so we must use a few tricks to get three ints
70 | int r = RandomStreams::Color()->getInt(255);
71 | int g = RandomStreams::Color()->getInt(255);
72 | int b = RandomStreams::Color()->getInt(255);
73 | return QColor(r,g,b).toHsv();
74 | } else if (type == Picture) {
75 | int x = RandomStreams::Color()->getInt(picture->width()-1);
76 | int y = RandomStreams::Color()->getInt(picture->height()-1);
77 | QRgb rgb = picture->pixel(x,y);
78 | return QColor(rgb).toHsv();
79 | } else if (type == ColorList) {
80 | int id = RandomStreams::Color()->getInt(colorList.count()-1);
81 | return colorList[id];
82 | }
83 | return QColor();
84 | }
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/StructureSynth/Model/ColorPool.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace StructureSynth {
9 | namespace Model {
10 |
11 | /// A ColorPool is a set or colors. It is used for drawing random colors using the 'color random' operator.
12 | /// The Builder maintainse single color pool in a project.
13 | class ColorPool {
14 | enum PoolType { RandomHue, GreyScale, RandomRGB, Picture, ColorList };
15 | public:
16 | ColorPool(QString initString);
17 | ~ColorPool();
18 | QColor drawColor(); // returns a random color from the pool (in HSV)
19 | private:
20 | PoolType type;
21 | QVector colorList; // only used by type: ColorList.
22 | QImage* picture; // Only used by type: Picture.
23 | };
24 |
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/StructureSynth/Model/CustomRule.cpp:
--------------------------------------------------------------------------------
1 | #include "CustomRule.h"
2 |
3 | #include "../../SyntopiaCore/Logging/Logging.h"
4 | #include "Builder.h"
5 |
6 | using namespace SyntopiaCore::Logging;
7 |
8 | namespace StructureSynth {
9 | namespace Model {
10 |
11 | CustomRule::CustomRule(QString name) : Rule(name) {
12 | weight = 1.0;
13 | retirementRule = 0;
14 | }
15 |
16 | CustomRule::~CustomRule() {
17 | //delete (retirementRule);
18 | }
19 |
20 | void CustomRule::apply(Builder* b) const {
21 |
22 | int newDepth = -1;
23 | /// If there is a maxdepth set for this object check it.
24 | if (getMaxDepth() != -1) {
25 | if (!b->getState().maxDepths.contains(this)) {
26 | /// We will add a new maxdepth for this rule to the state.
27 | newDepth = getMaxDepth()-1;
28 |
29 | } else {
30 | int depth = b->getState().maxDepths[this];
31 | if (depth <= 0) {
32 | /// This rule is retired.
33 | if (retirementRule) {
34 | b->getState().maxDepths[this] = maxDepth;
35 | retirementRule->rule()->apply(b);
36 |
37 | }
38 | return;
39 | } else {
40 | /// Decrease depth.
41 | newDepth = depth-1;
42 | }
43 | }
44 | }
45 |
46 | /// Apply all actions.
47 | for (int i = 0; i < actions.size(); i++) {
48 | if (getMaxDepth() != -1) {
49 | actions[i].apply(b, this, newDepth);
50 | } else {
51 | actions[i].apply(b, 0 ,0);
52 | }
53 | }
54 | }
55 |
56 | QList CustomRule::getRuleRefs() const {
57 | QList list;
58 | for (int i = 0; i < actions.size(); i++) {
59 | RuleRef* a = actions[i].getRuleRef();
60 | if (a) list.append(a);
61 | }
62 | if (retirementRule) list.append(retirementRule);
63 |
64 | return list;
65 | }
66 |
67 |
68 | }
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/StructureSynth/Model/CustomRule.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rule.h"
4 | #include "Action.h"
5 |
6 | namespace StructureSynth {
7 | namespace Model {
8 |
9 | /// A custom rule is a user defined rule.
10 | /// It consist of a number of actions,
11 | /// and a weight that is used if the rule definition is ambiguous (see 'AmbiguousRule').
12 | class CustomRule : public Rule {
13 | public:
14 | CustomRule(QString name);
15 | virtual ~CustomRule();
16 |
17 | virtual void apply(Builder* builder) const;
18 |
19 | /// Returns a list over rules that this rule references.
20 | virtual QList getRuleRefs() const;
21 |
22 | void appendAction(Action a) { actions.append(a); }
23 |
24 | double getWeight() const { return weight; }
25 | void setWeight(double w) { weight = w; }
26 |
27 | void setRetirementRule(QString ruleName) { retirementRule = new RuleRef(ruleName); };
28 |
29 | private:
30 | QList actions;
31 | double weight;
32 | RuleRef* retirementRule;
33 | };
34 |
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/StructureSynth/Model/ExecutionStack.cpp:
--------------------------------------------------------------------------------
1 | #include "Rule.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/StructureSynth/Model/ExecutionStack.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rule.h"
4 | #include "State.h"
5 |
6 | namespace StructureSynth {
7 | namespace Model {
8 |
9 | struct RuleState {
10 | RuleState() {};
11 | RuleState(Rule* rule, State state) : rule(rule), state(state) {};
12 |
13 | Rule* rule;
14 | State state;
15 | };
16 |
17 | /// The ExecutionStack keeps track of which operations to perform next.
18 | /// Rules are executed in generations:
19 | /// The rules on the stack are all executed in each generation,
20 | /// and each rule will add a number of new rules to the next generation of the stack.
21 | /// Only one level is recursion is followed at each generation.
22 | typedef QVector ExecutionStack;
23 |
24 | /*
25 | struct ExecutionStack {
26 | QList< RuleState > currentStack;
27 | };
28 | */
29 |
30 |
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/StructureSynth/Model/PrimitiveClass.cpp:
--------------------------------------------------------------------------------
1 | #include "PrimitiveClass.h"
2 |
3 | namespace StructureSynth {
4 | namespace Model {
5 |
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/StructureSynth/Model/PrimitiveClass.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace StructureSynth {
6 | namespace Model {
7 |
8 | /// Every PrimitiveRule can be assigned a class.
9 |
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/StructureSynth/Model/PrimitiveRule.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rule.h"
4 | #include "PrimitiveClass.h"
5 | #include "../../SyntopiaCore/GLEngine/Object3D.h"
6 |
7 | namespace StructureSynth {
8 | namespace Model {
9 |
10 | using namespace SyntopiaCore::GLEngine;
11 |
12 | /// These are the built-in primitives,
13 | /// for drawing boxes, spheres and other simple geometric shapes.
14 | class PrimitiveRule : public Rule {
15 | public:
16 | enum PrimitiveType { Box, Sphere, Dot, Grid, Cylinder, Line, Mesh, Template, Other } ;
17 |
18 | PrimitiveRule(PrimitiveType type, PrimitiveClass* primitiveClass);
19 | virtual void apply(Builder* builder) const;
20 |
21 | /// Returns a list over rules that this rule references.
22 | /// (Empty for all PrimitiveRules!)
23 | virtual QList getRuleRefs() const { return QList(); }
24 |
25 | /// 'class' is an identifier used for distinguishing between
26 | /// different forms of the the same PrimiteType.
27 | /// This is used together with Template Renderers.
28 | ///
29 | /// For instance 'box::metal' will be parsed in to a 'box' primitive with a 'metal' class identifier.
30 | void setClass(PrimitiveClass* primitiveClass) { this->primitiveClass = primitiveClass; }
31 | PrimitiveClass* getClass() { return primitiveClass; }
32 |
33 |
34 | protected:
35 | PrimitiveClass* primitiveClass;
36 | private:
37 | PrimitiveType type;
38 |
39 |
40 | };
41 |
42 | /// Triangle rules are special, since they have explicit coordinate representation.
43 | class TriangleRule : public PrimitiveRule {
44 | public:
45 |
46 | TriangleRule(SyntopiaCore::Math::Vector3f p1,
47 | SyntopiaCore::Math::Vector3f p2,
48 | SyntopiaCore::Math::Vector3f p3,
49 | PrimitiveClass* primitiveClass);
50 |
51 | virtual void apply(Builder* builder) const;
52 |
53 | private:
54 | SyntopiaCore::Math::Vector3f p1;
55 | SyntopiaCore::Math::Vector3f p2;
56 | SyntopiaCore::Math::Vector3f p3;
57 |
58 | };
59 |
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/StructureSynth/Model/RandomStreams.cpp:
--------------------------------------------------------------------------------
1 | #include "RandomStreams.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 | SyntopiaCore::Math::RandomNumberGenerator* RandomStreams::geometry = new SyntopiaCore::Math::RandomNumberGenerator(false);
7 | SyntopiaCore::Math::RandomNumberGenerator* RandomStreams::color = new SyntopiaCore::Math::RandomNumberGenerator(false);
8 |
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/StructureSynth/Model/RandomStreams.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../SyntopiaCore/Math/Random.h"
4 |
5 | namespace StructureSynth {
6 | namespace Model {
7 |
8 | /// These two independent random number generator streams are used in Structure Synth
9 | class RandomStreams {
10 | public:
11 | static SyntopiaCore::Math::RandomNumberGenerator* Geometry() { return geometry; }
12 | static SyntopiaCore::Math::RandomNumberGenerator* Color() { return color; }
13 | static void SetSeed(int seed) { geometry->setSeed(seed); color->setSeed(seed); }
14 | static void UseOldRandomGenerators(bool useOld) { geometry->useStdLib(useOld); color->useStdLib(useOld); }
15 | private:
16 | static SyntopiaCore::Math::RandomNumberGenerator* geometry;
17 | static SyntopiaCore::Math::RandomNumberGenerator* color;
18 | };
19 |
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Rendering/ObjRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "../../../SyntopiaCore/Math/Vector3.h"
5 | #include "../../../SyntopiaCore/Math/Matrix4.h"
6 | #include "../../../SyntopiaCore/GLEngine/Object3D.h"
7 | #include "Renderer.h"
8 |
9 | namespace StructureSynth {
10 | namespace Model {
11 | namespace Rendering {
12 |
13 | using namespace SyntopiaCore::Math;
14 | using namespace SyntopiaCore::GLEngine;
15 |
16 | struct VertexNormal {
17 | VertexNormal() {};
18 | VertexNormal(int vID, int nID) : vID(vID), nID(nID) {};
19 | int vID;
20 | int nID;
21 | };
22 |
23 | struct ObjGroup {
24 | QString groupName;
25 | QVector vertices;
26 | QVector normals;
27 | QVector > faces;
28 |
29 | void addGroup(ObjGroup g);
30 | void reduceVertices();
31 | };
32 |
33 | /// Obj file renderer
34 | class ObjRenderer : public Renderer {
35 | public:
36 | ObjRenderer(int sphereDT, int sphereDP, bool groupByTagging, bool groupByColor)
37 | : sphereDT(sphereDT), sphereDP(sphereDP), groupByTagging(groupByTagging), groupByColor(groupByColor) {};
38 | virtual ~ObjRenderer() {};
39 |
40 | /// Flow
41 | virtual void begin();
42 | virtual void end();
43 |
44 | /// This defines the identifier for our renderer.
45 | virtual QString renderClass() { return "ObjRenderer"; }
46 |
47 | /// The primitives
48 | virtual void drawBox(Vector3f base,
49 | Vector3f dir1,
50 | Vector3f dir2,
51 | Vector3f dir3,
52 | PrimitiveClass* classID);
53 |
54 | virtual void drawMesh( Vector3f startBase,
55 | Vector3f startDir1,
56 | Vector3f startDir2,
57 | Vector3f endBase,
58 | Vector3f endDir1,
59 | Vector3f endDir2,
60 | PrimitiveClass* classID);
61 |
62 | virtual void drawGrid(Vector3f base,
63 | Vector3f dir1,
64 | Vector3f dir2,
65 | Vector3f dir3,
66 | PrimitiveClass* classID);
67 |
68 | virtual void drawLine(Vector3f from,
69 | Vector3f to,
70 | PrimitiveClass* classID);
71 |
72 | virtual void drawDot(Vector3f pos,
73 | PrimitiveClass* classID);
74 |
75 | virtual void drawSphere(Vector3f center, float radius,
76 | PrimitiveClass* classID);
77 |
78 | virtual void drawTriangle(Vector3f p1,
79 | Vector3f p2,
80 | Vector3f p3,
81 | PrimitiveClass* classID);
82 |
83 | virtual void callGeneric(PrimitiveClass* ) {};
84 |
85 | // Color
86 | // RGB in [0;1] intervals.
87 | virtual void setColor(Vector3f rgb) { this->rgb = rgb; }
88 | virtual void setBackgroundColor(Vector3f /*rgb*/) {};
89 | virtual void setAlpha(double alpha) { this->alpha = alpha; }
90 |
91 | virtual void setPreviousColor(Vector3f /*rgb*/) {};
92 | virtual void setPreviousAlpha(double /*alpha*/) {};
93 |
94 |
95 | // Camera settings
96 | virtual void setTranslation(Vector3f /*translation*/) {};
97 | virtual void setScale(double /*scale*/) {};
98 | virtual void setRotation(Matrix4f /*rotation*/) {};
99 | virtual void setPivot(Vector3f /*pivot*/) {};
100 | virtual void setPerspectiveAngle(double /*angle*/) {};
101 |
102 | // Issues a command for a specific renderclass such as 'template' or 'opengl'
103 | virtual void callCommand(const QString& /*renderClass*/, const QString& /*command*/) {};
104 |
105 | void addQuad(ObjGroup& group, Vector3f v1,Vector3f v2,Vector3f v3,Vector3f v4);
106 | void addLineQuad(ObjGroup& group, Vector3f v1,Vector3f v2,Vector3f v3,Vector3f v4);
107 | void setClass(QString classID, Vector3f rgb, double alpha);
108 |
109 | void writeToStream(QTextStream& ts);
110 |
111 | private:
112 | QMap groups;
113 | QString currentGroup;
114 | SyntopiaCore::Math::Vector3f rgb;
115 | double alpha;
116 | int sphereDT;
117 | int sphereDP;
118 | bool groupByTagging;
119 | bool groupByColor;
120 |
121 | };
122 |
123 | }
124 | }
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Rendering/OpenGLRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "../../../SyntopiaCore/GLEngine/EngineWidget.h"
5 | #include "Renderer.h"
6 |
7 | #include "../../../SyntopiaCore/Math/Vector3.h"
8 |
9 |
10 | namespace StructureSynth {
11 | namespace Model {
12 | namespace Rendering {
13 |
14 | using namespace SyntopiaCore::GLEngine;
15 |
16 |
17 | /// A renderer implementation based on the SyntopiaCore openGL widget.
18 | class OpenGLRenderer : public Renderer {
19 | public:
20 | OpenGLRenderer(SyntopiaCore::GLEngine::EngineWidget* engine) : engine(engine) {};
21 | virtual ~OpenGLRenderer() {};
22 |
23 | /// The primitives
24 | virtual void drawBox(SyntopiaCore::Math::Vector3f base,
25 | SyntopiaCore::Math::Vector3f dir1 ,
26 | SyntopiaCore::Math::Vector3f dir2,
27 | SyntopiaCore::Math::Vector3f dir3,
28 | PrimitiveClass* classID);
29 |
30 |
31 | virtual void drawMesh( SyntopiaCore::Math::Vector3f startBase,
32 | SyntopiaCore::Math::Vector3f startDir1,
33 | SyntopiaCore::Math::Vector3f startDir2,
34 | SyntopiaCore::Math::Vector3f endBase,
35 | SyntopiaCore::Math::Vector3f endDir1,
36 | SyntopiaCore::Math::Vector3f endDir2,
37 | PrimitiveClass* classID);
38 |
39 | virtual void drawSphere(SyntopiaCore::Math::Vector3f center, float radius,
40 | PrimitiveClass* classID);
41 |
42 | virtual void drawGrid(SyntopiaCore::Math::Vector3f base,
43 | SyntopiaCore::Math::Vector3f dir1,
44 | SyntopiaCore::Math::Vector3f dir2,
45 | SyntopiaCore::Math::Vector3f dir3,
46 | PrimitiveClass* classID);
47 |
48 | virtual void drawLine(SyntopiaCore::Math::Vector3f from,
49 | SyntopiaCore::Math::Vector3f to,
50 | PrimitiveClass* classID);
51 |
52 | virtual void drawDot(SyntopiaCore::Math::Vector3f pos,
53 | PrimitiveClass* classID);
54 |
55 | virtual void drawTriangle(SyntopiaCore::Math::Vector3f p1,
56 | SyntopiaCore::Math::Vector3f p2,
57 | SyntopiaCore::Math::Vector3f p3,
58 | PrimitiveClass* classID);
59 |
60 | virtual void begin();
61 | virtual void end();
62 |
63 | virtual void setColor(SyntopiaCore::Math::Vector3f rgb) { this->rgb = rgb; }
64 | virtual void setBackgroundColor(SyntopiaCore::Math::Vector3f rgb);
65 | virtual void setAlpha(double alpha) { this->alpha = alpha; }
66 |
67 | virtual void setPreviousColor(SyntopiaCore::Math::Vector3f rgb) { this->oldRgb = rgb; }
68 | virtual void setPreviousAlpha(double alpha) { this->oldAlpha = alpha; }
69 |
70 |
71 | virtual void setTranslation(SyntopiaCore::Math::Vector3f /*translation*/);
72 | virtual void setScale(double /*scale*/);
73 | virtual void setRotation(SyntopiaCore::Math::Matrix4f /*rotation*/);
74 | virtual void setPivot(SyntopiaCore::Math::Vector3f /*pivot*/);
75 | virtual void setPerspectiveAngle(double /*angle*/);
76 |
77 | // Issues a command for a specific renderclass such as 'template' or 'opengl'
78 | virtual void callCommand(const QString& renderClass, const QString& command);
79 | private:
80 | SyntopiaCore::GLEngine::EngineWidget* engine;
81 | SyntopiaCore::Math::Vector3f rgb;
82 | double alpha;
83 | SyntopiaCore::Math::Vector3f oldRgb;
84 | double oldAlpha;
85 | };
86 |
87 | }
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Rendering/Renderer.cpp:
--------------------------------------------------------------------------------
1 | #include "Renderer.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 | namespace Renderer {
7 | }
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Rendering/Renderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "../../../SyntopiaCore/Math/Vector3.h"
5 | #include "../../../SyntopiaCore/Math/Matrix4.h"
6 | #include "../../../SyntopiaCore/GLEngine/Object3D.h"
7 |
8 | namespace StructureSynth {
9 | namespace Model {
10 | namespace Rendering {
11 |
12 |
13 | using namespace SyntopiaCore::GLEngine;
14 |
15 | /// Abstract base class for implementing a renderer
16 | class Renderer {
17 | public:
18 | Renderer() {};
19 | virtual ~Renderer() {};
20 |
21 | /// Flow
22 | virtual void begin() {};
23 | virtual void end() {};
24 |
25 | /// This defines the identifier for our renderer.
26 | virtual QString renderClass() { return ""; }
27 |
28 | /// The primitives
29 | virtual void drawBox(SyntopiaCore::Math::Vector3f base,
30 | SyntopiaCore::Math::Vector3f dir1,
31 | SyntopiaCore::Math::Vector3f dir2,
32 | SyntopiaCore::Math::Vector3f dir3,
33 | PrimitiveClass* classID) = 0;
34 |
35 | virtual void drawMesh( SyntopiaCore::Math::Vector3f startBase,
36 | SyntopiaCore::Math::Vector3f startDir1,
37 | SyntopiaCore::Math::Vector3f startDir2,
38 | SyntopiaCore::Math::Vector3f endBase,
39 | SyntopiaCore::Math::Vector3f endDir1,
40 | SyntopiaCore::Math::Vector3f endDir2,
41 | PrimitiveClass* classID) = 0;
42 |
43 | virtual void drawGrid(SyntopiaCore::Math::Vector3f base,
44 | SyntopiaCore::Math::Vector3f dir1,
45 | SyntopiaCore::Math::Vector3f dir2,
46 | SyntopiaCore::Math::Vector3f dir3,
47 | PrimitiveClass* classID) = 0;
48 |
49 | virtual void drawLine(SyntopiaCore::Math::Vector3f from,
50 | SyntopiaCore::Math::Vector3f to,
51 | PrimitiveClass* classID) = 0;
52 |
53 | virtual void drawDot(SyntopiaCore::Math::Vector3f pos,
54 | PrimitiveClass* classID) = 0;
55 |
56 | virtual void drawSphere(SyntopiaCore::Math::Vector3f center, float radius,
57 | PrimitiveClass* classID) = 0;
58 |
59 | virtual void drawTriangle(SyntopiaCore::Math::Vector3f p1,
60 | SyntopiaCore::Math::Vector3f p2,
61 | SyntopiaCore::Math::Vector3f p3,
62 | PrimitiveClass* classID) = 0;
63 |
64 | virtual void callGeneric(PrimitiveClass* ) {};
65 |
66 | // Color
67 | // RGB in [0;1] intervals.
68 | virtual void setColor(SyntopiaCore::Math::Vector3f rgb) = 0;
69 | virtual void setBackgroundColor(SyntopiaCore::Math::Vector3f rgb) = 0;
70 | virtual void setAlpha(double alpha) = 0;
71 |
72 | virtual void setPreviousColor(SyntopiaCore::Math::Vector3f rgb) = 0;
73 | virtual void setPreviousAlpha(double alpha) = 0;
74 |
75 |
76 | // Camera settings
77 | virtual void setTranslation(SyntopiaCore::Math::Vector3f /*translation*/) {};
78 | virtual void setScale(double /*scale*/) {};
79 | virtual void setRotation(SyntopiaCore::Math::Matrix4f /*rotation*/) {};
80 | virtual void setPivot(SyntopiaCore::Math::Vector3f /*pivot*/) {};
81 | virtual void setPerspectiveAngle(double /*angle*/) {};
82 |
83 | // Issues a command for a specific renderclass such as 'template' or 'opengl'
84 | virtual void callCommand(const QString& /*renderClass*/, const QString& /*command*/) {};
85 | };
86 |
87 | }
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Rule.cpp:
--------------------------------------------------------------------------------
1 | #include "Rule.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Rule.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rendering/Renderer.h"
4 | #include "State.h"
5 |
6 | namespace StructureSynth {
7 | namespace Model {
8 |
9 |
10 | class RuleRef; // forward decl.
11 | class Builder; // forward decl.
12 |
13 | /// (Abstract) Base class for rules.
14 | class Rule {
15 | public:
16 | /// Every rule must have a name.
17 | Rule(QString name) : name(name) { maxDepth = -1; };
18 | Rule() { maxDepth = -1; };
19 |
20 | virtual ~Rule() {};
21 |
22 | QString getName() const { return name; }
23 |
24 | /// When applied the rule will add new pending rules to the ExecutionStack for execution.
25 | /// Only PrimitiveRules will make use of the renderer.
26 | virtual void apply(Builder* builder) const = 0;
27 |
28 | /// Returns a list over rules that this rule references.
29 | virtual QList getRuleRefs() const { return QList(); }
30 |
31 | virtual void setMaxDepth(int maxDepth) { this->maxDepth = maxDepth; }
32 | virtual int getMaxDepth() const { return maxDepth; }
33 |
34 | protected:
35 | QString name;
36 | int maxDepth;
37 | };
38 | }
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/StructureSynth/Model/RuleRef.cpp:
--------------------------------------------------------------------------------
1 | #include "Rule.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/StructureSynth/Model/RuleRef.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rule.h"
4 |
5 | namespace StructureSynth {
6 | namespace Model {
7 |
8 | /// A RuleRef holds a pointer to a rule.
9 | /// Its is a placeholder, since rule are parsed as symbolic references,
10 | /// and need to be resolved into actual pointers after the complete parsing of the script.
11 | class RuleRef {
12 | public:
13 | RuleRef(QString namedReference) : reference(namedReference) { rulePtr = 0; };
14 | ~RuleRef() {};
15 |
16 | Rule* rule() { return rulePtr; }
17 |
18 | QString getReference() const { return reference; }
19 |
20 | void setRef(Rule* rule) { rulePtr = rule; }
21 |
22 | private:
23 | Rule* rulePtr;
24 | QString reference;
25 | };
26 |
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/StructureSynth/Model/RuleSet.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Rule.h"
4 | #include "PrimitiveClass.h"
5 | #include "CustomRule.h"
6 |
7 | #include "../../SyntopiaCore/GLEngine/Object3D.h"
8 |
9 | namespace StructureSynth {
10 | namespace Model {
11 |
12 | using namespace SyntopiaCore::GLEngine;
13 |
14 | /// Container for all rules.
15 | class RuleSet {
16 | public:
17 | /// Constructor. Automatically adds built-in rules.
18 | RuleSet();
19 |
20 | /// Deletes rules
21 | ~RuleSet();
22 |
23 | /// Added rules belong to the RuleSet and will be deleted by the RuleSet destructor.
24 | void addRule(Rule* rule);
25 |
26 | /// Resolve symbolic names into pointers
27 | /// Returns a list of the primitives used
28 | QStringList resolveNames();
29 |
30 | /// TODO: Implement
31 | QStringList getUnreferencedNames();
32 |
33 | Rule* getStartRule() const ;
34 |
35 | CustomRule* getTopLevelRule() const { return topLevelRule; }
36 |
37 | /// For debug
38 | void dumpInfo() const;
39 |
40 | void setRecurseDepthFirst(bool value) { recurseDepth = value; };
41 | bool recurseDepthFirst() { return recurseDepth; }
42 | void setRulesMaxDepth(int maxDepth);
43 |
44 | /// Returns the PrimitiveClass with this name. Constructs a new one if missing.
45 | PrimitiveClass* getPrimitiveClass(QString classLabel);
46 | bool existsPrimitiveClass(QString classLabel);
47 | PrimitiveClass* getDefaultClass() { return defaultClass; }
48 |
49 | private:
50 | QList rules;
51 | QVector primitiveClasses;
52 | PrimitiveClass* defaultClass;
53 | CustomRule* topLevelRule;
54 | bool recurseDepth;
55 | };
56 |
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/StructureSynth/Model/State.cpp:
--------------------------------------------------------------------------------
1 | #include "State.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 |
7 | State::State() :
8 | matrix(SyntopiaCore::Math::Matrix4f::Identity()),
9 | hsv(SyntopiaCore::Math::Vector3f(0,1.0f,1.0f)),
10 | alpha(1.0f), previous(0), seed(0) {
11 |
12 | }
13 |
14 | State& State::operator=(const State& rhs){
15 | this->matrix = rhs.matrix;
16 | this->hsv = rhs.hsv;
17 | this->alpha = rhs.alpha;
18 | this->maxDepths = rhs.maxDepths;
19 | this->seed = rhs.seed;
20 | if (rhs.previous) {
21 | delete(this->previous);
22 | this->previous = new PreviousState();
23 | *(this->previous) = *rhs.previous;
24 | } else {
25 | delete(this->previous);
26 | this->previous = 0;
27 | }
28 | return *this;
29 | }
30 |
31 | void State::setPreviousState(SyntopiaCore::Math::Matrix4f matrix,SyntopiaCore::Math::Vector3f hsv, float alpha) {
32 | if (previous) {delete (previous); }
33 |
34 | this->previous = new PreviousState();
35 | this->previous->matrix = matrix;
36 | this->previous->hsv = hsv;
37 | this->previous->alpha = alpha;
38 | }
39 |
40 |
41 | State::State(const State& rhs) : matrix(rhs.matrix),
42 | hsv(rhs.hsv),
43 | alpha(rhs.alpha), maxDepths(rhs.maxDepths), previous(0), seed(rhs.seed) {
44 |
45 | if (rhs.previous) {
46 | delete(this->previous);
47 | this->previous = new PreviousState();
48 | *(this->previous) = *rhs.previous;
49 | } else {
50 | delete(this->previous);
51 | this->previous = 0;
52 | }
53 | }
54 |
55 |
56 |
57 | State::~State() {
58 | delete(previous);
59 | }
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/StructureSynth/Model/State.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include "../../SyntopiaCore/Math/Matrix4.h"
6 |
7 | namespace StructureSynth {
8 | namespace Model {
9 |
10 | class Rule; // Forward
11 |
12 | // A slight trimmed version of a State.
13 | struct PreviousState {
14 | SyntopiaCore::Math::Matrix4f matrix; // Transformation matrix (4x4 homogenous representation)
15 | SyntopiaCore::Math::Vector3f hsv; // Hue, Saturation, Value colorspace state
16 | float alpha; // Transparency
17 |
18 | };
19 |
20 | /// A state represent the current rendering projection matrix and other rendering settings.
21 | struct State {
22 | State();
23 | State(const State& rhs);
24 | ~State();
25 |
26 | State& operator=(const State& rhs);
27 |
28 | void setPreviousState(SyntopiaCore::Math::Matrix4f matrix,SyntopiaCore::Math::Vector3f hsv,float alpha);
29 |
30 | SyntopiaCore::Math::Matrix4f matrix; // Transformation matrix (4x4 homogenous representation)
31 | SyntopiaCore::Math::Vector3f hsv; // Hue, Saturation, Value colorspace state
32 | float alpha; // Transparency
33 | QMap maxDepths; // Rules may have a max. recursion depth before they are retired.
34 | // We need to keep track of this in the state.
35 | PreviousState* previous;
36 | int seed;
37 | };
38 |
39 |
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/StructureSynth/Model/Transformation.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include "State.h"
6 | #include "ColorPool.h"
7 | #include "../../SyntopiaCore/Math/Matrix4.h"
8 |
9 | namespace StructureSynth {
10 | namespace Model {
11 |
12 | class Transformation {
13 | public:
14 | Transformation();
15 | ~Transformation();
16 |
17 | /// 'Applies' the transformation 'T' to this transformation.
18 | /// (For the matrix this corresponds to matrix multiplication).
19 | void append(const Transformation& T);
20 | State apply(const State& s, ColorPool* colorPool) const;
21 |
22 | // The predefined operators
23 | // Translations
24 | static Transformation createX(double offset);
25 | static Transformation createY(double offset);
26 | static Transformation createZ(double offset);
27 |
28 | // Rotations
29 | static Transformation createRX(double angle);
30 | static Transformation createRY(double angle);
31 | static Transformation createRZ(double angle);
32 |
33 | // Plane reflection
34 | static Transformation createPlaneReflection(SyntopiaCore::Math::Vector3f normal);
35 |
36 | // Scaling
37 | static Transformation createScale(double x, double y, double z);
38 |
39 | // Free transformation
40 | static Transformation createMatrix(QVector vals);
41 |
42 | // Color stuff
43 | static Transformation createHSV(float h, float s, float v, float a);
44 | static Transformation createColor(QString color);
45 | static Transformation createBlend(QString color, double strength);
46 |
47 |
48 | private:
49 | // Matrix and Color transformations here.
50 | SyntopiaCore::Math::Matrix4f matrix;
51 |
52 | // For color alterations
53 | float deltaH;
54 | float scaleS;
55 | float scaleV;
56 | float scaleAlpha;
57 | bool absoluteColor;
58 |
59 | // For color blends.
60 | QColor blendColor;
61 | double strength;
62 | };
63 |
64 | }
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/StructureSynth/Model/TransformationLoop.cpp:
--------------------------------------------------------------------------------
1 | #include "TransformationLoop.h"
2 |
3 |
4 | namespace StructureSynth {
5 | namespace Model {
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/StructureSynth/Model/TransformationLoop.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Transformation.h"
4 |
5 | namespace StructureSynth {
6 | namespace Model {
7 |
8 | /// A loop is a transformation which is repeated a number of times:
9 | /// e.g.:
10 | /// 20 * { x 1 } R1
11 | /// will create twenty R1 objects each succesively moved one unit in the x-directions.
12 | struct TransformationLoop {
13 | TransformationLoop() {};
14 | TransformationLoop(int repetitions, Transformation transformation) : repetitions(repetitions), transformation(transformation) {};
15 |
16 | int repetitions;
17 | Transformation transformation;
18 | };
19 |
20 |
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/StructureSynth/Parser/EisenParser.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Tokenizer.h"
4 | #include "../Model/Transformation.h"
5 | #include "../Model/Rule.h"
6 | #include "../Model/CustomRule.h"
7 | #include "../Model/RuleSet.h"
8 | #include "../Model/Action.h"
9 |
10 | namespace StructureSynth {
11 | namespace Parser {
12 |
13 |
14 | /// The' Eisenstein Engine' is a simple recursive descent parser,
15 | /// for parsing 'EisenScript'.
16 | class EisenParser {
17 |
18 | public:
19 | /// Constructor.
20 | EisenParser(Tokenizer* tokenizer);
21 |
22 | /// Destructor, The tokenizer is not deleted.
23 | ~EisenParser();
24 |
25 | /// Parses the input, and returns the corresponding ruleset.
26 | /// Throws a ParseError if any errors are encountered
27 | Model::RuleSet* parseRuleset();
28 | bool recurseDepthFirst() { return recurseDepth; }
29 |
30 | private:
31 | bool recurseDepth;
32 | void getSymbol();
33 | Model::Rule* rule();
34 | Model::RuleSet* ruleset();
35 | Model::Action action();
36 | Model::Action setAction();
37 | Model::Transformation transformationList();
38 | Model::Transformation transformation();
39 | void ruleModifierList(Model::CustomRule* customRule);
40 |
41 | bool accept(Symbol::SymbolType st);
42 | bool expect(Symbol::SymbolType st);
43 | Symbol symbol;
44 |
45 | Tokenizer* tokenizer;
46 | };
47 |
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/StructureSynth/Parser/Preprocessor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "../../SyntopiaCore/Exceptions/Exception.h"
8 |
9 | namespace StructureSynth {
10 | namespace Parser {
11 |
12 | class GuiParameter {
13 | public:
14 | GuiParameter(QString name) : name(name) {};
15 | virtual QString getName() { return name; }
16 | protected:
17 | QString name;
18 | };
19 |
20 | class FloatParameter : public GuiParameter {
21 | public:
22 | FloatParameter(QString name, double from, double to, double defaultValue) :
23 | GuiParameter(name), from(from), to(to), defaultValue(defaultValue) {};
24 |
25 | double getFrom() { return from; }
26 | double getTo() { return to; }
27 | double getDefaultValue() { return defaultValue; }
28 | private:
29 | double from;
30 | double to;
31 | double defaultValue;
32 | };
33 |
34 | class IntParameter : public GuiParameter {
35 | public:
36 | IntParameter(QString name, int from, int to, int defaultValue) :
37 | GuiParameter(name), from(from), to(to), defaultValue(defaultValue) {};
38 |
39 | int getFrom() { return from; }
40 | int getTo() { return to; }
41 | int getDefaultValue() { return defaultValue; }
42 | private:
43 | int from;
44 | int to;
45 | int defaultValue;
46 | };
47 |
48 | /// The preprocessor is responsible for expanding '#define'
49 | ///
50 | class Preprocessor {
51 |
52 | public:
53 | Preprocessor() {};
54 |
55 | // The preprocess replaces 'random[2,4]' statements with random numbers.
56 | // This requires a seed. Using the same seed as controls the EisenScript is probably the best idea her.
57 | QString Process(QString input, int seed = 0);
58 | QVector getParameters() { return params; }
59 |
60 | private:
61 | QVector params;
62 | };
63 |
64 | }
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/StructureSynth/Parser/Tokenizer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../../SyntopiaCore/Exceptions/Exception.h"
7 |
8 | namespace StructureSynth {
9 | namespace Parser {
10 |
11 | class ParseError : public SyntopiaCore::Exceptions::Exception {
12 | public:
13 | ParseError(QString message, int position) : Exception(message), position(position) {};
14 | int getPosition() { return position; }
15 | private:
16 | int position;
17 | };
18 |
19 | struct Symbol {
20 | enum SymbolType { Undefined, LeftBracket, RightBracket, MoreThan, End, Number, Multiply, UserString, Rule, Set, Operator } ;
21 |
22 |
23 |
24 | Symbol() : floatValue(0), intValue(0), isInteger(false),pos(-1), type(Undefined) { };
25 | Symbol(int pos, SymbolType s, QString original) : text(original),floatValue(0), intValue(0),isInteger(false), pos(pos), type(s) { };
26 |
27 |
28 | /// yes, yes, it is a bloated representation. (I don't like unions...)
29 | QString text; // The original text-string we parsed. Notice userstrings are converted to lower-case
30 | double floatValue;
31 | int intValue;
32 | bool isInteger;
33 | int pos; // the position (char-index) of the original text parsed.
34 | SymbolType type;
35 |
36 |
37 | double getNumerical() {
38 | if (isInteger) return intValue;
39 | return floatValue;
40 | }
41 | };
42 |
43 | /// The Tokenizer divides an input stream into distinct symbols,
44 | /// for subsequent parsing.
45 | class Tokenizer {
46 |
47 | public:
48 | /// Constructor.
49 | Tokenizer(QString input);
50 |
51 | /// Destructor
52 | ~Tokenizer();
53 |
54 | /// Returns the next symbol
55 | Symbol getSymbol();
56 |
57 | private:
58 |
59 | QList symbols;
60 | int currentSymbol;
61 | };
62 |
63 | }
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/StructureSynthDoc.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/StructureSynthDoc.ico
--------------------------------------------------------------------------------
/SyntopiaCore/Exceptions/Exception.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace SyntopiaCore {
4 | namespace Exceptions {
5 |
6 | /// A base exception class.
7 | ///
8 | /// When using Exceptions:
9 | /// (1) Throw temporaries (throw Exception("Error occoured");)
10 | /// (2) Catch by reference ( try {} catch (Exception& e) {} )
11 | ///
12 | /// (Perhaps this ought to inherit from std::exception?)
13 | class Exception {
14 |
15 | public:
16 | /// Constructor.
17 | Exception(QString message) : message(message) {};
18 |
19 | /// Returns the error message.
20 | QString getMessage() const { return message; }
21 |
22 | private:
23 | QString message;
24 |
25 | };
26 |
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Box.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 | #include "RaytraceTriangle.h"
6 |
7 |
8 | namespace SyntopiaCore {
9 | namespace GLEngine {
10 |
11 | class Box : public Object3D {
12 | public:
13 | Box(SyntopiaCore::Math::Vector3f base,
14 | SyntopiaCore::Math::Vector3f dir1 ,
15 | SyntopiaCore::Math::Vector3f dir2,
16 | SyntopiaCore::Math::Vector3f dir3);
17 |
18 | virtual ~Box();
19 |
20 | virtual QString name() { return "Box"; }
21 |
22 | virtual void draw() const;
23 |
24 | virtual bool intersectsRay(RayInfo* /*rayInfo*/);
25 | virtual bool intersectsAABB(SyntopiaCore::Math::Vector3f /*from*/, SyntopiaCore::Math::Vector3f /*to*/);
26 | virtual void prepareForRaytracing();
27 |
28 | private:
29 | bool useTriangles;
30 | QVector triangles;
31 | SyntopiaCore::Math::Vector3f base;
32 |
33 | SyntopiaCore::Math::Vector3f v1;
34 | SyntopiaCore::Math::Vector3f v2;
35 | SyntopiaCore::Math::Vector3f v3;
36 |
37 | SyntopiaCore::Math::Vector3f n21 ;
38 | SyntopiaCore::Math::Vector3f n32;
39 | SyntopiaCore::Math::Vector3f n13;
40 | SyntopiaCore::Math::Vector3f ac;
41 | SyntopiaCore::Math::Vector3f a[3];
42 | float h[3];
43 |
44 | };
45 |
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Dot.cpp:
--------------------------------------------------------------------------------
1 | #include "Dot.h"
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 |
5 | using namespace SyntopiaCore::Math;
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 | Dot::Dot(SyntopiaCore::Math::Vector3f pos) : pos(pos)
11 | {
12 | /// Bounding box
13 | from = pos;
14 | to = pos;
15 | };
16 |
17 | Dot::~Dot() { };
18 |
19 | void Dot::draw() const {
20 | glDisable (GL_LIGHTING);
21 | glColor4fv(primaryColor);
22 | glBegin(GL_POINTS);
23 | glVertex3f(pos.x(), pos.y(), pos.z());
24 | glEnd();
25 |
26 | glEnable (GL_LIGHTING);
27 |
28 | };
29 |
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Dot.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | class Dot : public Object3D {
10 | public:
11 | Dot(SyntopiaCore::Math::Vector3f pos);
12 |
13 | virtual QString name() { return "Dot"; }
14 |
15 | virtual ~Dot();
16 |
17 | virtual void draw() const;
18 |
19 | private:
20 | SyntopiaCore::Math::Vector3f pos;
21 | };
22 |
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Grid.cpp:
--------------------------------------------------------------------------------
1 | #include "Grid.h"
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 |
5 | using namespace SyntopiaCore::Math;
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 | Grid::Grid(SyntopiaCore::Math::Vector3f base,
11 | SyntopiaCore::Math::Vector3f dir1 ,
12 | SyntopiaCore::Math::Vector3f dir2,
13 | SyntopiaCore::Math::Vector3f dir3) : base(base), v1(dir1), v2(dir2), v3(dir3)
14 | {
15 | /// Bounding box
16 | from = base;
17 | to = base + dir1 + dir2 + dir3;
18 | };
19 |
20 |
21 | Grid::~Grid() { };
22 |
23 | void Grid::draw() const {
24 | glPushMatrix();
25 | glTranslatef( base.x(), base.y(), base.z() );
26 | glLineWidth( 1.0 );
27 |
28 | glDisable (GL_LIGHTING);
29 | glColor4fv( primaryColor );
30 |
31 | glBegin( GL_LINE_LOOP );
32 | Vector3f O(0,0,0);
33 | vertex(O);
34 | vertex(v2);
35 | vertex(v2+v1);
36 | vertex(v1);
37 | glEnd();
38 |
39 | glBegin( GL_LINE_LOOP );
40 | vertex(v3);
41 | vertex(v2+v3);
42 | vertex(v2+v1+v3);
43 | vertex(v1+v3);
44 | glEnd();
45 |
46 | glBegin( GL_LINES );
47 | vertex( v3 ); vertex( O );
48 | vertex( v2 ); vertex( v2+v3 );
49 | vertex( v1+v2 ); vertex( v1+v2+v3 );
50 | vertex( v1 ); vertex( v1+v3 );
51 | glEnd();
52 |
53 | glEnable (GL_LIGHTING);
54 |
55 | glPopMatrix();
56 | };
57 |
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Grid.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | class Grid : public Object3D {
10 | public:
11 | Grid(SyntopiaCore::Math::Vector3f base,
12 | SyntopiaCore::Math::Vector3f dir1 ,
13 | SyntopiaCore::Math::Vector3f dir2,
14 | SyntopiaCore::Math::Vector3f dir3);
15 |
16 | virtual ~Grid();
17 |
18 | virtual QString name() { return "Grid"; }
19 |
20 | virtual void draw() const;
21 |
22 | private:
23 | SyntopiaCore::Math::Vector3f base;
24 | SyntopiaCore::Math::Vector3f v1;
25 | SyntopiaCore::Math::Vector3f v2;
26 | SyntopiaCore::Math::Vector3f v3;
27 | };
28 |
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Line.cpp:
--------------------------------------------------------------------------------
1 | #include "Line.h"
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 |
5 | using namespace SyntopiaCore::Math;
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 |
11 | //GLUquadric* Sphere::myQuad = 0;
12 |
13 | Line::Line(SyntopiaCore::Math::Vector3f from, SyntopiaCore::Math::Vector3f to) : from(from), to(to)
14 | {
15 | /// Bounding box
16 | from = from;
17 | to = to;
18 | };
19 |
20 | Line::~Line() {
21 | };
22 |
23 | void vertex(Vector3f v) {
24 | glVertex3f(v.x(), v.y(), v.z());
25 | }
26 |
27 | void Line::draw() const {
28 |
29 | glLineWidth( 1.0 );
30 | glDisable (GL_LIGHTING);
31 | glColor4fv(primaryColor);
32 |
33 | glBegin(GL_LINES);
34 | vertex(from);
35 | vertex(to);
36 | glEnd();
37 |
38 | glEnable (GL_LIGHTING);
39 |
40 | };
41 |
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Line.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | class Line : public Object3D {
10 | public:
11 | Line(SyntopiaCore::Math::Vector3f from, SyntopiaCore::Math::Vector3f to);
12 |
13 | virtual ~Line();
14 |
15 | virtual QString name() { return "Line"; }
16 |
17 | virtual void draw() const;
18 |
19 | private:
20 | SyntopiaCore::Math::Vector3f from;
21 | SyntopiaCore::Math::Vector3f to;
22 | };
23 |
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Mesh.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 | #include "RaytraceTriangle.h"
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 | class Mesh : public Object3D {
11 | public:
12 | Mesh(SyntopiaCore::Math::Vector3f startBase,
13 | SyntopiaCore::Math::Vector3f startDir1 ,
14 | SyntopiaCore::Math::Vector3f startDir2,
15 | SyntopiaCore::Math::Vector3f endBase,
16 | SyntopiaCore::Math::Vector3f endDir1 ,
17 | SyntopiaCore::Math::Vector3f endDir2
18 | );
19 |
20 | virtual ~Mesh();
21 |
22 | virtual QString name() { return "Mesh"; }
23 |
24 | virtual void draw() const;
25 | void initTriangles();
26 |
27 | virtual bool intersectsRay(RayInfo* /*rayInfo*/);
28 | virtual bool intersectsAABB(SyntopiaCore::Math::Vector3f /*from*/, SyntopiaCore::Math::Vector3f /*to*/);
29 | virtual void prepareForRaytracing() {initTriangles(); };
30 | void setPreviousColor(SyntopiaCore::Math::Vector3f oldRgb, float oldAlpha) { this->oldRgb = oldRgb; this->oldAlpha = oldAlpha; }
31 |
32 |
33 |
34 | private:
35 | SyntopiaCore::Math::Vector3f startBase;
36 | SyntopiaCore::Math::Vector3f startDir1;
37 | SyntopiaCore::Math::Vector3f startDir2;
38 | SyntopiaCore::Math::Vector3f endBase;
39 | SyntopiaCore::Math::Vector3f endDir1;
40 | SyntopiaCore::Math::Vector3f endDir2;
41 | QVector triangles;
42 | SyntopiaCore::Math::Vector3f oldRgb;
43 | float oldAlpha;
44 | };
45 |
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Object3D.cpp:
--------------------------------------------------------------------------------
1 | #include "Object3D.h"
2 |
3 |
4 | using namespace SyntopiaCore::Math;
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | void Object3D::setColor(SyntopiaCore::Math::Vector3f rgb, float alpha) {
10 | primaryColor[0] = rgb[0];
11 | primaryColor[1] = rgb[1];
12 | primaryColor[2] = rgb[2];
13 | primaryColor[3] = alpha;
14 | }
15 |
16 | void Object3D::Expand(Vector3f& from, Vector3f& to, Vector3f test) {
17 | if (test.x()to.x()) to.x() = test.x();
21 | if (test.y()>to.y()) to.y() = test.y();
22 | if (test.z()>to.z()) to.z() = test.z();
23 | }
24 |
25 | void Object3D::vertex4n(SyntopiaCore::Math::Vector3f v1,SyntopiaCore::Math::Vector3f v2,SyntopiaCore::Math::Vector3f v3,SyntopiaCore::Math::Vector3f v4) const {
26 | Vector3f n = (v2-v1).cross(v4-v1);
27 | n.normalize();
28 | normal(n);
29 | vertex(v1);
30 | vertex(v2);
31 | vertex(v3);
32 | vertex(v4);
33 | }
34 |
35 | void Object3D::vertex4(const GLfloat* col1, SyntopiaCore::Math::Vector3f c1, SyntopiaCore::Math::Vector3f v1,SyntopiaCore::Math::Vector3f v2, const GLfloat* col2, SyntopiaCore::Math::Vector3f c2, SyntopiaCore::Math::Vector3f v3,SyntopiaCore::Math::Vector3f v4, bool reverse) const {
36 | /*
37 | Vector3f n = (v2-v1).cross(v4-v1);
38 | n.normalize();
39 | if (reverse) n =-n;
40 |
41 | normal(n);
42 | */
43 |
44 |
45 | glColor4fv(col1);
46 | if (reverse) {
47 | normal((c1-v1).normalized());
48 | } else {
49 | normal((v1-c1).normalized());
50 | }
51 | vertex(v1);
52 | if (reverse) {
53 | normal((c1-v2).normalized());
54 | } else {
55 | normal((v2-c1).normalized());
56 | }
57 | vertex(v2);
58 | glColor4fv(col2);
59 | if (reverse) {
60 | normal((c2-v3).normalized());
61 | } else {
62 | normal((v3-c2).normalized());
63 | }
64 | vertex(v3);
65 | if (reverse) {
66 | normal((c2-v4).normalized());
67 | } else {
68 | normal((v4-c2).normalized());
69 | }
70 | vertex(v4);
71 | }
72 |
73 | void Object3D::vertex3n(SyntopiaCore::Math::Vector3f v1,SyntopiaCore::Math::Vector3f v2,SyntopiaCore::Math::Vector3f v3) const {
74 | Vector3f n = (v2-v1).cross(v3-v1);
75 | n.normalize();
76 | normal(n);
77 | vertex(v1);
78 | vertex(v2);
79 | vertex(v3);
80 | }
81 |
82 | void Object3D::vertex4rn(SyntopiaCore::Math::Vector3f v1,SyntopiaCore::Math::Vector3f v2,SyntopiaCore::Math::Vector3f v3,SyntopiaCore::Math::Vector3f v4) const {
83 | Vector3f n = (v1-v2).cross(v4-v1);
84 | n.normalize();
85 | normal(n);
86 | vertex(v4);
87 | vertex(v3);
88 | vertex(v2);
89 | vertex(v1);
90 | }
91 |
92 | void Object3D::vertex4nc(SyntopiaCore::Math::Vector3f v1,SyntopiaCore::Math::Vector3f v2,SyntopiaCore::Math::Vector3f v3,SyntopiaCore::Math::Vector3f v4,SyntopiaCore::Math::Vector3f center) const {
93 | normal((v1-center).normalized());
94 | vertex(v1);
95 | normal((v2-center).normalized());
96 | vertex(v2);
97 | normal((v3-center).normalized());
98 | vertex(v3);
99 | normal((v4-center).normalized());
100 | vertex(v4);
101 | }
102 |
103 | void Object3D::vertex4rnc(SyntopiaCore::Math::Vector3f v1,SyntopiaCore::Math::Vector3f v2,SyntopiaCore::Math::Vector3f v3,SyntopiaCore::Math::Vector3f v4,SyntopiaCore::Math::Vector3f center) const {
104 | normal((v4-center).normalized());
105 | vertex(v4);
106 | normal((v3-center).normalized());
107 | vertex(v3);
108 | normal((v2-center).normalized());
109 | vertex(v2);
110 | normal((v1-center).normalized());
111 | vertex(v1);
112 | }
113 |
114 |
115 | void Object3D::getBoundingBox(SyntopiaCore::Math::Vector3f& from, SyntopiaCore::Math::Vector3f& to) const {
116 | from = this->from;
117 | to = this->to;
118 | };
119 |
120 | void Object3D::expandBoundingBox(SyntopiaCore::Math::Vector3f& from, SyntopiaCore::Math::Vector3f& to) const {
121 | for (unsigned int i = 0; i < 3; i++) if (this->from[i] < from[i]) from[i] = this->from[i];
122 | for (unsigned int i = 0; i < 3; i++) if (this->to[i] > to[i]) to[i] = this->to[i];
123 | };
124 |
125 |
126 | }
127 |
128 | }
129 |
130 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/RaytraceTriangle.cpp:
--------------------------------------------------------------------------------
1 | #include "RaytraceTriangle.h"
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 |
5 | using namespace SyntopiaCore::Math;
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 | using namespace SyntopiaCore::Math;
10 |
11 |
12 | RaytraceTriangle::RaytraceTriangle(Vector3f p1, Vector3f p2, Vector3f p3, Vector3f n1, Vector3f n2, Vector3f n3)
13 | : p1(p1),p2(p2),p3(p3),n1(n1),n2(n2),n3(n3) , cullBackFaces(true)
14 | {
15 |
16 | // We will use barycentric coordiantes.
17 | Vector3f p12 = p2-p1;
18 | Vector3f p13 = p3-p1;
19 | Vector3f p312 = (p12/p12.sqrLength())*Vector3f::dot(p12,p13);
20 | Vector3f pn3 = p13-p312;
21 | npn3 = pn3/pn3.sqrLength();
22 |
23 | Vector3f p32 = p2-p3;
24 | Vector3f p31 = p1-p3;
25 | Vector3f p132 = (p32/p32.sqrLength())*Vector3f::dot(p32,p31);
26 | Vector3f pn1 = p31-p132;
27 | npn1 = pn1/pn1.sqrLength();
28 |
29 | Vector3f p213 = (p13/p13.sqrLength())*Vector3f::dot(p13,p12);
30 | Vector3f pn2 = p12-p213;
31 | npn2 = pn2/pn2.sqrLength();
32 |
33 | if (npn1.sqrLength() * 0 != 0 || npn2.sqrLength() * 0 != 0 || npn3.sqrLength() * 0 != 0 ||
34 | p13.sqrLength() < 1E-8 || p12.sqrLength() < 1E-8 || p32.sqrLength() < 1E-8) {
35 | //INFO(QString("Bad Triangle (%0): %1, %2, %3").arg((p3-p2).sqrLength()).arg(p1.toString()).arg(p2.toString()).arg(p3.toString()));
36 | bad = true;
37 | } else {
38 | bad = false;
39 | }
40 |
41 | n1.normalize();
42 | n2.normalize();
43 | n3.normalize();
44 |
45 | n = Vector3f::cross(p13,p12);
46 | }
47 |
48 |
49 |
50 |
51 | void RaytraceTriangle::expandBoundingBox(Vector3f& from,Vector3f& to) {
52 | Vector3f p = p1;
53 | for (int i = 0; i < 3; i++) {
54 | if (i==1) p=p2;
55 | if (i==2) p=p3;
56 | if ( p.x() < from.x()) from.x() = p.x();
57 | if ( p.y() < from.y()) from.y() = p.y();
58 | if ( p.z() < from.z()) from.z() = p.z();
59 | if ( p.x() > to.x()) to.x() = p.x();
60 | if ( p.y() > to.y()) to.y() = p.y();
61 | if ( p.z() > to.z()) to.z() = p.z();
62 | }
63 | }
64 |
65 |
66 |
67 | //bool RayTraceTriangle::getIntersectionAndNormal(const Vector3f& startPoint, const Vector3f& lineDirection, double& intersection, Vector3f& normal, Vector3f& color, float& alpha ) {
68 |
69 | bool RaytraceTriangle::intersectsRay(RayInfo* ri) {
70 | if (bad) return false;
71 |
72 | if (cullBackFaces && Vector3f::dot(n,ri->lineDirection)>0) return false;
73 |
74 | float is = Vector3f::dot(n, p1-ri->startPoint)/Vector3f::dot(n, ri->lineDirection);
75 | Vector3f ip = ri->startPoint + ri->lineDirection * is;
76 |
77 | float k312 = Vector3f::dot((ip-p1),npn3);
78 | if (k312 > 1 || k312 <= 0) return false;
79 | float k132 = Vector3f::dot((ip-p3),npn1);
80 | if (k132 > 1 || k132 <= 0) return false;
81 | float k213 = Vector3f::dot((ip-p1),npn2);
82 | if (k213 > 1 || k213 <= 0) return false;
83 |
84 | ri->intersection = is;
85 | ri->normal = n3*k312+ n1*k132+n2*k213;
86 | if (!cullBackFaces && Vector3f::dot( ri->normal , ri->lineDirection)>0) ri->normal=-ri->normal;
87 |
88 | float c0 = k312*color3[0]+k132*color1[0]+k213*color2[0];
89 | float c1 = k312*color3[1]+k132*color1[1]+k213*color2[1];
90 | float c2 = k312*color3[2]+k132*color1[2]+k213*color2[2];
91 | float a = 1; //k312*color3[3]+k132*color1[3]+k213*color2[3];
92 | ri->color[0] = c0;
93 | ri->color[1] = c1;
94 | ri->color[2] = c2;
95 | ri->color[3] = a;
96 | return true;
97 | }
98 |
99 |
100 |
101 |
102 | RaytraceTriangle::~RaytraceTriangle(void) { }
103 |
104 | void RaytraceTriangle::Vertex4(Vector3f p1,Vector3f p2,Vector3f p3,Vector3f p4,bool reverse, QVector& list, float r, float g, float b, float a) {
105 | Vector3f n = -Vector3f::cross(p2-p1, p4-p1);
106 | if (reverse) n=-n;
107 | n.normalize();
108 | RaytraceTriangle r1(p1,p2,p4,n,n,n);
109 | r1.n = n;
110 | r1.setColor(r,g,b,a);
111 | list.append(r1);
112 | RaytraceTriangle r2(p3,p4,p2,n,n,n);
113 | r2.setColor(r,g,b,a);
114 | r2.n = n;
115 | list.append(r2);
116 | }
117 | }
118 | }
119 |
120 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/RaytraceTriangle.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | using namespace SyntopiaCore::Math;
10 |
11 | // Helper class for tesselated objects
12 | class RaytraceTriangle {
13 | public:
14 | RaytraceTriangle(Vector3f p1, Vector3f p2, Vector3f p3, Vector3f n1, Vector3f n2, Vector3f n3);
15 | RaytraceTriangle() : cullBackFaces(false) {};
16 | ~RaytraceTriangle(void);
17 | void expandBoundingBox(Vector3f& from,Vector3f& to);
18 | void setColor(float r, float g, float b, float a) {
19 | color1[0] = r; color1[1] = g; color1[2] = b; color1[3] = a;
20 | color2[0] = r; color2[1] = g; color2[2] = b; color2[3] = a;
21 | color3[0] = r; color3[1] = g; color3[2] = b; color3[3] = a;
22 | }
23 | virtual bool intersectsRay(RayInfo* /*rayInfo*/);
24 |
25 | static void Vertex4(Vector3f p1,Vector3f p2,Vector3f p3,Vector3f p4,bool reverse, QVector& list, float r, float b, float g, float a);
26 |
27 | Vector3f p1;
28 | Vector3f p2;
29 | Vector3f p3;
30 | Vector3f n1;
31 | Vector3f n2;
32 | Vector3f n3;
33 | GLfloat color1[4];
34 | GLfloat color2[4];
35 | GLfloat color3[4];
36 | Vector3f npn1;
37 | Vector3f npn2;
38 | Vector3f npn3;
39 |
40 | Vector3f to;
41 | Vector3f from;
42 | Vector3f n;
43 | bool bad;
44 | bool cullBackFaces;
45 |
46 | };
47 |
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/AtomicCounter.cpp:
--------------------------------------------------------------------------------
1 | #include "AtomicCounter.h"
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 |
5 | #include "AtomicCounter.h"
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 |
11 | }
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/AtomicCounter.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | class AtomicCounter {
10 | public:
11 | AtomicCounter() : current(0) { };
12 |
13 | int increase() {
14 | mutex.lock();
15 | int i = ++current;
16 | mutex.unlock();
17 | wc.wakeAll();
18 | return i;
19 | }
20 |
21 | void setValue(int value) {
22 | mutex.lock();
23 | current = value;
24 | mutex.unlock();
25 | wc.wakeAll();
26 | }
27 |
28 | bool wait(unsigned long time = ULONG_MAX) { wcm.lock(); bool w = wc.wait(&wcm,time); wcm.unlock(); return w; }
29 | int value() { mutex.lock(); int i = current; mutex.unlock(); return i; }
30 | private:
31 | int current;
32 | QMutex mutex;
33 | QMutex wcm;
34 | QWaitCondition wc;
35 | };
36 |
37 |
38 | }
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/ProgressiveOutput.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include "SyntopiaCore/Math/Vector3.h"
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 | using namespace SyntopiaCore::Math;
11 |
12 | class ProgressiveOutput {
13 | public:
14 | ProgressiveOutput(int w, int h) : w(w), h(h) {
15 | mutex = new QMutex();
16 | colors = new Vector3f[w*h];
17 | weights = new double[w*h];
18 | for (int x = 0; x < w; x++) {
19 | for (int y = 0; y < h; y++) {
20 | colors[x+y*w] = Vector3f(0,0,0);
21 | weights[x+y*w] = 0.0;
22 | }
23 | }
24 | }
25 |
26 | ~ProgressiveOutput() {
27 | delete mutex;
28 | delete[] colors;
29 | delete[] weights;
30 | }
31 |
32 | void addIteration(Vector3f* newColors, double* newWeights) {
33 | mutex->lock();
34 | for (int x = 0; x < w; x++) {
35 | for (int y = 0; y < h; y++) {
36 | colors[x+y*w] = colors[x+y*w] + newColors[x+y*w];
37 | weights[x+y*w] = weights[x+y*w] + newWeights[x+y*w];
38 | }
39 | }
40 | mutex->unlock();
41 | };
42 |
43 | void addColumn(int x, Vector3f* newColors) {
44 | mutex->lock();
45 | for (int y = 0; y < h; y++) {
46 | colors[x+y*w] = colors[x+y*w] + newColors[y];
47 | weights[x+y*w] = 1.0;
48 | }
49 | mutex->unlock();
50 | };
51 |
52 | // This function is responsible for tonemapping and gamma-conversion.
53 | // I prefer not converting to sRGB encode
54 | // and a simply clipping functions works better than an 'exposure'-simulation
55 | int encode(float c, float /*exposure*/)
56 | {
57 |
58 | // Enable below for sRGB encoding
59 | /*
60 | float out = 1.0f - expf(c * exposure);
61 | if (out <= 0.0031308f)
62 | {
63 | out = 12.92f * out;
64 | }
65 | else
66 | {
67 | out = 1.055f * powf(out, 0.4166667f) - 0.055f; // Inverse gamma 2.4
68 | }
69 | float out = 1.0f - expf(c * exposure);
70 | out = powf(c, 1);
71 | */
72 | if (c>1) c = 1; // Simple clipping...
73 | c *= 255;
74 | return (int)c;
75 | }
76 |
77 |
78 | QImage getImage() {
79 | QImage im(w,h, QImage::Format_RGB32);
80 |
81 | //mutex->lock();
82 | float exposure = -2;
83 | for (int y = 0; y < h; y++) {
84 | QRgb* s = (QRgb*) im.scanLine(y);
85 | for (int x = 0; x < w; x++) {
86 | Vector3f c = colors[x+y*w]/weights[x+y*w];
87 | *s = qRgb(encode(c.x(),exposure), encode(c.y(),exposure), encode(c.z(),exposure));
88 | s++;
89 | //im.setPixel(x,y,qRgb(c.x()*255, c.y()*255, c.z()*255));
90 | }
91 | }
92 | //mutex->unlock();
93 | return im;
94 | }
95 |
96 | private:
97 | int w;
98 | int h;
99 | Vector3f* colors;
100 | double* weights;
101 | QMutex* mutex;
102 | };
103 |
104 | }
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/RayTracer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../Object3D.h"
4 | #include "../EngineWidget.h"
5 | #include
6 | #include "SyntopiaCore/Math/Vector3.h"
7 | #include "SyntopiaCore/Math/Matrix4.h"
8 | #include "SyntopiaCore/Math/Random.h"
9 | #include "VoxelStepper.h"
10 | #include "RenderThread.h"
11 | #include "ProgressiveOutput.h"
12 |
13 | namespace SyntopiaCore {
14 | namespace GLEngine {
15 |
16 | using namespace SyntopiaCore::Math;
17 |
18 | class RayTracer {
19 | public:
20 | RayTracer(EngineWidget* widget, ProgressBox* progressBox, bool inGUI);
21 | QImage calculateImage(int width, int height);
22 | void setParameter(QString param, QString value);
23 | bool wasCancelled() { return userCancelled; }
24 | private:
25 | bool progressiveGUI;
26 | ProgressiveOutput* progressiveOutput;
27 | EngineWidget* engine;
28 | void startJobs(ProgressBox* progress);
29 | QList objects;
30 | float xmin;
31 | float ymin;
32 | float xmax;
33 | float ymax;
34 |
35 | int voxelSteps;
36 | int windowWidth;
37 | int windowHeight;
38 |
39 | // Matrices from the OpenGL view.
40 | GLdouble modelView[16];
41 | GLdouble projection[16];
42 | GLint viewPort[16];
43 | long aaPixels;
44 | bool userCancelled;
45 | int sizeX;
46 | int sizeY;
47 | int maxThreads;
48 | QVector threads;
49 | AtomicCounter nextUnit;
50 | AtomicCounter completedUnits;
51 | int maxUnits;
52 | RenderThread rt;
53 | bool progressiveRender;
54 | ProgressBox* progressBox;
55 | };
56 |
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/RenderThread.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "../Object3D.h"
5 | #include "AtomicCounter.h"
6 | #include "VoxelStepper.h"
7 | #include "Sampler.h"
8 | #include "ProgressiveOutput.h"
9 | #include "SyntopiaCore/Math/Random.h"
10 |
11 | namespace SyntopiaCore {
12 | namespace GLEngine {
13 |
14 | using namespace SyntopiaCore::Math;
15 |
16 |
17 | class RenderThread : public QThread {
18 | public:
19 | enum Task { Raytrace, RaytraceProgressive } ;
20 | RenderThread();
21 | ~RenderThread();
22 | void setTask(Task task) { this->task = task; };
23 | RenderThread(const RenderThread& other);
24 | void raytrace(int newUnit);
25 | void raytraceProgressive(int newUnit);
26 | void setCounters(AtomicCounter* nextUnit, AtomicCounter* completedUnits, int maxUnits);
27 | void alloc(int w, int h);
28 | void setObjects(int count);
29 | static void msleep(int i) { QThread::msleep(i); }
30 | void run();
31 | Vector3f rayCastPixel(float x, float y);
32 | void setTerminated(bool value) { terminated = value; }
33 | void seed(int value) { rg.setSeed(value); };
34 | double getAOStrength(Object3D* object, Vector3f objectNormal, Vector3f objectIntersection);
35 | Vector3f rayCast(Vector3f startPoint, Vector3f direction, Object3D* excludeThis, int level = 0);
36 |
37 | private:
38 | Task task;
39 | AtomicCounter* nextUnit;
40 | AtomicCounter* completedUnits;
41 | int maxUnits;
42 | int w;
43 | int h;
44 |
45 | bool terminated;
46 |
47 | Vector3f frontStart;
48 | Vector3f frontX;
49 | Vector3f frontY;
50 | Vector3f backStart;
51 | Vector3f backX;
52 | Vector3f backY;
53 |
54 | Vector3f lightPos;
55 | Vector3f backgroundColor;
56 | int rayID;
57 | QVector rayIDs;
58 | int pixels;
59 | int maxDepth;
60 | int checks;
61 | VoxelStepper* accelerator;
62 |
63 | int aoSamples;
64 | int totalAOCasts;
65 | int aaSamples;
66 | int width;
67 | int height;
68 | bool useShadows;
69 | double dofCenter;
70 | double dofFalloff;
71 |
72 | Math::RandomNumberGenerator rg;
73 |
74 | Vector3f color;
75 | bool copy;
76 |
77 | Sampler* sampler;
78 | ProgressiveOutput* progressiveOutput;
79 | friend class RayTracer;
80 | int rayNumber;
81 | Filter* filter;
82 | };
83 |
84 |
85 |
86 | }
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/Sampler.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Random.h"
4 | #include "SyntopiaCore/Math/Vector3.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | using namespace SyntopiaCore::Math;
10 |
11 | class Filter {
12 | public:
13 | Filter() {};
14 | virtual float getWeight(float xSqr, float ySqr) = 0;
15 | virtual int getExtent() = 0;
16 | };
17 |
18 | class BoxFilter : public Filter {
19 | public:
20 | BoxFilter() {};
21 | virtual float getWeight(float, float) { return 1.0; }
22 | virtual int getExtent() { return 0; };
23 | };
24 |
25 | class GaussianFilter : public Filter {
26 | public:
27 | GaussianFilter(double ext, double alpha) : extent(extent), alpha(alpha) {
28 | this->extent = int(0.5+ext);
29 | s = -exp(-alpha*(ext*ext));
30 | };
31 |
32 | virtual float getWeight(float xSqr, float ySqr) {
33 | return (gaussian(xSqr)*gaussian(ySqr));
34 | };
35 |
36 | float gaussian(float v) {
37 | float a= exp(-alpha*v)+s;
38 | return a > 0 ? a : 0;
39 | }
40 |
41 | virtual int getExtent() { return extent; };
42 | private:
43 | int extent;
44 | double s;
45 | double alpha;
46 | };
47 |
48 | class TriangleFilter : public Filter {
49 | public:
50 | TriangleFilter(double halfwidth) : halfwidth(halfwidth) {
51 | this->extent = int(halfwidth-0.5+1);
52 | };
53 |
54 | virtual float getWeight(float xSqr, float ySqr) {
55 | return (triangle(sqrt(xSqr))*triangle(sqrt(ySqr)));
56 | };
57 |
58 | float triangle(float v) {
59 | float a= 1-v/halfwidth;
60 | return a > 0 ? a : 0;
61 | }
62 |
63 | virtual int getExtent() { return extent; };
64 | private:
65 | int extent;
66 | double halfwidth;
67 | };
68 |
69 |
70 | // A simple sampler. Draws uniform numbers, but no stratification.
71 | class Sampler {
72 | public:
73 | Sampler(Math::RandomNumberGenerator* rg);
74 | virtual ~Sampler();
75 | virtual Vector3f getAASample(int /*index*/) { return Vector3f(rg->getDouble(-0.5,0.5), rg->getDouble(-0.5,0.5),1.0); }
76 | virtual Vector3f getAODirection(int /*index*/) { return rg->getUniform3D(); }
77 | virtual Vector3f getLensSample(int /*index*/) { return rg->getUniform2D(); }
78 | virtual void prepareSamples(int /*nSamplesSqrt*/, int /*nAOSamplesSqrt*/) {};
79 | virtual Sampler* clone(Math::RandomNumberGenerator* rg) { return new Sampler(rg); }
80 | protected:
81 | Math::RandomNumberGenerator* rg;
82 | };
83 |
84 | // Stratified sampling
85 | class StratifiedSampler : public Sampler {
86 | public:
87 | StratifiedSampler(Math::RandomNumberGenerator* rg) : Sampler(rg) {};
88 | virtual Vector3f getAASample(int index);
89 | virtual Vector3f getAODirection(int index);
90 | virtual Vector3f getLensSample(int index);
91 | Vector3f sampleSphere(double u1, double u2);
92 | virtual void prepareSamples(int nSamplesSqrt, int nAOSamplesSqrt);
93 | virtual Sampler* clone(Math::RandomNumberGenerator* rg) { return new StratifiedSampler(rg); }
94 |
95 | private:
96 | QVector aoSamples;
97 | QVector aaSamples;
98 | QVector lensSamples;
99 | };
100 |
101 | // Stratified sampling
102 | class ProgressiveStratifiedSampler : public Sampler {
103 | public:
104 | ProgressiveStratifiedSampler(Math::RandomNumberGenerator* rg) :
105 | Sampler(rg) {}
106 | virtual Vector3f getAASample(int index);
107 | virtual Vector3f getAODirection(int index);
108 | virtual Vector3f getLensSample(int index);
109 | Vector3f sampleSphere(double u1, double u2);
110 | virtual void prepareSamples(int nSamplesSqrt, int nAOSamplesSqrt);
111 | virtual Sampler* clone(Math::RandomNumberGenerator* rg);
112 | void setAAOrder(QVector aaOrder) { this->aaOrder = aaOrder; }
113 | private:
114 | int aoSamplesSqrt;
115 | int aaSamplesSqrt;
116 | QVector aaOrder;
117 |
118 | };
119 |
120 |
121 | }
122 | }
123 |
124 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Raytracer/VoxelStepper.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "../Object3D.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 | using namespace SyntopiaCore::Math;
9 |
10 | /// See here for details about this approach:
11 | /// http://www.devmaster.net/articles/raytracing_series/part4.php
12 | class VoxelStepper {
13 | public:
14 | VoxelStepper(Vector3f minPos, Vector3f maxPos, int steps) ;
15 | ~VoxelStepper();
16 |
17 | void registerObject(Object3D* obj) ;
18 | QList* setupRay(Vector3f pos, Vector3f dir, double& maxT);
19 |
20 | inline double minn(double a, double b, double c) {
21 | if (a* advance(double& maxT);
26 | void setCopy(bool value) { this->copy = value; }
27 |
28 | private:
29 | bool copy;
30 | double currentT;
31 | double tDeltaX;
32 | double tDeltaY;
33 | double tDeltaZ;
34 | double tMaxX;
35 | double tMaxY;
36 | double tMaxZ;
37 | int stepX;
38 | int stepY;
39 | int stepZ;
40 | int cx;
41 | int cy;
42 | int cz;
43 |
44 | Vector3f pos;
45 | Vector3f dir;
46 | int steps;
47 | Vector3f minPos;
48 | Vector3f maxPos;
49 | const Vector3f size;
50 | QList* grid;
51 | };
52 |
53 |
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Sphere.cpp:
--------------------------------------------------------------------------------
1 | #include "Sphere.h"
2 |
3 | using namespace SyntopiaCore::Math;
4 |
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 |
10 | //GLUquadric* Sphere::myQuad = 0;
11 | int Sphere::displayListIndex = 0;
12 |
13 | Sphere::Sphere(SyntopiaCore::Math::Vector3f center, float radius) : center(center), radius(radius) {
14 | myQuad = gluNewQuadric();
15 | gluQuadricDrawStyle(myQuad, GLU_FILL);
16 |
17 | /// Bounding box
18 | Vector3f v = Vector3f(radius,radius,radius);
19 | from = center-v;
20 | to = center+v;
21 |
22 | if (displayListIndex == 0) {
23 | displayListIndex = glGenLists(1);
24 | glNewList(displayListIndex, GL_COMPILE);
25 | gluSphere(myQuad, 1, 7,7);
26 | glEndList();
27 | }
28 |
29 |
30 | };
31 |
32 | Sphere::~Sphere() {
33 | gluDeleteQuadric(myQuad);
34 | };
35 |
36 | void Sphere::draw() const {
37 | glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, primaryColor );
38 | if (primaryColor[3] < 1) {
39 | glEnable( GL_BLEND );
40 | }
41 |
42 | glPushMatrix();
43 | glTranslatef( center.x(), center.y(), center.z() );
44 | if (displayListIndex!=0) {
45 | glScalef(radius,radius,radius);
46 | glCallList(displayListIndex);
47 | } else {
48 | gluSphere(myQuad, radius, 7, 7);
49 | }
50 | glPopMatrix();
51 | };
52 |
53 |
54 |
55 |
56 | bool Sphere::intersectsRay(RayInfo* ri) {
57 | // Following: http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/
58 |
59 | double a = ri->lineDirection.sqrLength();
60 | double b = 2*(Vector3f::dot(ri->lineDirection, (ri->startPoint - center)));
61 | double c = (center-ri->startPoint).sqrLength() - radius*radius;
62 |
63 | double d = b*b-4*a*c;
64 |
65 | if (d<0) {
66 | ri->intersection = -1;
67 | return false;
68 | } else {
69 | // We always choose the negative solution, since it will be closest to the startPoint. (If intersection is positive)
70 | ri->intersection = (b - sqrt(d))/(-2*a);
71 | double intersection2 = (b + sqrt(d))/(-2*a);
72 | if (intersection2intersection) ri->intersection = intersection2;
73 |
74 | ri->normal = (ri->startPoint + ri->lineDirection*ri->intersection)-center;
75 | ri->normal.normalize();
76 | for (int i = 0; i < 4; i++) ri->color[i] = primaryColor[i];
77 | return true;
78 | }
79 | };
80 |
81 | bool Sphere::intersectsAABB(Vector3f from, Vector3f to) {
82 | // Based on http://www.gamasutra.com/features/19991018/Gomez_4.htm
83 | float s, d = 0;
84 |
85 | //find the square of the distance
86 | //from the sphere to the box
87 | for( long i=0 ; i<3 ; i++ )
88 | {
89 | if( center[i] < from[i] )
90 | {
91 | s = center[i] - from[i];
92 | d += s*s;
93 | } else if( center[i] > to[i] ) {
94 | s = center[i] - to[i];
95 | d += s*s;
96 | }
97 | }
98 | return d <= radius*radius;
99 | };
100 |
101 |
102 |
103 | }
104 | }
105 |
106 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Sphere.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 |
6 | namespace SyntopiaCore {
7 | namespace GLEngine {
8 |
9 | class Sphere : public Object3D {
10 | public:
11 | Sphere(SyntopiaCore::Math::Vector3f center, float radius);
12 | virtual ~Sphere();
13 |
14 | virtual QString name() { return "Sphere"; }
15 |
16 | virtual void draw() const;
17 | void setCenter(SyntopiaCore::Math::Vector3f center) { this->center = center; }
18 |
19 | virtual bool intersectsRay(RayInfo* /*rayInfo*/);
20 | virtual bool intersectsAABB(SyntopiaCore::Math::Vector3f /*from*/, SyntopiaCore::Math::Vector3f /*to*/);
21 |
22 | private:
23 | SyntopiaCore::Math::Vector3f center;
24 | float radius;
25 | GLUquadric* myQuad;
26 | static int displayListIndex;
27 | };
28 |
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Triangle.cpp:
--------------------------------------------------------------------------------
1 | #include "Triangle.h"
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 |
5 | using namespace SyntopiaCore::Math;
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 |
11 | Triangle::Triangle(SyntopiaCore::Math::Vector3f p1 ,
12 | SyntopiaCore::Math::Vector3f p2,
13 | SyntopiaCore::Math::Vector3f p3) : p1(p1), p2(p2), p3(p3)
14 | {
15 | from = p1;
16 | to = p3;
17 |
18 | Vector3f n1 = Vector3f::cross(p3-p1, p2-p1);
19 | n1.normalize();
20 | rt = RaytraceTriangle(p1,p2,p3,n1,n1,n1);
21 | rt.expandBoundingBox(from,to);
22 | rt.cullBackFaces = false;
23 | };
24 |
25 | Triangle::~Triangle() { };
26 |
27 | void Triangle::prepareForRaytracing() {
28 | rt.setColor(primaryColor[0],primaryColor[1],primaryColor[2], primaryColor[3]);
29 | }
30 |
31 | void Triangle::draw() const {
32 | glPushMatrix();
33 |
34 | glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, primaryColor );
35 | glPolygonMode(GL_FRONT, GL_FILL);
36 |
37 | glEnable(GL_CULL_FACE);
38 | glEnable (GL_LIGHTING);
39 |
40 | glEnable (GL_BLEND);
41 | glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
42 |
43 | glMateriali(GL_FRONT, GL_SPECULAR, 30);
44 | glMateriali(GL_FRONT, GL_SHININESS, 127);
45 |
46 | glBegin(GL_TRIANGLES);
47 | vertex3n(p1,p2,p3);
48 | glEnd();
49 |
50 | glPopMatrix();
51 | };
52 |
53 |
54 | bool Triangle::intersectsRay(RayInfo* ri) {
55 | return rt.intersectsRay(ri);
56 | };
57 |
58 |
59 | bool Triangle::intersectsAABB(Vector3f from2, Vector3f to2) {
60 | return (from.x() < to2.x()) && (to.x() > from2.x()) &&
61 | (from.y() < to2.y()) && (to.y() > from2.y()) &&
62 | (from.z() < to2.z()) && (to.z() > from2.z());
63 | };
64 |
65 |
66 |
67 | }
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/SyntopiaCore/GLEngine/Triangle.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "SyntopiaCore/Math/Vector3.h"
4 | #include "Object3D.h"
5 | #include "RaytraceTriangle.h"
6 |
7 | namespace SyntopiaCore {
8 | namespace GLEngine {
9 |
10 | class Triangle : public Object3D {
11 | public:
12 | Triangle(SyntopiaCore::Math::Vector3f p1 ,
13 | SyntopiaCore::Math::Vector3f p2,
14 | SyntopiaCore::Math::Vector3f p3);
15 |
16 | virtual ~Triangle();
17 |
18 | virtual QString name() { return "Triangle"; }
19 | virtual void draw() const;
20 | virtual void prepareForRaytracing();
21 | virtual bool intersectsRay(RayInfo* /*rayInfo*/);
22 | virtual bool intersectsAABB(SyntopiaCore::Math::Vector3f /*from*/, SyntopiaCore::Math::Vector3f /*to*/);
23 |
24 | private:
25 | RaytraceTriangle rt;
26 | SyntopiaCore::Math::Vector3f p1;
27 | SyntopiaCore::Math::Vector3f p2;
28 | SyntopiaCore::Math::Vector3f p3;
29 | };
30 |
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/SyntopiaCore/Logging/ListWidgetLogger.cpp:
--------------------------------------------------------------------------------
1 | #include "ListWidgetLogger.h"
2 |
3 |
4 |
5 | namespace SyntopiaCore {
6 | namespace Logging {
7 |
8 | ListWidgetLogger::ListWidgetLogger(QWidget* parent) : parent(parent) {
9 | listWidget = new QListWidget(parent);
10 | }
11 |
12 | ListWidgetLogger::~ListWidgetLogger() {
13 | }
14 |
15 | void ListWidgetLogger::log(QString message, LogLevel priority) {
16 | QListWidgetItem* i = new QListWidgetItem(message, listWidget);
17 |
18 | // Levels: NoneLevel, DebugLevel, TimingLevel, InfoLevel, WarningLevel, CriticalLevel, AllLevel
19 |
20 | if ( priority == InfoLevel ) {
21 | i->setBackgroundColor(QColor(255,255,255));
22 | } else if ( priority == WarningLevel ) {
23 | parent->show();
24 | i->setBackgroundColor(QColor(255,243,73));
25 | } else if ( priority == CriticalLevel ) {
26 | parent->show();
27 | i->setBackgroundColor(QColor(255,2,0));
28 | } else if ( priority == TimingLevel ) {
29 | parent->show();
30 | i->setBackgroundColor(QColor(25,255,0));
31 | } else {
32 | i->setBackgroundColor(QColor(220,220,220));
33 | }
34 | listWidget->scrollToItem(i);
35 |
36 | }
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/SyntopiaCore/Logging/ListWidgetLogger.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "Logging.h"
8 |
9 | namespace SyntopiaCore {
10 | namespace Logging {
11 |
12 | class ListWidgetLogger : public Logger {
13 | public:
14 | ListWidgetLogger(QWidget* parent);
15 |
16 | virtual ~ListWidgetLogger();
17 |
18 | /// This method all loggers must implement
19 | void log(QString message, LogLevel priority);
20 |
21 | QListWidget* getListWidget() { return listWidget; }
22 |
23 | private:
24 | QListWidget* listWidget;
25 | QWidget* parent;
26 | };
27 |
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/SyntopiaCore/Logging/Logging.cpp:
--------------------------------------------------------------------------------
1 | #include "Logging.h"
2 |
3 |
4 | #ifdef WIN32
5 | #include "windows.h"
6 | #endif
7 |
8 | /// TODO's
9 | /// - Nested log entris
10 | /// - Time
11 | /// - Setting a log view level
12 |
13 |
14 | namespace SyntopiaCore {
15 | namespace Logging {
16 | QVector Logger::loggers;
17 | QStack Logger::timeStack;
18 | QStack Logger::timeStringStack;
19 |
20 | void LOG(QString message, LogLevel priority) {
21 |
22 | // On Windows this allows us to see debug in the Output::Debug window while running.
23 | #ifdef WIN32
24 | OutputDebugString((LPCWSTR) (message+"\r\n").utf16());
25 | #endif
26 |
27 | for (int i = 0; i < Logger::loggers.size(); i++) {
28 | Logger::loggers[i]->log(message, priority);
29 | }
30 | }
31 |
32 | /// Useful aliases
33 | void Debug(QString text) { LOG(text, DebugLevel); }
34 | void INFO(QString text) { LOG(text, InfoLevel); }
35 | void WARNING(QString text) { LOG(text, WarningLevel); }
36 | void CRITICAL(QString text) { LOG(text, CriticalLevel); }
37 |
38 | void TIME(QString text) {
39 | LOG(text, TimingLevel);
40 |
41 | Logger::timeStack.push(QTime::currentTime());
42 | Logger::timeStringStack.push(text);
43 | } ;
44 |
45 | void TIME(int repetitions) {
46 | QTime t = Logger::timeStack.pop();
47 | QString s = Logger::timeStringStack.pop();
48 | int secs = t.msecsTo(QTime::currentTime());
49 | if (repetitions == 0) {
50 | LOG(QString("Time: %1s for ").arg(secs/1000.0f) + s, TimingLevel);
51 | } else {
52 | LOG(QString("Time: %1s for %2. %3 repetitions, %4s per repetition.").arg(secs/1000.0f).arg(s)
53 | .arg(repetitions).arg((secs/repetitions)/1000.0f), TimingLevel);
54 | }
55 | }; // End time...
56 |
57 |
58 |
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/SyntopiaCore/Logging/Logging.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | namespace SyntopiaCore {
9 | namespace Logging {
10 | /// Predefined logging levels
11 | enum LogLevel { NoneLevel, DebugLevel, TimingLevel, InfoLevel, WarningLevel, CriticalLevel, AllLevel };
12 |
13 | /// Abstract base class for all loggers
14 | class Logger {
15 | public:
16 | /// The destructors and constructors automatically add to the list of installed loggers.
17 | Logger() {
18 | loggers.append(this);
19 | }
20 |
21 | virtual ~Logger() {
22 | // Remove from list of available loggers.
23 | for (int i = loggers.size()-1; i >= 0; i--) {
24 | if (loggers[i] == this) loggers.remove(i);
25 | }
26 | }
27 |
28 | /// This method all loggers must implement
29 | virtual void log(QString message, LogLevel priority) = 0;
30 |
31 | /// Log messages are sent to this list of loggers.
32 | static QVector loggers;
33 | static QStack timeStack;
34 | static QStack timeStringStack;
35 | private:
36 |
37 | };
38 |
39 |
40 | void LOG(QString message, LogLevel priority);
41 |
42 | /// Useful aliases
43 | void Debug(QString text);
44 | void INFO(QString text);
45 | void TIME(QString text);
46 | void TIME(int repetitions = 0); // End time...
47 | void WARNING(QString text);
48 | void CRITICAL(QString text);
49 |
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/SyntopiaCore/Math/Matrix4.cpp:
--------------------------------------------------------------------------------
1 | #include "Matrix4.h"
2 |
3 |
4 | namespace SyntopiaCore {
5 | namespace Math {
6 |
7 |
8 |
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/SyntopiaCore/Math/Random.cpp:
--------------------------------------------------------------------------------
1 | #include "Random.h"
2 |
3 |
4 | namespace SyntopiaCore {
5 | namespace Math {
6 |
7 | namespace {
8 | struct SortPair {
9 | SortPair() {};
10 | SortPair(int index, double sortValue) : index(index), sortValue(sortValue) {};
11 | int index;
12 | double sortValue;
13 | bool operator< (const SortPair& rhs) const { return sortValue < rhs.sortValue; }
14 | };
15 | }
16 |
17 | QVector RandomNumberGenerator::getRandomIndices(int count) {
18 | QVector sp(count);
19 | for (int i = 0; i < count; i++) sp[i] = SortPair(i, getDouble());
20 | qSort(sp);
21 | QVector out(count);
22 | for (int i = 0; i < count; i++) out[i] = sp[i].index;
23 | return out;
24 | }
25 |
26 | Vector3f RandomNumberGenerator::getUniform2D() {
27 | Vector3f v;
28 | do {
29 | v = Vector3f(getDouble(-1,1),getDouble(-1,1),0);
30 | } while (v.sqrLength()>1.0);
31 | return v;
32 | }
33 |
34 | Vector3f RandomNumberGenerator::getUniform3D() {
35 | Vector3f v;
36 | do {
37 | v = Vector3f(getDouble(-1,1),getDouble(-1,1),getDouble(-1,1));
38 | } while (v.sqrLength()>1.0);
39 | return v;
40 | }
41 |
42 | namespace {
43 | const int UniformTableSize = 10000; // size of precalculated tables.
44 | }
45 |
46 | // Uses precalculated tables.
47 | // Initialized on first use (so init before using in multithreaded code)
48 | Vector3f RandomNumberGenerator::getUniform2DFromTable() {
49 | static QVector uniform2D;
50 | if (uniform2D.count() == 0) {
51 | for (int i = 0; i < UniformTableSize; i++) uniform2D.append(getUniform2D());
52 | }
53 | uniformCounter2D++;
54 | if (uniformCounter2D>=uniform2D.count()) uniformCounter2D = 0;
55 | return uniform2D[uniformCounter2D];
56 | }
57 |
58 | Vector3f RandomNumberGenerator::getUniform3DFromTable() {
59 | static QVector uniform3D;
60 | if (uniform3D.count() == 0) {
61 | for (int i = 0; i < UniformTableSize; i++) uniform3D.append(getUniform3D());
62 | }
63 | uniformCounter3D++;
64 | if (uniformCounter3D>=uniform3D.count()) uniformCounter3D = 0;
65 | return uniform3D[uniformCounter3D];
66 | }
67 |
68 | void RandomNumberGenerator::randomizeUniformCounter(){
69 | uniformCounter2D = getInt(UniformTableSize);
70 | uniformCounter3D = getInt(UniformTableSize);
71 | }
72 |
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/SyntopiaCore/Math/Random.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "../../ThirdPartyCode/MersenneTwister/MersenneTwister.h"
9 | #include "Vector3.h"
10 |
11 | namespace SyntopiaCore {
12 | namespace Math {
13 |
14 | /// A simple class for generating random numbers
15 | /// It is possible to have multiple independent streams, if the underlying RNG is the Mersenne Twister.
16 | /// If set to useStdLib, the CStdLib 'rand' and 'srand' functions are used - these are not independent - not even with multiple instances of this class.
17 | class RandomNumberGenerator {
18 | public:
19 | RandomNumberGenerator(bool useOldLibrary = false) : uniformCounter2D(0), uniformCounter3D(0) { if (useOldLibrary) { rng = 0; } else { rng = new MTRand(); } setSeed(0); };
20 | ~RandomNumberGenerator() { delete rng; };
21 |
22 | // This is only useful for backward compatibility.
23 | // The Mersenne Twister is much better since it allows multiple independent streams.
24 | void useStdLib(bool useOldLibrary) {
25 | delete rng; rng = 0;
26 | if (!useOldLibrary) {
27 | rng = new MTRand();
28 | }
29 | setSeed(lastSeed);
30 | };
31 |
32 | QVector getRandomIndices(int count);
33 |
34 | // Returns a vector, where the elements are ranked randomly.
35 | template
36 | QVector randomize(QVector list) {
37 | QVector indices = getRandomIndices(list.count());
38 | QVector copy(list.count());
39 | for (int i = 0; i < list.count(); i++) copy[i] = list[indices[i]];
40 | return copy;
41 | }
42 |
43 |
44 | bool isUsingStdLib() { return (rng == 0); }
45 |
46 | // Returns a double in the interval [0;1]
47 | double getDouble() {
48 | if (rng) {
49 | return rng->rand();
50 | } else {
51 | return rand()/(double)RAND_MAX;
52 | /*
53 | This one would be more correct, but the old cstdlib rand is implemented for backward compatibility:
54 | return (double)rand() / ((double)(RAND_MAX)+(double)(1)) ; // There are reasons for the multiple (double) casts, see: http://members.cox.net/srice1/random/crandom.html
55 | */
56 | }
57 | };
58 |
59 | // Normal distributed number with mean zero.
60 | double getNormal(double variance) {
61 | /// Note: requires MT RNG!
62 | return rng->randNorm(0,variance);
63 | }
64 |
65 | double getDouble(double min, double max) {
66 | return getDouble()*(max-min)+min;
67 | }
68 |
69 |
70 | // Returns an integer between 0 and max (both inclusive).
71 | int getInt(int max) {
72 | if (rng) {
73 | return rng->randInt(max);
74 | } else {
75 | return rand() % (max+1); // Probably not very good, use mersenne instead
76 | }
77 | }
78 |
79 | int getInt() {
80 | if (rng) {
81 | return rng->randInt();
82 | } else {
83 | return rand();
84 | }
85 | }
86 |
87 | void setSeed(int seed) {
88 | lastSeed = seed;
89 | if (rng) {
90 | rng->seed(seed);
91 | } else {
92 | srand(seed);
93 | }
94 | };
95 |
96 | // Return uniform samples on either unit disc (z=0) or unit sphere
97 | // Uses Monto-carlo sampling which might be slow
98 | Vector3f getUniform2D();
99 | Vector3f getUniform3D();
100 |
101 | // Uses precalculated tables.
102 | // Initialized on first use (so init before using in multithreaded code)
103 | Vector3f getUniform2DFromTable();
104 | Vector3f getUniform3DFromTable();
105 | void randomizeUniformCounter(); // use this to avoid coherence between different rg's
106 | void setUniformCounter2D(int value) { uniformCounter2D = value; }
107 | void setUniformCounter3D(int value) { uniformCounter3D = value; }
108 | private:
109 | int lastSeed;
110 | MTRand* rng;
111 | int uniformCounter2D;
112 | int uniformCounter3D;
113 |
114 | };
115 |
116 | }
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/SyntopiaCore/Math/Vector3.cpp:
--------------------------------------------------------------------------------
1 | #include "Vector3.h"
2 |
3 |
4 | namespace SyntopiaCore {
5 | namespace Math {
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/SyntopiaCore/Math/Vector3.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 |
9 | namespace SyntopiaCore {
10 | namespace Math {
11 |
12 | /// A simple class for representing three-dimensional vectors.
13 | template class Vector3 {
14 | public:
15 | Vector3() { s[0] = 0; s[1] = 0; s[2] = 0;}
16 | Vector3(scalar x, scalar y, scalar z) { s[0] = x; s[1] = y; s[2] = z; }
17 |
18 | // Constructor. Parses input such as "[1 2 3]";
19 | Vector3(QString input, bool& succes2) {
20 | input.remove('[');
21 | input.remove(']');
22 |
23 | QStringList sl = input.split(" ");
24 | if (sl.size() != 3) { succes2 = false; return; }
25 |
26 | bool succes = false;
27 | float f;
28 | f = sl[0].toFloat(&succes); if (!succes) { succes2 = false; return; }; s[0] = f;
29 | f = sl[1].toFloat(&succes); if (!succes) { succes2 = false; return; }; s[1] = f;
30 | f = sl[2].toFloat(&succes); if (!succes) { succes2 = false; return; }; s[2] = f;
31 |
32 | succes2 = true;
33 | }
34 |
35 |
36 | // data access
37 | scalar x() const { return s[0]; }
38 | scalar y() const { return s[1]; };
39 | scalar z() const { return s[2]; };
40 | scalar& x() { return s[0]; }
41 | scalar& y() { return s[1]; };
42 | scalar& z() { return s[2]; };
43 | scalar operator[] (int index) const { return s[index]; };
44 | scalar& operator[] (int index) { return s[index]; };
45 |
46 | scalar sqrLength() const { return s[0]*s[0]+s[1]*s[1]+s[2]*s[2]; }
47 | scalar length() const { return sqrt(s[0]*s[0]+s[1]*s[1]+s[2]*s[2]); }
48 |
49 | Vector3 normalized() const { scalar l = 1.0/length(); return Vector3(s[0]*l,s[1]*l,s[2]*l); }
50 | void normalize() { scalar l = 1.0/length(); s[0]*=l; s[1]*=l; s[2]*=l; }
51 | Vector3 operator- (const Vector3& rhs) const { return Vector3(s[0]-rhs.s[0], s[1]-rhs.s[1], s[2]-rhs.s[2]); }
52 | Vector3 operator+ (const Vector3& rhs) const { return Vector3(s[0]+rhs.s[0], s[1]+rhs.s[1], s[2]+rhs.s[2]); }
53 | Vector3 operator- () const { return Vector3(-s[0], -s[1], -s[2]); }
54 | bool operator== (const Vector3& rhs) const { return (s[0]==rhs.s[0] && s[1]==rhs.s[1] && s[2]==rhs.s[2]); }
55 |
56 | Vector3 operator* (scalar rhs) const { return Vector3(s[0]*rhs, s[1]*rhs, s[2]*rhs); }
57 | Vector3 operator/ (scalar rhs) const { scalar t = 1.0/rhs; return Vector3(s[0]*t, s[1]*t, s[2]*t); }
58 |
59 |
60 | QString toString() const {
61 | return QString("[%1 %2 %3]").arg(s[0]).arg(s[1]).arg(s[2]);
62 | }
63 |
64 | Vector3 cross(const Vector3 b) const {
65 | return Vector3(
66 | s[1]*b.s[2] - s[2]*b.s[1] ,
67 | s[2]*b.s[0] - s[0]*b.s[2] ,
68 | s[0]*b.s[1] - s[1]*b.s[0]);
69 | }
70 |
71 | static Vector3 cross(const Vector3 a, const Vector3 b) {
72 | return Vector3(
73 | a.s[1]*b.s[2] - a.s[2]*b.s[1] ,
74 | a.s[2]*b.s[0] - a.s[0]*b.s[2] ,
75 | a.s[0]*b.s[1] - a.s[1]*b.s[0]);
76 | }
77 |
78 | static scalar dot(const Vector3 a, const Vector3 b) {
79 | return a.s[0]*b.s[0] + a.s[1]*b.s[1] + a.s[2]*b.s[2] ;
80 | }
81 |
82 | private:
83 | scalar s[3];
84 | };
85 |
86 | template
87 | Vector3 operator*(T lhs, Vector3 rhs) { return Vector3(rhs[0]*lhs, rhs[1]*lhs, rhs[2]*lhs); }
88 |
89 | typedef Vector3 Vector3f ;
90 | typedef Vector3 Vector3d ;
91 |
92 | }
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/ColorUtils.cpp:
--------------------------------------------------------------------------------
1 | #include "ColorUtils.h"
2 | #include "../Logging/Logging.h"
3 |
4 | using namespace SyntopiaCore::Math;
5 | using namespace SyntopiaCore::Logging;
6 |
7 |
8 | namespace SyntopiaCore {
9 | namespace Misc {
10 |
11 | SyntopiaCore::Math::Vector3f ColorUtils::HSVtoRGB(SyntopiaCore::Math::Vector3f hsv) {
12 | /// Implementation based on: http://en.wikipedia.org/wiki/HSV_color_space
13 | if (hsv[0] >= 360) hsv[0]-=360;
14 | int Hi = (int)(hsv[0] / 60) % 6;
15 | double f = (hsv[0] / 60) - Hi;
16 | double p = hsv[2]*(1-hsv[1]);
17 | double q = hsv[2]*(1-f*hsv[1]);
18 | double t = hsv[2]*(1-(1-f)*hsv[1]);
19 | if (Hi == 0) return Vector3f(hsv[2],t,p);
20 | if (Hi == 1) return Vector3f(q,hsv[2],p);
21 | if (Hi == 2) return Vector3f(p,hsv[2],t);
22 | if (Hi == 3) return Vector3f(p,q,hsv[2]);
23 | if (Hi == 4) return Vector3f(t,p,hsv[2]);
24 | if (Hi == 5) return Vector3f(hsv[2],p,q);
25 | WARNING("ColorUtils::HSVtoRGB failed");
26 | return Vector3f(0,0,0);
27 | }
28 |
29 |
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/ColorUtils.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include "../Math/Vector3.h"
7 |
8 | namespace SyntopiaCore {
9 | namespace Misc {
10 |
11 |
12 | class ColorUtils {
13 | public:
14 | static SyntopiaCore::Math::Vector3f HSVtoRGB(SyntopiaCore::Math::Vector3f hsv);
15 | };
16 |
17 |
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/MiniParser.cpp:
--------------------------------------------------------------------------------
1 | #include "MiniParser.h"
2 |
3 | #include "../Logging/Logging.h"
4 |
5 | using namespace SyntopiaCore::Logging;
6 |
7 | namespace SyntopiaCore {
8 | namespace Misc {
9 |
10 |
11 | MiniParser::MiniParser( QString value, QChar separator ) : separator(separator), original(value), value(value), paramCount(0) {
12 | }
13 |
14 | MiniParser& MiniParser::getInt(int& val) {
15 | paramCount++;
16 | QString first = value.section(separator, 0,0);
17 | value = value.section(separator, 1);
18 |
19 |
20 | if (first.isEmpty()) {
21 | WARNING(QString("Expected argument number %1 for %2").arg(paramCount).arg(original));
22 | }
23 |
24 | bool succes = false;
25 | int i = first.toInt(&succes);
26 | if (!succes) {
27 | WARNING(QString("Expected argument number %1 to be an integer. Found: %2").arg(paramCount).arg(first));
28 | }
29 | val = i;
30 |
31 | return *this;
32 | }
33 |
34 |
35 |
36 | MiniParser& MiniParser::getBool(bool& val) {
37 | paramCount++;
38 | QString first = value.section(separator, 0,0);
39 | value = value.section(separator, 1);
40 |
41 | if (first.isEmpty()) {
42 | WARNING(QString("Expected argument number %1 for %2").arg(paramCount).arg(original));
43 | }
44 |
45 | if (first.toLower() == "true") {
46 | val = true;
47 | } else if (first.toLower() == "false") {
48 | val = false;
49 | } else {
50 | WARNING(QString("Expected argument number %1 to be either true or false. Found: %2").arg(paramCount).arg(first));
51 | }
52 |
53 | return *this;
54 | }
55 |
56 | MiniParser& MiniParser::getDouble(double& val) {
57 | paramCount++;
58 | QString first = value.section(separator, 0,0);
59 | value = value.section(separator, 1);
60 |
61 | if (first.isEmpty()) {
62 | WARNING(QString("Expected argument number %1 for %2").arg(paramCount).arg(original));
63 | }
64 |
65 | bool succes = false;
66 | double d = first.toDouble(&succes);
67 | if (!succes) {
68 | WARNING(QString("Expected argument number %1 to be an double. Found: %2").arg(paramCount).arg(first));
69 | }
70 | val = d;
71 |
72 | return *this;
73 | }
74 |
75 | MiniParser& MiniParser::getFloat(float& val) {
76 | paramCount++;
77 | QString first = value.section(separator, 0,0);
78 | value = value.section(separator, 1);
79 |
80 | if (first.isEmpty()) {
81 | WARNING(QString("Expected argument number %1 for %2").arg(paramCount).arg(original));
82 | }
83 |
84 | bool succes = false;
85 | float d = first.toFloat(&succes);
86 | if (!succes) {
87 | WARNING(QString("Expected argument number %1 to be an float. Found: %2").arg(paramCount).arg(first));
88 | }
89 | val = d;
90 |
91 | return *this;
92 | }
93 |
94 |
95 |
96 | }
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/MiniParser.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 |
7 | namespace SyntopiaCore {
8 | namespace Misc {
9 |
10 | /// Small class for parsing values from simple text strings.
11 | class MiniParser {
12 | public:
13 | MiniParser( QString value, QChar separator = ',');
14 |
15 | MiniParser& getInt(int& val);
16 | MiniParser& getBool(bool& val);
17 | MiniParser& getDouble(double& val);
18 | MiniParser& getFloat(float& val);
19 | private:
20 | QChar separator;
21 | QString original;
22 | QString value;
23 | int paramCount ;
24 | };
25 |
26 | }
27 | }
28 |
29 |
30 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/Persistence.cpp:
--------------------------------------------------------------------------------
1 | #include "Persistence.h"
2 |
3 | #include "../Logging/Logging.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | using namespace SyntopiaCore::Logging;
14 |
15 | namespace SyntopiaCore {
16 | namespace Misc {
17 |
18 |
19 |
20 |
21 | QMap& Persistence::GetStore() {
22 | static QMap p;
23 | return p;
24 | }
25 |
26 | void Persistence::Store(QWidget* widget, QString storageName) {
27 | if (storageName.isEmpty()) storageName = widget->objectName();
28 | if (qobject_cast(widget)) {
29 | QLineEdit* lineEdit = qobject_cast(widget);
30 | GetStore()[storageName] = QVariant(lineEdit->text());
31 | } else if (qobject_cast(widget)) {
32 | QCheckBox* cb = qobject_cast(widget);
33 | GetStore()[storageName] = QVariant(cb->isChecked());
34 | } else if (qobject_cast(widget)) {
35 | QSpinBox* sb = qobject_cast(widget);
36 | GetStore()[storageName] = QVariant(sb->value());
37 | } else if (qobject_cast(widget)) {
38 | QRadioButton* rb = qobject_cast(widget);
39 | GetStore()[storageName] = QVariant(rb->isChecked());
40 | } else if (qobject_cast(widget)) {
41 | QComboBox* cb = qobject_cast(widget);
42 | GetStore()[storageName] = QVariant(cb->currentText());
43 | } else {
44 | WARNING("Unsupported widget: " + widget->objectName());
45 | }
46 | }
47 |
48 | void Persistence::Restore(QWidget* widget, QString storageName) {
49 | if (storageName.isEmpty()) storageName = widget->objectName();
50 | if (qobject_cast(widget)) {
51 | QLineEdit* lineEdit = qobject_cast(widget);
52 | if (GetStore().contains(storageName)) {
53 | lineEdit->setText(GetStore()[storageName].toString());
54 | }
55 |
56 | } else if (qobject_cast(widget)) {
57 | QCheckBox* cb = qobject_cast(widget);
58 | if (GetStore().contains(storageName)) {
59 | cb->setChecked(GetStore()[storageName].toBool());
60 | }
61 |
62 | } else if (qobject_cast(widget)) {
63 | QSpinBox* sb = qobject_cast(widget);
64 | if (GetStore().contains(storageName)) {
65 | sb->setValue(GetStore()[storageName].toInt());
66 | }
67 |
68 | } else if (qobject_cast(widget)) {
69 | QRadioButton* rb = qobject_cast(widget);
70 | if (GetStore().contains(storageName)) {
71 | rb->setChecked(GetStore()[storageName].toInt());
72 | }
73 |
74 | } else if (qobject_cast(widget)) {
75 | QComboBox* rb = qobject_cast(widget);
76 | if (GetStore().contains(storageName)) {
77 | int i = rb->findText(GetStore()[storageName].toString());
78 | if (i!=-1) {
79 | rb->setCurrentIndex(i);
80 | } else {
81 | }
82 | }
83 |
84 | } else {
85 | WARNING("Unsupported widget: " + widget->objectName());
86 | }
87 | }
88 |
89 | bool Persistence::Contains(QString storageName) {
90 | return GetStore().contains(storageName);
91 | }
92 |
93 | QVariant Persistence::Get(QString storageName) {
94 | return GetStore()[storageName];
95 | }
96 |
97 | void Persistence::Put(QString storageName, QVariant value) {
98 | GetStore()[storageName] = value;
99 | }
100 |
101 |
102 | }
103 | }
104 |
105 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/Persistence.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 |
8 | namespace SyntopiaCore {
9 | namespace Misc {
10 |
11 |
12 | /// Util classes for making GUI settings persistent.
13 | /// (i.e. remember the state of drop-downs, line-edits, and so on).
14 | ///
15 | /// Per default, the widget is stored under its objectName, but it possible to specify
16 | /// another name (e.g. to share widget data between dialogs).
17 | ///
18 | /// Notice that widgets must be hardcoded into the cpp-file to be supported
19 | class Persistence {
20 | public:
21 | static void Store(QWidget* widget, QString storageName = QString());
22 | static void Restore(QWidget* widget, QString storageName = QString());
23 | static bool Contains(QString storageName);
24 | static QVariant Get(QString storageName);
25 | static void Put(QString storageName, QVariant value);
26 | private:
27 | static QMap& GetStore();
28 | };
29 |
30 |
31 | }
32 | }
33 |
34 |
35 |
--------------------------------------------------------------------------------
/SyntopiaCore/Misc/Version.cpp:
--------------------------------------------------------------------------------
1 | #include "Version.h"
2 |
3 | #include "../Logging/Logging.h"
4 |
5 | using namespace SyntopiaCore::Logging;
6 |
7 | namespace SyntopiaCore {
8 | namespace Misc {
9 |
10 | Version::Version() : revision(0), build(0), codename("") {
11 | this->major = 0;
12 | this->minor = 0;
13 | }
14 |
15 | Version::Version(int major, int minor, int revision, int build, QString codename) : revision(revision), build(build), codename(codename) {
16 | this->major = major;
17 | this->minor = minor;
18 | }
19 |
20 | QList Version::GetNewVersions(QString /*url*/) const {
21 | return QList();
22 | }
23 |
24 | QString Version::toLongString() const {
25 | QString s = QString("%1.%2").arg(major).arg(minor);
26 | if (revision >= 0) s+= QString(".%3").arg(revision);
27 | if (build >= 0) s+= QString(".%4").arg(build);
28 |
29 | if (!codename.isEmpty()) s+= " " + codename;
30 |
31 | return s;
32 | }
33 |
34 | bool Version::operator<(const Version &rhs) {
35 | if (major == rhs.major) {
36 | if (minor == rhs.minor) {
37 | if (revision == rhs.revision) {
38 | return (build < rhs.build);
39 | } else {
40 | return (revision < rhs.revision);
41 | }
42 | } else {
43 | return (minor < rhs.minor);
44 | }
45 | } else {
46 | return (major < rhs.major);
47 | }
48 |
49 | }
50 |
51 | bool Version::operator>(const Version &rhs) {
52 | if ( (*this) == rhs ) return false;
53 | return !((*this)
4 | #include
5 |
6 |
7 | namespace SyntopiaCore {
8 | namespace Misc {
9 |
10 | /// For keeping track of versions
11 | /// Having a formalized version object, can
12 | /// be helpful when checking the internet for updates.
13 | class Version {
14 | public:
15 | /// Constructor.
16 | /// Settings revision or build to -1 indicates they are not in use.
17 | Version();
18 | Version(int major, int minor, int revision = -1, int build = -1, QString codename = "");
19 |
20 | /// Long human-readable version.
21 | QString toLongString() const;
22 |
23 | /// Returns a list of versions, newer than 'this' version,
24 | /// by reading an XML-file from the specified URL.
25 | ///
26 | /// Todo: Implement
27 | QList GetNewVersions(QString url) const;
28 |
29 | /// Comparisons
30 | bool operator<(const Version &rhs);
31 | bool operator>(const Version &rhs);
32 | bool operator==(const Version &rhs);
33 |
34 | private:
35 | int major;
36 | int minor;
37 | int revision;
38 | int build;
39 | QString codename;
40 | };
41 |
42 |
43 | }
44 | }
45 |
46 |
47 |
--------------------------------------------------------------------------------
/bugs.txt:
--------------------------------------------------------------------------------
1 | Bug List:
2 | ---------
3 | Priority 0-5, 5 is worst:
4 |
5 | - [3] Some reports of mesh showing up with broken polygons (they are quads, so I think this is because of faulty normal interpolation)
6 | - [3] Some Ubuntu user has problems with loosing the cursor in the edit view (I can not reproduce this in my VM-Ware)
7 | - [2] Triangles does not support ClassID
8 | - [2] Face Culling does not work for boxes, when coordinates are flipped.
9 | - [2] A self-refering cycle of rule retirements would crash structure synth.
10 | - [2] Parser do not allow operator names as rule names. 'rule R1 maxdepth 2 > c ' fails.
11 | - [1] Syntax Highlightning has several errors.
12 |
13 | Other TO-DO's:
14 |
15 |
16 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/changelog.txt
--------------------------------------------------------------------------------
/images/agt_internet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/agt_internet.png
--------------------------------------------------------------------------------
/images/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/copy.png
--------------------------------------------------------------------------------
/images/cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/cut.png
--------------------------------------------------------------------------------
/images/documentinfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/documentinfo.png
--------------------------------------------------------------------------------
/images/exit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/exit.png
--------------------------------------------------------------------------------
/images/fileclose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileclose.png
--------------------------------------------------------------------------------
/images/fileicons/Structure Synth.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/Structure Synth.icns
--------------------------------------------------------------------------------
/images/fileicons/Structure Synth.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/Structure Synth.ico
--------------------------------------------------------------------------------
/images/fileicons/StructureSynth-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/StructureSynth-16.png
--------------------------------------------------------------------------------
/images/fileicons/StructureSynth-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/StructureSynth-256.png
--------------------------------------------------------------------------------
/images/fileicons/StructureSynthDoc-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/StructureSynthDoc-256.png
--------------------------------------------------------------------------------
/images/fileicons/StructureSynthDoc.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/StructureSynthDoc.icns
--------------------------------------------------------------------------------
/images/fileicons/StructureSynthDoc.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/StructureSynthDoc.ico
--------------------------------------------------------------------------------
/images/fileicons/icon.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/icon.pdn
--------------------------------------------------------------------------------
/images/fileicons/icon2.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/fileicons/icon2.pdn
--------------------------------------------------------------------------------
/images/filesaveas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/filesaveas.png
--------------------------------------------------------------------------------
/images/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/folder.png
--------------------------------------------------------------------------------
/images/mail_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/mail_new.png
--------------------------------------------------------------------------------
/images/new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/new.png
--------------------------------------------------------------------------------
/images/open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/open.png
--------------------------------------------------------------------------------
/images/paste.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/paste.png
--------------------------------------------------------------------------------
/images/render.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/render.png
--------------------------------------------------------------------------------
/images/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/save.png
--------------------------------------------------------------------------------
/images/saveas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/saveas.png
--------------------------------------------------------------------------------
/images/structuresynth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/images/structuresynth.png
--------------------------------------------------------------------------------
/notes.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanth/Structure-Synth/dfdc230d18b1e4f669e3886151e6b2993a7fcde5/notes.txt
--------------------------------------------------------------------------------
/resource.h:
--------------------------------------------------------------------------------
1 | #define IDI_ICON1 1
2 | #define IDI_ICON2 2
3 |
--------------------------------------------------------------------------------
/structure-synth.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Structure Synth
3 | Name[ru]=Structure Synth
4 | Comment=Creating 3D structures from a set of user specified rules
5 | Comment[ru]=Создание трехмерных структур по заданным правилам
6 | Exec=structure-synth
7 | Icon=structure-synth.png
8 | Categories=Graphics;VectorGraphics;Qt;
9 | Terminal=false
10 | Type=Application
11 | X-SuSE-translate=true
12 |
--------------------------------------------------------------------------------
/structuresynth.rc:
--------------------------------------------------------------------------------
1 | #include "resource.h"
2 |
3 | IDI_ICON1 ICON "StructureSynth.ico"
4 | IDI_ICON2 ICON "StructureSynthDoc.ico"
5 |
6 | // Version
7 |
8 | VS_VERSION_INFO VERSIONINFO
9 | FILEVERSION 0,9,5,0
10 | PRODUCTVERSION 0,9,5,0
11 | FILEFLAGSMASK 0x17L
12 | #ifdef _DEBUG
13 | FILEFLAGS 0x1L
14 | #else
15 | FILEFLAGS 0x0L
16 | #endif
17 | FILEOS 0x4L
18 | FILETYPE 0x1L
19 | FILESUBTYPE 0x0L
20 | BEGIN
21 | BLOCK "StringFileInfo"
22 | BEGIN
23 | BLOCK "080004b0"
24 | BEGIN
25 | VALUE "CompanyName", "Syntopia"
26 | VALUE "FileDescription", "Structure Synth Main Executable"
27 | VALUE "FileVersion", "0, 9, 5, 0"
28 | VALUE "InternalName", "StructureSynth"
29 | VALUE "LegalCopyright", "Copyright (C) 2007-2009 Syntopia"
30 | VALUE "LegalTrademarks", "Structure Synth"
31 | VALUE "OriginalFilename", "StructureSynth.exe"
32 | VALUE "ProductName", "Structure Synth"
33 | VALUE "ProductVersion", "0, 9, 5, 0"
34 | END
35 | END
36 | BLOCK "VarFileInfo"
37 | BEGIN
38 | VALUE "Translation", 0x409, 1200
39 | END
40 | END
41 |
--------------------------------------------------------------------------------