Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - d3x0r

Pages: 1 2 [3] 4 5
31
Programming with Blackvoxel / Re: Custom VoxelTypes
« on: November 18, 2014, 04:11:21 am »

Hum, I wouldn’t recommend doing this.

The way the storage was made is for memory bandwidth efficiency.

Packing these data will lead to waste an important amount of memory bandwidth.

This is a weird side effect of how modern processors access memory with prefetch mechanisms and important bus width : processors can't fetch only a byte or short.

Sectors are 16384 indexes... voxel types are 2 bytes... so 32k or 8 4k pages.
TempInfos is another short for block temperature; this should probably be in an infos since in general blocks don't change behavior based on tempurature....
OtherInfos is 4/8 bytes to reference voxel instance data; VoxelExtension*... 

all together 341 + 4 bytes to 512 per page..........

total is 32k + 32k + 64k(32 bit)/128k(64 bit)  (I've been running 64 bit build, because I have more sectors of smaller voxels usually)

128k/192k ..  32 or 48 pages (4096 bytes) for a sector...

-------------------
I made a branch at that point... I wasn't sure how much of a performance hit it would be... I'm aware of cache... *see below*

I guess given the defined scope of the project
for the renderer which only needs voxel type, then it needs to only fill 8 pages instead of 48... given no custom render for custom voxels... (color shading)... although maybe renderer uses TempInfos to determine texture... so 16 pages; even if blocks are rarely shaded, so temp isn't checked always... could be less...

voxel reactor uses (tempurature?  does temp get modified except by time and water?  Does it dissapate?  Each voxelType have a thermal coefficient thing? :)  ) and OtherInfos... unless a highly static level is used with non extended voxels... with an active environment, OtherInfo will definatly be cached... so no 8+32.. 40 pages loaded without tempurature... so there's no real savings at this level...

Feature: at a voxel-is-center-of-universe view, if I'm given an offset to my data, to get near voxel's (extended)data... I dunno I guess I still need the sector reference...

so ya... a highly static map benefits from only needing 32k loaded for working with a sector (plus another page for the sector, and another for the voxel type manager) ... but then again in a 1M cache 32 sectors can potentially be loaded... so that's only a few more than the block of 9 around the player at any point... so it still has to scroll through the memory...

....
in a sequence of processing blocks, only 4-6 pages are used ... (the center, left/right) (above and below) (forward and backward) , especially on boundaries of sectors... I dunno; the working set is still the same.... this is tripled with the current scheme... because mirror otherinfo, tempinfo pages may be used... 12-18 working set pages...

it resulted in more efficient assembly because there was only one pointer and other offsets computed from that...in the other place I was looking at I do remember noting that...

It may be arguably better if they were allocated all together... and put all voxeltypes and all tempinfos and all otherinfos together instead of interlaced, but with a single pointer...

What is lost is gained in other ways.... and I don't notice a particular performance hit from this change...

--------------

Once upon a time I got to play with/use a logic analyzer that decoded the pins interfacing from 386 to motherboard... got to see read/write memory to fetch instruction blocks... so there's the clearing of cache on calls and jumps backward... jumps forward are better handled by setting a ignore flag and processing the prefetch cache anyway... kinda like how arm handles short jumps.... but anyway... it's just much wider now... and burst mode...

32
Programming with Blackvoxel / Re: Custom VoxelTypes
« on: November 16, 2014, 12:26:08 am »
A large performance increase can be made in the water processor...

Code: [Select]
// original
                              for(i=0,j=4,vCount=0,WaveCount=0;i<4;i++,j++)
                              {
                                cx = x+bft[i].x ; cy = y+bft[i].y ; cz = z+bft[i].z ; SecondaryOffset[i] = If_x[cx]+If_y[cy]+If_z[cz];St[i] = SectorTable[ Of_x[cx] + Of_y[cy] + Of_z[cz] ]; Vp[i] = &St[i]->Data[ SecondaryOffset[i] ].Data;
                                cx = x+bft[j].x ; cy = y+bft[j].y ; cz = z+bft[j].z ; SecondaryOffset[j] = If_x[cx]+If_y[cy]+If_z[cz];St[j] = SectorTable[ Of_x[cx] + Of_y[cy] + Of_z[cz] ]; Vp[j] = &St[j]->Data[ SecondaryOffset[j] ].Data;
                                if (VoxelTypeManager->VoxelTable[*Vp[i]]->Is_CanBeReplacedBy_Water && VoxelTypeManager->VoxelTable[*Vp[j]]->Is_CanBeReplacedBy_Water) {vCount++; DirEn[i]=true;}
                                else DirEn[i]=false;
                                if (VoxelTypeManager->VoxelTable[*Vp[i]]->Is_CanBeReplacedBy_Water) {WaveCount++;WaveDirEn[i] = true;}
                                else                                                                {WaveDirEn[i] = false;}
                              }

