📄 t3dlib8.cpp
字号:
vertex_ccodes[2] = CLIP_CODE_GZ;
}
else
if (curr_poly->tvlist[2].z < cam->near_clip_z)
{
vertex_ccodes[2] = CLIP_CODE_LZ;
}
else
{
vertex_ccodes[2] = CLIP_CODE_IZ;
num_verts_in++;
}
// test for trivial rejections, polygon completely beyond far or near
// z clipping planes
if ( ((vertex_ccodes[0] == CLIP_CODE_GZ) &&
(vertex_ccodes[1] == CLIP_CODE_GZ) &&
(vertex_ccodes[2] == CLIP_CODE_GZ) ) ||
((vertex_ccodes[0] == CLIP_CODE_LZ) &&
(vertex_ccodes[1] == CLIP_CODE_LZ) &&
(vertex_ccodes[2] == CLIP_CODE_LZ) ) )
{
// clip the poly completely out of frustrum
SET_BIT(curr_poly->state, POLY4DV2_STATE_CLIPPED);
// move on to next polygon
continue;
} // end if
// test if any vertex has protruded beyond near clipping plane?
if ( ( (vertex_ccodes[0] | vertex_ccodes[1] | vertex_ccodes[2]) & CLIP_CODE_LZ) )
{
// at this point we are ready to clip the polygon to the near
// clipping plane no need to clip to the far plane since it can't
// possible cause problems. We have two cases: case 1: the triangle
// has 1 vertex interior to the near clipping plane and 2 vertices
// exterior, OR case 2: the triangle has two vertices interior of
// the near clipping plane and 1 exterior
// step 1: classify the triangle type based on number of vertices
// inside/outside
// case 1: easy case :)
if (num_verts_in == 1)
{
// we need to clip the triangle against the near clipping plane
// the clipping procedure is done to each edge leading away from
// the interior vertex, to clip we need to compute the intersection
// with the near z plane, this is done with a parametric equation of
// the edge, once the intersection is computed the old vertex position
// is overwritten along with re-computing the texture coordinates, if
// there are any, what's nice about this case, is clipping doesn't
// introduce any added vertices, so we can overwrite the old poly
// the other case below results in 2 polys, so at very least one has
// to be added to the end of the rendering list -- bummer
// step 1: find vertex index for interior vertex
if ( vertex_ccodes[0] == CLIP_CODE_IZ)
{ v0 = 0; v1 = 1; v2 = 2; }
else
if (vertex_ccodes[1] == CLIP_CODE_IZ)
{ v0 = 1; v1 = 2; v2 = 0; }
else
{ v0 = 2; v1 = 0; v2 = 1; }
// step 2: clip each edge
// basically we are going to generate the parametric line p = v0 + v01*t
// then solve for t when the z component is equal to near z, then plug that
// back into to solve for x,y of the 3D line, we could do this with high
// level code and parametric lines, but to save time, lets do it manually
// clip edge v0->v1
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &v);
// the intersection occurs when z = near z, so t =
t1 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
// now plug t back in and find x,y intersection with the plane
xi = curr_poly->tvlist[v0].x + v.x * t1;
yi = curr_poly->tvlist[v0].y + v.y * t1;
// now overwrite vertex with new vertex
curr_poly->tvlist[v1].x = xi;
curr_poly->tvlist[v1].y = yi;
curr_poly->tvlist[v1].z = cam->near_clip_z;
// clip edge v0->v2
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);
// the intersection occurs when z = near z, so t =
t2 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
// now plug t back in and find x,y intersection with the plane
xi = curr_poly->tvlist[v0].x + v.x * t2;
yi = curr_poly->tvlist[v0].y + v.y * t2;
// now overwrite vertex with new vertex
curr_poly->tvlist[v2].x = xi;
curr_poly->tvlist[v2].y = yi;
curr_poly->tvlist[v2].z = cam->near_clip_z;
// now that we have both t1, t2, check if the poly is textured, if so clip
// texture coordinates
if (curr_poly->attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
{
ui = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v1].u0 - curr_poly->tvlist[v0].u0)*t1;
vi = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v1].v0 - curr_poly->tvlist[v0].v0)*t1;
curr_poly->tvlist[v1].u0 = ui;
curr_poly->tvlist[v1].v0 = vi;
ui = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v2].u0 - curr_poly->tvlist[v0].u0)*t2;
vi = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v2].v0 - curr_poly->tvlist[v0].v0)*t2;
curr_poly->tvlist[v2].u0 = ui;
curr_poly->tvlist[v2].v0 = vi;
} // end if textured
// finally, we have obliterated our pre-computed normal length
// it needs to be recomputed!!!!
// build u, v
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &u);
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);
// compute cross product
VECTOR4D_Cross(&u, &v, &n);
// compute length of normal accurately and store in poly nlength
// +- epsilon later to fix over/underflows
curr_poly->nlength = VECTOR4D_Length_Fast(&n);
} // end if
else
if (num_verts_in == 2)
{ // num_verts = 2
// must be the case with num_verts_in = 2
// we need to clip the triangle against the near clipping plane
// the clipping procedure is done to each edge leading away from
// the interior vertex, to clip we need to compute the intersection
// with the near z plane, this is done with a parametric equation of
// the edge, however unlike case 1 above, the triangle will be split
// into two triangles, thus during the first clip, we will store the
// results into a new triangle at the end of the rendering list, and
// then on the last clip we will overwrite the triangle being clipped
// step 0: copy the polygon
memcpy(&temp_poly, curr_poly, sizeof(POLYF4DV2) );
// step 1: find vertex index for exterior vertex
if ( vertex_ccodes[0] == CLIP_CODE_LZ)
{ v0 = 0; v1 = 1; v2 = 2; }
else
if (vertex_ccodes[1] == CLIP_CODE_LZ)
{ v0 = 1; v1 = 2; v2 = 0; }
else
{ v0 = 2; v1 = 0; v2 = 1; }
// step 2: clip each edge
// basically we are going to generate the parametric line p = v0 + v01*t
// then solve for t when the z component is equal to near z, then plug that
// back into to solve for x,y of the 3D line, we could do this with high
// level code and parametric lines, but to save time, lets do it manually
// clip edge v0->v1
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &v);
// the intersection occurs when z = near z, so t =
t1 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
// now plug t back in and find x,y intersection with the plane
x01i = curr_poly->tvlist[v0].x + v.x * t1;
y01i = curr_poly->tvlist[v0].y + v.y * t1;
// clip edge v0->v2
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);
// the intersection occurs when z = near z, so t =
t2 = ( (cam->near_clip_z - curr_poly->tvlist[v0].z) / v.z );
// now plug t back in and find x,y intersection with the plane
x02i = curr_poly->tvlist[v0].x + v.x * t2;
y02i = curr_poly->tvlist[v0].y + v.y * t2;
// now we have both intersection points, we must overwrite the inplace
// polygon's vertex 0 with the intersection point, this poly 1 of 2 from
// the split
// now overwrite vertex with new vertex
curr_poly->tvlist[v0].x = x01i;
curr_poly->tvlist[v0].y = y01i;
curr_poly->tvlist[v0].z = cam->near_clip_z;
// now comes the hard part, we have to carefully create a new polygon
// from the 2 intersection points and v2, this polygon will be inserted
// at the end of the rendering list, but for now, we are building it up
// in temp_poly
// so leave v2 alone, but overwrite v1 with v01, and overwrite v0 with v02
temp_poly.tvlist[v1].x = x01i;
temp_poly.tvlist[v1].y = y01i;
temp_poly.tvlist[v1].z = cam->near_clip_z;
temp_poly.tvlist[v0].x = x02i;
temp_poly.tvlist[v0].y = y02i;
temp_poly.tvlist[v0].z = cam->near_clip_z;
// now that we have both t1, t2, check if the poly is textured, if so clip
// texture coordinates
if (curr_poly->attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)
{
// compute poly 1 new texture coordinates from split
u01i = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v1].u0 - curr_poly->tvlist[v0].u0)*t1;
v01i = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v1].v0 - curr_poly->tvlist[v0].v0)*t1;
// compute poly 2 new texture coordinates from split
u02i = curr_poly->tvlist[v0].u0 + (curr_poly->tvlist[v2].u0 - curr_poly->tvlist[v0].u0)*t2;
v02i = curr_poly->tvlist[v0].v0 + (curr_poly->tvlist[v2].v0 - curr_poly->tvlist[v0].v0)*t2;
// write them all at the same time
// poly 1
curr_poly->tvlist[v0].u0 = u01i;
curr_poly->tvlist[v0].v0 = v01i;
// poly 2
temp_poly.tvlist[v0].u0 = u02i;
temp_poly.tvlist[v0].v0 = v02i;
temp_poly.tvlist[v1].u0 = u01i;
temp_poly.tvlist[v1].v0 = v01i;
} // end if textured
// finally, we have obliterated our pre-computed normal lengths
// they need to be recomputed!!!!
// poly 1 first, in place
// build u, v
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v1].v, &u);
VECTOR4D_Build(&curr_poly->tvlist[v0].v, &curr_poly->tvlist[v2].v, &v);
// compute cross product
VECTOR4D_Cross(&u, &v, &n);
// compute length of normal accurately and store in poly nlength
// +- epsilon later to fix over/underflows
curr_poly->nlength = VECTOR4D_Length_Fast(&n);
// now poly 2, temp_poly
// build u, v
VECTOR4D_Build(&temp_poly.tvlist[v0].v, &temp_poly.tvlist[v1].v, &u);
VECTOR4D_Build(&temp_poly.tvlist[v0].v, &temp_poly.tvlist[v2].v, &v);
// compute cross product
VECTOR4D_Cross(&u, &v, &n);
// compute length of normal accurately and store in poly nlength
// +- epsilon later to fix over/underflows
temp_poly.nlength = VECTOR4D_Length_Fast(&n);
// now we are good to go, insert the polygon into list
// if the poly won't fit, it won't matter, the function will
// just return 0
Insert_POLYF4DV2_RENDERLIST4DV2(rend_list, &temp_poly);
} // end else
} // end if near_z clipping has occured
} // end if z planes
} // end for poly
} // end Clip_Polys_RENDERLIST4DV2
////////////////////////////////////////////////////////////
int Generate_Terrain_OBJECT4DV2(OBJECT4DV2_PTR obj, // pointer to object
float twidth, // width in world coords on x-axis
float theight, // height (length) in world coords on z-axis
float vscale, // vertical scale of terrain
char *height_map_file, // filename of height bitmap encoded in 256 colors
char *texture_map_file, // filename of texture map
int rgbcolor, // color of terrain if no texture
VECTOR4D_PTR pos, // initial position
VECTOR4D_PTR rot, // initial rotations
int poly_attr) // the shading attributes we would like
{
// this function generates a terrain of width x height in the x-z plane
// the terrain is defined by a height field encoded as color values
// of a 256 color texture, 0 being ground level 255 being 1.0, this value
// is scaled by vscale for the height of each point in the height field
// the height field generated will be composed of triangles where each vertex
// in the height field is derived from the height map, thus if the height map
// is 256 x 256 points then the final mesh will be (256-1) x (256-1) polygons
// with a absolute world size of width x height (in the x-z plane)
// also if there is a texture map file then it will be mapped onto the terrain
// and texture coordinates will be generated
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -