-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNode.cs
More file actions
95 lines (81 loc) · 3.01 KB
/
Node.cs
File metadata and controls
95 lines (81 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System;
using System.Collections.Generic;
using OpenTK;
using Template_P3;
namespace template_P3
{
class Node
{
public Mesh mesh;
public Vector3 localRotate;
public Vector3 localTranslate;
internal float scale = 1;
List<Node> children = new List<Node>();
private float a;
public int PI { get; private set; }
internal void Render(Shader shader, Matrix4 parentTransform, Matrix4 world, Plane[] bb, float frameDuration)
{
Matrix4 transform = GetLocalTransform(world, parentTransform, frameDuration);
world = transform * world;
transform *= parentTransform;
if (mesh != null && this.IsInViewFrustrum(bb, transform)) mesh.Render(shader, transform, world);
foreach (Node child in this.children)
{
child.Render(shader, transform, world, bb, frameDuration);
}
}
internal bool IsInViewFrustrum(Plane[] bb, Matrix4 transform)
{
if (mesh != null)
{
transform.Transpose();
Sphere s = GetBoundingSphere();
s.origin = Vector3.Transform(s.origin, transform);
for (int i = 0; i < 6; i++)
{
if (Vector3.Dot(bb[i].normal, s.origin) + s.r < 0)
return false;
}
}
return true;
}
private Sphere GetBoundingSphere()
{
Vector3 o = new Vector3(); // Average of all vectors in mesh is the sphere origin
foreach (var vertex in mesh.vertices)
{
o += vertex.Vertex;
}
Vector3.Divide(o, mesh.vertices.Length);
// Get largest disdance from center
float r2 = 0;
float dis = 0;
foreach (var vertex in mesh.vertices)
{
dis = (vertex.Vertex.X - o.X) * (vertex.Vertex.X - o.X)
+ (vertex.Vertex.Y - o.Y) * (vertex.Vertex.Y - o.Y)
+ (vertex.Vertex.Z - o.Z) * (vertex.Vertex.Z - o.Z);
if (dis > r2) r2 = dis;
}
return new Sphere(o, (float)Math.Sqrt(r2));
}
private Matrix4 GetLocalTransform(Matrix4 world, Matrix4 parentTransform, float frameDuration)
{
Matrix4 transform = Matrix4.Identity;
if (localRotate != Vector3.Zero)
{
transform = Matrix4.CreateFromAxisAngle(localRotate, a);
}
transform *= Matrix4.CreateScale(scale);
transform *= Matrix4.CreateTranslation(localTranslate);
// update rotation
a += 0.001f * frameDuration;
if (a > 2 * PI) a -= 2 * PI;
return transform;
}
internal void AddChild(Node node)
{
children.Add(node);
}
}
}