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())
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(30,0,1,0),Trans_Scale(1200)), this);
if(GetDirection() == COMD_Right) SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(-110,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_Translate(0,1000,5000),Trans_Rotate(-110,0,1,0)), this);
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());
if(velocity < 1) return Clonk_WalkStand;
if(velocity < 10) return Clonk_WalkWalk;
@ -2021,7 +2021,7 @@ HangOnto = {
SetProperty("Name", "Clonk", def);
// 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);
}

View File

@ -225,5 +225,5 @@ func Deselection()
*/
func Definition(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) {
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)
{
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",
}, }, 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->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->SetMeshTransform(NULL);

View File

@ -1089,7 +1089,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
if (C4ValueToMatrix(value, &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);
}
else
@ -1116,7 +1116,7 @@ void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByP
C4DrawTransform trf(Transform, float(iTx), float(iTy));
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->SetMeshTransform(NULL);
}
@ -1199,7 +1199,7 @@ void C4GraphicsOverlay::DrawPicture(C4Facet &cgo, C4Object *pForObj, C4DrawTrans
if(trans) trf *= *trans;
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->SetMeshTransform(NULL);
}

View File

@ -551,10 +551,20 @@ void C4Object::DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy,
C4Value value;
GetPropertyVal(P_MeshTransformation, value);
StdMeshMatrix matrix;
if (C4ValueToMatrix(value, &matrix))
lpDDraw->SetMeshTransform(&matrix);
if (!C4ValueToMatrix(value, &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);
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
for (int x = 0; x < twdt; x += 10)

View File

@ -130,7 +130,7 @@ public:
// Surface
bool PrepareRendering(SURFACE sfcToSurface); // check if/make rendering possible to given surface
// 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);
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);

View File

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

View File

@ -259,9 +259,9 @@ public:
bool Blit(SURFACE sfcSource, float fx, float fy, float fwdt, float fhgt,
SURFACE sfcTarget, float tx, float ty, float twdt, float thgt,
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 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)
SURFACE sfcTarget, int tx, int ty, int twdt, int thgt,
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
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.
// Note this still fails if mesh is scaled in Z direction or
// there are attached meshes.
const float scz = 1.0/(mesh.GetBoundingRadius()*scale);
const float scz = 1.0/(mesh.GetBoundingRadius());
glTranslatef(dx, dy, 0.0f);
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);
}
if(scale != 1)
{
glScalef(scale, scale, scale);
glEnable(GL_NORMALIZE);
}
// Apply mesh transformation matrix
if (MeshTransform)
{
@ -1303,15 +1297,13 @@ void CStdGL::PerformMesh(StdMeshInstance &instance, float tx, float ty, float tw
if (det < 0) parity = !parity;
// 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)
glEnable(GL_NORMALIZE);
// Apply Matrix in the coordinate system in which the mesh
// is centered, not in the mesh's coordinate system.
glTranslatef(MeshCenter.x, MeshCenter.y, MeshCenter.z);
// Apply MeshTransformation (in the Mesh's coordinate system)
glMultMatrixf(Matrix);
glTranslatef(-MeshCenter.x, -MeshCenter.y, -MeshCenter.z);
}
// Convert from Ogre to Clonk coordinate system

View File

@ -111,7 +111,7 @@ public:
// Blit
void SetupTextureEnv(bool fMod2, bool landscape);
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,
SURFACE sfcTarget, float tx, float ty, float wdt, float hgt, const SURFACE textures[]);
void FillBG(DWORD dwClr=0);

View File

@ -40,7 +40,7 @@ public:
virtual bool PrepareRendering(SURFACE) { return true; }
virtual void FillBG(DWORD dwClr=0) { }
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 DrawQuadDw(SURFACE, float *, DWORD, DWORD, DWORD, DWORD) { }
virtual void PerformPix(SURFACE, float, float, DWORD) { }