Apply Mesh/PictureTransformation in the meshes' frame of reference

This allows drawing meshes into a distorted target area by using the
transformation matrix.

This change might change the picture graphics of several objects. I fixed the
most important ones, others are still good but there might be a few more out
there that need to be updated.
stable-5.1
Armin Burgmeier 2010-07-21 22:23:34 +02:00
parent a52ae4e2c9
commit 04f3bf4dc9
15 changed files with 39 additions and 37 deletions

View File

@ -777,11 +777,11 @@ func GetCurrentWalkAnimation()
{ {
if(Contained()) if(Contained())
{ {
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(30,0,1,0),Trans_Scale(1200)), this); SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,1000,5000),Trans_Rotate(30,0,1,0)), this);
if(GetDirection() == COMD_Right) SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(-110,0,1,0),Trans_Scale(1200)), this); if(GetDirection() == COMD_Right) SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,1000,5000),Trans_Rotate(-110,0,1,0)), this);
return Clonk_WalkInside; return Clonk_WalkInside;
} }
else SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(70,0,1,0),Trans_Scale(1300)), this); else SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,1000,5000), Trans_Rotate(70,0,1,0)), this);
var velocity = Distance(0,0,GetXDir(),GetYDir()); var velocity = Distance(0,0,GetXDir(),GetYDir());
if(velocity < 1) return Clonk_WalkStand; if(velocity < 1) return Clonk_WalkStand;
if(velocity < 10) return Clonk_WalkWalk; if(velocity < 10) return Clonk_WalkWalk;
@ -2021,7 +2021,7 @@ HangOnto = {
SetProperty("Name", "Clonk", def); SetProperty("Name", "Clonk", def);
// Set perspective // Set perspective
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(70,0,1,0),Trans_Scale(1300)), def); SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,1000,5000), Trans_Rotate(70,0,1,0)), def);
_inherited(def); _inherited(def);
} }

View File

@ -225,5 +225,5 @@ func Deselection()
*/ */
func Definition(def) { func Definition(def) {
SetProperty("Name", "$Name$", def); SetProperty("Name", "$Name$", def);
SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(-2000,-2000),Trans_Rotate(180,0,1,0),Trans_Rotate(-25,1,0,1)),def); SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(-2000,-3000,-2000),Trans_Rotate(180,0,1,0),Trans_Rotate(-25,1,0,1)),def);
} }

View File

@ -169,5 +169,5 @@ func RejectCollect(id shotid, object shot)
func Definition(def) { func Definition(def) {
SetProperty("Name", "$Name$", def); SetProperty("Name", "$Name$", def);
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1),Trans_Scale(1200)),def); SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1500,0,-1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1)),def);
} }

View File

@ -53,5 +53,5 @@ private func Close()
protected func Definition(def) protected func Definition(def)
{ {
SetProperty("Name", "$Name$", def); SetProperty("Name", "$Name$", def);
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(-30,1,0,0),Trans_Rotate(30,0,1,0),Trans_Translate(1000,1,0,0)),def); SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(0,-3000,-5000),Trans_Rotate(-30,1,0,0),Trans_Rotate(30,0,1,0),Trans_Translate(1000,1,0)),def);
} }

View File

@ -209,5 +209,5 @@ Build = {
PhaseCall="Smoking", PhaseCall="Smoking",
}, }, def); }, }, def);
SetProperty("Name", "$Name$", def); SetProperty("Name", "$Name$", def);
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0,0,7000),Trans_Rotate(-20,1,0,0),Trans_Rotate(30,0,1,0)), def); SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(2000,0,7000),Trans_Rotate(-20,1,0,0),Trans_Rotate(30,0,1,0)), def);
} }

View File