// modified; move the test for (*Vp ) as a common point, then Vp[j] doesn't have to be computed, or tested, because it's an and condition with Vp
Code: [Select]

                              for(i=0,j=4,vCount=0,WaveCount=0;i<4;i++,j++)
                              {
                                cx = x+bft[i].x ; cy = y+bft[i].y ; cz = z+bft[i].z ; SecondaryOffset[i] = If_x[cx]+If_y[cy]+If_z[cz];St[i] = SectorTable[ Of_x[cx] + Of_y[cy] + Of_z[cz] ]; Vp[i] = &St[i]->Data[ SecondaryOffset[i] ].Data;
                                if (VoxelTypeManager->VoxelTable[*Vp[i]]->Is_CanBeReplacedBy_Water )
                                {
                                  cx = x+bft[j].x ; cy = y+bft[j].y ; cz = z+bft[j].z ; SecondaryOffset[j] = If_x[cx]+If_y[cy]+If_z[cz];St[j] = SectorTable[ Of_x[cx] + Of_y[cy] + Of_z[cz] ]; Vp[j] = &St[j]->Data[ SecondaryOffset[j] ].Data;
                                  if( VoxelTypeManager->VoxelTable[*Vp[j]]->Is_CanBeReplacedBy_Water) {vCount++; DirEn[i]=true;}
                                  else DirEn[i]=false;
                                  {WaveCount++;WaveDirEn[i] = true;}  // bad braces
                                }
                                else  {WaveDirEn[i] = false; DirEn[i]=false;}
                              }

50% processing time reduction

