Skip to content

Commit

Permalink
new gravity system
Browse files Browse the repository at this point in the history
  • Loading branch information
zyxkad committed Dec 20, 2023
1 parent 9a241ac commit 2eb3be5
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 118 deletions.
107 changes: 107 additions & 0 deletions bitset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// molecular is a 3D physics engine written in Go
// Copyright (C) 2023 Kevin Z <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package molecular

import (
"encoding/binary"
)

type Bitset struct {
data []uint32
}

// NewBitset creates a Bitset with at least `n` bits
func NewBitset(n int) *Bitset {
return &Bitset{
data: make([]uint32, (n+31)/32),
}
}

// Cap returns the bit slots of the Bitset
func (b *Bitset) Cap() int {
return len(b.data) * 32
}

// Get will return true if the target bit is one
func (b *Bitset) Get(i int) bool {
n := i % 32
i /= 32
if i >= len(b.data) {
return false
}
return b.data[i]&(1<<n) != 0
}

// Set set the bit to one
func (b *Bitset) Set(i int) {
n := i % 32
i /= 32
if i >= len(b.data) {
b.data = growToLen(b.data, i+1)
}
b.data[i] |= 1 << n
}

// Clear set the bit to zero
func (b *Bitset) Clear(i int) {
n := i % 32
i /= 32
if i >= len(b.data) {
b.data = growToLen(b.data, i+1)
}
b.data[i] &^= 1 << n
}

// Flip toggle the bit, and returns the old value
func (b *Bitset) Flip(i int) bool {
n := i % 32
i /= 32
if i >= len(b.data) {
b.data = growToLen(b.data, i+1)
} else if b.data[i]&(1<<n) != 0 {
b.data[i] &^= 1 << n
return true
}
b.data[i] |= 1 << n
return false
}

func (b *Bitset) String() string {
const prefix = "bitset:"
buf := make([]byte, len(prefix)+len(b.data)*32)
copy(buf, prefix)
for i, v := range b.data {
for j := 0; j < 32; j++ {
n := i*32 + j + len(prefix)
if v&(1<<j) == 0 {
buf[n] = '0'
} else {
buf[n] = '1'
}
}
}
return (string)(buf)
}

// Bytes encode the Bitset to bytes use LittleEndian mode
func (b *Bitset) Bytes() (buf []byte) {
buf = make([]byte, len(b.data)*4)
for i, v := range b.data {
binary.LittleEndian.PutUint32(buf[i*4:], v)
}
return
}
68 changes: 68 additions & 0 deletions bitset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// molecular is a 3D physics engine written in Go
// Copyright (C) 2023 Kevin Z <[email protected]>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package molecular_test

import (
. "github.com/LiterMC/molecular"
"testing"
)

func TestBitset(t *testing.T) {
b := NewBitset(0)
b.Set(1)
if b.Get(0) {
t.Errorf("Bitset(1).Get(0) is true")
}
if b.Get(33) {
t.Errorf("Bitset(1).Get(33) is true")
}
if b.Get(32) {
t.Errorf("Bitset(1).Get(32) is true")
}
if b.Get(31) {
t.Errorf("Bitset(1).Get(31) is true")
}
if !b.Get(1) {
t.Errorf("Bitset(1).Get(1) is false")
}
if b.Bytes()[0] != 0x02 {
t.Errorf("Bitset(1).Bytes()[0] != 0x02")
}
if b.Bytes()[3] != 0x00 {
t.Errorf("Bitset(1).Bytes()[3] != 0x00")
}
b.Set(32)
if b.Get(0) {
t.Errorf("Bitset(1).Get(0) is true")
}
if b.Get(33) {
t.Errorf("Bitset(1).Get(33) is true")
}
if !b.Get(32) {
t.Errorf("Bitset(1).Get(32) is false")
}
if b.Get(31) {
t.Errorf("Bitset(1).Get(31) is true")
}
if !b.Get(1) {
t.Errorf("Bitset(1).Get(1) is false")
}
b.Clear(1)
if b.Get(1) {
t.Errorf("Bitset(1).Get(1) is true")
}
}
5 changes: 2 additions & 3 deletions block.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.


package molecular

type Facing uint8
Expand Down
5 changes: 2 additions & 3 deletions box.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.


package molecular

type Cube struct {
Expand Down
5 changes: 2 additions & 3 deletions box_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.


package molecular_test

import (
Expand Down
5 changes: 2 additions & 3 deletions conflict.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.


package molecular

func (e *Engine) appendObjsInsideRange(objs []*Object, pos Vec3, radius float64) []*Object {
Expand Down
23 changes: 14 additions & 9 deletions engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.


package molecular

import (
"sync"
"time"

"github.com/google/uuid"
)
Expand Down Expand Up @@ -97,6 +97,9 @@ func (e *Engine) NewObject(typ ObjType, anchor *Object, pos Vec3, processors ...
id := e.generateObjectId()
o = e.newAndPutObject(id, stat)
o.SetType(typ)
if anchor != nil {
anchor.addChild(o)
}
for _, p := range processors {
p(o)
}
Expand Down Expand Up @@ -143,6 +146,8 @@ func (e *Engine) ForeachObject(cb func(o *Object)) {

func (e *Engine) ForeachBlock(cb func(b Block)) {
e.ForeachObject(func(o *Object) {
o.RLock()
defer o.RUnlock()
for _, b := range o.blocks {
cb(b)
}
Expand All @@ -165,7 +170,7 @@ func (e *Engine) queueEvent(event *eventWave) {
}

// Tick will call tick on the main anchor
func (e *Engine) Tick(dt float64) {
func (e *Engine) Tick(dt time.Duration) {
var wg sync.WaitGroup
// tick objects
e.tickObjectLocked(&wg, dt)
Expand All @@ -176,11 +181,11 @@ func (e *Engine) Tick(dt float64) {
wg.Wait()

// sync object status
e.syncStatusLocked(&wg)
e.syncStatusLocked(&wg, dt)
wg.Wait()
}

func (e *Engine) tickObjectLocked(wg *sync.WaitGroup, dt float64) {
func (e *Engine) tickObjectLocked(wg *sync.WaitGroup, dt time.Duration) {
e.RLock()
defer e.RUnlock()

Expand All @@ -193,7 +198,7 @@ func (e *Engine) tickObjectLocked(wg *sync.WaitGroup, dt float64) {
}
}

func (e *Engine) tickEventLocked(wg *sync.WaitGroup, dt float64) {
func (e *Engine) tickEventLocked(wg *sync.WaitGroup, dt time.Duration) {
e.RLock()
defer e.RUnlock()

Expand All @@ -210,15 +215,15 @@ func (e *Engine) tickEventLocked(wg *sync.WaitGroup, dt float64) {
}
}

func (e *Engine) syncStatusLocked(wg *sync.WaitGroup) {
func (e *Engine) syncStatusLocked(wg *sync.WaitGroup, dt time.Duration) {
e.Lock()
defer e.Unlock()

for _, o := range e.objects {
wg.Add(1)
go func(o *Object) {
defer wg.Done()
o.saveStatus()
o.saveStatus(dt)
}(o)
}
// remove not alive events
Expand Down
Loading

0 comments on commit 2eb3be5

Please sign in to comment.