📄 t3dlib5.cpp
字号:
default: break;
} // end switch
// finally set the polygon to active
obj->plist[poly].state = POLY4DV1_STATE_ACTIVE;
} // end for poly
// close the file
fclose(fp);
// return success
return(1);
} // end Load_OBJECT4DV1_PLG
//////////////////////////////////////////////////////////////
void Translate_OBJECT4DV1(OBJECT4DV1_PTR obj, VECTOR4D_PTR vt)
{
// NOTE: Not matrix based
// this function translates an object without matrices,
// simply updates the world_pos
VECTOR4D_Add(&obj->world_pos, vt, &obj->world_pos);
} // end Translate_OBJECT4DV1
/////////////////////////////////////////////////////////////
void Scale_OBJECT4DV1(OBJECT4DV1_PTR obj, VECTOR4D_PTR vs)
{
// NOTE: Not matrix based
// this function scales and object without matrices
// modifies the object's local vertex list
// additionally the radii is updated for the object
// for each vertex in the mesh scale the local coordinates by
// vs on a componentwise basis, that is, sx, sy, sz
for (int vertex=0; vertex < obj->num_vertices; vertex++)
{
obj->vlist_local[vertex].x*=vs->x;
obj->vlist_local[vertex].y*=vs->y;
obj->vlist_local[vertex].z*=vs->z;
// leave w unchanged, always equal to 1
} // end for vertex
// now since the object is scaled we have to do something with
// the radii calculation, but we don't know how the scaling
// factors relate to the original major axis of the object,
// therefore for scaling factors all ==1 we will simple multiply
// which is correct, but for scaling factors not equal to 1, we
// must take the largest scaling factor and use it to scale the
// radii with since it's the worst case scenario of the new max and
// average radii
// find max scaling factor
float scale = MAX(vs->x, vs->y);
scale = MAX(scale, vs->z);
// now scale
obj->max_radius*=scale;
obj->avg_radius*=scale;
} // end Scale_OBJECT4DV1
/////////////////////////////////////////////////////////////
void Build_XYZ_Rotation_MATRIX4X4(float theta_x, // euler angles
float theta_y,
float theta_z,
MATRIX4X4_PTR mrot) // output
{
// this helper function takes a set if euler angles and computes
// a rotation matrix from them, usefull for object and camera
// work, also we will do a little testing in the function to determine
// the rotations that need to be performed, since there's no
// reason to perform extra matrix multiplies if the angles are
// zero!
MATRIX4X4 mx, my, mz, mtmp; // working matrices
float sin_theta=0, cos_theta=0; // used to initialize matrices
int rot_seq = 0; // 1 for x, 2 for y, 4 for z
// step 0: fill in with identity matrix
MAT_IDENTITY_4X4(mrot);
// step 1: based on zero and non-zero rotation angles, determine
// rotation sequence
if (fabs(theta_x) > EPSILON_E5) // x
rot_seq = rot_seq | 1;
if (fabs(theta_y) > EPSILON_E5) // y
rot_seq = rot_seq | 2;
if (fabs(theta_z) > EPSILON_E5) // z
rot_seq = rot_seq | 4;
// now case on sequence
switch(rot_seq)
{
case 0: // no rotation
{
// what a waste!
return;
} break;
case 1: // x rotation
{
// compute the sine and cosine of the angle
cos_theta = Fast_Cos(theta_x);
sin_theta = Fast_Sin(theta_x);
// set the matrix up
Mat_Init_4X4(&mx, 1, 0, 0, 0,
0, cos_theta, sin_theta, 0,
0, -sin_theta, cos_theta, 0,
0, 0, 0, 1);
// that's it, copy to output matrix
MAT_COPY_4X4(&mx, mrot);
return;
} break;
case 2: // y rotation
{
// compute the sine and cosine of the angle
cos_theta = Fast_Cos(theta_y);
sin_theta = Fast_Sin(theta_y);
// set the matrix up
Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,
0, 1, 0, 0,
sin_theta, 0, cos_theta, 0,
0, 0, 0, 1);
// that's it, copy to output matrix
MAT_COPY_4X4(&my, mrot);
return;
} break;
case 3: // xy rotation
{
// compute the sine and cosine of the angle for x
cos_theta = Fast_Cos(theta_x);
sin_theta = Fast_Sin(theta_x);
// set the matrix up
Mat_Init_4X4(&mx, 1, 0, 0, 0,
0, cos_theta, sin_theta, 0,
0, -sin_theta, cos_theta, 0,
0, 0, 0, 1);
// compute the sine and cosine of the angle for y
cos_theta = Fast_Cos(theta_y);
sin_theta = Fast_Sin(theta_y);
// set the matrix up
Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,
0, 1, 0, 0,
sin_theta, 0, cos_theta, 0,
0, 0, 0, 1);
// concatenate matrices
Mat_Mul_4X4(&mx, &my, mrot);
return;
} break;
case 4: // z rotation
{
// compute the sine and cosine of the angle
cos_theta = Fast_Cos(theta_z);
sin_theta = Fast_Sin(theta_z);
// set the matrix up
Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,
-sin_theta, cos_theta, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
// that's it, copy to output matrix
MAT_COPY_4X4(&mz, mrot);
return;
} break;
case 5: // xz rotation
{
// compute the sine and cosine of the angle x
cos_theta = Fast_Cos(theta_x);
sin_theta = Fast_Sin(theta_x);
// set the matrix up
Mat_Init_4X4(&mx, 1, 0, 0, 0,
0, cos_theta, sin_theta, 0,
0, -sin_theta, cos_theta, 0,
0, 0, 0, 1);
// compute the sine and cosine of the angle z
cos_theta = Fast_Cos(theta_z);
sin_theta = Fast_Sin(theta_z);
// set the matrix up
Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,
-sin_theta, cos_theta, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
// concatenate matrices
Mat_Mul_4X4(&mx, &mz, mrot);
return;
} break;
case 6: // yz rotation
{
// compute the sine and cosine of the angle y
cos_theta = Fast_Cos(theta_y);
sin_theta = Fast_Sin(theta_y);
// set the matrix up
Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,
0, 1, 0, 0,
sin_theta, 0, cos_theta, 0,
0, 0, 0, 1);
// compute the sine and cosine of the angle z
cos_theta = Fast_Cos(theta_z);
sin_theta = Fast_Sin(theta_z);
// set the matrix up
Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,
-sin_theta, cos_theta, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
// concatenate matrices
Mat_Mul_4X4(&my, &mz, mrot);
return;
} break;
case 7: // xyz rotation
{
// compute the sine and cosine of the angle x
cos_theta = Fast_Cos(theta_x);
sin_theta = Fast_Sin(theta_x);
// set the matrix up
Mat_Init_4X4(&mx, 1, 0, 0, 0,
0, cos_theta, sin_theta, 0,
0, -sin_theta, cos_theta, 0,
0, 0, 0, 1);
// compute the sine and cosine of the angle y
cos_theta = Fast_Cos(theta_y);
sin_theta = Fast_Sin(theta_y);
// set the matrix up
Mat_Init_4X4(&my,cos_theta, 0, -sin_theta, 0,
0, 1, 0, 0,
sin_theta, 0, cos_theta, 0,
0, 0, 0, 1);
// compute the sine and cosine of the angle z
cos_theta = Fast_Cos(theta_z);
sin_theta = Fast_Sin(theta_z);
// set the matrix up
Mat_Init_4X4(&mz, cos_theta, sin_theta, 0, 0,
-sin_theta, cos_theta, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
// concatenate matrices, watch order!
Mat_Mul_4X4(&mx, &my, &mtmp);
Mat_Mul_4X4(&mtmp, &mz, mrot);
} break;
default: break;
} // end switch
} // end Build_XYZ_Rotation_MATRIX4X4
///////////////////////////////////////////////////////////
void Build_Model_To_World_MATRIX4X4(VECTOR4D_PTR vpos, MATRIX4X4_PTR m)
{
// this function builds up a general local to world
// transformation matrix that is really nothing more than a translation
// of the origin by the amount specified in vpos
Mat_Init_4X4(m, 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
vpos->x, vpos->y, vpos->z, 1 );
} // end Build_Model_To_World_MATRIX4X4
//////////////////////////////////////////////////////////
void Build_Camera_To_Perspective_MATRIX4X4(CAM4DV1_PTR cam, MATRIX4X4_PTR m)
{
// this function builds up a camera to perspective transformation
// matrix, in most cases the camera would have a 2x2 normalized
// view plane with a 90 degree FOV, since the point of the having
// this matrix must be to also have a perspective to screen (viewport)
// matrix that scales the normalized coordinates, also the matrix
// assumes that you are working in 4D homogenous coordinates and at
// some point there will be a 4D->3D conversion, it might be immediately
// after this transform is applied to vertices, or after the perspective
// to screen transform
Mat_Init_4X4(m, cam->view_dist, 0, 0, 0,
0, cam->view_dist*cam->aspect_ratio, 0, 0,
0, 0, 1, 1,
0, 0, 0, 0);
} // end Build_Camera_To_Perspective_MATRIX4X4
///////////////////////////////////////////////////////////
void Build_Perspective_To_Screen_4D_MATRIX4X4(CAM4DV1_PTR cam, MATRIX4X4_PTR m)
{
// this function builds up a perspective to screen transformation
// matrix, the function assumes that you want to perform the
// transform in homogeneous coordinates and at raster time there will be
// a 4D->3D homogenous conversion and of course only the x,y points
// will be considered for the 2D rendering, thus you would use this
// function's matrix is your perspective coordinates were still
// in homgeneous form whene this matrix was applied, additionally
// the point of this matrix to to scale and translate the perspective
// coordinates to screen coordinates, thus the matrix is built up
// assuming that the perspective coordinates are in normalized form for
// a (2x2)/aspect_ratio viewplane, that is, x: -1 to 1, y:-1/aspect_ratio to 1/aspect_ratio
float alpha = (0.5*cam->viewport_width-0.5);
float beta = (0.5*cam->viewport_height-0.5);
Mat_Init_4X4(m, alpha, 0, 0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -