1) the actor TILT and PITCH has a bad influence on shadows rotation and position.
2) the actor YAW hasn't any influence. it doesn't rotate with actor.
can we fix theese issues? i think that the better result for our games is to have stenciled shadows on meshes structures and bitmap shadows (you can set the alpha to make them quite similar to stenciled) for fast dynamic objects.
I think that this is the bitmap shadow code:
Code: Select all
if(RenderBitmapShadow)
{
// end change gekido
if(theEntry->ShadowSize > 0.0f && theEntry->ShadowBitmap) // changed QD 06/26/04
{
geVec3d Pos1, Pos2;
GE_Collision Collision;
geVec3d right, up;
GE_LVertex vertex[4];
geVec3d Axis[3];
int major, i;
geVec3d Impact, normal;
#define fab(a) (a > 0 ? a : -a)
// changed Pickles Jul 04 -- PWX
//Pos1 = thePosition.Translation;
geXForm3d BoneXForm;
geActor_GetBoneTransformByIndex(theEntry->Actor, 0, &BoneXForm);
Pos1 = BoneXForm.Translation;
// end changed Pickles Jul 04 -- PWX
Pos2 = Pos1;
Pos2.Y -= 30000.0f;
geWorld_Collision(CCD->World(), NULL, NULL,
&Pos1, &Pos2, GE_CONTENTS_SOLID_CLIP | GE_CONTENTS_WINDOW,
GE_COLLIDE_MODELS, 0x0, NULL, NULL, &Collision);
//CCD->Collision()->CheckForWCollision(NULL, NULL,
//Pos1, Pos2, &Collision, theEntry->Actor);
Impact = Collision.Impact;
normal = Collision.Plane.Normal;
// changed QD 12/15/05
// can't be negative (sqrt!)
// float dist = (float)fabs(geVec3d_DistanceBetween(&Pos1, &Impact));
// if(dist<0.0f)
// dist = 0.0f;
float dist = geVec3d_DistanceBetween(&Pos1, &Impact);
if(dist<(theEntry->ShadowSize*2.0f))
{
for(i=0; i<4; i++)
{
// texture coordinates
vertex[i].u = 0.0f;
vertex[i].v = 0.0f;
// color
vertex[i].r = 24.0f;
vertex[i].g = 24.0f;
vertex[i].b = 24.0f;
// changed QD 06/26/04
// changed RF064
// vertex[i].a = ShadowAlpha;
// end change RF064
vertex[i].a = theEntry->ShadowAlpha;
// end change QD
}
vertex[3].u = 1.0f;
vertex[2].u = 1.0f;
vertex[2].v = 1.0f;
vertex[1].v = 1.0f;
for(i=0; i<3; i++)
{
Axis[i].X = 0.0f;
Axis[i].Y = 0.0f;
Axis[i].Z = 0.0f;
}
Axis[0].X = 1.0f;
Axis[1].Y = 1.0f;
Axis[2].Z = 1.0f;
major = 0;
if(fab(normal.Y) > fab(normal.X))
{
major = 1;
if(fab(normal.Z) > fab(normal.Y))
major = 2;
}
else
{
if(fab(normal.Z) > fab(normal.X))
major = 2;
}
if(fab(normal.X) == 1.0f || fab(normal.Y) == 1.0f || fab(normal.Z) == 1.0f)
{
if((major == 0 && normal.X > 0) || major == 1)
{
right.X = 0.0f;
right.Y = 0.0f;
right.Z = -1.0f;
}
else if(major == 0)
{
right.X = 0.0f;
right.Y = 0.0f;
right.Z = 1.0f;
}
else
{
right.X = normal.Z;
right.Y = 0.0f;
right.Z = 0.0f;
}
}
else
geVec3d_CrossProduct(&Axis[major], &normal, &right);
// start Pickles Jul 04
InVector(theEntry->Actor,&up);
LeftVector(theEntry->Actor,&right);
geVec3d_Inverse(&right);
// end Pickles Jul 04
geVec3d_CrossProduct(&normal, &right, &up);
geVec3d_Normalize(&up);
geVec3d_Normalize(&right);
geVec3d_Scale(&right, (theEntry->ShadowSize-(dist*0.5f))*0.5f, &right);
geVec3d_Scale(&up, (theEntry->ShadowSize-(dist*0.5f))*0.5f, &up);
geVec3d_MA(&Impact, 0.4f, &normal, &Impact);
// calculate vertices from corners
vertex[1].X = Impact.X + ((-right.X - up.X));
vertex[1].Y = Impact.Y + ((-right.Y - up.Y));
vertex[1].Z = Impact.Z + ((-right.Z - up.Z));
vertex[2].X = Impact.X + ((right.X - up.X));
vertex[2].Y = Impact.Y + ((right.Y - up.Y));
vertex[2].Z = Impact.Z + ((right.Z - up.Z));
vertex[3].X = Impact.X + ((right.X + up.X));
vertex[3].Y = Impact.Y + ((right.Y + up.Y));
vertex[3].Z = Impact.Z + ((right.Z + up.Z));
vertex[0].X = Impact.X + ((-right.X + up.X));
vertex[0].Y = Impact.Y + ((-right.Y + up.Y));
vertex[0].Z = Impact.Z + ((-right.Z + up.Z));
geWorld_AddPolyOnce(CCD->World(),
vertex,
4,
// changed QD 06/26/04
// changed RF064
// ShadowBitmap,
// end change RF064
theEntry->ShadowBitmap,
// end change QD
GE_TEXTURED_POLY,
GE_RENDER_DO_NOT_OCCLUDE_OTHERS | GE_RENDER_DEPTH_SORT_BF,
1.0f);
}
}
// end change RF063
}