33
Programming with Blackvoxel / Re: Custom VoxelTypes
« on: November 14, 2014, 06:12:28 am »
Voxel extensions don't come from pooled memory.
Moving a voxel from one place to another that has extension causes new and delete operators; and the new voxel is not the same as the prior... (maybe there's a copy operator)...

but also there is no 'move voxel to' or 'swap voxel with' which could move the reference to the original voxelExtension.

So motion is (set new voxel, create extension ) (clear old voxel, delete old extension)

34
Programming with Blackvoxel / Re: Custom VoxelTypes
« on: November 12, 2014, 10:00:54 am »
Managed to add Aroma Generator and Aroma types.
Aroma diffuses itself such that if it is near itself, it moves away from itself, otherwise if it is not in free space it moves.  I dunno basically it works pretty well... gave me something to think about regarding inter-mingling voxels, and various things... like 'wind' .... and what it actually is useful for... and what meaning it would have...

the particles also age-out so after 12 seconds they evaporate... but worked good for a long time without despawning... also had a really cool overflow that resulted in a solid growing bubble form... not sure if the inside was just solid transparent of it if was just the outside sheet somehow... but it's fixed now and that was a memory fault anyway...

https://github.com/d3x0r/Blackvoxel/blob/group_voxel_datas/src/ZVoxelType_AromaGenerator.cpp
https://github.com/d3x0r/Blackvoxel/blob/group_voxel_datas/src/ZVoxelType_Aroma.cpp

also; in consideration of making a container for voxels, needed to know what a voxel was, so I reimplemented Sector->Data,OtherInfos,TempInfos as VoxelData *Data;

https://github.com/d3x0r/Blackvoxel/blob/group_voxel_datas/src/ZVoxelSector.h#L203

------------
just messing around... it is rather stable backend for dynamic updates to voxels ...

noting that there should be some more standard routines... like to get the array of voxels around a single voxel...

----------
Oh; a sector reactor... to do computations between sectors... could use a point per sector as a air pressure, and create a gradient between sectors for 'wind'... wind as a velocity could represent a propability of motion in time rather than a linear motion....

1.0 = 1 voxel in (100ms?) a 1 tick... how long is a 'tick' target?
0.5 = 50% chance to move 1 voxel in 1 tick.. something... for partial motions... I guess use the fraction as a proabilty to move one more (if available )... might work


35
Programming with Blackvoxel / Re: Custom VoxelTypes
« on: November 10, 2014, 12:52:38 pm »
Hmm... does the mem pool really help?  Is new and delete not really based on malloc/free?  Glibc usually collects garbage pretty well... I had my own memory allocator that was in the core of my library; still do, just hard to initialize a dynamic program without having initialized memory; and sometimes core debugging becomes impossible....

In my library I made a set allocator which is a linked list of nodes that have a bitmap mask of used mono-sized nodes... also keep a counter of used nodes so can just check if all used, otherwise scan the bits 32 at a time until it's not ~0 ... otherwise allocates a new block of nodes... so all nodes are continuous in memory ...

even if you're recycling previously allocated things, they're still jumbled all over memory....

36
Programming with Blackvoxel / Re: MSVC or non-GCC Porting
« on: November 10, 2014, 11:24:25 am »

Stack overflow 'compare and swap atomics...'
Quote from: StackOverflow

On Mac OS X and Windows there are builtin CompareAndSwap functions you should be using anyway (InterlockedCompareExchange() and OSAtomicCompareAndSwapPtrBarrier() respectively). Thus will work regardless of the compilers on those platforms.

How to get predefined macros...
Quote
Code: [Select]

Command lines
Compiler C macros C++ macros
Clang/LLVM clang -dM -E -x c /dev/null clang++ -dM -E -x c++ /dev/null
GNU GCC/G++        gcc   -dM -E -x c /dev/null g++     -dM -E -x c++ /dev/null
Hewlett-Packard C/aC++ cc    -dM -E -x c /dev/null aCC     -dM -E -x c++ /dev/null
IBM XL C/C++     xlc   -qshowmacros -E /dev/null xlc++   -qshowmacros -E /dev/null
Intel ICC/ICPC icc   -dM -E -x c /dev/null icpc    -dM -E -x c++ /dev/null
Microsoft Visual Studio (none) (none)
Oracle Solaris Studio cc    -xdumpmacros -E /dev/null CC      -xdumpmacros -E /dev/null
Portland Group PGCC/PGCPP pgcc  -dM -E (none)
looks to me like also ICC is a gcc variant that might (and on further research it does....)  and maybe that hewlett-packard version...


Modified location to "ZOs_Specific_Various.h"
modified define test to #if defined( _MSC_VER ) || defined( __WATCOMC__ )
for known exceptions.


37
Programming with Blackvoxel / Re: Custom VoxelTypes
« on: November 10, 2014, 10:17:25 am »

Interesting ideas. We dreamed to make some agriculture and food in blackvoxel since a long time.  But, be careful of animals that could be present in some other voxel games.
Maybe you could make it as some extra terrestrial animals. If you keep reference to some known animals, they could be very different of what we know. In blackvoxel, the idea is that one should be surprised from what he is expecting (when possible, of course).
I agree; was going to make some cyber-space names for them.. but fell back to my idea of foxes and rabbits .... predator/prey and make the foliage be like data nodes... but the concept of growth didn't apply so much... am open to ideas ... maybe 'bit scav'/'virus' and 'antivirus'... so a virus consumes data and anti-virus consumes viruses...

general properties of an 'animal'
health/data size
damage/data consumption
level/entities consumed  (improve damage application effectiveness)
propagation_threshold - if health > threshold spawn new X
age maybe - builtin obsolescence
scent?

----------
Something I've been considering; making transparent voxels have a base voxel extension that can store other voxels... fish in water; animals in plants, animals sharing spots... 1) animals could attack horizontally and just require nearness... 2) animals could be 'on top of' plants... 3) could be a meta voxel type 'fish in water' that behaves like water... but...
Something I'd like to implement is 'smell' that is empty (air) voxels will be like a textureless voxel that's not zero; and contain information about aromas in the air...

normally the player isn't a voxel; so voxels that are player-like should also respect 'can player pass through' ... but then they would be in the voxel.... and since there's only a current reprensentation of a single voxel type in any voxel, it could be an interface implemented on transparent voxels that allow being 'in' the voxel.  Can do a multi-layered render of the voxel at some point to represent the contained voxels... thoughts?  I will assert that from previous experience, I think you'd prefer to keep to a purist approach, and animals will just hop from ground to the top of foliage, and animals can attack animals nearby disregarding height differences.. and then I can't really populate air ... because eventually aroma voxels will exist above fertile land and prevent growth....

Quote

There is a particularity in C++ games : the  operator "new" should be avoided in "game loops" whenever possible because use of the system heap memory manager is always slow (and could lead to massive use causing memory fragmentation problems).
There is no garbage collector like in C# or Java, so that's very different in programming style.
depends on your allocer; most malloc will return the same block as was last freed... so allocating short term storage doesn't fragment.. yes returning into a caller-owned struct solves it.... was more concerned with keeping the function signature the same for quickness; and when not deleted was what was causing my memory error :)  ended up removing that.

well... memory deallocated is defragmented and allowed for reuse; so the things you throw away are collected, so there is garbage collection; just not automagic object reference increment/decrements... and garbage on the stack is collected...

And even so; you still have to intentionally throw away things like Datatables because of the circular references they won't auto implode.... so you should never count on things just going away.

free works kinda like ZMonoSizeMemoryPool::Free such that when released, it's immediately reused for new mallocs...
I find it's better to do a slight more work, and do 2 comparisons in the free list to order free blocks from least memory address to most; further reducing fragmentation... also if the allocer has a minimum memory block size there's less chance of having blocks that are not big enough laying around; my MUD terminal (dekware) improved greatly by setting minimum alloc at 60 bytes... at not that much increase in memory usage.
Also block types that are tiny like binary tree nodes come from a pool of structs so there's only a few allocs from physical memory.

so ya; I saw the techniques and recognized their purpose :) 
----------------------------

