You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
6.9 KiB
288 lines
6.9 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU 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 General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
|
|
#ifndef plSpanInstance_inc |
|
#define plSpanInstance_inc |
|
|
|
#include "hsGeometry3.h" |
|
#include "hsMatrix44.h" |
|
|
|
// plClusterGroup |
|
// array of templates |
|
// array of materials (indexed by templates) |
|
// array of clusters |
|
// array of LOD blend |
|
// array of vis sets |
|
|
|
// plCluster |
|
// array of span instances that are combinable |
|
// LOD blend start and end index |
|
// vis set index |
|
// Combinable means: |
|
// same material |
|
// same format |
|
// same LOD blend |
|
// same vis set |
|
// same lights |
|
// same encoding? |
|
|
|
// plSpanInstance |
|
// template idx |
|
// 3x4 transform |
|
// encoding flags |
|
// (what components does it include, delPos? color?) |
|
// (what's the encoding? 32bit RGBA? 16Bit/Chan? 10Bit/Chan? 8Bit/Chan?) |
|
// (need an encoding per channel) |
|
|
|
// plSpanTemplate |
|
// numVerts |
|
// Format (assume pos & norm?) |
|
// kUVWMask |
|
// kColMask |
|
// kWeightMask |
|
// fPos |
|
// fNorm |
|
// fCol |
|
// fUVWs |
|
// fWeights |
|
|
|
|
|
class plSpanEncoding |
|
{ |
|
public: |
|
enum |
|
{ |
|
kPosNone = 0x0, |
|
kPos888 = 0x1, |
|
kPos161616 = 0x2, |
|
kPos101010 = 0x4, |
|
kPos008 = 0x8, |
|
kPosMask = kPos888 | kPos161616 | kPos101010 | kPos008, |
|
|
|
kColNone = 0x0, |
|
kColA8 = 0x10, |
|
kColI8 = 0x20, |
|
kColAI88 = 0x40, |
|
kColRGB888 = 0x80, |
|
kColARGB8888 = 0x100, |
|
kColMask = kColNone |
|
| kColA8 |
|
| kColI8 |
|
| kColAI88 |
|
| kColRGB888 |
|
| kColARGB8888, |
|
}; |
|
|
|
UInt32 fCode; |
|
hsScalar fPosScale; |
|
|
|
plSpanEncoding() : fCode(kPosNone|kColNone), fPosScale(0) {} |
|
plSpanEncoding(UInt32 c, hsScalar s) : fCode(c), fPosScale(s) {} |
|
|
|
UInt32 Code() const { return fCode; } |
|
hsScalar Scale() const { return fPosScale; } |
|
|
|
void Read(hsStream* s); |
|
void Write(hsStream* s) const; |
|
}; |
|
|
|
class plSpanInstance |
|
{ |
|
protected: |
|
UInt8* fPosDelta; |
|
UInt8* fCol; |
|
|
|
hsScalar fL2W[3][4]; |
|
|
|
friend class plSpanInstanceIter; |
|
public: |
|
plSpanInstance(); |
|
~plSpanInstance(); |
|
|
|
void Read(hsStream* s, const plSpanEncoding& encoding, UInt32 numVerts); |
|
void Write(hsStream* s, const plSpanEncoding& encoding, UInt32 numVerts) const; |
|
|
|
void Encode(const plSpanEncoding& encoding, UInt32 numVerts, const hsVector3* delPos, const UInt32* color); |
|
|
|
void Alloc(const plSpanEncoding& encoding, UInt32 numVerts); |
|
void DeAlloc(); |
|
|
|
hsMatrix44 LocalToWorld() const; |
|
hsMatrix44 WorldToLocal() const; |
|
|
|
void SetLocalToWorld(const hsMatrix44& l2w); |
|
|
|
hsBool HasPosDelta() const { return fPosDelta != nil; } |
|
hsBool HasColor() const { return fCol != nil; } |
|
|
|
static UInt16 PosStrideFromEncoding(const plSpanEncoding& encoding) |
|
{ |
|
switch(encoding.fCode & plSpanEncoding::kPosMask) |
|
{ |
|
case plSpanEncoding::kPos888: |
|
return 3; |
|
case plSpanEncoding::kPos161616: |
|
return 6; |
|
case plSpanEncoding::kPos101010: |
|
return 4; |
|
case plSpanEncoding::kPos008: |
|
return 1; |
|
} |
|
return 0; |
|
} |
|
static UInt16 ColStrideFromEncoding(const plSpanEncoding& encoding) |
|
{ |
|
switch(encoding.fCode & plSpanEncoding::kPosMask) |
|
{ |
|
case plSpanEncoding::kColNone: |
|
return 0; |
|
case plSpanEncoding::kColA8: |
|
return 1; |
|
case plSpanEncoding::kColI8: |
|
return 1; |
|
case plSpanEncoding::kColAI88: |
|
return 2; |
|
case plSpanEncoding::kColRGB888: |
|
return 3; |
|
case plSpanEncoding::kColARGB8888: |
|
return 4; |
|
} |
|
return 0; |
|
} |
|
}; |
|
|
|
class plSpanInstanceIter |
|
{ |
|
protected: |
|
plSpanInstance* fInst; |
|
plSpanEncoding fEncoding; |
|
UInt32 fNumVerts; |
|
Int32 fNumVertsLeft; |
|
UInt16 fPosStride; |
|
UInt16 fColStride; |
|
|
|
union { |
|
Int8* fPos888; |
|
Int16* fPos161616; |
|
UInt32* fPos101010; |
|
}; |
|
union { |
|
UInt8* fA8; |
|
UInt8* fI8; |
|
UInt16* fAI88; |
|
UInt8* fRGB888; |
|
UInt32* fARGB8888; |
|
}; |
|
|
|
public: |
|
plSpanInstanceIter(); |
|
plSpanInstanceIter(plSpanInstance* inst, const plSpanEncoding& encoding, UInt32 numVerts) { Init(inst, encoding, numVerts); } |
|
|
|
void Init(plSpanInstance* inst, const plSpanEncoding& encoding, UInt32 numVerts) |
|
{ |
|
fInst = inst; |
|
fEncoding = encoding; |
|
fNumVerts = numVerts; |
|
fPosStride = inst->PosStrideFromEncoding(fEncoding); |
|
fColStride = inst->ColStrideFromEncoding(fEncoding); |
|
fNumVertsLeft = 0; |
|
} |
|
|
|
void Begin() |
|
{ |
|
fPos888 = (Int8*)fInst->fPosDelta; |
|
fA8 = fInst->fCol; |
|
|
|
fNumVertsLeft = fNumVerts; |
|
} |
|
void Advance() |
|
{ |
|
fPos888 += fPosStride; |
|
fA8 += fColStride; |
|
|
|
fNumVertsLeft--; |
|
} |
|
hsBool More() const { return fNumVertsLeft > 0; } |
|
|
|
hsVector3 DelPos() const |
|
{ |
|
switch(fEncoding.fCode & plSpanEncoding::kPosMask) |
|
{ |
|
case plSpanEncoding::kPos888: |
|
return hsVector3(fPos888[0] * fEncoding.fPosScale, |
|
fPos888[1] * fEncoding.fPosScale, |
|
fPos888[2] * fEncoding.fPosScale); |
|
case plSpanEncoding::kPos161616: |
|
return hsVector3(fPos161616[0] * fEncoding.fPosScale, |
|
fPos161616[1] * fEncoding.fPosScale, |
|
fPos161616[2] * fEncoding.fPosScale); |
|
case plSpanEncoding::kPos101010: |
|
return hsVector3(int(*fPos101010 & 0x3f) * fEncoding.fPosScale, |
|
int((*fPos101010 >> 10) & 0x3f) * fEncoding.fPosScale, |
|
int((*fPos101010 >> 20) & 0x3f) * fEncoding.fPosScale); |
|
case plSpanEncoding::kPos008: |
|
return hsVector3(0,0, *fPos888 * fEncoding.fPosScale); |
|
} |
|
return hsVector3(0,0,0); |
|
}; |
|
hsPoint3 Position(const hsPoint3& p) const |
|
{ |
|
hsPoint3 pos(p); |
|
pos += DelPos(); |
|
return pos; |
|
}; |
|
UInt32 Color(UInt32 c) const |
|
{ |
|
switch(fEncoding.fCode & plSpanEncoding::kColMask) |
|
{ |
|
case plSpanEncoding::kColA8: |
|
return (c & 0x00ffffff) | *fA8; |
|
case plSpanEncoding::kColI8: |
|
return (c & 0xff000000) |
|
| (*fI8 << 16) |
|
| (*fI8 << 8) |
|
| (*fI8 << 0); |
|
case plSpanEncoding::kColAI88: |
|
{ |
|
const UInt32 col = *fAI88 & 0xff; |
|
return ((*fAI88 & 0xff00) << 24) |
|
| (col << 16) |
|
| (col << 8) |
|
| (col << 0); |
|
} |
|
case plSpanEncoding::kColRGB888: |
|
return (c & 0xff000000) |
|
| (fRGB888[0] << 16) |
|
| (fRGB888[1] << 8) |
|
| (fRGB888[2] << 0); |
|
case plSpanEncoding::kColARGB8888: |
|
return *fARGB8888; |
|
} |
|
return c; |
|
}; |
|
}; |
|
|
|
#endif // plSpanInstance_inc
|
|
|