@ -698,7 +698,7 @@ void C4Def::Draw(C4Facet &cgo, bool fSelected, DWORD iColor, C4Object *pObj, int
lpDDraw->SetMeshTransform(&matrix); lpDDraw->SetMeshTransform(&matrix);
lpDDraw->SetPerspective(true); lpDDraw->SetPerspective(true);
lpDDraw->RenderMesh(*instance, cgo.Surface, cgo.X,cgo.Y, cgo.Wdt, cgo.Hgt, 1.0f, pObj ? pObj->Color : iColor, trans); lpDDraw->RenderMesh(*instance, cgo.Surface, cgo.X,cgo.Y, cgo.Wdt, cgo.Hgt, pObj ? pObj->Color : iColor, trans);
lpDDraw->SetPerspective(false); lpDDraw->SetPerspective(false);
lpDDraw->SetMeshTransform(NULL); lpDDraw->SetMeshTransform(NULL);

View File

@ -1089,7 +1089,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (C4ValueToMatrix(value, &matrix)) if (C4ValueToMatrix(value, &matrix))
lpDDraw->SetMeshTransform(&matrix); lpDDraw->SetMeshTransform(&matrix);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, iTx - pDef->Shape.Wdt/2.0, iTy - pDef->Shape.Hgt/2.0, pDef->Shape.Wdt, pDef->Shape.Hgt, 1.0f, pForObj->Color, &trf); lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, iTx - pDef->Shape.Wdt/2.0, iTy - pDef->Shape.Hgt/2.0, pDef->Shape.Wdt, pDef->Shape.Hgt, pForObj->Color, &trf);
lpDDraw->SetMeshTransform(NULL); lpDDraw->SetMeshTransform(NULL);
} }
else else
@ -1116,7 +1116,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
C4DrawTransform trf(Transform, float(iTx), float(iTy)); C4DrawTransform trf(Transform, float(iTx), float(iTy));
lpDDraw->SetPerspective(true); lpDDraw->SetPerspective(true);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, iTx - twdt/2, iTy - thgt/2, twdt, thgt, 1.0f, pForObj->Color, &trf); lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, iTx - twdt/2, iTy - thgt/2, twdt, thgt, pForObj->Color, &trf);
lpDDraw->SetPerspective(false); lpDDraw->SetPerspective(false);
lpDDraw->SetMeshTransform(NULL); lpDDraw->SetMeshTransform(NULL);
} }
@ -1199,7 +1199,7 @@ void C4GraphicsOverlay::DrawPicture(C4Facet &cgo, C4Object *pForObj, C4DrawTrans
if(trans) trf *= *trans; if(trans) trf *= *trans;
lpDDraw->SetPerspective(true); lpDDraw->SetPerspective(true);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, cgo.X, cgo.Y, pForObj->Shape.Wdt, pForObj->Shape.Hgt, 1.0f, pForObj->Color, &trf); lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, cgo.X, cgo.Y, pForObj->Shape.Wdt, pForObj->Shape.Hgt, pForObj->Color, &trf);
lpDDraw->SetPerspective(false); lpDDraw->SetPerspective(false);
lpDDraw->SetMeshTransform(NULL); lpDDraw->SetMeshTransform(NULL);
} }

View File

@ -551,10 +551,20 @@ void C4Object::DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy,
C4Value value; C4Value value;
GetPropertyVal(P_MeshTransformation, value); GetPropertyVal(P_MeshTransformation, value);
StdMeshMatrix matrix; StdMeshMatrix matrix;
if (C4ValueToMatrix(value, &matrix)) if (!C4ValueToMatrix(value, &matrix))
lpDDraw->SetMeshTransform(&matrix); matrix = StdMeshMatrix::Identity();
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, tx, ty, twdt, thgt, twdt/fwdt, Color, transform); if(twdt != fwdt || thgt != fhgt)
{
// Also scale Z so that the mesh is not totally distorted and
// so that normals halfway keep pointing into sensible directions.
// We don't have a better guess so use the geometric mean for Z scale.
matrix = StdMeshMatrix::Scale(twdt/fwdt,thgt/fhgt,std::sqrt(twdt*thgt/(fwdt*fhgt))) * matrix;
}
lpDDraw->SetMeshTransform(&matrix);
lpDDraw->RenderMesh(*pMeshInstance, cgo.Surface, tx, ty, twdt, thgt, Color, transform);
lpDDraw->SetMeshTransform(NULL); lpDDraw->SetMeshTransform(NULL);
break; break;
} }

View File