And back on aromatics; could do seed dropping too... for vegetation... maybe fertile gruond is just ground until fertilized... I kind of see an evolution of foliage more.. so it's not just that it's A plant that grows, but really the plant type changes... so when it propagates, a 'tall/thick foliage' would cause more thick folliage to grow... that itself being an enemy to the vegetation consumer... I guess the diffusion function would be different for that...



38
Programming with Blackvoxel / Custom VoxelTypes
« on: November 09, 2014, 01:26:37 am »
Success!
I have a block called 'fertile ground' that in a second or 2 from creation grows 'low foliage' aka food.
food will eventually age and become medium and tall; which will be unusable by the first animals... a block called rabbit and a block called fox....
------------
I implemented a type called ZVoxelRef
Code: [Select]
#ifndef ZVOXEL_REF_DEFINED
#define ZVOXEL_REF_DEFINED

#include "ZVoxelSector.h"
#include "../ZVoxelExtension.h"
class ZVoxelWorld;
class ZVoxelRef
{
public:
ZVoxelSector * Sector;
int Offset;
int x, y, z;
UShort VoxelType;
ZVoxelWorld *World;
ZVoxelTypeManager *VoxelTypeManager;
ZVoxelExtension *VoxelExtension;
ZVoxelRef( ZVoxelWorld *world, ZVoxelTypeManager *vtm, long x = 0, long y = 0, long z = 0, ZVoxelSector *Sector=NULL, UShort VoxelType = 0, int offset = 0 )
{
this->x = x;
this->y = y;
this->z = z;
this->Sector = Sector;
this->Offset = offset;
this->World = world;
this->VoxelType = VoxelType;
VoxelTypeManager = vtm;
}
static int ForEachVoxel( ZVoxelWorld * World, ZVoxelRef *v1, ZVoxelRef *v2, int (*f)(ZVoxelRef *v) );

};

#endif

that I for implemented for the result of raycast at maxiter... before I changed method to render selection cube in space in front of player...


