作者:pombredann
项目:ran
func random() (r gfx.Bounds) {
f := func() float64 {
return (rand.Float64() * 2.0) - 1.0
}
size := .013123
posScale := .5123213
r.Min = math.Vec3{
f() * size,
f() * size,
f() * size,
}
r.Max = r.Min.Add(math.Vec3{
rand.Float64() * size,
rand.Float64() * size,
rand.Float64() * size,
})
// Random position
pos := math.Vec3{f(), f(), f()}
pos = pos.MulScalar(posScale)
r.Max = r.Max.Add(pos)
r.Min = r.Min.Add(pos)
return r
}
作者:pombredann
项目:ran
// Takes a child node position and returns it's bounds.
func (n *Node) childBounds(pos, divisor math.Vec3) math.Rect3 {
size := n.childSize(divisor)
cb := math.Rect3{
Min: pos,
Max: pos.Add(size),
}
if !n.bounds.Contains(cb.Min) || !n.bounds.Contains(cb.Max) {
fmt.Println(pos)
fmt.Println(n.bounds)
fmt.Println(n.bounds.Contains(cb.Min))
fmt.Println(n.bounds.Contains(cb.Max))
panic("not contained")
}
if !cb.In(n.bounds) {
//fmt.Println("pos ", pos)
//fmt.Println("size ", size)
//fmt.Println("child ", cb)
//fmt.Println("parent", n.bounds)
//panic("")
}
return math.Rect3{
Min: pos,
Max: pos.Add(size),
}
}
作者:pombredann
项目:ran
// Takes a child node position and returns it's bounds.
func (n *Node) childBounds(pos, divisor math.Vec3) math.Rect3 {
size := n.childSize(divisor)
return math.Rect3{
Min: pos,
Max: pos.Add(size),
}
}
作者:pombredann
项目:ran
func randomAABB(size, posScale float64) (r gfx.AABB) {
f := func() float64 {
return (rand.Float64() * 2.0) - 1.0
}
max := f() * size
min := f() * size
r.Max = math.Vec3{max, max, max}
r.Min = math.Vec3{
max - min,
max - min,
max - min,
}
// Center
center := r.Center()
r.Min = r.Min.Sub(center)
r.Max = r.Max.Sub(center)
// Random position
pos := math.Vec3{f(), f(), f()}
pos = pos.MulScalar(posScale)
r.Max = r.Max.Add(pos)
r.Min = r.Min.Add(pos)
return r
}
作者:pombredann
项目:ran
// Index returns the data index for the given point in space.
func (t *Table) Index(p gmath.Vec3) int {
p.X *= primeX
p.Y *= primeY
p.Z *= primeZ
x := int(math.Abs(p.X)) % t.Size
y := int(math.Abs(p.Y)) % t.Size
z := int(math.Abs(p.Z)) % t.Size
return x + t.Size*(y+t.Size*z)
}
作者:pombredann
项目:ran
func sortEntries(p gmath.Vec3, entries []entry) ([]entry, []float64) {
sorted := make([]entry, len(entries))
dists := make([]float64, len(entries))
for i := 0; i < len(entries); i++ {
sorted[i] = entries[i]
bounds := entries[i].bounds
dists[i] = p.Sub(bounds.Min).LengthSq()
}
sort.Sort(entrySlice{sorted, dists, p})
return sorted, dists
}
作者:pombredann
项目:ran
func random() gfx.Spatial {
o := math.Vec3{
rand.Float64() * float64(rand.Int()),
rand.Float64() * float64(rand.Int()),
rand.Float64() * float64(rand.Int()),
}
min := math.Vec3{rand.Float64(), rand.Float64(), rand.Float64()}
max := min.Add(math.Vec3{rand.Float64(), rand.Float64(), rand.Float64()})
min = min.Add(o)
max = max.Add(o)
return gfx.Bounds{min, max}
}
作者:pombredann
项目:ran
func (t *Tree) nearestNeighbors(k int, p gmath.Vec3, n *node, dists []float64, nearest []gfx.Spatial) ([]gfx.Spatial, []float64) {
if n.leaf {
for _, e := range n.entries {
dist := p.Sub(e.bounds.Min).Length()
dists, nearest = insertNearest(k, dists, nearest, dist, e.obj)
}
} else {
branches, branchDists := sortEntries(p, n.entries)
branches = pruneEntries(p, branches, branchDists)
for _, e := range branches {
nearest, dists = t.nearestNeighbors(k, p, e.child, dists, nearest)
}
}
return nearest, dists
}
作者:pombredann
项目:ran
func pruneEntries(p gmath.Vec3, entries []entry, minDists []float64) []entry {
minMinMaxDist := math.MaxFloat64
for i := range entries {
minMaxDist := p.Sub(entries[i].bounds.Max).LengthSq()
if minMaxDist < minMinMaxDist {
minMinMaxDist = minMaxDist
}
}
// remove all entries with minDist > minMinMaxDist
pruned := []entry{}
for i := range entries {
if minDists[i] <= minMinMaxDist {
pruned = append(pruned, entries[i])
}
}
return pruned
}
作者:pombredann
项目:ran
func (t *Tree) nearestNeighbor(p gmath.Vec3, n *node, d float64, nearest gfx.Spatial) (gfx.Spatial, float64) {
if n.leaf {
for _, e := range n.entries {
dist := p.Sub(e.bounds.Min).Length()
if dist < d {
d = dist
nearest = e.obj
}
}
} else {
branches, dists := sortEntries(p, n.entries)
branches = pruneEntries(p, branches, dists)
for _, e := range branches {
subNearest, dist := t.nearestNeighbor(p, e.child, d, nearest)
if dist < d {
d = dist
nearest = subNearest
}
}
}
return nearest, d
}
作者:pombredann
项目:ran
func LineVerts(start, end math.Vec3, width float64, result []gfx.Vec3) []gfx.Vec3 {
hw := math.Vec3Zero.AddScalar(width).DivScalar(2.0)
start = start.Sub(hw)
end = end.Add(hw)
return CubeVerts(start, end, result)
}
作者:pombredann
项目:ran
// Closest returns the closest point on the plane p nearest to the point q.
//
// Implemented as described in:
// Real-Time Collision Detection, 5.1.1 "Closest Point on Plane to Point".
func (p Plane3) Closest(q math.Vec3) math.Vec3 {
t := p.Normal.Dot(q) - p.Pos
return q.Sub(t).Mul(p.Normal)
}
作者:pombredann
项目:ran
// Dist calculates the signed distance of q to the plane p.
//
// Implemented as described in:
// Real-Time Collision Detection, 5.1.1 "Closest Point on Plane to Point".
func (p Plane3) Dist(q math.Vec3) float64 {
return q.Dot(p.Normal) - p.Pos
}
作者:pombredann
项目:ran
// gfxLoop is responsible for drawing things to the window. This loop must be
// independent of the Chippy main loop.
func gfxLoop(w *chippy.Window, r gfx.Renderer) {
// Load the Ice file.
scene, err := ice.LoadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
// Setup a camera to use a perspective projection.
camera := gfx.NewCamera()
camFOV := 75.0
camNear := 0.1
camFar := 100.0
camera.SetPersp(r.Bounds(), camFOV, camNear, camFar)
// Move the camera -2 on the Y axis (back two units away from the triangle
// object).
//camera.SetPos(math.Vec3{0, -50, 10})
//camera.SetPos(math.Vec3{0, -5, 2})
camera.SetPos(math.Vec3{0, -7, 3})
// Create a simple shader.
shader := gfx.NewShader("SimpleShader")
shader.GLSLVert = glslVert
shader.GLSLFrag = glslFrag
// Preload the shader (useful for seeing shader errors, if any).
onLoad := make(chan *gfx.Shader, 1)
r.LoadShader(shader, onLoad)
go func() {
<-onLoad
shader.RLock()
if !shader.Loaded {
log.Println(string(shader.Error))
}
shader.RUnlock()
}()
// Assign the shader to each object in the scene.
for _, o := range scene.Objects {
o.Shader = shader
o.State.FaceCulling = gfx.NoFaceCulling
//var verts = make([]gfx.Vec3, 0, len(o.Meshes[0].Indices))
//for _, v := range o.Meshes[0].Indices {
// verts = append(verts, o.Meshes[0].Vertices[v])
//}
//o.Meshes[0].Vertices = verts
//o.Meshes[0].Indices = nil
//if len(o.Meshes[0].Indices) > 5 {
// log.Println(name, len(o.Meshes[0].Indices))
// bad := o.Meshes[0].Indices[743]
// log.Println(o.Meshes[0].Vertices[bad])
// o.Meshes[0].Indices = o.Meshes[0].Indices[744-3:744]
//}
}
// Start a goroutine to handle window events and move the camera around.
go func() {
event := w.Events()
for {
select {
case e := <-event:
switch ev := e.(type) {
case keyboard.TypedEvent:
if ev.Rune == 'm' {
// Toggle MSAA now.
msaa := !r.MSAA()
r.SetMSAA(msaa)
log.Println("MSAA Enabled?", msaa)
}
case mouse.Event:
if ev.Button == mouse.Left && ev.State == mouse.Down {
w.SetCursorGrabbed(!w.CursorGrabbed())
}
}
}
}
}()
event := w.Events()
for {
camEvents:
for {
select {
case e := <-event:
switch ev := e.(type) {
case chippy.ResizedEvent:
// Update the camera's projection matrix for the new width and
// height.
camera.Lock()
camera.SetPersp(r.Bounds(), camFOV, camNear, camFar)
camera.Unlock()
case chippy.CursorPositionEvent:
if w.CursorGrabbed() {
dt := r.Clock().Dt()
camera.Lock()
camRot := camera.Rot()
//.........这里部分代码省略.........