]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - transform.c
rewrote memory system entirely (hunk, cache, and zone are gone, memory pools replaced...
[xonotic/darkplaces.git] / transform.c
index b4945e1992ae9e2e32e22004e1baca787e8528fa..91bdd1a7d1b27d0f7f2bd9d700fab67aef8c4695 100644 (file)
-// LordHavoc: transform code for purposes of transpoly, wallpoly, etc
 
 #include "quakedef.h"
 
-vec3_t softwaretransform_x;
-vec3_t softwaretransform_y;
-vec3_t softwaretransform_z;
-vec_t softwaretransform_scale;
-vec3_t softwaretransform_offset;
+vec_t softwaretransform_rotatematrix[3][4];
+vec_t softwaretransform_matrix[3][4];
+vec_t softwaretransform_invmatrix[3][4];
+int softwaretransform_complexity;
 
-// set to different transform code depending on complexity of transform
-void (*softwaretransform) (vec3_t in, vec3_t out);
-
-// the real deal
-void softwaretransform_dorotatescaletranslate (vec3_t in, vec3_t out)
-{
-       out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]) * softwaretransform_scale + softwaretransform_offset[0];
-       out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]) * softwaretransform_scale + softwaretransform_offset[1];
-       out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]) * softwaretransform_scale + softwaretransform_offset[2];
-}
-
-void softwaretransform_doscaletranslate (vec3_t in, vec3_t out)
-{
-       out[0] = in[0] * softwaretransform_scale + softwaretransform_offset[0];
-       out[1] = in[1] * softwaretransform_scale + softwaretransform_offset[1];
-       out[2] = in[2] * softwaretransform_scale + softwaretransform_offset[2];
-}
-
-void softwaretransform_dorotatetranslate (vec3_t in, vec3_t out)
-{
-       out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]) + softwaretransform_offset[0];
-       out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]) + softwaretransform_offset[1];
-       out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]) + softwaretransform_offset[2];
-}
-
-void softwaretransform_dotranslate (vec3_t in, vec3_t out)
-{
-       out[0] = in[0] + softwaretransform_offset[0];
-       out[1] = in[1] + softwaretransform_offset[1];
-       out[2] = in[2] + softwaretransform_offset[2];
-}
-
-void softwaretransform_dorotatescale (vec3_t in, vec3_t out)
-{
-       out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]) * softwaretransform_scale;
-       out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]) * softwaretransform_scale;
-       out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]) * softwaretransform_scale;
-}
-
-void softwaretransform_doscale (vec3_t in, vec3_t out)
-{
-       out[0] = in[0] * softwaretransform_scale + softwaretransform_offset[0];
-       out[1] = in[1] * softwaretransform_scale + softwaretransform_offset[1];
-       out[2] = in[2] * softwaretransform_scale + softwaretransform_offset[2];
-}
-
-void softwaretransform_dorotate (vec3_t in, vec3_t out)
+vec_t softwaretransform_identitymatrix[3][4] =
 {
-       out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]);
-       out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]);
-       out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]);
-}
+       {1, 0, 0, 0},
+       {0, 1, 0, 0},
+       {0, 0, 1, 0}
+};
 
-void softwaretransform_docopy (vec3_t in, vec3_t out)
+void softwaretransformidentity(void)
 {
-       out[0] = in[0];
-       out[1] = in[1];
-       out[2] = in[2];
+       memcpy(softwaretransform_rotatematrix, softwaretransform_identitymatrix, sizeof(vec_t[3][4]));
+       memcpy(softwaretransform_matrix      , softwaretransform_identitymatrix, sizeof(vec_t[3][4]));
+       memcpy(softwaretransform_invmatrix   , softwaretransform_identitymatrix, sizeof(vec_t[3][4]));
+       softwaretransform_complexity = 0;
 }
 