// modified GetVoxel which just returned the UShort from a world coordinate
//  to return the World, Sector, relative x,y,z within the sector, and the UShort type
// the sector has it's x,y,z scaled world coordinate... so the absolute coord is knowable from the reference.
... reviewing this a little... the ref could be used for all the temp variables themselves... this actually returns a copy of the world coordinate, React uses it as x,y,z within the sector...
Code: [Select]
inline ZVoxelRef *ZVoxelWorld::GetVoxelRef(Long x, Long y, Long z)
{
  ZVoxelSector * Sector;
  Long Offset;

  Sector = FindSector( x>>ZVOXELBLOCSHIFT_X , y>>ZVOXELBLOCSHIFT_Y , z>>ZVOXELBLOCSHIFT_Z );

  if (!Sector) return NULL;

  Offset =  (y & ZVOXELBLOCMASK_Y)
         + ((x & ZVOXELBLOCMASK_X) <<  ZVOXELBLOCSHIFT_Y )
         + ((z & ZVOXELBLOCMASK_Z) << (ZVOXELBLOCSHIFT_Y + ZVOXELBLOCSHIFT_X));

  return new ZVoxelRef( this, VoxelTypeManager, x, y, z, Sector, Sector->Data[Offset], Offset );
}


inline UShort ZVoxelWorld::GetVoxel(Long x, Long y, Long z)
{
  ZVoxelSector * Sector;
  Long Offset;

  Sector = FindSector( x>>ZVOXELBLOCSHIFT_X , y>>ZVOXELBLOCSHIFT_Y , z>>ZVOXELBLOCSHIFT_Z );

  if (!Sector) return(-1);

  Offset =  (y & ZVOXELBLOCMASK_Y)
         + ((x & ZVOXELBLOCMASK_X) <<  ZVOXELBLOCSHIFT_Y )
         + ((z & ZVOXELBLOCMASK_Z) << (ZVOXELBLOCSHIFT_Y + ZVOXELBLOCSHIFT_X));

  return(Sector->Data[Offset]);
}

