1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
#ifndef WATCHMAKER_T3D_MESH_H
#define WATCHMAKER_T3D_MESH_H
#include "watchmaker/3d/t3d_face.h"
#include "watchmaker/t3d.h"
namespace Watchmaker {
struct t3dMESH {
Common::String name; // mesh name
Common::String portalName; // dest room name (if portal)
uint16 NumFaces() {
return FList.size();
}; // faces number
uint16 NumVerts = 0; // verts number
uint16 NumNormals = 0; // face normals number
uint16 NumVerticesNormals = 0; // verts normals number
gVertex *SavedVertexBuffer = nullptr; // saved vertices pos (original)
gVertex *VertexBuffer = nullptr; // cur vertices pos
gVertex *OldVertexBuffer = nullptr; // last vertices pos
t3dV3F *VertsInterpolants = nullptr; // verts interpolants (for blending)
gVertex *VBptr = nullptr; // temp pointer to vertexbuffer
Common::Array<t3dMORPH> MorphFrames; // morph frames list
Common::Array<t3dFACE> FList; // faces list
NormalList NList; // normals list
t3dV3F Pos; // mesh center
t3dV3F Trasl; // mesh traslation (world)
t3dF32 Radius = 0.0f; // radius for Bounding Sphere culling
t3dVERTEX BBox[8] = {}; // Bounding box
t3dNORMAL BBoxNormal[6] = {}; // bound box normals
t3dF32 BBoxAverageZ = 0.0f; // average distance from eye
t3dV3F Intersection; // intersecton form eye
t3dM3X3F Matrix; // transformation matrix (useful only for 1st mesh in body)
uint16 LightmapDim = 0; // lightmap texture dimensions
Common::Array<t3dMODVERTS> ModVertices; // mod vertices list
t3dBONEANIM DefaultAnim; // Default Animations
t3dBONEANIM Anim; // Animations
int16 CurFrame = 0; // current animation frames (0 no anim)
int16 LastFrame = 0; // last animation frames
uint8 BlendPercent = 0; // blend animation percentage
uint8 LastBlendPercent = 0; // last blend animation percentage
uint32 ExpressionFrame = 0; // current expression frames
uint32 LastExpressionFrame = 0; // last expression frames
int32 *WaterBuffer1 = nullptr; // pointers to ripple buffer
int32 *WaterBuffer2 = nullptr; // pointers to ripple buffer
t3dF32 WavesSpeed; // waves speed
t3dF32 YSpeed; // waves y speed
t3dF32 XInc, YInc; // waves movements
t3dV3F SolarRGBVar[4]; // Override ambient color variation for solar movement
uint32 Flags; // Flags
t3dBODY *PortalList = nullptr; // Pointer to portal connected
Common::Array<t3dMESH *> RejectedMeshes; // rejected mesh from portal
void saveVertexBuffer() { // Scorre le mesh
this->VBptr = this->VertexBuffer;
if (this->OldVertexBuffer)
memcpy(this->OldVertexBuffer, this->VBptr, sizeof(gVertex)*this->NumVerts);
if (this->SavedVertexBuffer)
memcpy(this->SavedVertexBuffer, this->VBptr, sizeof(gVertex)*this->NumVerts);
this->VBptr = nullptr;
}
void preCalcLights(const t3dV3F &ambientLight) {
#ifndef WMGEN
this->VBptr = this->VertexBuffer;
#endif
for (uint16 j = 0; j < this->NumFaces(); j++) { // Scorre le facce
t3dFACE &Face = this->FList[j];
MaterialPtr Material = Face.getMaterial();
uint32 alphaval = 2;
uint32 rr = 0, gg = 0, bb = 0;
rr = Material->r; // Prende Ambient da materiale
gg = Material->g;
bb = Material->b;
if (Material->hasFlag(T3D_MATERIAL_CLIPMAP)) { // Se il materiale e' clipmap
alphaval = 0xfe;
Face.flags |= T3D_MATERIAL_CLIPMAP; // lo setta sulla faccia
/* Face->flags&=~T3D_MATERIAL_OPACITY;
Face->flags&=~T3D_MATERIAL_GLASS;
Material->Flags&=~T3D_MATERIAL_OPACITY;
Material->Flags&=~T3D_MATERIAL_GLASS;*/
// r=g=b=0;
}
if (Material->hasFlag(T3D_MATERIAL_OPACITY)) { // Se il materiale e' opacity
Face.flags |= T3D_MATERIAL_OPACITY; // lo setta sulla faccia
alphaval = 0x88;
rr = gg = bb = 0;
}
if (Material->hasFlag(T3D_MATERIAL_GLASS)) { // Se e' un glass
Face.flags |= T3D_MATERIAL_GLASS; // lo setta sulla faccia
alphaval = 0xfe;
rr = gg = bb = 255;
}
if (Material->hasFlag(T3D_MATERIAL_BOTTLE)) { // Se e' un bottle
Face.flags |= T3D_MATERIAL_BOTTLE; // sulla faccia
alphaval = 0x88;
rr = gg = bb = 255;
}
if (Material->hasFlag(T3D_MATERIAL_ADDITIVE)) { // Se e' un additivo
Face.flags |= T3D_MATERIAL_ADDITIVE; // sulla faccia
alphaval = 0x88;
rr = gg = bb = 255;
}
if (rr < ambientLight.x) rr = (uint8)ambientLight.x;
if (gg < ambientLight.y) gg = (uint8)ambientLight.y;
if (bb < ambientLight.z) bb = (uint8)ambientLight.z;
this->VBptr[Face.VertexIndex[0]].diffuse = RGBA_MAKE(rr, gg, bb, alphaval); // Cambia diffse dei vertici della mesh
this->VBptr[Face.VertexIndex[1]].diffuse = RGBA_MAKE(rr, gg, bb, alphaval);
this->VBptr[Face.VertexIndex[2]].diffuse = RGBA_MAKE(rr, gg, bb, alphaval);
}
#ifndef WMGEN
this->VBptr = nullptr;
#endif
// rOptimizeVertexArray(Mesh->VertexBuffer);
}
t3dMESH() = default;
t3dMESH(t3dBODY *b, Common::SeekableReadStream &stream, t3dMESH *&ReceiveRipples, uint8 &Mirror);
t3dMESH(const t3dMESH &other);
t3dMESH(t3dMESH &&old);
t3dMESH& operator=(t3dMESH rhs);
~t3dMESH();
void loadFaces(t3dBODY *b, Common::SeekableReadStream &stream, int numFaces);
void release();
void releaseAnim(uint8 flag);
bool hasFaceMaterial() const {
return !this->FList.empty() && (bool)(this->FList[0].getMaterial());
}
void setMovieFrame(uint32 dwCurrFrame) {
// TODO: Could just inline rSetMovieFrame?
if (!this->FList.empty() && this->FList[0].getMaterial()) {
rSetMovieFrame(this->FList[0].getMaterial(), dwCurrFrame);
}
}
uint32 getMovieFrame() {
assert(!this->FList.empty() && this->FList[0].getMaterial());
return rGetMovieFrame(this->FList[0].getMaterial());
}
};
} // End of namespace Watchmaker
#endif // WATCHMAKER_T3D_MESH_H
|