@ -270,7 +270,7 @@ void CStdD3D::PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool
} }
} }
void CStdD3D::PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform *pTransform) void CStdD3D::PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform *pTransform)
{ {
// TODO: Implement this // TODO: Implement this
for (int x = 0; x < twdt; x += 10) for (int x = 0; x < twdt; x += 10)

View File

@ -130,7 +130,7 @@ public:
// Surface // Surface
bool PrepareRendering(SURFACE sfcToSurface); // check if/make rendering possible to given surface bool PrepareRendering(SURFACE sfcToSurface); // check if/make rendering possible to given surface
// Blit // Blit
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform* pTransform); virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform* pTransform);
void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact); void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact);
bool BlitTex2Window(CTexRef *pTexRef, HDC hdcTarget, RECT &rtFrom, RECT &rtTo); bool BlitTex2Window(CTexRef *pTexRef, HDC hdcTarget, RECT &rtFrom, RECT &rtTo);
bool BlitSurface2Window(SURFACE sfcSource, int fX, int fY, int fWdt, int fHgt, HWND hWnd, int tX, int tY, int tWdt, int tHgt); bool BlitSurface2Window(SURFACE sfcSource, int fX, int fY, int fWdt, int fHgt, HWND hWnd, int tX, int tY, int tWdt, int tHgt);

View File

@ -677,7 +677,7 @@ bool CStdDDraw::Blit(SURFACE sfcSource, float fx, float fy, float fwdt, float fh
return true; return true;
} }
bool CStdDDraw::RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform* pTransform) bool CStdDDraw::RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform* pTransform)
{ {
// TODO: Emulate rendering // TODO: Emulate rendering
if (!sfcTarget->IsRenderTarget()) return false; if (!sfcTarget->IsRenderTarget()) return false;
@ -693,7 +693,7 @@ bool CStdDDraw::RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float t
if(MeshTransform) mat = *MeshTransform * mat; if(MeshTransform) mat = *MeshTransform * mat;
instance.ReorderFaces(&mat); instance.ReorderFaces(&mat);
// Render mesh // Render mesh
PerformMesh(instance, tx, ty, twdt, thgt, scale, dwPlayerColor, pTransform); PerformMesh(instance, tx, ty, twdt, thgt, dwPlayerColor, pTransform);
// success // success
return true; return true;
} }

View File

@ -259,9 +259,9 @@ public:
bool Blit(SURFACE sfcSource, float fx, float fy, float fwdt, float fhgt, bool Blit(SURFACE sfcSource, float fx, float fy, float fwdt, float fhgt,
SURFACE sfcTarget, float tx, float ty, float twdt, float thgt, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt,
bool fSrcColKey=false, CBltTransform *pTransform=NULL); bool fSrcColKey=false, CBltTransform *pTransform=NULL);
bool RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform* pTransform); // Call PrepareMaterial with Mesh's material before bool RenderMesh(StdMeshInstance &instance, SURFACE sfcTarget, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform* pTransform); // Call PrepareMaterial with Mesh's material before
virtual void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact) = 0; virtual void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact) = 0;
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform* pTransform) = 0; virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform* pTransform) = 0;
bool Blit8(SURFACE sfcSource, int fx, int fy, int fwdt, int fhgt, // force 8bit-blit (inline) bool Blit8(SURFACE sfcSource, int fx, int fy, int fwdt, int fhgt, // force 8bit-blit (inline)
SURFACE sfcTarget, int tx, int ty, int twdt, int thgt, SURFACE sfcTarget, int tx, int ty, int twdt, int thgt,
bool fSrcColKey=false, CBltTransform *pTransform=NULL); bool fSrcColKey=false, CBltTransform *pTransform=NULL);

View File

