brender-1997/d3drend/mapping.c
2022-05-03 14:31:40 -07:00

368 lines
12 KiB
C

/*
* Copyright (c) 1993-1995 Argonaut Technologies Limited. All rights reserved.
*
* $Id: mapping.c 1.2 1997/08/11 14:25:53 jon Exp JON $
* $Locker: JON $
*
* Generation of U,V components
*/
#include "drv.h"
#include "shortcut.h"
#include "brassert.h"
#include "math_ip.h"
BR_RCS_ID("$Id: mapping.c 1.2 1997/08/11 14:25:53 jon Exp JON $");
#define APPLY_UV(du,dv,su,sv) do { \
du = BrScalarToFloat(BR_ADD( \
BR_MAC2(self->state.surface.map_transform.m[0][0],su, \
self->state.surface.map_transform.m[1][0],sv), \
self->state.surface.map_transform.m[2][0])); \
dv = BrScalarToFloat(BR_ADD( \
BR_MAC2(self->state.surface.map_transform.m[0][1],su, \
self->state.surface.map_transform.m[1][1],sv), \
self->state.surface.map_transform.m[2][1])); \
} while (0)
/*
* Generate U,V for environment assuming infinite eye
*/
void SURFACE_CALL SurfaceMapEnvironmentInfinite(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *normal, br_colour colour, D3DTLVERTEX *d3dtlv)
{
br_vector3 r,wr;
br_scalar d,cu,cv;
/*
* Generate reflected vector
*
* - - - - -
* R = 2N(N.E)-E
*/
d = BR_CONST_MUL(BrVector3Dot(&scache.eye_m_normalised,normal),2);
BrVector3Scale(&r,normal,d);
BrVector3Sub(&r,&r,&scache.eye_m_normalised);
/*
* If there is an environment frame, rotate vector into it
*/
if(self->state.matrix.view_to_environment_hint != BRT_DONT_CARE) {
BrMatrix34ApplyV(&wr, &r, &scache.model_to_environment);
BrVector3Normalise(&wr, &wr);
} else
wr = r;
/*
* Convert vector to environment coordinates
*/
cu = BrAngleToScalar(BR_ATAN2(wr.v[0],-wr.v[2]));
#if 0
cv = BrAngleToScalar(BR_ASIN(-wr.v[1]/2+BR_SCALAR(0.5)));
#else
cv = -wr.v[1]/2+BR_SCALAR(0.5);
#endif
APPLY_UV(d3dtlv->dvTU,d3dtlv->dvTV,cu,cv);
}
/*
* Generate U,V for environment assuming local eye
*/
void SURFACE_CALL SurfaceMapEnvironmentLocal(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *normal, br_colour colour, D3DTLVERTEX *d3dtlv)
{
br_vector3 eye;
br_vector3 r,wr;
br_scalar d,cu,cv;
/*
* Generate eye vector -
*/
BrVector3Sub(&eye,&scache.eye_m,p);
BrVector3Normalise(&eye, &eye);
/*
* Generate reflected vector
*
* - - - - -
* R = 2N(N.E)-E
*/
d = BR_CONST_MUL(BrVector3Dot(&eye,normal),2);
BrVector3Scale(&r,normal,d);
BrVector3Sub(&r,&r,&eye);
/*
* If there is an environment frame, rotate vector into it
*/
if(self->state.matrix.view_to_environment_hint != BRT_DONT_CARE) {
BrMatrix34ApplyV(&wr, &r, &scache.model_to_environment);
BrVector3Normalise(&wr, &wr);
} else
wr = r;
/*
* Convert vector to environment coordinates
*/
cu = BrAngleToScalar(BR_ATAN2(wr.v[0],-wr.v[2]));
#if 0
cv = BrAngleToScalar(BR_ASIN(-wr.v[1]/2+BR_SCALAR(0.5)));
#else
cv = -wr.v[1]/2+BR_SCALAR(0.5);
#endif
APPLY_UV(d3dtlv->dvTU,d3dtlv->dvTV,cu,cv);
}
/*
* Take U,V from vertex y,z
*/
void SURFACE_CALL SurfaceMapGeometryX(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
APPLY_UV(d3dtlv->dvTU,d3dtlv->dvTV,p->v[1],p->v[2]);
}
void SURFACE_CALL SurfaceMapGeometryY(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
APPLY_UV(d3dtlv->dvTU,d3dtlv->dvTV,p->v[2],p->v[0]);
}
void SURFACE_CALL SurfaceMapGeometryZ(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
APPLY_UV(d3dtlv->dvTU,d3dtlv->dvTV,p->v[0],p->v[1]);
}
/*
* Take U,V from vertex u,v
*/
void SURFACE_CALL SurfaceMapGeometryMap(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
APPLY_UV(d3dtlv->dvTU,d3dtlv->dvTV,map->v[0],map->v[1]);
}
/*
* Scale only
*/
void SURFACE_CALL SurfaceMapGeometryMapScale(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
d3dtlv->dvTU = BrScalarToFloat(BR_MUL(self->state.surface.map_transform.m[0][0],map->v[0]));
d3dtlv->dvTV = BrScalarToFloat(BR_MUL(self->state.surface.map_transform.m[1][1],map->v[1]));
}
/*
* Scale and translate only
*/
void SURFACE_CALL SurfaceMapGeometryMapScaleTranslate(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
d3dtlv->dvTU = BrScalarToFloat(BR_ADD(BR_MUL(self->state.surface.map_transform.m[0][0],map->v[0]),self->state.surface.map_transform.m[2][0]));
d3dtlv->dvTV = BrScalarToFloat(BR_ADD(BR_MUL(self->state.surface.map_transform.m[1][1],map->v[1]),self->state.surface.map_transform.m[2][1]));
}
void SURFACE_CALL SurfaceMapGeometryMapCopy(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
d3dtlv->dvTU = BrScalarToFloat(map->v[0]);
d3dtlv->dvTV = BrScalarToFloat(map->v[1]);
}
#if BASED_FIXED
/*
* Take U,V from vertex, assumeing offset == 0 and scales are a power of 2
*/
void SURFACE_CALL SurfaceMapGeometryMapShift(br_renderer *self,
br_vector3 *p, br_vector2 *map, br_vector3 *n, br_colour colour, D3DTLVERTEX *d3dtlv)
{
d3dtlv->dvTU = BrScalarToFloat((map->v[0] << self->state.cache.u_shift) + self->state.surface.map_transform.m[2][0]);
d3dtlv->dvTV = BrScalarToFloat((map->v[1] << self->state.cache.v_shift) + self->state.surface.map_transform.m[2][1]);
}
#endif
void BR_ASM_CALL OpTriangleMapQuadIndexed(struct brp_block *block, WORD *index, br_boolean modified, struct v11face *fp, struct temp_face *tfp)
{
br_vector2 *qv = (br_vector2*)&rend.renderer->state.cache.quad_transformed;
switch (rend.face_flags[fp-rend.faces] & BR_FACEF_QUAD_MASK) {
case BR_FACEF_QUAD_012:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[0].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[0].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[1].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[1].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[2].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[2].v[1]);
break;
case BR_FACEF_QUAD_123:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[1].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[1].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[2].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[2].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[3].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[3].v[1]);
break;
case BR_FACEF_QUAD_230:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[2].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[2].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[3].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[3].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[0].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[0].v[1]);
break;
case BR_FACEF_QUAD_301:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[3].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[3].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[0].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[0].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[1].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[1].v[1]);
break;
case BR_FACEF_QUAD_032:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[0].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[0].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[3].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[3].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[2].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[2].v[1]);
break;
case BR_FACEF_QUAD_103:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[1].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[1].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[0].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[0].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[3].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[3].v[1]);
break;
case BR_FACEF_QUAD_210:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[2].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[2].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[1].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[1].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[0].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[0].v[1]);
break;
case BR_FACEF_QUAD_321:
rend.d3dtlvertices[index[0]].dvTU = BrScalarToFloat(qv[3].v[0]);
rend.d3dtlvertices[index[0]].dvTV = BrScalarToFloat(qv[3].v[1]);
rend.d3dtlvertices[index[1]].dvTU = BrScalarToFloat(qv[2].v[0]);
rend.d3dtlvertices[index[1]].dvTV = BrScalarToFloat(qv[2].v[1]);
rend.d3dtlvertices[index[2]].dvTU = BrScalarToFloat(qv[1].v[0]);
rend.d3dtlvertices[index[2]].dvTV = BrScalarToFloat(qv[1].v[1]);
break;
}
block->chain->render_indexed(block->chain, index, BR_TRUE, fp, tfp);
}
void BR_ASM_CALL OpTriangleMapQuad(struct brp_block *block, WORD *index, D3DTLVERTEX *vertex,
struct v11face *fp, struct temp_face *tfp)
{
br_vector2 *qv = (br_vector2*)&rend.renderer->state.cache.quad_transformed;
switch (rend.face_flags[fp-rend.faces] & BR_FACEF_QUAD_MASK) {
case BR_FACEF_QUAD_012:
vertex[0].dvTU = BrScalarToFloat(qv[0].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[0].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[1].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[1].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[2].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[2].v[1]);
break;
case BR_FACEF_QUAD_123:
vertex[0].dvTU = BrScalarToFloat(qv[1].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[1].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[2].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[2].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[3].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[3].v[1]);
break;
case BR_FACEF_QUAD_230:
vertex[0].dvTU = BrScalarToFloat(qv[2].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[2].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[3].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[3].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[0].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[0].v[1]);
break;
case BR_FACEF_QUAD_301:
vertex[0].dvTU = BrScalarToFloat(qv[3].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[3].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[0].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[0].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[1].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[1].v[1]);
break;
case BR_FACEF_QUAD_032:
vertex[0].dvTU = BrScalarToFloat(qv[0].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[0].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[3].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[3].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[2].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[2].v[1]);
break;
case BR_FACEF_QUAD_103:
vertex[0].dvTU = BrScalarToFloat(qv[1].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[1].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[0].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[0].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[3].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[3].v[1]);
break;
case BR_FACEF_QUAD_210:
vertex[0].dvTU = BrScalarToFloat(qv[2].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[2].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[1].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[1].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[0].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[0].v[1]);
break;
case BR_FACEF_QUAD_321:
vertex[0].dvTU = BrScalarToFloat(qv[3].v[0]);
vertex[0].dvTV = BrScalarToFloat(qv[3].v[1]);
vertex[1].dvTU = BrScalarToFloat(qv[2].v[0]);
vertex[1].dvTV = BrScalarToFloat(qv[2].v[1]);
vertex[2].dvTU = BrScalarToFloat(qv[1].v[0]);
vertex[2].dvTV = BrScalarToFloat(qv[1].v[1]);
break;
}
if (block->chain != NULL)
block->chain->render(block->chain, index, vertex, fp, tfp);
}