42 byte* animbuf =
nullptr;
47 buffer = (
const char*)animbuf;
78 anim->
from = atoi(token);
82 Com_Error(
ERR_FATAL,
"R_ModLoadAnims: start frame is higher than models frame count (%i) (model: %s)",
89 anim->
to = atoi(token);
93 Com_Error(
ERR_FATAL,
"R_ModLoadAnims: end frame is higher than models frame count (%i) (model: %s)",
100 anim->
time = (atof(token) > 0.01) ? (1000.0 / atof(token)) : (1000.0 / 0.01);
124 const int numIndexes = mesh->
num_tris * 3;
125 const int32_t* indexArray = mesh->
indexes;
129 float* texcoords, *verts, *normals, *tangents;
144 for (
i = 0, j = 0;
i < numIndexes;
i += 3, j++) {
149 VectorSubtract(vertexes[indexArray[
i + 0]].point, vertexes[indexArray[
i + 1]].point, dir1);
150 VectorSubtract(vertexes[indexArray[
i + 2]].point, vertexes[indexArray[
i + 1]].point, dir2);
151 Vector2Subtract(stcoords[indexArray[
i + 0]], stcoords[indexArray[
i + 1]], dir1uv);
152 Vector2Subtract(stcoords[indexArray[
i + 2]], stcoords[indexArray[
i + 1]], dir2uv);
161 if ((dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]) != 0.0) {
162 const float frac = 1.0 / (dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]);
166 VectorMul(-1.0 * dir2uv[1] * frac, dir1, tmp1);
168 VectorAdd(tmp1, tmp2, triangleTangents[j]);
171 VectorMul(-1.0 * dir2uv[0] * frac, dir1, tmp1);
173 VectorAdd(tmp1, tmp2, triangleBitangents[j]);
196 for (j = 0; j <
len; j++) {
197 const int32_t idx = list[j] / 3;
200 VectorAdd(b, triangleBitangents[idx], b);
216 for (j = 0; j <
len; j++) {
217 const int32_t idx = list[j];
218 const int meshIndex = mesh->
indexes[list[j]];
219 Vector2Copy(stcoords[meshIndex], (texcoords + (2 * idx)));
220 VectorAdd(vertexes[meshIndex].point, translate, (verts + (3 * idx)));
239 byte* buffer =
nullptr, *
buf;
240 const int32_t* intbuf;
262 buffer +=
sizeof(uint32_t);
264 intbuf = (
const int32_t*) buffer;
323 const int numIndexes = mesh->
num_tris * 3;
324 const int32_t* indexArray = mesh->
indexes;
335 for (
i = 0, j = 0;
i < numIndexes;
i += 3, j++) {
340 VectorSubtract(vertexes[indexArray[
i + 0]].point, vertexes[indexArray[
i + 1]].point, dir1);
341 VectorSubtract(vertexes[indexArray[
i + 2]].point, vertexes[indexArray[
i + 1]].point, dir2);
342 Vector2Subtract(stcoords[indexArray[
i + 0]], stcoords[indexArray[
i + 1]], dir1uv);
343 Vector2Subtract(stcoords[indexArray[
i + 2]], stcoords[indexArray[
i + 1]], dir2uv);
350 if ((dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]) != 0.0) {
351 const float frac = 1.0 / (dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]);
355 VectorMul(-1.0 * dir2uv[1] * frac, dir1, tmp1);
357 VectorAdd(tmp1, tmp2, triangleTangents[j]);
360 VectorMul(-1.0 * dir2uv[0] * frac, dir1, tmp1);
362 VectorAdd(tmp1, tmp2, triangleBitangents[j]);
364 const float frac = 1.0 / (0.00001);
368 VectorMul(-1.0 * dir2uv[1] * frac, dir1, tmp1);
370 VectorAdd(tmp1, tmp2, triangleTangents[j]);
373 VectorMul(-1.0 * dir2uv[0] * frac, dir1, tmp1);
375 VectorAdd(tmp1, tmp2, triangleBitangents[j]);
387 for (
i = 0;
i < numIndexes;
i++) {
388 const int idx = (
i -
i % 3) / 3;
389 VectorCopy(triangleNormals[idx], tmpVertexes[
i].normal);
390 VectorCopy(triangleTangents[idx], tmpVertexes[
i].tangent);
391 VectorCopy(triangleBitangents[idx], tmpBitangents[
i]);
393 for (j = 0; j < numIndexes; j++) {
394 const int idx2 = (j - j % 3) / 3;
401 if (
VectorEqual(vertexes[indexArray[
i]].point, vertexes[indexArray[j]].point)
402 &&
DotProduct(triangleNormals[idx], triangleNormals[idx2]) > smoothness) {
404 VectorAdd(tmpVertexes[
i].normal, triangleNormals[idx2], tmpVertexes[
i].normal);
412 if (
Vector2Equal(stcoords[indexArray[
i]], stcoords[indexArray[j]])
413 &&
DotProduct(triangleTangents[idx], triangleTangents[idx2]) > smoothness
414 &&
DotProduct(triangleBitangents[idx], triangleBitangents[idx2]) > smoothness) {
416 VectorAdd(tmpVertexes[
i].tangent, triangleTangents[idx2], tmpVertexes[
i].tangent);
417 VectorAdd(tmpBitangents[
i], triangleBitangents[idx2], tmpBitangents[
i]);
428 for (
i = 0;
i < numIndexes;
i++)
432 for (
i = 0;
i < numIndexes;
i++) {
434 if (indRemap[
i] != -1)
437 for (j =
i + 1; j < numIndexes; j++) {
438 if (
Vector2Equal(stcoords[indexArray[
i]], stcoords[indexArray[j]])
439 &&
VectorEqual(vertexes[indexArray[
i]].point, vertexes[indexArray[j]].point)
440 && (
DotProduct(tmpVertexes[
i].normal, tmpVertexes[j].normal) > smoothness)
441 && (
DotProduct(tmpVertexes[
i].tangent, tmpVertexes[j].tangent) > smoothness)) {
443 newIndexArray[j] = numVerts;
467 newIndexArray[
i] = numVerts++;
471 for (
i = 0;
i < numVerts;
i++)
474 for (
i = 0;
i < numIndexes;
i++)
475 sharedTris[newIndexArray[
i]]++;
479 for (
i = 0;
i < numVerts;
i++) {
487 for (
i = 0;
i < numIndexes;
i++) {
488 const int idx = indexArray[indRemap[
i]];
489 const int idx2 = newIndexArray[
i];
492 VectorCopy(vertexes[idx].point, newVertexes[idx2].point);
498 for (
i = 1;
i < nFrames;
i++) {
499 for (j = 0; j < numIndexes; j++) {
500 const int idx = indexArray[indRemap[j]] + (mesh->
num_verts *
i);
501 const int idx2 = newIndexArray[j] + (numVerts *
i);
503 VectorCopy(vertexes[idx].point, newVertexes[idx2].point);
557 Com_Error(
ERR_DROP,
"Texture is already freed and no longer uploaded, texnum is invalid for model %s",
579 const float frontlerp = 1.0 - backlerp;
580 vec_t* texcoord_array, *vertex_array_3d;
582 frame = mod->
frames + framenum;
583 oldframe = mod->
frames + oldframenum;
586 if (
r_state.lighting_enabled) {
632 for (
i = 0;
i < 3;
i++)
637 move[0] + ov->
point[0] * backlerp +
v->point[0] * frontlerp,
638 move[1] + ov->
point[1] * backlerp +
v->point[1] * frontlerp,
639 move[2] + ov->
point[2] * backlerp +
v->point[2] * frontlerp);
645 vertex_array_3d =
r_state.vertex_array_3d;
649 for (
int j = 0; j < 3; j++) {
650 const int arrayIndex = 3 *
i + j;
651 const int meshIndex = mesh->
indexes[arrayIndex];
653 VectorCopy(r_mesh_verts[meshIndex], vertex_array_3d);
656 vertex_array_3d += 3;
668 const int t = mesh->
num_tris * 3 * 4;
669 const int st = mesh->
num_tris * 3 * 2;
671 assert(mesh->
verts ==
nullptr);
673 assert(mesh->
normals ==
nullptr);
memPool_t * vid_modelPool
void Com_Error(int code, const char *fmt,...)
void Com_Printf(const char *const fmt,...)
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
void FS_FreeFile(void *buffer)
void Orthogonalize(vec3_t out, const vec3_t in)
Grahm-Schmidt orthogonalization.
void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross)
binary operation on vectors in a three-dimensional space
void VectorNormalizeFast(vec3_t v)
fast vector normalize routine that does not check to make sure that length != 0, nor does it return l...
#define Mem_PoolAllocTypeN(type, n, pool)
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
int Com_CountTokensInBuffer(const char *buffer)
Counts the tokens in the given buffer that the Com_Parse function would extract.
Shared parsing functions.
QGL_EXTERN GLuint GLchar GLuint * len
QGL_EXTERN int GLboolean GLfloat * v
image_t * R_FindImage(const char *pname, imagetype_t type)
Finds or loads the given image.
local graphics definitions
image_t * R_AliasModelState(const model_t *mod, int *mesh, int *frame, int *oldFrame, int *skin)
bool R_ModLoadMDX(model_t *mod)
Tries to load a mdx file that contains the normals and the tangents for a model.
void R_ModCalcUniqueNormalsAndTangents(mAliasMesh_t *mesh, int nFrames, float smoothness)
Calculates normals and tangents for all frames and does vertex merging based on smoothness.
image_t * R_AliasModelGetSkin(const char *modelFileName, const char *skin)
void R_FillArrayData(mAliasModel_t *mod, mAliasMesh_t *mesh, float backlerp, int framenum, int oldframenum, bool prerender)
Converts the model data into the opengl arrays.
void R_ModLoadAnims(mAliasModel_t *mod, const char *animname)
static void R_ModCalcNormalsAndTangents(mAliasMesh_t *mesh, int framenum, const vec3_t translate, bool backlerp)
Calculates a per-vertex tangentspace basis and stores it in GL arrays attached to the mesh.
void R_ModLoadArrayData(mAliasModel_t *mod, mAliasMesh_t *mesh, bool loadNormals)
Allocates data arrays for animated models. Only called once at loading time.
void R_ReallocateTexunitArray(gltexunit_t *texunit, int size)
Reallocate texcoord array of the specified texunit, if needed.
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
void Com_StripExtension(const char *in, char *out, const size_t size)
Removes the file extension from a filename.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
void Com_DefaultExtension(char *path, size_t len, const char *extension)
Sets a default extension if there is none.
void Com_ReplaceFilename(const char *inputPath, const char *expectedFileName, char *outputPath, size_t size)
Replaces the filename from one path with another one.
mAliasVertex_t * vertexes
mIndexList_t * revIndexes
char name[MODEL_MAX_PATH]
#define VectorMul(scalar, b, dest)
#define VectorEqual(a, b)
#define Vector4Copy(src, dest)
#define Vector2Equal(a, b)
#define VectorSubtract(a, b, dest)
#define VectorCopy(src, dest)
#define Vector2Subtract(a, b, dest)
#define VectorAdd(a, b, dest)
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
#define VectorSet(v, x, y, z)
#define Vector2Copy(src, dest)