-void softwareuntransform (vec3_t in, vec3_t out)
+void softwaretransformset (vec3_t origin, vec3_t angles, vec_t scale)
 {
-       vec3_t v;
-       float s = 1.0f / softwaretransform_scale;
-       v[0] = in[0] - softwaretransform_offset[0];
-       v[1] = in[1] - softwaretransform_offset[1];
-       v[2] = in[2] - softwaretransform_offset[2];
-       out[0] = (v[0] * softwaretransform_x[0] + v[1] * softwaretransform_x[1] + v[2] * softwaretransform_x[2]) * s;
-       out[1] = (v[0] * softwaretransform_y[0] + v[1] * softwaretransform_y[1] + v[2] * softwaretransform_y[2]) * s;
-       out[2] = (v[0] * softwaretransform_z[0] + v[1] * softwaretransform_z[1] + v[2] * softwaretransform_z[2]) * s;
+       float invscale;
+       invscale = 1.0f / scale;
+       if (scale == 0)
+               Host_Error("softwaretransformset: 0 scale\n");
+
+       AngleMatrix(angles, origin, softwaretransform_rotatematrix);
+
+       softwaretransform_matrix[0][0] = softwaretransform_rotatematrix[0][0] * scale;
+       softwaretransform_matrix[0][1] = softwaretransform_rotatematrix[0][1] * scale;
+       softwaretransform_matrix[0][2] = softwaretransform_rotatematrix[0][2] * scale;
+       softwaretransform_matrix[1][0] = softwaretransform_rotatematrix[1][0] * scale;
+       softwaretransform_matrix[1][1] = softwaretransform_rotatematrix[1][1] * scale;
+       softwaretransform_matrix[1][2] = softwaretransform_rotatematrix[1][2] * scale;
+       softwaretransform_matrix[2][0] = softwaretransform_rotatematrix[2][0] * scale;
+       softwaretransform_matrix[2][1] = softwaretransform_rotatematrix[2][1] * scale;
+       softwaretransform_matrix[2][2] = softwaretransform_rotatematrix[2][2] * scale;
+       softwaretransform_matrix[0][3] = softwaretransform_rotatematrix[0][3];
+       softwaretransform_matrix[1][3] = softwaretransform_rotatematrix[1][3];
+       softwaretransform_matrix[2][3] = softwaretransform_rotatematrix[2][3];
+
+       softwaretransform_invmatrix[0][0] = softwaretransform_rotatematrix[0][0] * invscale;
+       softwaretransform_invmatrix[0][1] = softwaretransform_rotatematrix[1][0] * invscale;
+       softwaretransform_invmatrix[0][2] = softwaretransform_rotatematrix[2][0] * invscale;
+       softwaretransform_invmatrix[1][0] = softwaretransform_rotatematrix[0][1] * invscale;
+       softwaretransform_invmatrix[1][1] = softwaretransform_rotatematrix[1][1] * invscale;
+       softwaretransform_invmatrix[1][2] = softwaretransform_rotatematrix[2][1] * invscale;
+       softwaretransform_invmatrix[2][0] = softwaretransform_rotatematrix[0][2] * invscale;
+       softwaretransform_invmatrix[2][1] = softwaretransform_rotatematrix[1][2] * invscale;
+       softwaretransform_invmatrix[2][2] = softwaretransform_rotatematrix[2][2] * invscale;
+       softwaretransform_invmatrix[0][3] = softwaretransform_rotatematrix[0][3];
+       softwaretransform_invmatrix[1][3] = softwaretransform_rotatematrix[1][3];
+       softwaretransform_invmatrix[2][3] = softwaretransform_rotatematrix[2][3];
+
+       // choose transform mode
+       if (softwaretransform_matrix[0][0] != 1 || softwaretransform_matrix[0][1] != 0 || softwaretransform_matrix[0][2] != 0
+        || softwaretransform_matrix[1][0] != 0 || softwaretransform_matrix[1][1] != 1 || softwaretransform_matrix[1][2] != 0
+        || softwaretransform_matrix[2][0] != 0 || softwaretransform_matrix[2][1] != 0 || softwaretransform_matrix[2][2] != 1)
+               softwaretransform_complexity = 2;
+       else if (softwaretransform_matrix[0][3] != 0 || softwaretransform_matrix[1][3] != 0 || softwaretransform_matrix[2][3] != 0)
+               softwaretransform_complexity = 1;
+       else
+               softwaretransform_complexity = 0;
 }
 
-// to save time on transforms, choose the appropriate function
-void softwaretransform_classify(void)
+void softwaretransformforentity (entity_render_t *r)
 {
-       if (softwaretransform_offset[0] != 0 || softwaretransform_offset[1] != 0 || softwaretransform_offset[2] != 0)
+       vec3_t angles;
+       if (r->model->type == mod_brush)
        {
-               if (softwaretransform_scale != 1)
-               {
-                       if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
-                               softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
-                               softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
-                               softwaretransform = &softwaretransform_dorotatescaletranslate;
-                       else
-                               softwaretransform = &softwaretransform_doscaletranslate;
-               }
-               else
-               {
-                       if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
-                               softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
-                               softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
-                               softwaretransform = &softwaretransform_dorotatetranslate;
-                       else
-                               softwaretransform = &softwaretransform_dotranslate;
-               }
+               angles[0] = r->angles[0];
+               angles[1] = r->angles[1];
+               angles[2] = r->angles[2];
+               softwaretransformset(r->origin, angles, r->scale);
        }
        else
        {
-               if (softwaretransform_scale != 1)
-               {
-                       if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
-                               softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
-                               softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
-                               softwaretransform = &softwaretransform_dorotatescale;
-                       else
-                               softwaretransform = &softwaretransform_doscale;
-               }
-               else
-               {
-                       if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
-                               softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
-                               softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
-                               softwaretransform = &softwaretransform_dorotate;
-                       else
-                               softwaretransform = &softwaretransform_docopy;
-               }
+               angles[0] = -r->angles[0];
+               angles[1] = r->angles[1];
+               angles[2] = r->angles[2];
+               softwaretransformset(r->origin, angles, r->scale);
        }
 }
-
-void softwaretransformidentity(void)
-{
-       softwaretransform_offset[0] = softwaretransform_offset[1] = softwaretransform_offset[2] = softwaretransform_x[1] = softwaretransform_x[2] = softwaretransform_y[0] = softwaretransform_y[2] = softwaretransform_z[0] = softwaretransform_z[1] = 0;
-       softwaretransform_x[0] = softwaretransform_y[1] = softwaretransform_z[2] = 1;
-       softwaretransform_scale = 1;
-       // we know what it is
-       softwaretransform = &softwaretransform_docopy;
-}
-
-void softwaretransformset (vec3_t origin, vec3_t angles, vec_t scale)
-{
-       VectorCopy(origin, softwaretransform_offset);
-       AngleVectors(angles, softwaretransform_x, softwaretransform_y, softwaretransform_z);
-       softwaretransform_y[0] = -softwaretransform_y[0];
-       softwaretransform_y[1] = -softwaretransform_y[1];
-       softwaretransform_y[2] = -softwaretransform_y[2];
-       softwaretransform_scale = scale;
-       // choose best transform code
-       softwaretransform_classify();
-}
-
-void softwaretransformforentity (entity_t *e)
-{
-       vec3_t angles;
-       angles[0] = -e->render.angles[0];
-       angles[1] = e->render.angles[1];
-       angles[2] = e->render.angles[2];
-       softwaretransformset(e->render.origin, angles, e->render.scale);
-}