-------------
Used this in VoxelReactor to call React virtual method in voxel table...
Code: [Select]
      Long RSx = Sector->Pos_x << ZVOXELBLOCSHIFT_X;
      Long RSy = Sector->Pos_y << ZVOXELBLOCSHIFT_Y;
      Long RSz = Sector->Pos_z << ZVOXELBLOCSHIFT_Z;
  ZVoxelRef ref(World,VoxelTypeManager, 0,0,0,Sector );
    // z, x, y should just be ref.x, ref.y, ref.z, ... redundant copy
      for (z = 0; z < ZVOXELBLOCSIZE_Z; z++)
        for (x = 0; x < ZVOXELBLOCSIZE_X; x++)
          for (y = 0; y < ZVOXELBLOCSIZE_Y; y++)
          {
VoxelType = *(VoxelP);
            if (ActiveTable->Get(VoxelType))
            {
              if (!Sector->ModifTracker.Get( MainOffset ) ) // If voxel is already processed, don't process it once more in the same cycle.
              {
                switch(VoxelType)
                {
default:
  ref.x = x; ref.y = y; ref.z = z;
  ref.Offset = VoxelP - DisplayData;
  ref.VoxelType = VoxelType;

IsActiveVoxels = true;
ref.VoxelExtension = (ZVoxelExtension*)Sector->OtherInfos[MainOffset];
// not sure what St is ...
//St[i]->ModifTracker.Set(SecondaryOffset[i]);
VoxelTypeManager->VoxelTable[VoxelType]->React( ref, LastLoopTime);
break;


39
Programming with Blackvoxel / Re: How hard could smoothing be?
« on: November 09, 2014, 12:46:03 am »

This is a code snippet that's mostly standalone; use of libpng to read/write images.  1/2 is read 1/2 is write.
basically my image stucture is
struct image {
  int x, y;
  unsigned int w, h;
  byte[4] *image; // color data
}


https://code.google.com/p/c-system-abstraction-component-gui/source/browse/src/imglib/pngimage.c

several editors on windows support png and the alpha transparent layer... none (few); probably you use gimp?  support 32 bit alpha saving.  I Have a command line utility that converts 24 to 32; but makes the alpha channel opaque. 

png is like bmp that it is lossless... but it is a zip compression per channel...  works good for RLE encodable images basically... or mostly constant images... but does have 1 byte alpha channel support.

can google 'sample libpng read' which is what my code was based on... which is mostly copy and pastable....

----------
On image loading; I open the file memory mapped and pass the pointer to that memory to a routine that trys passing it to several loader routines, which then result with an image... basically if( !ZBitmapImage.PNGLoad(file) ) if( !ZBitmapImage.BMPLoad( file ) ) ... if (!... JPGLoad() ) ...

can just pass the open file and rewind it between....
SDL has an image loading library...
FreeImage is a LARGE library that loads just about everything... but it's like 2M .. png is a few hundred K
-----------

40
Programming with Blackvoxel / Re: MSVC or non-GCC Porting
« on: November 08, 2014, 10:26:58 am »
Sorry, should be Pointer not 32/64 bit switch...
needed to reverse b and c params and add test if result is the assigned value... not exactly the intrinsic.
Code: [Select]
#ifndef __GNUC__
#    define __sync_bool_compare_and_swap(a,b,c) (InterlockedCompareExchangePointer((void*volatile*)a,c,b), (*a)==(c))
#endif

41
Programming with Blackvoxel / Re: MSVC or non-GCC Porting
« on: November 08, 2014, 07:42:57 am »

Code: [Select]
// in ZTypes.h
#ifdef _WIN32
#    define MANUAL_BREAKPOINT  DebugBreak()
#else
#    define MANUAL_BREAKPOINT  asm volatile ("int3;")
#endif
// #define MANUAL_BREAKPOINT  asm volatile ("int3;")

42
Programming with Blackvoxel / MSVC or non-GCC Porting
« on: November 08, 2014, 06:15:32 am »
Specific to using MSVC instead of GCC to build (or OpenWatcom; although doesn't solve OpenWatcom on Linux)

Code: [Select]
#ifndef __GCC__
#    ifdef __64__
#          define __sync_bool_compare_and_swap(a,b,c) InterlockedCompareExchange64((__int64*)a,(__int64)b,(__int64)c)
#    else
#          define __sync_bool_compare_and_swap(a,b,c) InterlockedCompareExchange(a,b,c)
#   endif
#endif

although as a quick and dirty hack the following code works
Code: [Select]
// in src\z\ZMemPool_Optimized.cpp
#ifdef __GCC__
      if (__sync_bool_compare_and_swap(&MemTable[BitPosition],NewBlock,NewBlock->Next))
#else
if( (MemTable[BitPosition] == NewBlock) ? (MemTable[BitPosition]=NewBlock->Next),1:0)
#endif

which does the same job, but without lock.....

43
Programming with Blackvoxel / Re: How hard could smoothing be?
« on: November 04, 2014, 12:23:39 pm »
I I continued to do some merging, and ... I have gui popup displays rendering... but as soon as I do the textures ...
*and as I typed that I realized what it might have been*
So the last thing that's being done is drawing a black text output, which left glColor set at 0,0,0.. and apparently whatever the last color before the swap is, is what the glCallList lists use... so everything seemed to be there, but it was all black... like the geometry opaqued my displays in the depth buffer... but had no color themselves... finally reset the color back to 1,1,1 before swap and now

.. *deleted*. http://youtu.be/V9TR1w2yEtg

Doh; stupid opengl window doesn't record right.

44
Programming with Blackvoxel / Re: How hard could smoothing be?
« on: November 03, 2014, 09:22:01 pm »
compare_swap_and_xchg and InterlockedExchange are similar; other than the function results...
I see; that is one thing I had an issue with when porting; think I made it thread unsafe...

Here's something I was playing with - surround-o-vision

http://youtu.be/R2izTRpP2kM 

each display is actually independant, and should build its display list appropriate for its view direction, but right now, everything is added to every display list, and 6 windows shown each rendering pass... at very low frame rates there is frame tear between the displays....

More optimal would be to target 3 monitor, and just show forward left and right.. a single display stretched across 3 displays is not right, and perspective gets distorted badly.

----
So ya I'll turn my attention more to voxel based operations... I dunno just feel I'm missing something... like I saw the voxel engine

45
Programming with Blackvoxel / Re: How hard could smoothing be?
« on: November 02, 2014, 09:06:03 am »
The other example of 'poor relationships' I ran into is C# has a type called DataTable, which is a representation of a SQL table, with dynamic columns with types and rows, etc.  But datatables contain columns and rows but all columns know the datatable they are in, and all rows know the datatable, also datatables can be contained in datasets which is a group of datatables and adds the foriegn key relationships between tables.  So from any row you can get to any other row in any other table that row is remotely related to... so there's sometimes merits of having... say worlds know all sectors, but sectors know their world, and hence their renderer...  or something.

Pages: 1 2 [3] 4 5