Rasterize voxels #5 Up and Down childrens

Published January 15, 2020
Advertisement

In the previous version of this algorithm, the way to level down in the octree was to maintain the arrangement of sums and masks for each level, calculating these numbers by dividing by 2.

In the current version there was an improvement in this aspect, instead of calculating for each level these values ​​and masks divided into 2 what we are going to do is multiply by two the position, this makes the sums per child are the same and the mask also.

See and example in 2d:

bitmask for a quadree of length 16

        +------+  every line are the half of len!!
  +------+      
      +------+  
+------+        

bitmask for this lines (in hex)

11555577eeaaaa88

and the sum for childres are:

sum[0..3]=(0,6,2,8)

for example for the pixel 6 (start in 0)

        +------+
  +---X--+      
      X------+  
+-----X+        
      6
     
11555577eeaaaa88

the first level give me the child mask $7 (%0111 in binary) then can down to childrens 0,1 and 2.

the second level when children 0 are:

X=(6-sum[0])*2 ; 6 are the previous value, 0 are the children number
X=12

then new children mask is $a (%1010), only 1 and 3 children.

        +------+
  +---X--+      
      X------+  
+-----X+        
    +-X+
 +--+
   +--X
+--+

The second level when children 1 are:

X=(6-sum[1])*2 ; 6 are the previous value, 1 are the children number
X=0

then new children mask is $1 (%0001), only children 0

        +------+
  +---X--+      
      X------+  
+-----X+        
          +--+
       +--+
         +--+
      X--+

Now in code:

The word for get the next child, in the stack, like parameters, there are the childrens order and the len of side rectangle.

:nextchild | norden len -- norden len
	1 << swap		| len norden
	dup b> xy zz stack4!
	$7 and 1 over << 1 - >r
	3 << 'vecpos +
	@+ xy swap - 1 << 'xy ! @ neg 'zz +!		| new XY and ZZ
    b@+ dup r> and popcnt swap 8 >> + 2 << b+	| calc of next node
	b> $pixels >=? ( octcolor a! 0 ; ) drop	| end of octree?
	getyxmaskl		| len bm
	b@ and 0? ( drop prevchild ; )
	fillchild		| len norden
	swap ;

the more complicated thing is the calc of next node. What this line does is, first, given the child to enter, calculate the mask that corresponds to the previous children, ( 1<<mask)-1 This mask serves to know how many children there are before the corresponding one, doing an AND with the children of the node and adding the offset to calculate the new address. The funny thing about this calculation is that use POPCNT, the only time I use this function.

prevchild, for up level

:prevchild | len -- ordenn len
	1 >> 0? ( dup ; )	| duplicate len
	stack2@2 $ffffffff and	
	4 >>> 0? ( 2drop prevchild ; ) | next child
	stackvar
	swap >b swap ;

A trick for avoid memory asignation is en stack2@2, only get 2 values from 4 stacked, and only when have children get this values to vars.

I need the mask $ffffffff because r3 is 64 bits and when get a value in 32, the procesor fill the sign (x64 rules) and I need this value without sign.

Remember, all the code is in

https://github.com/phreda4/r3vm/blob/master/r3/dev/cuboiso5.r3

0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement