diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index ccd7c751f..93c2faae3 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -2174,6 +2174,19 @@ entity_t *V_AddEntity(entity_t *in) return ent; } +entity_t *V_AddNewEntity(void) +{ + entity_t *ent; + + if (cl_numvisedicts == cl_maxvisedicts) + { + cl_expandvisents = true; + return NULL; // object list is full + } + ent = &cl_visedicts[cl_numvisedicts]; + cl_numvisedicts++; + return ent; +} /* void VQ2_AddLerpEntity(entity_t *in) //a convienience function { diff --git a/engine/client/render.h b/engine/client/render.h index 2f8f305ac..e1dd152d3 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -569,6 +569,7 @@ int Mod_RegisterModelFormatMagic(void *module, const char *formatname, qbyte *ma void Mod_UnRegisterModelFormat(void *module, int idx); void Mod_UnRegisterAllModelFormats(void *module); void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b); +void Mod_SubmodelLoaded(struct model_s *mod, int state); #ifdef RUNTIMELIGHTING struct relight_ctx_s; diff --git a/engine/client/view.h b/engine/client/view.h index 19f503413..ad32cf972 100644 --- a/engine/client/view.h +++ b/engine/client/view.h @@ -36,6 +36,7 @@ void V_UpdatePalette (qboolean force); void V_ClearCShifts (void); void V_ClearEntity(entity_t *e); entity_t *V_AddEntity(entity_t *in); +entity_t *V_AddNewEntity(void); void VQ2_AddLerpEntity(entity_t *in); void V_AddAxisEntity(entity_t *in); void CLQ1_AddShadow(entity_t *ent); diff --git a/engine/common/com_bih.c b/engine/common/com_bih.c index 61f9f5f6b..460bbc7bb 100644 --- a/engine/common/com_bih.c +++ b/engine/common/com_bih.c @@ -870,6 +870,35 @@ static void BIH_RecursiveTrace (struct bihtrace_s *fte_restrict tr, const struct if (node->data.contents & tr->hitcontents) BIH_ClipToTriangle(tr, &node->data); return; + case BIH_MODEL: + { + trace_t sub; + vec3_t start_l; + vec3_t end_l; + + VectorSubtract (tr->startpos, node->data.mesh.tr->origin, start_l); + VectorSubtract (tr->endpos, node->data.mesh.tr->origin, end_l); + node->data.mesh.model->funcs.NativeTrace(node->data.mesh.model, 0, NULLFRAMESTATE, node->data.mesh.tr->axis, start_l, end_l, tr->size.min, tr->size.max, tr->shape==shape_iscapsule, tr->hitcontents, &sub); + + if (sub.truefraction < tr->trace.truefraction) + { + tr->trace.truefraction = sub.truefraction; + tr->trace.fraction = sub.fraction; + tr->trace.plane.dist = sub.plane.dist; + VectorCopy(sub.plane.normal, tr->trace.plane.normal); + tr->trace.surface = sub.surface; + tr->trace.contents = sub.contents; + tr->trace.startsolid |= sub.startsolid; + tr->trace.allsolid = sub.allsolid; + VectorAdd (sub.endpos, node->data.mesh.tr->origin, tr->trace.endpos); + } + else + { + tr->trace.startsolid |= sub.startsolid; + tr->trace.allsolid &= sub.allsolid; + } + } + return; case BIH_GROUP: { int i; @@ -1140,6 +1169,35 @@ static void BIH_RecursiveTest (struct bihtrace_s *fte_restrict tr, const struct if (node->data.contents & tr->hitcontents) BIH_TestToTriangle(tr, &node->data); return; + case BIH_MODEL: + { //lame... + trace_t sub; + vec3_t start_l; + vec3_t end_l; + + VectorSubtract (tr->startpos, node->data.mesh.tr->origin, start_l); + VectorSubtract (tr->endpos, node->data.mesh.tr->origin, end_l); + node->data.mesh.model->funcs.NativeTrace(node->data.mesh.model, 0, NULLFRAMESTATE, node->data.mesh.tr->axis, start_l, end_l, tr->size.min, tr->size.max, tr->shape==shape_iscapsule, tr->hitcontents, &sub); + + if (sub.truefraction < tr->trace.truefraction) + { + tr->trace.truefraction = sub.truefraction; + tr->trace.fraction = sub.fraction; + tr->trace.plane.dist = sub.plane.dist; + VectorCopy(sub.plane.normal, tr->trace.plane.normal); + tr->trace.surface = sub.surface; + tr->trace.contents = sub.contents; + tr->trace.startsolid |= sub.startsolid; + tr->trace.allsolid = sub.allsolid; + VectorAdd (sub.endpos, node->data.mesh.tr->origin, tr->trace.endpos); + } + else + { + tr->trace.startsolid |= sub.startsolid; + tr->trace.allsolid &= sub.allsolid; + } + } + return; case BIH_GROUP: { int i; @@ -1403,6 +1461,12 @@ restart: #endif case BIH_TRIANGLE: return 0; + case BIH_MODEL: + { + vec3_t pos; + VectorSubtract (p, node->data.mesh.tr->origin, pos); + return node->data.mesh.model->funcs.PointContents(node->data.mesh.model, node->data.mesh.tr->axis, pos); + } case BIH_GROUP: { int i; diff --git a/engine/common/com_bih.h b/engine/common/com_bih.h index caa577663..39be6b30b 100644 --- a/engine/common/com_bih.h +++ b/engine/common/com_bih.h @@ -71,6 +71,7 @@ enum bihtype_e BIH_TRISOUP, #endif BIH_TRIANGLE, + BIH_MODEL, }; struct bihdata_s { @@ -88,6 +89,14 @@ struct bihdata_s index_t *indexes; //might be better to just bake 3 indexes instead of using a pointer to them vecV_t *xyz; } tri; + struct { + model_t *model; + struct bihtransform_s + { + vec3_t axis[3]; + vec3_t origin; + } *tr; + } mesh; }; }; struct bihleaf_s diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 661146a47..dfcf0138b 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -223,6 +223,7 @@ typedef struct galiasinfo_s } galiasinfo_t; struct terrainfuncs_s; +struct bihleaf_s; typedef struct modplugfuncs_s { int version; @@ -252,6 +253,17 @@ typedef struct modplugfuncs_s void (QDECL *NormaliseTextureVectors)(vec3_t *n, vec3_t *s, vec3_t *t, int v, qboolean calcnorms); model_t *(QDECL *GetModel)(const char *identifier, enum mlverbosity_e verbosity); + model_t *(QDECL *BeginSubmodelLoad)(const char *identifier); + qboolean (*LoadEntities)(struct model_s *mod, const char *entdata, size_t entdatasize); + void (*LoadMapArchive)(struct model_s *mod, void *archivedata, size_t archivesize); + void (*BIH_Build) (struct model_s *mod, struct bihleaf_s *leafs, size_t numleafs); + void (*BIH_BuildAlias) (struct model_s *mod, galiasinfo_t *meshes); + size_t (*ClipPlaneToBrush)(vecV_t *points, size_t maxpoints, void *planes, size_t planestride, size_t numplanes, vec4_t face); + shader_t *(*RegisterBasicShader)(struct model_s *mod, const char *texname, unsigned int usageflags, const char *shadertext, uploadfmt_t pixelfmt, unsigned int width, unsigned int height, void *pixeldata, void *palettedata); + void (*Batches_Build)(struct model_s *mod, builddata_t *bd); + void (*RenderDynamicLightmaps) (struct msurface_s *surf); + entity_t *(*NewSceneEntity) (void); + void (*EndSubmodelLoad)(struct model_s *submod, int modelloadstate); #define plugmodfuncs_name "Models" } plugmodfuncs_t; #define MODPLUGFUNCS_VERSION 2 diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 9f8db19d3..994b020bd 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -5,6 +5,7 @@ #include "quakedef.h" #include "fs.h" #include "vr.h" +#include "com_bih.h" #define FTEENGINE #include "../plugins/plugin.h" @@ -2088,7 +2089,26 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s #endif Mod_AccumulateTextureVectors, Mod_NormaliseTextureVectors, - Mod_ForName + Mod_ForName, + + Mod_FindName, + Mod_LoadEntitiesBlob, + Mod_LoadMapArchive, + BIH_Build, + BIH_BuildAlias, + Fragment_ClipPlaneToBrush, +#ifdef HAVE_CLIENT + Mod_RegisterBasicShader, + Mod_Batches_Build, + Surf_RenderDynamicLightmaps, + V_AddNewEntity, +#else + NULL, + NULL, + NULL, + NULL, +#endif + Mod_SubmodelLoaded, }; if (structsize == sizeof(funcs)) return &funcs; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 13ebf80a5..6a4c3323f 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1063,6 +1063,10 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b) break; } } +void Mod_SubmodelLoaded(model_t *mod, int state) +{ + COM_AddWork(WG_MAIN, Mod_ModelLoaded, mod, NULL, MLS_LOADED, 0); +} /* ================== Mod_LoadModel @@ -3234,6 +3238,33 @@ void Mod_Batches_Build(model_t *mod, builddata_t *bd) if (BE_GenBrushModelVBO) BE_GenBrushModelVBO(mod); } + +shader_t *Mod_RegisterBasicShader(struct model_s *mod, const char *texname, unsigned int usageflags, const char *shadertext, uploadfmt_t pixelfmt, unsigned int width, unsigned int height, void *pixeldata, void *palettedata) +{ + shader_t *s; + unsigned int maps; + char mapbase[64]; + if (shadertext) + s = R_RegisterShader(texname, usageflags, shadertext); + else if (mod->type == mod_brush) + s = R_RegisterCustom(mod, texname, usageflags, Shader_DefaultSkin, NULL); + else + s = R_RegisterCustom(mod, texname, usageflags, Shader_DefaultBSPLM, NULL); + + + maps = 0; + maps |= SHADER_HASPALETTED; + maps |= SHADER_HASDIFFUSE; + if (r_fb_bmodels.ival) + maps |= SHADER_HASFULLBRIGHT; + if (r_loadbumpmapping || s->defaulttextures->reflectcube) + maps |= SHADER_HASNORMALMAP; + if (gl_specular.ival) + maps |= SHADER_HASGLOSS; + COM_FileBase(mod->name, mapbase, sizeof(mapbase)); + R_BuildLegacyTexnums(s, texname, mapbase, maps, 0, pixelfmt, width, height, pixeldata, palettedata); + return s; +} #endif