@ -1100,7 +1100,7 @@ namespace
} }
} }
void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform* pTransform) void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform* pTransform)
{ {
// Field of View for perspective projection, in degrees // Field of View for perspective projection, in degrees
static const float FOV = 60.0f; static const float FOV = 60.0f;
@ -1186,7 +1186,7 @@ void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float tw
// by MeshTransformation, so use GetBoundingRadius to be safe. // by MeshTransformation, so use GetBoundingRadius to be safe.
// Note this still fails if mesh is scaled in Z direction or // Note this still fails if mesh is scaled in Z direction or
// there are attached meshes. // there are attached meshes.
const float scz = 1.0/(mesh.GetBoundingRadius()*scale); const float scz = 1.0/(mesh.GetBoundingRadius());
glTranslatef(dx, dy, 0.0f); glTranslatef(dx, dy, 0.0f);
glScalef(1.0f, 1.0f, scz); glScalef(1.0f, 1.0f, scz);
@ -1281,12 +1281,6 @@ void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float tw
gluLookAt(EyeX, EyeY, EyeZ, MeshCenter.x, MeshCenter.y, MeshCenter.z, UpX, UpY, UpZ); gluLookAt(EyeX, EyeY, EyeZ, MeshCenter.x, MeshCenter.y, MeshCenter.z, UpX, UpY, UpZ);
} }
if(scale != 1)
{
glScalef(scale, scale, scale);
glEnable(GL_NORMALIZE);
}
// Apply mesh transformation matrix // Apply mesh transformation matrix
if (MeshTransform) if (MeshTransform)
{ {
@ -1303,15 +1297,13 @@ void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float tw
if (det < 0) parity = !parity; if (det < 0) parity = !parity;
// Renormalize if transformation resizes the mesh // Renormalize if transformation resizes the mesh
// for lighting to be correct // for lighting to be correct.
// TODO: Also needs to check for orthonormality to be correct
if (det != 1 && det != -1) if (det != 1 && det != -1)
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
// Apply Matrix in the coordinate system in which the mesh // Apply MeshTransformation (in the Mesh's coordinate system)
// is centered, not in the mesh's coordinate system.
glTranslatef(MeshCenter.x, MeshCenter.y, MeshCenter.z);
glMultMatrixf(Matrix); glMultMatrixf(Matrix);
glTranslatef(-MeshCenter.x, -MeshCenter.y, -MeshCenter.z);
} }
// Convert from Ogre to Clonk coordinate system // Convert from Ogre to Clonk coordinate system

View File

@ -111,7 +111,7 @@ public:
// Blit // Blit
void SetupTextureEnv(bool fMod2, bool landscape); void SetupTextureEnv(bool fMod2, bool landscape);
virtual void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact); virtual void PerformBlt(CBltData &rBltData, CTexRef *pTex, DWORD dwModClr, bool fMod2, bool fExact);
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, float scale, DWORD dwPlayerColor, CBltTransform* pTransform); virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, CBltTransform* pTransform);
virtual void BlitLandscape(SURFACE sfcSource, float fx, float fy, virtual void BlitLandscape(SURFACE sfcSource, float fx, float fy,
SURFACE sfcTarget, float tx, float ty, float wdt, float hgt, const SURFACE textures[]); SURFACE sfcTarget, float tx, float ty, float wdt, float hgt, const SURFACE textures[]);
void FillBG(DWORD dwClr=0); void FillBG(DWORD dwClr=0);

View File

@ -40,7 +40,7 @@ public:
virtual bool PrepareRendering(SURFACE) { return true; } virtual bool PrepareRendering(SURFACE) { return true; }
virtual void FillBG(DWORD dwClr=0) { } virtual void FillBG(DWORD dwClr=0) { }
virtual void PerformBlt(CBltData &, CTexRef *, DWORD, bool, bool) { } virtual void PerformBlt(CBltData &, CTexRef *, DWORD, bool, bool) { }
virtual void PerformMesh(StdMeshInstance &, float, float, float, float, float, DWORD, CBltTransform* pTransform) { } virtual void PerformMesh(StdMeshInstance &, float, float, float, float, DWORD, CBltTransform* pTransform) { }
virtual void PerformLine(SURFACE, float, float, float, float, DWORD) { } virtual void PerformLine(SURFACE, float, float, float, float, DWORD) { }
virtual void DrawQuadDw(SURFACE, float *, DWORD, DWORD, DWORD, DWORD) { } virtual void DrawQuadDw(SURFACE, float *, DWORD, DWORD, DWORD, DWORD) { }
virtual void PerformPix(SURFACE, float, float, DWORD) { } virtual void PerformPix(SURFACE, float, float, DWORD) { }