Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
174 lines
4.5 KiB
C++
174 lines
4.5 KiB
C++
#ifndef _OCTTREE_H
|
|
#define _OCTTREE_H
|
|
#include"image.h"
|
|
|
|
|
|
/// Maximum octree reduction level
|
|
static const int O_MaxDepth = 7;
|
|
|
|
// Number of quantized colors
|
|
static const int O_NumColor = 256;
|
|
|
|
class OctNode // Octree node
|
|
{
|
|
private:
|
|
int level; // Node level
|
|
BOOL leaf_flag; // Leaf flag
|
|
BOOL mark_flag; // Marked flag
|
|
DWORD count; // Pixel count
|
|
|
|
ImgRGBColor sum;
|
|
|
|
int index; // Color palette index
|
|
int children; // Number of child nodes
|
|
OctNode *pchild[8]; // Children node pointers
|
|
OctNode *pnext; // Next reducible node pointer
|
|
OctNode *pprev; // Previous reducible node pointer
|
|
|
|
int TestBit(BYTE val, int index)
|
|
{ return ((val & (1 << index)) > index) ? 1 : 0; }
|
|
|
|
public:
|
|
OctNode( int node_level, BOOL leaf )
|
|
{
|
|
int i; // Loop index
|
|
|
|
level = node_level;
|
|
leaf_flag = leaf;
|
|
mark_flag = FALSE;
|
|
count = 0L;
|
|
index = 0;
|
|
children = 0;
|
|
sum=0;
|
|
|
|
for (i=0;i<8;i++) pchild[i]=NULL;
|
|
|
|
pnext=pprev=NULL;
|
|
};
|
|
|
|
BOOL IsLeaf() { return leaf_flag; }
|
|
BOOL IsMark() { return mark_flag; }
|
|
DWORD GetCount() { return count; }
|
|
ImgRGBColor GetColor() { return sum/count; }
|
|
int GetIndex() { return index; }
|
|
int GetLevel() { return level; }
|
|
|
|
// Determine child node according to color
|
|
int FindChild( ImgRGBColor &c )
|
|
{
|
|
int index; // Child node pointer index
|
|
|
|
// Determine child node pointer index
|
|
index = TestBit((unsigned char)c.r, O_MaxDepth - level) << 2 |
|
|
TestBit((unsigned char)c.g, O_MaxDepth - level) << 1 |
|
|
TestBit((unsigned char)c.b, O_MaxDepth - level);
|
|
|
|
return index;
|
|
}
|
|
|
|
OctNode *GetChild( int i ) { return pchild[i]; }
|
|
OctNode *GetNext() { return pnext; }
|
|
OctNode *GetPrev() { return pprev; }
|
|
int GetNumChild() { return children; }
|
|
|
|
// Add RGB color to node
|
|
void AddColor( ImgRGBColor &c ) { sum+=c; count++; }
|
|
void DecNumChild() { children--; }
|
|
void IncNumChild() { children++; }
|
|
void SetChild( int i, OctNode *pc ) { pchild[i] = pc; }
|
|
void SetIndex( int i ) { index = i; }
|
|
void SetLeaf( BOOL flag ) { leaf_flag = flag; }
|
|
void SetMark( BOOL flag ) { mark_flag = flag; }
|
|
void SetNext( OctNode *pn ) { pnext = pn; }
|
|
void SetPrev( OctNode *pn ) { pprev = pn; }
|
|
};
|
|
|
|
class OctQuant // Octree color quantization
|
|
{
|
|
private:
|
|
int leaf_level; // Leaf level
|
|
int num_leaf; // Number of leaf nodes
|
|
|
|
// Reducible node list pointers
|
|
OctNode *prnl[O_MaxDepth +1];
|
|
|
|
protected:
|
|
int height; // Bitmap height
|
|
int width; // Bitmap width
|
|
int max_color; // Maximum number of colors
|
|
|
|
OctNode *proot; // Octree root node pointer
|
|
|
|
Image *image;
|
|
BYTE *newdata,*olddata;
|
|
|
|
BOOL InsertNode( OctNode *, ImgRGBColor & );
|
|
|
|
OctNode *MakeNode( int level )
|
|
{
|
|
BOOL leaf; // Leaf node flag
|
|
leaf=(level>=leaf_level)?TRUE:FALSE;
|
|
if (leaf == TRUE) num_leaf++;
|
|
return new OctNode(level,leaf);
|
|
}
|
|
|
|
OctNode *GetReducible();
|
|
|
|
// Quantize color
|
|
int QuantizeColor( OctNode *pn, ImgRGBColor &c )
|
|
{
|
|
int c_index; // Child node pointer index
|
|
if ((pn->IsLeaf()==TRUE) || pn->GetLevel()==leaf_level) return pn->GetIndex();
|
|
c_index=pn->FindChild(c);
|
|
if(!pn->GetChild(c_index)) return pn->GetIndex();
|
|
return QuantizeColor(pn->GetChild(c_index), c);
|
|
}
|
|
|
|
void DeleteNode( OctNode * );
|
|
void DeleteTree() { DeleteNode(proot); }
|
|
void FillPalette( OctNode *, int * );
|
|
|
|
// Add node to reducible list
|
|
void MakeReducible( OctNode *pn )
|
|
{
|
|
int level; // Node level
|
|
OctNode *phead; // List head node
|
|
|
|
level = pn->GetLevel();
|
|
phead = prnl[level];
|
|
pn->SetNext(phead);
|
|
if (phead != NULL)
|
|
phead->SetPrev(pn);
|
|
prnl[level] = pn;
|
|
|
|
pn->SetMark(TRUE);
|
|
}
|
|
|
|
void ReduceTree();
|
|
|
|
public:
|
|
OctQuant()
|
|
{
|
|
int i; // Loop index
|
|
|
|
width = height = 0;
|
|
num_leaf = 0;
|
|
max_color = O_NumColor;
|
|
leaf_level = O_MaxDepth + 1;
|
|
|
|
// Clear the reducible node list pointers
|
|
for (i = 0; i < leaf_level; i++) prnl[i] = NULL;
|
|
// Clear the color palette
|
|
proot = NULL;
|
|
}
|
|
|
|
BOOL BuildTree();
|
|
BOOL MapColors();
|
|
BOOL Quantize(Image *img);
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|