Skip to content

Commit

Permalink
Added axis helper object, updated geometry version, changed renderabl…
Browse files Browse the repository at this point in the history
…es to an interface
  • Loading branch information
qkmaxware committed Sep 5, 2020
1 parent 8d376ca commit b2a11d7
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 21 deletions.
20 changes: 14 additions & 6 deletions Render.Test/tests/Rendering.Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class RenderingTest {

// Create object
var mesh = new Geometry.Primitives.Cube(size: 1, centre: Vec3.Zero);
var obj = new Renderable(mesh: mesh, uv: UV.Spherical(mesh), material: new Wireframe(Color.Red));
var obj = new MeshRenderer(mesh: mesh, uv: UV.Spherical(mesh), material: new Wireframe(Color.Red));
scene.Add(obj);

// Render
Expand All @@ -42,9 +42,9 @@ public class RenderingTest {
var bblock = Transformation.Scale(new Vec3(0.2, 1, 0.2)) * new Cube(size: 1, centre: Vec3.Zero);
var ball = new Sphere(radius: 0.2, centre: Vec3.Zero);

var aobj = new Renderable(mesh: ablock, material: new UnlitColour(Color.Red));
var bobj = new Renderable(mesh: bblock, material: new UnlitColour(Color.Blue));
var ballobj = new Renderable(mesh: ball, material: new UnlitColour(Color.Yellow));
var aobj = new MeshRenderer(mesh: ablock, material: new UnlitColour(Color.Red));
var bobj = new MeshRenderer(mesh: bblock, material: new UnlitColour(Color.Blue));
var ballobj = new MeshRenderer(mesh: ball, material: new UnlitColour(Color.Yellow));

aobj.Transform = Transformation.Offset(new Vec3(-1, 0, 0));
bobj.Transform = Transformation.Offset(new Vec3(1, 0, 0));
Expand All @@ -68,6 +68,8 @@ public class RenderingTest {
camera.Skybox = new GradientSkybox(Color.FromArgb (255, 58, 58, 82), Color.FromArgb (255, 2, 1, 17));

// Create objects
var helper = new AxisHelper();

var planet = new Geometry.Primitives.Sphere(radius: 1, centre: Vec3.Zero, horizontalResolution: 32, verticalResolution: 32);
var planetTexture = LoadImage("assets/planet.png");

Expand All @@ -77,13 +79,19 @@ public class RenderingTest {
var hierarchy = new SceneNode();
scene.Add(hierarchy);

var planetObj = new Renderable(mesh: planet, uv: UV.Spherical(planet), material: new UnlitTexture(planetTexture));
var planetObj = new MeshRenderer(mesh: planet, uv: UV.Spherical(planet), material: new UnlitTexture(planetTexture));
hierarchy.Add(planetObj);

var satelliteObj = new Renderable(mesh: satellite, uv: UV.Spherical(satellite), material: new UnlitTexture(satelliteTexture));
var satelliteObj = new MeshRenderer(mesh: satellite, uv: UV.Spherical(satellite), material: new UnlitTexture(satelliteTexture));
satelliteObj.Transform = Transformation.Offset(new Vec3(-1.6, 1.6, 0.1));
hierarchy.Add(satelliteObj);

helper.Transform = Transformation.Scale(Vec3.One * 1.3);
helper.XLabel = "X";
helper.YLabel = "Y";
helper.ZLabel = "Z";
hierarchy.Add(helper);

// Render
SaveAnimation("render.complex", SpinAnimation(camera, hierarchy, frames: 64));
}
Expand Down
4 changes: 2 additions & 2 deletions Render/Render.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<PropertyGroup>
<PackageId>Qkmaxware.Rendering</PackageId>
<Version>1.0.1</Version>
<Version>1.0.2</Version>
<Authors>Colin Halseth</Authors>
<PackageTags>softrendering</PackageTags>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
Expand All @@ -26,7 +26,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Qkmaxware.Geometry" Version="1.0.4" />
<PackageReference Include="Qkmaxware.Geometry" Version="1.0.6" />
</ItemGroup>

</Project>
104 changes: 104 additions & 0 deletions Render/src/AxisHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System.Drawing;
using Qkmaxware.Geometry;
using Qkmaxware.Geometry.Primitives;

namespace Qkmaxware.Rendering {

/// <summary>
/// XYZ axis helper
/// </summary>
public class AxisHelper : SceneNode {

private MeshRenderer XObject;
private MeshRenderer XLabelObject;
private MeshRenderer YObject;
private MeshRenderer YLabelObject;
private MeshRenderer ZObject;
private MeshRenderer ZLabelObject;

/// <summary>
/// Create a new axis helper
/// </summary>
public AxisHelper() {
var rootX = CreateAxis(new UnlitColour(Color.Red), out XObject, out XLabelObject);
var rootY = CreateAxis(new UnlitColour(Color.Green), out YObject, out YLabelObject);
var rootZ = CreateAxis(new UnlitColour(Color.Blue), out ZObject, out ZLabelObject);

rootX.Transform = Transformation.Ry(-90 * Angle.Deg2Rad);
rootY.Transform = Transformation.Rx(-90 * Angle.Deg2Rad);
}

private string? xLabel;

/// <summary>
/// The label used for the x-Axis
/// </summary>
/// <value>the label</value>
public string? XLabel {
get {
return xLabel;
}
set {
this.xLabel = value;
if (value != null) {
var mesh = new TextMesh(value);
XLabelObject.Mesh = mesh;
XLabelObject.Material = XObject.Material;
}
}
}

private string? yLabel;
/// <summary>
/// The label used for the y-Axis
/// </summary>
/// <value>the label</value>
public string? YLabel {
get {
return yLabel;
}
set {
this.yLabel = value;
if (value != null) {
var mesh = new TextMesh (value);
YLabelObject.Mesh = mesh;
YLabelObject.Material = YObject.Material;
}
}
}

private string? zLabel;
/// <summary>
/// The label used for the z-Axis
/// </summary>
/// <value>the label</value>
public string? ZLabel {
get {
return zLabel;
}
set {
this.zLabel = value;
if (value != null) {
var mesh = new TextMesh(value);
ZLabelObject.Mesh = mesh;
ZLabelObject.Material = ZObject.Material;
}
}
}

private SceneNode CreateAxis(Material mat, out MeshRenderer arrow, out MeshRenderer label) {
var arrowMesh = new Arrow(length: 1);
arrow = new MeshRenderer(mesh: arrowMesh, material: mat);
label = new MeshRenderer();
label.Transform = Transformation.Offset(new Vec3(0, 0, 1.1)) * Transformation.Ry(90 * Angle.Deg2Rad);

var root = new SceneNode();
root.Add(arrow);
root.Add(label);

this.Add(root);
return root;
}
}

}
6 changes: 3 additions & 3 deletions Render/src/BaseCamera.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ public abstract class BaseCamera : SceneNode {
vars.LightSources = scene.OfType<LightSource>().ToList().AsReadOnly();

// Loop over all models
foreach (var renderable in scene.OfType<Renderable>()) {
foreach (var renderable in scene.OfType<IRenderable>()) {
vars.ModelToWorld = renderable.LocalToWorldMatrix;
if (renderable.Mesh != null && renderable.Material != null) {
Render(ref vars, renderable.Mesh, renderable.UVs, renderable.Material);
Render(ref vars, renderable.Mesh, renderable.UVs, (Material)renderable.Material);
}
}
}
Expand Down Expand Up @@ -220,7 +220,7 @@ public abstract class BaseCamera : SceneNode {

private void SetPixel(Vec3 pixel, Color c) {
var x = (int)Math.Floor(pixel.X);
var y = (int)Math.Floor(pixel.Y);
var y = Size.Height - (int)Math.Floor(pixel.Y);
var depth = pixel.Z;

if (x >= 0 && y >= 0 && x < Size.Width && y < Size.Height) {
Expand Down
28 changes: 28 additions & 0 deletions Render/src/IRenderable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Generic;
using Qkmaxware.Geometry;

namespace Qkmaxware.Rendering {

/// <summary>
/// Interface for any renderable 3d objects
/// </summary>
public interface IRenderable {
/// <summary>
/// Mesh to render
/// </summary>
IEnumerable<Triangle>? Mesh {get;}
/// <summary>
/// Vertex UV coordinates
/// </summary>
IUvMap? UVs {get;}
/// <summary>
/// Render material
/// </summary>
Material? Material {get;}
// <summary>
/// Matrix to convert from local to world space
/// </summary>
Transformation LocalToWorldMatrix {get;}
}

}
17 changes: 10 additions & 7 deletions Render/src/Renderable.cs → Render/src/MeshRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,33 @@ namespace Qkmaxware.Rendering {
/// <summary>
/// Object that can be rendered by the camera
/// </summary>
public class Renderable : SceneNode {
public class MeshRenderer : SceneNode, IRenderable {
/// <summary>
/// Mesh to render
/// </summary>
public IEnumerable<Triangle>? Mesh;
/// <returns>mesh</returns>
public IEnumerable<Triangle>? Mesh {get; set;}
/// <summary>
/// Vertex UV coordinates
/// </summary>
public IUvMap? UVs;
/// <returns>uv map</returns>
public IUvMap? UVs {get; set;}
/// <summary>
/// Render material
/// </summary>
public Material Material = new UnlitColour(Color.White);
/// <returns>material</returns>
public Material? Material {get; set;} = new UnlitColour(Color.White);

/// <summary>
/// Create empty renderable
/// </summary>
public Renderable() {}
public MeshRenderer() {}

/// <summary>
/// Create renderable with geometry
/// </summary>
/// <param name="mesh">geometry</param>
public Renderable(IEnumerable<Triangle> mesh) {
public MeshRenderer(IEnumerable<Triangle> mesh) {
this.Mesh = mesh;
}

Expand All @@ -40,7 +43,7 @@ public class Renderable : SceneNode {
/// <param name="mesh">geometry</param>
/// <param name="material">material</param>
/// <param name="uv">uv map</param>
public Renderable(IEnumerable<Triangle> mesh, Material material, IUvMap? uv = null) {
public MeshRenderer(IEnumerable<Triangle> mesh, Material material, IUvMap? uv = null) {
this.Mesh = mesh;
this.UVs = uv;
this.Material = material;
Expand Down
2 changes: 1 addition & 1 deletion Render/src/Skybox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class GradientSkybox : Skybox {
} else {
var vangle = Math.Acos(z / length);
var interpolation_factor = vangle / Math.PI; // angles are 0deg to 180deg (0 to Pi radians)
return Blend(top, bottom, interpolation_factor);
return Blend(bottom, top, interpolation_factor);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions docs/using.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ All scene management start off from the `Scene` class which acts as the root of
Scene scene = new Scene();
```

We can attach `SceneNode` objects to the scene and to other scene nodes in order to fill out the scene hierarchy. Currently there are 3 types of scene nodes. The base `SceneNode` class is used purely to construct the hierarchy and provides no additional functionality. The `Renderable` class is used to render a geometric object to the camera. This object can be provided with a UV map which is used to map geometry vertices to texture coordinates as well as a material which defines how the object is coloured. Additionally the `Animator` class is used with an `AnimatedScene` to apply actions to nodes between animation frames which is covered the section [Animated Scenes](#animated-scenes).
We can attach `SceneNode` objects to the scene and to other scene nodes in order to fill out the scene hierarchy. Currently there are 3 types of scene nodes. The base `SceneNode` class is used purely to construct the hierarchy and provides no additional functionality. The `MeshRenderer` class is used to render a geometric object to the camera. This object can be provided with a UV map which is used to map geometry vertices to texture coordinates as well as a material which defines how the object is coloured. Additionally the `Animator` class is used with an `AnimatedScene` to apply actions to nodes between animation frames which is covered the section [Animated Scenes](#animated-scenes).

```cs
SceneNode emptyNode = new SceneNode();
scene.Add(emptyNode);

Renderable mesh = new Renderable(
MeshRenderer mesh = new MeshRenderer(
mesh: new Sphere(radius: 1, centre: Vec3.Zero),
uv: null,
material: new Wireframe(Color.Red)
Expand Down

0 comments on commit b2a11d7

Please sign in to comment.