first commit
This commit is contained in:
commit
2418b06414
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
||||||
|
<Properties StartupConfiguration="{3C95A1AE-389C-4012-BBC7-CC03EF11C767}|Default">
|
||||||
|
<MonoDevelop.Ide.ItemProperties.RaytracerEngine PreferredExecutionTarget="MonoDevelop.Default" />
|
||||||
|
<MonoDevelop.Ide.Workbench ActiveDocument="test/Form1.cs">
|
||||||
|
<Files>
|
||||||
|
<File FileName="test/vec3.cs" Line="20" Column="10" />
|
||||||
|
<File FileName="test/hitable.cs" />
|
||||||
|
<File FileName="test/sphere.cs" />
|
||||||
|
<File FileName="test/triangle.cs" />
|
||||||
|
<File FileName="test/camera.cs" />
|
||||||
|
<File FileName="test/Form1.cs" Line="38" Column="15" />
|
||||||
|
</Files>
|
||||||
|
<Pads>
|
||||||
|
<Pad Id="ProjectPad">
|
||||||
|
<State name="__root__">
|
||||||
|
<Node name="RaytracerEngine" expanded="True">
|
||||||
|
<Node name="RaytracerEngine" expanded="True">
|
||||||
|
<Node name="Form1.cs" selected="True" />
|
||||||
|
</Node>
|
||||||
|
</Node>
|
||||||
|
</State>
|
||||||
|
</Pad>
|
||||||
|
</Pads>
|
||||||
|
</MonoDevelop.Ide.Workbench>
|
||||||
|
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
|
||||||
|
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
|
||||||
|
<MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
|
<BreakpointStore />
|
||||||
|
</MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
|
<MultiItemStartupConfigurations />
|
||||||
|
</Properties>
|
|
@ -0,0 +1 @@
|
||||||
|
{"Format":1,"ProjectReferences":[],"MetadataReferences":[{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/Microsoft.CSharp.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/mscorlib.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Core.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Data.DataSetExtensions.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Data.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Deployment.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Drawing.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Net.Http.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Windows.Forms.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Xml.dll","Aliases":[]},{"FilePath":"/Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/4.6.2-api/System.Xml.Linq.dll","Aliases":[]}],"Files":["/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/camera.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/DirectBitmap.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Form1.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Form1.Designer.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/hitable.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/LockBitmap.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Program.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Properties/AssemblyInfo.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/ray.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/sphere.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/triangle.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/vec3.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Form1.resx","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Properties/Resources.resx","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Properties/Resources.Designer.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Properties/Settings.settings","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/Properties/Settings.Designer.cs","/Users/Zongor/Documents/Raytracers/RaytracerEngine/test/App.config"],"BuildActions":["Compile","Compile","Compile","Compile","Compile","Compile","Compile","Compile","Compile","Compile","Compile","Compile","EmbeddedResource","EmbeddedResource","Compile","None","Compile","None"],"Analyzers":[]}
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public class DirectBitmap : IDisposable
|
||||||
|
{
|
||||||
|
public Bitmap Bitmap { get; private set; }
|
||||||
|
public Int32[] Bits { get; private set; }
|
||||||
|
public bool Disposed { get; private set; }
|
||||||
|
public int Height { get; private set; }
|
||||||
|
public int Width { get; private set; }
|
||||||
|
|
||||||
|
protected GCHandle BitsHandle { get; private set; }
|
||||||
|
|
||||||
|
public DirectBitmap(int width, int height)
|
||||||
|
{
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
Bits = new Int32[width * height];
|
||||||
|
BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned);
|
||||||
|
Bitmap = new Bitmap(width, height, width * 4, PixelFormat.Format32bppPArgb, BitsHandle.AddrOfPinnedObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (Disposed) return;
|
||||||
|
Disposed = true;
|
||||||
|
Bitmap.Dispose();
|
||||||
|
BitsHandle.Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
partial class Form1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
|
||||||
|
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||||
|
this.timer1 = new System.Windows.Forms.Timer(this.components);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// pictureBox1
|
||||||
|
//
|
||||||
|
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.pictureBox1.Name = "pictureBox1";
|
||||||
|
this.pictureBox1.Size = new System.Drawing.Size(800, 720);
|
||||||
|
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||||
|
this.pictureBox1.TabIndex = 0;
|
||||||
|
this.pictureBox1.TabStop = false;
|
||||||
|
//
|
||||||
|
// timer1
|
||||||
|
//
|
||||||
|
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
|
||||||
|
//
|
||||||
|
// Form1
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(800, 720);
|
||||||
|
this.Controls.Add(this.pictureBox1);
|
||||||
|
this.Name = "Form1";
|
||||||
|
this.Text = "Form1";
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.ColorDialog colorDialog1;
|
||||||
|
private System.Windows.Forms.PictureBox pictureBox1;
|
||||||
|
private System.Windows.Forms.Timer timer1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using static RaytracerEngine.hitable;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public partial class Form1 : Form
|
||||||
|
{
|
||||||
|
vec3 origin;
|
||||||
|
vec3 lower_left_corner;
|
||||||
|
vec3 horizontal;
|
||||||
|
vec3 vertical;
|
||||||
|
List<hitable> objects;
|
||||||
|
Bitmap bmp;
|
||||||
|
LockBitmap dbm;
|
||||||
|
int nx = 200;
|
||||||
|
int ny = 100;
|
||||||
|
int ns = 3;
|
||||||
|
bool left;
|
||||||
|
bool right;
|
||||||
|
bool fore;
|
||||||
|
bool back;
|
||||||
|
bool look_left;
|
||||||
|
bool look_right;
|
||||||
|
Random rnd;
|
||||||
|
float rand { get{ return (float)rnd.NextDouble();}}
|
||||||
|
|
||||||
|
public Form1()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
//DoubleBuffered = true;
|
||||||
|
left = false;
|
||||||
|
right = false;
|
||||||
|
fore = false;
|
||||||
|
back = false;
|
||||||
|
look_left = false;
|
||||||
|
look_right = false;
|
||||||
|
origin = new vec3(0, 0, 0);
|
||||||
|
lower_left_corner = new vec3(-2.0f, -1.0f, -1.0f);
|
||||||
|
horizontal = new vec3(4.0f, 0.0f, 0.0f);
|
||||||
|
vertical = new vec3(0.0f, 2.0f, 0.0f);
|
||||||
|
objects = new List<hitable>();
|
||||||
|
//OLD VERSION
|
||||||
|
//lower_left_corner = new vec3(-2.0f, -1.0f, -1.0f);
|
||||||
|
//horizontal = new vec3(4.0f, 0.0f, 0.0f);
|
||||||
|
//vertical = new vec3(0.0f, 2.0f, 0.0f);
|
||||||
|
lower_left_corner = new vec3(2.0f, 1.0f, -1.0f);
|
||||||
|
horizontal = new vec3(-4.0f, 0.0f, 0.0f);
|
||||||
|
vertical = new vec3(0.0f, -2.0f, 0.0f);
|
||||||
|
|
||||||
|
objects = new List<hitable>();
|
||||||
|
//objects.Add(new sphere(new vec3(0, 0, -1.0f), 0.5f));
|
||||||
|
//objects.Add(new sphere(new vec3(0, -100.5f, -1f), 100f));
|
||||||
|
|
||||||
|
objects.Add(new sphere(new vec3(0, 0, -16), 2));
|
||||||
|
objects.Add(new sphere(new vec3(3, -1, -14), 1));
|
||||||
|
objects.Add(new sphere(new vec3(-3, -1, -14), 1));
|
||||||
|
|
||||||
|
objects.Add(new triangle(new vec3(-8, -2, -20), new vec3(8, -2, -20), new vec3(8, 10, -20), 0));
|
||||||
|
objects.Add(new triangle(new vec3(-8, -2, -20), new vec3(8, 10, -20), new vec3(-8, 10, -20), 0));
|
||||||
|
objects.Add(new triangle(new vec3(-8, -2, -20), new vec3(8, -2, -10), new vec3(8, -2, -20), 0));
|
||||||
|
objects.Add(new triangle(new vec3(-8, -2, -20), new vec3(-8, -2, -10), new vec3(8, -2, -10), 0));
|
||||||
|
objects.Add(new triangle(new vec3(8, -2, -20), new vec3(8, -2, -10), new vec3(8, 10, -20), 0));
|
||||||
|
|
||||||
|
bmp = new Bitmap(nx, ny);
|
||||||
|
dbm = new LockBitmap(bmp);
|
||||||
|
rnd = new Random();
|
||||||
|
timer1.Interval = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnLoad(EventArgs e)
|
||||||
|
{
|
||||||
|
timer1.Start();
|
||||||
|
base.OnLoad(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnClosed(EventArgs e)
|
||||||
|
{
|
||||||
|
bmp.Dispose();
|
||||||
|
timer1.Stop();
|
||||||
|
base.OnClosed(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 color(ray r, int reflect)
|
||||||
|
{
|
||||||
|
bool hit_any = false;
|
||||||
|
hit_record temp_rec = new hit_record();
|
||||||
|
hit_record rec = new hit_record();
|
||||||
|
float closest = float.MaxValue;
|
||||||
|
|
||||||
|
foreach(var o in objects)
|
||||||
|
{
|
||||||
|
if (o.hit(r, 0.001f, closest, out temp_rec))
|
||||||
|
{
|
||||||
|
hit_any = true;
|
||||||
|
closest = temp_rec.t;
|
||||||
|
rec = temp_rec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit_any && reflect>0)
|
||||||
|
{
|
||||||
|
vec3 target = rec.p + rec.normal; //+ random_unit_in_sphere();
|
||||||
|
return 0.5f * color(new ray(rec.p, target - rec.p), --reflect);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 unit_dir = vec3.unit_vector(r.direction);
|
||||||
|
float t = 0.5f * (unit_dir.y + 1.0f);
|
||||||
|
return (1.0f - t) * new vec3(1.0f, 1.0f, 1.0f) + t * new vec3(0.5f, 0.7f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private vec3 random_unit_in_sphere()
|
||||||
|
{
|
||||||
|
vec3 p;
|
||||||
|
float o = 0f;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p = 2.0f * new vec3(rand, rand, rand) - new vec3(1,1,1);
|
||||||
|
o = p.square_length();
|
||||||
|
} while (o >= 1f);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void draw_scene()
|
||||||
|
{
|
||||||
|
dbm.LockBits();
|
||||||
|
for (int j = ny - 1; j >= 0; j--)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < nx; i++)
|
||||||
|
{
|
||||||
|
vec3 col = new vec3(0, 0, 0);
|
||||||
|
float u = (float)i / (float)nx;
|
||||||
|
float v = (float)j / (float)ny;
|
||||||
|
//for (int s = 0; s < ns; s++)
|
||||||
|
//{
|
||||||
|
// float u = (float)(i + rand) / (float)nx;
|
||||||
|
// float v = (float)(j + rand) / (float)ny;
|
||||||
|
ray r = new ray(origin, lower_left_corner + u * horizontal + v * vertical);
|
||||||
|
col = color(r, 4);
|
||||||
|
//}
|
||||||
|
//col /= (float)ns;
|
||||||
|
int ir = (int)(255.99 * col.r);
|
||||||
|
int ig = (int)(255.99 * col.g);
|
||||||
|
int ib = (int)(255.99 * col.b);
|
||||||
|
dbm.SetPixel(i, j, Color.FromArgb(255, (byte)ir, (byte)ig, (byte)ib));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbm.UnlockBits();
|
||||||
|
pictureBox1.Image = bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void timer1_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
const float scale = 0.7f;//for 'walking' speed
|
||||||
|
vec3 forwards_back = vec3.cross(horizontal, vertical);
|
||||||
|
forwards_back.normalize();
|
||||||
|
vec3 left_right = vec3.cross(vertical, forwards_back);
|
||||||
|
left_right.normalize();
|
||||||
|
|
||||||
|
if (left)
|
||||||
|
origin = origin - left_right * scale;
|
||||||
|
|
||||||
|
if (right)
|
||||||
|
origin = origin + left_right * scale;
|
||||||
|
|
||||||
|
if (fore)
|
||||||
|
origin = origin - forwards_back * scale;
|
||||||
|
|
||||||
|
if (back)
|
||||||
|
origin = origin + forwards_back * scale;
|
||||||
|
|
||||||
|
if (look_left)
|
||||||
|
{
|
||||||
|
//rotational matrix on camera left 25*
|
||||||
|
lower_left_corner = vec3.turn_y(lower_left_corner, ((float)Math.PI / 16));
|
||||||
|
horizontal = vec3.turn_y(horizontal, ((float)Math.PI / 16));
|
||||||
|
vertical = vec3.turn_y(vertical, ((float)Math.PI / 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (look_right)
|
||||||
|
{
|
||||||
|
//rotational matrix on camera right 25*
|
||||||
|
lower_left_corner = vec3.turn_y(lower_left_corner, -((float)Math.PI / 16));
|
||||||
|
horizontal = vec3.turn_y(horizontal, -((float)Math.PI / 16));
|
||||||
|
vertical = vec3.turn_y(vertical, -((float)Math.PI / 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_scene();
|
||||||
|
pictureBox1.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
|
{
|
||||||
|
draw_scene();
|
||||||
|
base.OnPaint(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnKeyDown(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyValue == 'A')
|
||||||
|
left = true;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'D')
|
||||||
|
right = true;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'W')
|
||||||
|
fore = true;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'S')
|
||||||
|
back = true;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'Q')
|
||||||
|
look_left = true;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'E')
|
||||||
|
look_right = true;
|
||||||
|
|
||||||
|
base.OnKeyDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnKeyUp(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyValue == 'A')
|
||||||
|
left = false;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'D')
|
||||||
|
right = false;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'W')
|
||||||
|
fore = false;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'S')
|
||||||
|
back = false;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'Q')
|
||||||
|
look_left = false;
|
||||||
|
|
||||||
|
if (e.KeyValue == 'E')
|
||||||
|
look_right = false;
|
||||||
|
|
||||||
|
base.OnKeyUp(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="colorDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>138, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
|
@ -0,0 +1,168 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
class LockBitmap
|
||||||
|
{
|
||||||
|
Bitmap source = null;
|
||||||
|
IntPtr Iptr = IntPtr.Zero;
|
||||||
|
BitmapData bitmapData = null;
|
||||||
|
|
||||||
|
public byte[] Pixels { get; set; }
|
||||||
|
public int Depth { get; private set; }
|
||||||
|
public int Width { get; private set; }
|
||||||
|
public int Height { get; private set; }
|
||||||
|
|
||||||
|
public LockBitmap(Bitmap source)
|
||||||
|
{
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lock bitmap data
|
||||||
|
/// </summary>
|
||||||
|
public void LockBits()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get width and height of bitmap
|
||||||
|
Width = source.Width;
|
||||||
|
Height = source.Height;
|
||||||
|
|
||||||
|
// get total locked pixels count
|
||||||
|
int PixelCount = Width * Height;
|
||||||
|
|
||||||
|
// Create rectangle to lock
|
||||||
|
Rectangle rect = new Rectangle(0, 0, Width, Height);
|
||||||
|
|
||||||
|
// get source bitmap pixel format size
|
||||||
|
Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);
|
||||||
|
|
||||||
|
// Check if bpp (Bits Per Pixel) is 8, 24, or 32
|
||||||
|
if (Depth != 8 && Depth != 24 && Depth != 32)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock bitmap and return bitmap data
|
||||||
|
bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
|
||||||
|
source.PixelFormat);
|
||||||
|
|
||||||
|
// create byte array to copy pixel values
|
||||||
|
int step = Depth / 8;
|
||||||
|
Pixels = new byte[PixelCount * step];
|
||||||
|
Iptr = bitmapData.Scan0;
|
||||||
|
|
||||||
|
// Copy data from pointer to array
|
||||||
|
Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unlock bitmap data
|
||||||
|
/// </summary>
|
||||||
|
public void UnlockBits()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Copy data from byte array to pointer
|
||||||
|
Marshal.Copy(Pixels, 0, Iptr, Pixels.Length);
|
||||||
|
|
||||||
|
// Unlock bitmap data
|
||||||
|
source.UnlockBits(bitmapData);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the color of the specified pixel
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x"></param>
|
||||||
|
/// <param name="y"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Color GetPixel(int x, int y)
|
||||||
|
{
|
||||||
|
Color clr = Color.Empty;
|
||||||
|
|
||||||
|
// Get color components count
|
||||||
|
int cCount = Depth / 8;
|
||||||
|
|
||||||
|
// Get start index of the specified pixel
|
||||||
|
int i = ((y * Width) + x) * cCount;
|
||||||
|
|
||||||
|
if (i > Pixels.Length - cCount)
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
|
||||||
|
if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha
|
||||||
|
{
|
||||||
|
byte b = Pixels[i];
|
||||||
|
byte g = Pixels[i + 1];
|
||||||
|
byte r = Pixels[i + 2];
|
||||||
|
byte a = Pixels[i + 3]; // a
|
||||||
|
clr = Color.FromArgb(a, r, g, b);
|
||||||
|
}
|
||||||
|
if (Depth == 24) // For 24 bpp get Red, Green and Blue
|
||||||
|
{
|
||||||
|
byte b = Pixels[i];
|
||||||
|
byte g = Pixels[i + 1];
|
||||||
|
byte r = Pixels[i + 2];
|
||||||
|
clr = Color.FromArgb(r, g, b);
|
||||||
|
}
|
||||||
|
if (Depth == 8)
|
||||||
|
// For 8 bpp get color value (Red, Green and Blue values are the same)
|
||||||
|
{
|
||||||
|
byte c = Pixels[i];
|
||||||
|
clr = Color.FromArgb(c, c, c);
|
||||||
|
}
|
||||||
|
return clr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the color of the specified pixel
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x"></param>
|
||||||
|
/// <param name="y"></param>
|
||||||
|
/// <param name="color"></param>
|
||||||
|
public void SetPixel(int x, int y, Color color)
|
||||||
|
{
|
||||||
|
// Get color components count
|
||||||
|
int cCount = Depth / 8;
|
||||||
|
|
||||||
|
// Get start index of the specified pixel
|
||||||
|
int i = ((y * Width) + x) * cCount;
|
||||||
|
|
||||||
|
if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha
|
||||||
|
{
|
||||||
|
Pixels[i] = color.B;
|
||||||
|
Pixels[i + 1] = color.G;
|
||||||
|
Pixels[i + 2] = color.R;
|
||||||
|
Pixels[i + 3] = color.A;
|
||||||
|
}
|
||||||
|
if (Depth == 24) // For 24 bpp set Red, Green and Blue
|
||||||
|
{
|
||||||
|
Pixels[i] = color.B;
|
||||||
|
Pixels[i + 1] = color.G;
|
||||||
|
Pixels[i + 2] = color.R;
|
||||||
|
}
|
||||||
|
if (Depth == 8)
|
||||||
|
// For 8 bpp set color value (Red, Green and Blue values are the same)
|
||||||
|
{
|
||||||
|
Pixels[i] = color.B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new Form1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("test")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("test")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("3c95a1ae-389c-4012-bbc7-cc03ef11c767")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,63 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace RaytracerEngine.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RaytracerEngine.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
|
@ -0,0 +1,26 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace RaytracerEngine.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.1.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
|
@ -0,0 +1,3 @@
|
||||||
|
This is a semi-real time raytracer implemented from the book [Ray Tracing In One Weekend](https://raytracing.github.io/books/RayTracingInOneWeekend.html)
|
||||||
|
|
||||||
|
It also allows you to move around the scene using the WASD for horizontal and Q/E for vertical movement
|
|
@ -0,0 +1,120 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{3C95A1AE-389C-4012-BBC7-CC03EF11C767}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>RaytracerEngine</RootNamespace>
|
||||||
|
<AssemblyName>RaytracerEngine</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="camera.cs" />
|
||||||
|
<Compile Include="DirectBitmap.cs" />
|
||||||
|
<Compile Include="Form1.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form1.Designer.cs">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="hitable.cs" />
|
||||||
|
<Compile Include="LockBitmap.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ray.cs" />
|
||||||
|
<Compile Include="sphere.cs" />
|
||||||
|
<Compile Include="triangle.cs" />
|
||||||
|
<Compile Include="vec3.cs" />
|
||||||
|
<EmbeddedResource Include="Form1.resx">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Compile>
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2012
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RaytracerEngine", "RaytracerEngine.csproj", "{3C95A1AE-389C-4012-BBC7-CC03EF11C767}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{3C95A1AE-389C-4012-BBC7-CC03EF11C767}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,9 @@
|
||||||
|
<Properties StartupConfiguration="{3C95A1AE-389C-4012-BBC7-CC03EF11C767}|Default">
|
||||||
|
<MonoDevelop.Ide.Workbench />
|
||||||
|
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
|
||||||
|
<MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
|
<BreakpointStore />
|
||||||
|
</MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
|
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
|
||||||
|
<MultiItemStartupConfigurations />
|
||||||
|
</Properties>
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
class camera
|
||||||
|
{
|
||||||
|
vec3 origin;
|
||||||
|
vec3 lower_left_corner;
|
||||||
|
vec3 horizontal;
|
||||||
|
vec3 vertical;
|
||||||
|
private const float scale = 0.1f;
|
||||||
|
|
||||||
|
public camera()
|
||||||
|
{
|
||||||
|
origin = new vec3(0, 0, 0);
|
||||||
|
lower_left_corner = new vec3(-2.0f, -1.0f, -1.0f);
|
||||||
|
horizontal = new vec3(4.0f, 0.0f, 0.0f);
|
||||||
|
vertical = new vec3(0.0f, 2.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ray get_ray(float u, float v) { return new ray(origin, lower_left_corner + u*horizontal + v*vertical - origin); }
|
||||||
|
|
||||||
|
public void turn_left()
|
||||||
|
{
|
||||||
|
//rotational matrix on camera left 25*
|
||||||
|
lower_left_corner = vec3.turn_y(lower_left_corner, 25);
|
||||||
|
horizontal = vec3.turn_y(horizontal, 25);
|
||||||
|
vertical = vec3.turn_y(vertical, 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void turn_right()
|
||||||
|
{
|
||||||
|
//rotational matrix on camera right 25*
|
||||||
|
lower_left_corner = vec3.turn_y(lower_left_corner, -25);
|
||||||
|
horizontal = vec3.turn_y(horizontal, -25);
|
||||||
|
vertical = vec3.turn_y(vertical, -25);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void strafe_left()
|
||||||
|
{
|
||||||
|
vec3 forwards_back = vec3.cross(horizontal, vertical);
|
||||||
|
forwards_back.normalize();
|
||||||
|
vec3 left_right = vec3.cross(vertical, forwards_back);
|
||||||
|
left_right.normalize();
|
||||||
|
origin = origin - left_right * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void strafe_right()
|
||||||
|
{
|
||||||
|
vec3 forwards_back = vec3.cross(horizontal, vertical);
|
||||||
|
forwards_back.normalize();
|
||||||
|
vec3 left_right = vec3.cross(vertical, forwards_back);
|
||||||
|
left_right.normalize();
|
||||||
|
origin = origin + left_right * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fore()
|
||||||
|
{
|
||||||
|
vec3 forwards_back = vec3.cross(horizontal, vertical);
|
||||||
|
forwards_back.normalize();
|
||||||
|
origin = origin - forwards_back * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void back()
|
||||||
|
{
|
||||||
|
vec3 forwards_back = vec3.cross(horizontal, vertical);
|
||||||
|
forwards_back.normalize();
|
||||||
|
origin = origin + forwards_back * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public abstract class hitable
|
||||||
|
{
|
||||||
|
public struct hit_record
|
||||||
|
{
|
||||||
|
public float t;
|
||||||
|
public vec3 p;
|
||||||
|
public vec3 normal;
|
||||||
|
}
|
||||||
|
public virtual bool hit(ray r, float t_min, float t_max, out hit_record rec) { rec = new hit_record(); return false; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public class ray
|
||||||
|
{
|
||||||
|
private vec3 A;
|
||||||
|
private vec3 B;
|
||||||
|
public ray() { }
|
||||||
|
public ray(vec3 a, vec3 b) { A = a; B = b; }
|
||||||
|
public vec3 origin { get { return A; } }
|
||||||
|
public vec3 direction { get { return B; } }
|
||||||
|
public vec3 pap(float t) { return A + t * B; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public class sphere : hitable
|
||||||
|
{
|
||||||
|
vec3 center;
|
||||||
|
float radius;
|
||||||
|
public sphere() { }
|
||||||
|
public sphere(vec3 cen, float r) { center = cen; radius = r; }
|
||||||
|
|
||||||
|
public override bool hit(ray r, float t_min, float t_max, out hit_record rec)
|
||||||
|
{
|
||||||
|
vec3 oc = r.origin - center;
|
||||||
|
float a = vec3.dot(r.direction, r.direction);
|
||||||
|
float b = vec3.dot(oc, r.direction);
|
||||||
|
float c = vec3.dot(oc, oc) - radius * radius;
|
||||||
|
float discriminant = b * b - a * c;
|
||||||
|
if (discriminant > 0)
|
||||||
|
{
|
||||||
|
float temp = (float)((-b - Math.Sqrt(discriminant)) / a);
|
||||||
|
if (temp < t_max && temp > t_min)
|
||||||
|
{
|
||||||
|
rec.t = temp;
|
||||||
|
rec.p = r.pap(rec.t);
|
||||||
|
rec.normal = (rec.p - center) / radius;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
temp = (float)((-b + Math.Sqrt(discriminant)) / a);
|
||||||
|
if (temp < t_max && temp > t_min)
|
||||||
|
{
|
||||||
|
rec.t = temp;
|
||||||
|
rec.p = r.pap(rec.t);
|
||||||
|
rec.normal = (rec.p - center) / radius;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rec = new hit_record();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public class triangle : hitable
|
||||||
|
{
|
||||||
|
vec3 posa;
|
||||||
|
vec3 posb;
|
||||||
|
vec3 posc;
|
||||||
|
int reflect;
|
||||||
|
public triangle() { }
|
||||||
|
public triangle(vec3 a, vec3 b, vec3 c, int r) { posa = a; posb = b; posc = c; reflect = r; }
|
||||||
|
|
||||||
|
public override bool hit(ray r, float t_min, float t_max, out hit_record rec)
|
||||||
|
{
|
||||||
|
// The three triangle vertices.
|
||||||
|
vec3 verta, vertb, vertc;
|
||||||
|
vec3 vecray, posray;
|
||||||
|
vec3 n = new vec3(0,0,0); // Normal vector
|
||||||
|
float xa, xb, xc, xd, xe, ya, yb, yc, yd, ye, za, zb, zc, zd, ze; // The components to determine t.
|
||||||
|
float m, beta, gamma, t; // Components to determine the Barycentric coordinates.
|
||||||
|
float a, b, c, d, e, f, g, h, i, j, k, l;
|
||||||
|
|
||||||
|
// Copy the three positions from the triangle class into the x, y, z arrays.
|
||||||
|
verta = posa;
|
||||||
|
vertb = posb;
|
||||||
|
vertc = posc;
|
||||||
|
vecray = r.direction;
|
||||||
|
posray = r.origin;
|
||||||
|
|
||||||
|
// Set up the a,b, and c components of the 3 vertices.
|
||||||
|
xa = verta[0];
|
||||||
|
xb = vertb[0];
|
||||||
|
xc = vertc[0];
|
||||||
|
xd = vecray[0];
|
||||||
|
xe = posray[0];
|
||||||
|
ya = verta[1];
|
||||||
|
yb = vertb[1];
|
||||||
|
yc = vertc[1];
|
||||||
|
yd = vecray[1];
|
||||||
|
ye = posray[1];
|
||||||
|
za = verta[2];
|
||||||
|
zb = vertb[2];
|
||||||
|
zc = vertc[2];
|
||||||
|
zd = vecray[2];
|
||||||
|
ze = posray[2];
|
||||||
|
|
||||||
|
// Set up the components.
|
||||||
|
a = xa - xb;
|
||||||
|
b = ya - yb;
|
||||||
|
c = za - zb;
|
||||||
|
d = xa - xc;
|
||||||
|
e = ya - yc;
|
||||||
|
f = za - zc;
|
||||||
|
g = xd;
|
||||||
|
h = yd;
|
||||||
|
i = zd;
|
||||||
|
j = xa - xe;
|
||||||
|
k = ya - ye;
|
||||||
|
l = za - ze;
|
||||||
|
|
||||||
|
// Calculate M, Beta, Gamma, and t.
|
||||||
|
m = (a * ((e * i) - (h * f))) + (b * ((g * f) - (d * i))) + (c * ((d * h) - (e * g)));
|
||||||
|
t = (-(((f * ((a * k) - (j * b))) + (e * ((j * c) - (a * l))) + (d * ((b * l) - (k * c))))) / m);
|
||||||
|
|
||||||
|
// Return the result of the intersection.
|
||||||
|
if (t < 0) {
|
||||||
|
t = 0;
|
||||||
|
rec = new hit_record();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
gamma = (((i * ((a * k) - (j * b))) + (h * ((j * c) - (a * l))) + (g * ((b * l) - (k * c)))) / m);
|
||||||
|
if ((gamma < 0) || (gamma > 1)) {
|
||||||
|
t = 0;
|
||||||
|
rec = new hit_record();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
beta = ((j * ((e * i) - (h * f)) + (k * ((g * f) - (d * i))) + (l * ((d * h) - (e * g)))) / m);
|
||||||
|
if ((beta < 0) || (beta > (1-gamma))) {
|
||||||
|
t = 0;
|
||||||
|
rec = new hit_record();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the normal of the triangle
|
||||||
|
vec3 u = new vec3(0, 0, 0);
|
||||||
|
vec3 v = new vec3(0, 0, 0);
|
||||||
|
u = vertb - verta;
|
||||||
|
v = vertc - verta;
|
||||||
|
n = vec3.cross(v, u);
|
||||||
|
|
||||||
|
// Determine the position that the vector hits the object.
|
||||||
|
vec3 hit_pos = new vec3(0, 0, 0);
|
||||||
|
vecray = vecray * t;
|
||||||
|
hit_pos = posray + vecray;
|
||||||
|
|
||||||
|
// Set up the normal of the triangle in regards to the hit position.
|
||||||
|
vec3 normal = new vec3(0, 0, 0);
|
||||||
|
normal = hit_pos - n;
|
||||||
|
normal.normalize();
|
||||||
|
|
||||||
|
if (t < t_max && t > t_min)
|
||||||
|
{
|
||||||
|
rec.t = t;
|
||||||
|
rec.p = hit_pos;
|
||||||
|
rec.normal = normal;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rec = new hit_record();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace RaytracerEngine
|
||||||
|
{
|
||||||
|
public class vec3
|
||||||
|
{
|
||||||
|
protected float[] e;
|
||||||
|
public vec3() { e = new float[3]; }
|
||||||
|
public vec3(float e0, float e1, float e2) { e = new float[3]; e[0] = e0; e[1] = e1; e[2] = e2; }
|
||||||
|
public float x { get { return e[0]; } set { e[0] = value; } }
|
||||||
|
public float y { get { return e[1]; } set { e[1] = value; } }
|
||||||
|
public float z { get { return e[2]; } set { e[2] = value; } }
|
||||||
|
public float r { get { return e[0]; } set { e[0] = value; } }
|
||||||
|
public float g { get { return e[1]; } set { e[1] = value; } }
|
||||||
|
public float b { get { return e[2]; } set { e[2] = value; } }
|
||||||
|
public float this[int i] { get { return e[i]; } set { e[i] = value; } }
|
||||||
|
public float square_length() { return (e[0] * e[0] + e[1] * e[1] + e[2] * e[2]); }
|
||||||
|
public float length() { return (float)Math.Sqrt(e[0]* e[0] + e[1]* e[1] + e[2]* e[2]); }
|
||||||
|
public void normalize()
|
||||||
|
{
|
||||||
|
float k = 1.0f / (float)Math.Sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
|
||||||
|
e[0] *= k; e[1] *= k; e[2] *= k;
|
||||||
|
}
|
||||||
|
public static vec3 operator -(vec3 v) { return new vec3(-v.x, -v.y, -v.z); }
|
||||||
|
public static vec3 operator +(vec3 v, vec3 o) { return new vec3(v.x + o.x, v.y + o.y, v.z + o.z); }
|
||||||
|
public static vec3 operator -(vec3 v, vec3 o) { return new vec3(v.x - o.x, v.y - o.y, v.z - o.z); }
|
||||||
|
public static vec3 operator *(vec3 v, vec3 o) { return new vec3(v.x * o.x, v.y * o.y, v.z * o.z); }
|
||||||
|
public static vec3 operator /(vec3 v, vec3 o) { return new vec3(v.x / o.x, v.y / o.y, v.z / o.z); }
|
||||||
|
public static vec3 operator *(float t, vec3 v) { return new vec3(t * v.x, t * v.y, t * v.z); }
|
||||||
|
public static vec3 operator *(vec3 v, float t) { return new vec3(t * v.x, t * v.y, t * v.z); }
|
||||||
|
public static vec3 operator /(vec3 v, float t) { return new vec3(v.x / t, v.y / t, v.z / t); }
|
||||||
|
public static float dot(vec3 v, vec3 o) { return v.x * o.x + v.y * o.y + v.z * o.z; }
|
||||||
|
public static vec3 cross(vec3 v, vec3 o) { return new vec3(v.y * o.z - v.z * o.y, -(v.x * o.z - v.z * o.x), v.x * o.y - v.y * o.x); }
|
||||||
|
public static vec3 unit_vector(vec3 v) { return v / v.length(); }
|
||||||
|
public static vec3 turn_x(vec3 v, float d)
|
||||||
|
{
|
||||||
|
float y = 0, z = 0;
|
||||||
|
y = (float)(Math.Cos(d) * v.y + -Math.Sin(d) * v.z);
|
||||||
|
z = (float)(Math.Sin(d) * v.y + Math.Cos(d) * v.z);
|
||||||
|
return new vec3(v.x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static vec3 turn_y(vec3 v, float d)
|
||||||
|
{
|
||||||
|
float x = 0, z = 0;
|
||||||
|
x = (float)(Math.Cos(d) * v.x + Math.Sin(d) * v.z);
|
||||||
|
z = (float)(-Math.Sin(d) * v.x + Math.Cos(d) * v.z);
|
||||||
|
return new vec3(x, v.y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static vec3 turn_z(vec3 v, float d)
|
||||||
|
{
|
||||||
|
float x = 0, y = 0;
|
||||||
|
x = (float)(Math.Cos(d) * v.x + -Math.Sin(d) * v.y);
|
||||||
|
y = (float)(Math.Sin(d) * v.x + Math.Cos(d) * v.y);
|
||||||
|
return new vec3(x, y, v.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue