mesh

package
v0.0.0-...-1c48c43 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 21, 2017 License: MIT Imports: 4 Imported by: 1

Documentation

Overview

Package mesh provides a triangle mesh implementation using a K-D tree

Index

Examples

Constants

View Source
const (
	MaxTreeDepth     = 10
	TrianglesPerLeaf = 20
)

If the depth of the KDtree reaches MaxTreeDepth, the node becomes leaf whith node.Triangles the remaining triangles

Variables

This section is empty.

Functions

func IntersectTriangle

func IntersectTriangle(ray *ray.Ray, A, B, C *maths.Vec3) (bool, float64)

IntersectTriangle find whether there's an intersection point between the ray and the triangle using barycentric coordinates and calculate the distance

Types

type BoundingBox

type BoundingBox struct {
	MaxVolume, MinVolume [3]float64
}

BoundingBox represents a cuboid which surrounds a part of the mesh. The points in the cuboid are those (x, y, z), for which is true: MinVolume[0] < x < MaxVolume[0] MinVolume[1] < y < MaxVolume[1] MinVolume[2] < z , MaxVolume[2]

func NewBoundingBox

func NewBoundingBox() *BoundingBox

NewBoundingBox creates a bounding box with no volume (min > max)

func (*BoundingBox) AddPoint

func (b *BoundingBox) AddPoint(point *maths.Vec3)

AddPoint expands the volume of the box, if the point isn't already in the box

Example
box := NewBoundingBox()

box.AddPoint(maths.NewVec3(-1, -1, -1))
box.AddPoint(maths.NewVec3(0, 5, -0.5))
box.AddPoint(maths.NewVec3(1, 0, 2))

fmt.Printf("%s\n", box)
Output:

bbox[min: (-1, -1, -1), max: (1, 5, 2)]

func (*BoundingBox) Inside

func (b *BoundingBox) Inside(point *maths.Vec3) bool

Inside checks if a point is inside the box

Example
box := &BoundingBox{
	MinVolume: [3]float64{-1, -1, -1},
	MaxVolume: [3]float64{1, 1, 1},
}

fmt.Printf("0, 0, 0: %v\n", box.Inside(maths.NewVec3(0, 0, 0)))
fmt.Printf("0, 0, 2: %v\n", box.Inside(maths.NewVec3(0, 0, 2)))
Output:

0, 0, 0: true
0, 0, 2: false

func (*BoundingBox) Intersect

func (b *BoundingBox) Intersect(ray *ray.Ray) bool

Intersect check if a ray intersects the bounding box

Example
box := &BoundingBox{
	MinVolume: [3]float64{-1, -1, -1},
	MaxVolume: [3]float64{1, 1, 1},
}

ray1 := &ray.Ray{
	Start:     *maths.NewVec3(0, 0, 0),
	Direction: *maths.NewVec3(1, 0, 0),
}

ray2 := &ray.Ray{
	Start:     *maths.NewVec3(-5, 0, 0.5),
	Direction: *maths.NewVec3(1, 0, 0),
}

ray3 := &ray.Ray{
	Start:     *maths.NewVec3(-5, 0, 0.5),
	Direction: *maths.NewVec3(-1, 0, 0),
}

ray4 := &ray.Ray{
	Start:     *maths.NewVec3(-5, 0, 0),
	Direction: *maths.NewVec3(1, 0, 5),
}
ray1.Init()
ray2.Init()
ray3.Init()
ray4.Init()

fmt.Printf("ray 1: %v\n", box.Intersect(ray1))
fmt.Printf("ray 2: %v\n", box.Intersect(ray2))
fmt.Printf("ray 3: %v\n", box.Intersect(ray3))
fmt.Printf("ray 4: %v\n", box.Intersect(ray4))
Output:

ray 1: true
ray 2: true
ray 3: false
ray 4: false

func (*BoundingBox) IntersectAxis

func (b *BoundingBox) IntersectAxis(ray *ray.Ray, axis int) bool

IntersectAxis checks whether there's interaction between the ray and the box.

func (*BoundingBox) IntersectTriangle

func (b *BoundingBox) IntersectTriangle(A, B, C *maths.Vec3) bool

IntersectTriangle checks if the bounding box intersects with a triangle 1) To have a vertex in the box 2) The edge of the triangle intersects with the box 3) The middle of the triangle to be inside the box, while the vertices aren't

func (*BoundingBox) IntersectWall

func (b *BoundingBox) IntersectWall(axis int, median float64, ray *ray.Ray) bool

IntersectWall checks if a ray intersects a wall inside the bounding box (the wall is defined by the axis and median, as with Split)

func (*BoundingBox) Split

func (b *BoundingBox) Split(axis int, median float64) (*BoundingBox, *BoundingBox)

Split returns two new bounding boxes which are the result of spliting the original on the given axis and median

func (*BoundingBox) String

func (b *BoundingBox) String() string

String returns the string representation of the boundingBox in the form of bbox[min: _, max: _]

type KDtree

type KDtree struct {
	Axis      int
	Median    float64
	Triangles []int
	Children  [2]*KDtree
}

KDtree represents a node in a KD tree

func NewLeaf

func NewLeaf(triangles []int) *KDtree

NewLeaf returns a new KDtree with triangles - the list of the given triangles and sets the axis to leaf

func NewNode

func NewNode(median float64, axis int) *KDtree

NewNode returns a new KDtree node with the givena axis and median

func (*KDtree) String

func (t *KDtree) String() string

String returns the string representation of the KDtree in the form of axis{median}(child1, child2)

type Mesh

type Mesh struct {
	Vertices []Vertex   `json:"vertices"`
	Faces    []Triangle `json:"faces"`

	BoundingBox *BoundingBox
	// contains filtered or unexported fields
}

Mesh is a triangle mesh

func (*Mesh) GetBoundingBox

func (m *Mesh) GetBoundingBox() *BoundingBox

GetBoundingBox returns the boundig box of the mesh, adding every vertex to the box

func (*Mesh) Init

func (m *Mesh) Init()

Init of Mesh sets the Triangle indices in the Faces array, calculates the bounding box and KD tree, sets the surfaceOx and Oy and Cross Products of the sides of each triangle

func (*Mesh) Intersect

func (m *Mesh) Intersect(incoming *ray.Ray) *ray.Intersection

Intersect finds the intersection between a ray and the mesh and returns their intersection and the surface material. Returns nil and -1 if they don't intersect Has O(log(n)) amortised complexity.

Example
meshData := []byte(`{
		"vertices": [
			{
				"normal": [0, 0, 1],
				"coordinates": [0, 0, 0],
				"uv": [0, 0]
			},
			{
				"normal": [0, 0, 1],
				"coordinates": [1, 0, 0],
				"uv": [1, 0]
			},
			{
				"normal": [0, 0, 1],
				"coordinates": [0, 1, 0],
				"uv": [0, 1]
			}
		],
		"faces": [
			{
				"vertices": [0, 1, 2],
				"material": 42
			}
		]
	}`)
mesh := &Mesh{}
err := json.Unmarshal(meshData, &mesh)
if err != nil {
	fmt.Printf("Error reading json: %s\n", err)
	return
}

mesh.Init()

testRay := &ray.Ray{
	Start:     *maths.NewVec3(0.15, 0.11, 1),
	Direction: *maths.NewVec3(0, 0, -1),
}

var (
	intersection *ray.Intersection
)
intersection = mesh.Intersect(testRay)

if intersection == nil {
	fmt.Printf("no intersection\n")
} else {
	fmt.Printf("intersection point: %s\n", intersection.Point)
	fmt.Printf("caused by ray: %s\n", intersection.Incoming)
	fmt.Printf("at a distance: %.3g\n", intersection.Distance)
	fmt.Printf("with surface coordinates: (%.3g, %.3g)\n",
		intersection.U, intersection.V)
	fmt.Printf("surface normal: %s\n", intersection.Normal)
	fmt.Printf("surface coordinate system: Ox: %s, Oy: %s\n",
		intersection.SurfaceOx, intersection.SurfaceOy)
	fmt.Printf("surface material: %d\n", intersection.Material)
}
Output:

intersection point: (0.15, 0.11, 0)
caused by ray: (0.15, 0.11, 1) -> (0, 0, -1)
at a distance: 1
with surface coordinates: (0.15, 0.11)
surface normal: (0, 0, 1)
surface coordinate system: Ox: (1, 0, 0), Oy: (0, 1, 0)
surface material: 42

func (*Mesh) IntersectKD

func (m *Mesh) IntersectKD(ray *ray.Ray, boundingBox *BoundingBox, node *KDtree, intersectionInfo *ray.Intersection) bool

IntersectKD returns whether there's an intersection with the ray. The the current node is leaf we check each of its triangles and divide the bounding box and check for each child

func (*Mesh) SlowIntersect

func (m *Mesh) SlowIntersect(incoming *ray.Ray) *ray.Intersection

SlowIntersect finds the intersection between a ray and the mesh and returns their intersection and the surface material. Returns nil and -1 if they don't intersect Has O(n) complexity.

type Triangle

type Triangle struct {
	Vertices      [3]int `json:"vertices"`
	Material      int    `json:"material"`
	AB, AC, ABxAC *maths.Vec3
	Normal        *maths.Vec3 `json:"normal"`
	// contains filtered or unexported fields
}

Triangle is a face with 3 vertices (indices in the vertex array)

type Vertex

type Vertex struct {
	Normal      maths.Vec3 `json:"normal"`
	Coordinates maths.Vec3 `json:"coordinates"`
	UV          maths.Vec3 `json:"uv"`
}

Vertex is a single vertex in a mesh

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL