mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-01-24 08:41:06 +00:00
- Switch the raytrace function to use different collision routines
This commit is contained in:
parent
99a4ffa69f
commit
8958790fed
9 changed files with 247 additions and 137 deletions
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "framework/tarray.h"
|
||||
#include "lightmap/kexlib/math/mathlib.h"
|
||||
#include "lightmap/collision.h"
|
||||
#include <memory>
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
|
||||
|
@ -345,6 +347,11 @@ struct FLevel
|
|||
|
||||
// Dlight helpers
|
||||
|
||||
TArray<kexVec3> MeshVertices;
|
||||
TArray<unsigned int> MeshElements;
|
||||
TArray<int> MeshSurfaces;
|
||||
std::unique_ptr<TriangleMeshShape> CollisionMesh;
|
||||
|
||||
leaf_t *leafs = nullptr;
|
||||
uint8_t *mapPVS = nullptr;
|
||||
|
||||
|
|
|
@ -28,6 +28,24 @@ typedef unsigned int uint32;
|
|||
typedef signed int int32;
|
||||
#include "framework/xs_Float.h"
|
||||
|
||||
static void CopyUDMFString(char *dest, int destlen, const char *udmfvalue)
|
||||
{
|
||||
destlen--;
|
||||
|
||||
char endchar = 0;
|
||||
if (udmfvalue[0] == '"' || udmfvalue[0] == '\'')
|
||||
{
|
||||
endchar = udmfvalue[0];
|
||||
udmfvalue++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < destlen && udmfvalue[i] != 0 && udmfvalue[i] != endchar; i++)
|
||||
{
|
||||
*(dest++) = udmfvalue[i];
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
class StringBuffer
|
||||
{
|
||||
|
@ -251,6 +269,14 @@ void FProcessor::ParseSidedef(IntSideDef *sd)
|
|||
{
|
||||
SC_MustGetStringName("{");
|
||||
sd->sector = NO_INDEX;
|
||||
sd->textureoffset = 0;
|
||||
sd->rowoffset = 0;
|
||||
sd->toptexture[0] = '-';
|
||||
sd->toptexture[1] = 0;
|
||||
sd->midtexture[0] = '-';
|
||||
sd->midtexture[1] = 0;
|
||||
sd->bottomtexture[0] = '-';
|
||||
sd->bottomtexture[1] = 0;
|
||||
while (!SC_CheckString("}"))
|
||||
{
|
||||
const char *value;
|
||||
|
@ -262,6 +288,27 @@ void FProcessor::ParseSidedef(IntSideDef *sd)
|
|||
continue; // do not store in props
|
||||
}
|
||||
|
||||
if (stricmp(key, "texturetop") == 0)
|
||||
{
|
||||
CopyUDMFString(sd->toptexture, 8, value);
|
||||
}
|
||||
else if (stricmp(key, "texturemiddle") == 0)
|
||||
{
|
||||
CopyUDMFString(sd->midtexture, 8, value);
|
||||
}
|
||||
else if (stricmp(key, "texturebottom") == 0)
|
||||
{
|
||||
CopyUDMFString(sd->bottomtexture, 8, value);
|
||||
}
|
||||
else if (stricmp(key, "offsetx_mid") == 0)
|
||||
{
|
||||
sd->textureoffset = CheckInt(key);
|
||||
}
|
||||
else if (stricmp(key, "offsety_mid") == 0)
|
||||
{
|
||||
sd->rowoffset = CheckInt(key);
|
||||
}
|
||||
|
||||
// now store the key in its unprocessed form
|
||||
UDMFKey k = {key, value};
|
||||
sd->props.Push(k);
|
||||
|
@ -274,25 +321,6 @@ void FProcessor::ParseSidedef(IntSideDef *sd)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
static void CopyUDMFString(char *dest, int destlen, const char *udmfvalue)
|
||||
{
|
||||
destlen--;
|
||||
|
||||
char endchar = 0;
|
||||
if (udmfvalue[0] == '"' || udmfvalue[0] == '\'')
|
||||
{
|
||||
endchar = udmfvalue[0];
|
||||
udmfvalue++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < destlen && udmfvalue[i] != 0 && udmfvalue[i] != endchar; i++)
|
||||
{
|
||||
*(dest++) = udmfvalue[i];
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
void FProcessor::ParseSector(IntSector *sec)
|
||||
{
|
||||
memset(&sec->data, 0, sizeof(sec->data));
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#undef min
|
||||
#undef max
|
||||
|
||||
TriangleMeshShape::TriangleMeshShape(const kexVec3 *vertices, int num_vertices, const unsigned int *elements, int num_elements)
|
||||
: vertices(vertices), num_vertices(num_vertices), elements(elements), num_elements(num_elements), root(-1)
|
||||
TriangleMeshShape::TriangleMeshShape(const kexVec3 *vertices, int num_vertices, const unsigned int *elements, int num_elements, const int *surfaces)
|
||||
: vertices(vertices), num_vertices(num_vertices), elements(elements), num_elements(num_elements), surfaces(surfaces)
|
||||
{
|
||||
int num_triangles = num_elements / 3;
|
||||
if (num_triangles <= 0)
|
||||
|
@ -71,6 +71,15 @@ bool TriangleMeshShape::find_any_hit(TriangleMeshShape *shape, const kexVec3 &ra
|
|||
return find_any_hit(shape, ray_start, ray_end, shape->root);
|
||||
}
|
||||
|
||||
TraceHit TriangleMeshShape::find_first_hit(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end)
|
||||
{
|
||||
TraceHit hit;
|
||||
find_first_hit(shape, ray_start, ray_end, shape->root, &hit);
|
||||
if (hit.surface != -1)
|
||||
hit.surface = shape->surfaces[hit.surface / 3];
|
||||
return hit;
|
||||
}
|
||||
|
||||
float TriangleMeshShape::sweep(TriangleMeshShape *shape1, SphereShape *shape2, int a, const kexVec3 &target)
|
||||
{
|
||||
if (sweep_overlap_bv_sphere(shape1, shape2, a, target))
|
||||
|
@ -178,6 +187,27 @@ bool TriangleMeshShape::find_any_hit(TriangleMeshShape *shape, const kexVec3 &ra
|
|||
return false;
|
||||
}
|
||||
|
||||
void TriangleMeshShape::find_first_hit(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end, int a, TraceHit *hit)
|
||||
{
|
||||
if (overlap_bv_ray(shape, ray_start, ray_end, a))
|
||||
{
|
||||
if (shape->is_leaf(a))
|
||||
{
|
||||
float t = intersect_triangle_ray(shape, ray_start, ray_end, a);
|
||||
if (t < hit->fraction)
|
||||
{
|
||||
hit->fraction = t;
|
||||
hit->surface = shape->nodes[a].element_index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
find_first_hit(shape, ray_start, ray_end, shape->nodes[a].left, hit);
|
||||
find_first_hit(shape, ray_start, ray_end, shape->nodes[a].right, hit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TriangleMeshShape::overlap_bv_ray(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end, int a)
|
||||
{
|
||||
return IntersectionTest::ray_aabb(ray_start, ray_end, shape->nodes[a].aabb) == IntersectionTest::overlap;
|
||||
|
@ -194,6 +224,49 @@ float TriangleMeshShape::intersect_triangle_ray(TriangleMeshShape *shape, const
|
|||
shape->vertices[shape->elements[start_element + 2]]
|
||||
};
|
||||
|
||||
#if 1
|
||||
|
||||
kexVec3 e1 = p[1] - p[0];
|
||||
kexVec3 e2 = p[2] - p[0];
|
||||
|
||||
kexVec3 triangleNormal = kexVec3::Cross(e1, e2);
|
||||
float dist = kexVec3::Dot(p[0], triangleNormal);
|
||||
float distA = kexVec3::Dot(ray_start, triangleNormal) - dist;
|
||||
float distB = kexVec3::Dot(ray_end, triangleNormal) - dist;
|
||||
|
||||
if (distA * distB >= 0.0f)
|
||||
return 1.0f;
|
||||
|
||||
// Backface check
|
||||
//if (distA < 0.0f)
|
||||
// return 1.0f;
|
||||
|
||||
float projLength = distA - distB;
|
||||
float distance = (distA) / (projLength);
|
||||
if (distance > 1.0f)
|
||||
return 1.0f;
|
||||
|
||||
float edgeTolerance = triangleNormal.LengthSq() * -0.0001f;
|
||||
kexVec3 point = ray_start * (1.0f - distance) + ray_end * distance;
|
||||
|
||||
kexVec3 v0p = p[0] - point;
|
||||
kexVec3 v1p = p[1] - point;
|
||||
kexVec3 cp0 = kexVec3::Cross(v0p, v1p);
|
||||
if (kexVec3::Dot(cp0, triangleNormal) < edgeTolerance)
|
||||
return 1.0f;
|
||||
|
||||
kexVec3 v2p = p[2] - point;
|
||||
kexVec3 cp1 = kexVec3::Cross(v1p, v2p);
|
||||
if (kexVec3::Dot(cp1, triangleNormal) < edgeTolerance)
|
||||
return 1.0f;
|
||||
|
||||
kexVec3 cp2 = kexVec3::Cross(v2p, v0p);
|
||||
if (kexVec3::Dot(cp2, triangleNormal) < edgeTolerance)
|
||||
return 1.0f;
|
||||
|
||||
return distance;
|
||||
|
||||
#else
|
||||
// Moeller–Trumbore ray-triangle intersection algorithm:
|
||||
|
||||
kexVec3 D = ray_end - ray_start;
|
||||
|
@ -206,6 +279,10 @@ float TriangleMeshShape::intersect_triangle_ray(TriangleMeshShape *shape, const
|
|||
kexVec3 P = kexVec3::Cross(D, e2);
|
||||
float det = kexVec3::Dot(e1, P);
|
||||
|
||||
// Backface check
|
||||
//if (det < 0.0f)
|
||||
// return 1.0f;
|
||||
|
||||
// If determinant is near zero, ray lies in plane of triangle
|
||||
if (det > -FLT_EPSILON && det < FLT_EPSILON)
|
||||
return 1.0f;
|
||||
|
@ -238,6 +315,7 @@ float TriangleMeshShape::intersect_triangle_ray(TriangleMeshShape *shape, const
|
|||
|
||||
// No hit, no win
|
||||
return 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool TriangleMeshShape::sweep_overlap_bv_sphere(TriangleMeshShape *shape1, SphereShape *shape2, int a, const kexVec3 &target)
|
||||
|
|
|
@ -35,10 +35,16 @@ public:
|
|||
float radius = 0.0f;
|
||||
};
|
||||
|
||||
struct TraceHit
|
||||
{
|
||||
float fraction = 1.0f;
|
||||
int surface = -1;
|
||||
};
|
||||
|
||||
class TriangleMeshShape
|
||||
{
|
||||
public:
|
||||
TriangleMeshShape(const kexVec3 *vertices, int num_vertices, const unsigned int *elements, int num_elements);
|
||||
TriangleMeshShape(const kexVec3 *vertices, int num_vertices, const unsigned int *elements, int num_elements, const int *surfaces);
|
||||
|
||||
int get_min_depth();
|
||||
int get_max_depth();
|
||||
|
@ -51,25 +57,28 @@ public:
|
|||
static bool find_any_hit(TriangleMeshShape *shape1, SphereShape *shape2);
|
||||
static bool find_any_hit(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end);
|
||||
|
||||
static TraceHit find_first_hit(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end);
|
||||
|
||||
struct Node
|
||||
{
|
||||
Node() : left(-1), right(-1), element_index(-1) { }
|
||||
Node(const kexVec3 &aabb_min, const kexVec3 &aabb_max, int element_index) : aabb(aabb_min, aabb_max), left(-1), right(-1), element_index(element_index) { }
|
||||
Node(const kexVec3 &aabb_min, const kexVec3 &aabb_max, int left, int right) : aabb(aabb_min, aabb_max), left(left), right(right), element_index(-1) { }
|
||||
Node() = default;
|
||||
Node(const kexVec3 &aabb_min, const kexVec3 &aabb_max, int element_index) : aabb(aabb_min, aabb_max), element_index(element_index) { }
|
||||
Node(const kexVec3 &aabb_min, const kexVec3 &aabb_max, int left, int right) : aabb(aabb_min, aabb_max), left(left), right(right) { }
|
||||
|
||||
kexBBox aabb;
|
||||
int left;
|
||||
int right;
|
||||
int element_index;
|
||||
int left = -1;
|
||||
int right = -1;
|
||||
int element_index = -1;
|
||||
};
|
||||
|
||||
const kexVec3 *vertices;
|
||||
const int num_vertices;
|
||||
const unsigned int *elements;
|
||||
int num_elements;
|
||||
const kexVec3 *vertices = nullptr;
|
||||
const int num_vertices = 0;
|
||||
const unsigned int *elements = nullptr;
|
||||
int num_elements = 0;
|
||||
const int *surfaces = nullptr;
|
||||
|
||||
std::vector<Node> nodes;
|
||||
int root;
|
||||
int root = -1;
|
||||
|
||||
private:
|
||||
static float sweep(TriangleMeshShape *shape1, SphereShape *shape2, int a, const kexVec3 &target);
|
||||
|
@ -78,6 +87,8 @@ private:
|
|||
static bool find_any_hit(TriangleMeshShape *shape1, SphereShape *shape2, int a);
|
||||
static bool find_any_hit(TriangleMeshShape *shape1, const kexVec3 &ray_start, const kexVec3 &ray_end, int a);
|
||||
|
||||
static void find_first_hit(TriangleMeshShape *shape1, const kexVec3 &ray_start, const kexVec3 &ray_end, int a, TraceHit *hit);
|
||||
|
||||
inline static bool overlap_bv_ray(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end, int a);
|
||||
inline static float intersect_triangle_ray(TriangleMeshShape *shape, const kexVec3 &ray_start, const kexVec3 &ray_end, int a);
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
//#define EXPORT_TEXELS_OBJ
|
||||
|
||||
kexWorker lightmapWorker;
|
||||
|
||||
const kexVec3 kexLightmapBuilder::gridSize(64, 64, 128);
|
||||
|
@ -223,22 +221,22 @@ kexBBox kexLightmapBuilder::GetBoundsFromSurface(const surface_t *surface)
|
|||
// light if the surface that was traced is a sky
|
||||
//
|
||||
|
||||
bool kexLightmapBuilder::EmitFromCeiling(kexTrace &trace, const surface_t *surface, const kexVec3 &origin,
|
||||
const kexVec3 &normal, float *dist)
|
||||
bool kexLightmapBuilder::EmitFromCeiling(kexTrace &trace, const surface_t *surface, const kexVec3 &origin, const kexVec3 &normal, kexVec3 &color)
|
||||
{
|
||||
*dist = normal.Dot(map->GetSunDirection());
|
||||
float dist = normal.Dot(map->GetSunDirection());
|
||||
|
||||
if(*dist <= 0)
|
||||
if(dist <= 0)
|
||||
{
|
||||
// plane is not even facing the sunlight
|
||||
return false;
|
||||
}
|
||||
|
||||
trace.Trace(origin, origin + (map->GetSunDirection() * 32768));
|
||||
trace.Trace(origin, origin + (map->GetSunDirection() * 32768.0f));
|
||||
|
||||
if(trace.fraction == 1 || trace.hitSurface == NULL)
|
||||
if(trace.fraction == 1.0f)
|
||||
{
|
||||
// nothing was hit
|
||||
//color.x += 1.0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -248,6 +246,8 @@ bool kexLightmapBuilder::EmitFromCeiling(kexTrace &trace, const surface_t *surfa
|
|||
return false;
|
||||
}
|
||||
|
||||
color += map->GetSunColor() * dist;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -336,15 +336,8 @@ kexVec3 kexLightmapBuilder::LightTexelSample(kexTrace &trace, const kexVec3 &ori
|
|||
if(surface->type != ST_CEILING && map->bSSectsVisibleToSky[surface->subSector - map->GLSubsectors])
|
||||
{
|
||||
// see if it's exposed to sunlight
|
||||
if(EmitFromCeiling(trace, surface, origin, plane.Normal(), &dist))
|
||||
{
|
||||
dist = (dist * 4);
|
||||
kexMath::Clamp(dist, 0, 1);
|
||||
|
||||
color += map->GetSunColor() * dist;
|
||||
|
||||
if(EmitFromCeiling(trace, surface, origin, plane.Normal(), color))
|
||||
tracedTexels++;
|
||||
}
|
||||
}
|
||||
|
||||
// trace against surface lights
|
||||
|
@ -504,13 +497,6 @@ void kexLightmapBuilder::TraceSurface(surface_t *surface)
|
|||
|
||||
normal = surface->plane.Normal();
|
||||
|
||||
// debugging stuff - used to help visualize where texels are positioned in the level
|
||||
#ifdef EXPORT_TEXELS_OBJ
|
||||
static int cnt = 0;
|
||||
FILE *f = fopen(Va("texels_%02d.obj", cnt++), "w");
|
||||
int indices = 0;
|
||||
#endif
|
||||
|
||||
// start walking through each texel
|
||||
for(i = 0; i < sampleHeight; i++)
|
||||
{
|
||||
|
@ -522,13 +508,6 @@ void kexLightmapBuilder::TraceSurface(surface_t *surface)
|
|||
(surface->lightmapSteps[0] * (float)j) +
|
||||
(surface->lightmapSteps[1] * (float)i);
|
||||
|
||||
// debugging stuff
|
||||
#ifdef EXPORT_TEXELS_OBJ
|
||||
ExportTexelsToObjFile(f, pos, indices);
|
||||
indices += 8;
|
||||
#endif
|
||||
|
||||
// accumulate color samples
|
||||
kexVec3 c = LightTexelSample(trace, pos, surface);
|
||||
|
||||
// if nothing at all was traced and color is completely black
|
||||
|
@ -543,10 +522,6 @@ void kexLightmapBuilder::TraceSurface(surface_t *surface)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef EXPORT_TEXELS_OBJ
|
||||
fclose(f);
|
||||
#endif
|
||||
|
||||
// SVE redraws the scene for lightmaps, so for optimizations,
|
||||
// tell the engine to ignore this surface if completely black
|
||||
if(bShouldLookupTexture == false)
|
||||
|
|
|
@ -64,7 +64,7 @@ private:
|
|||
kexBBox GetBoundsFromSurface(const surface_t *surface);
|
||||
kexVec3 LightTexelSample(kexTrace &trace, const kexVec3 &origin, surface_t *surface);
|
||||
kexVec3 LightCellSample(const int gridid, kexTrace &trace, const kexVec3 &origin, const MapSubsectorEx *sub);
|
||||
bool EmitFromCeiling(kexTrace &trace, const surface_t *surface, const kexVec3 &origin, const kexVec3 &normal, float *dist);
|
||||
bool EmitFromCeiling(kexTrace &trace, const surface_t *surface, const kexVec3 &origin, const kexVec3 &normal, kexVec3 &color);
|
||||
void ExportTexelsToObjFile(FILE *f, const kexVec3 &org, int indices);
|
||||
void WriteBlock(FILE *f, const int i, const kexVec3 &org, int indices, kexBBox &box);
|
||||
|
||||
|
|
|
@ -34,14 +34,8 @@
|
|||
#include "mapdata.h"
|
||||
#include "surfaces.h"
|
||||
|
||||
//#define EXPORT_OBJ
|
||||
|
||||
kexArray<surface_t*> surfaces;
|
||||
|
||||
//
|
||||
// Surface_AllocateFromSeg
|
||||
//
|
||||
|
||||
static void Surface_AllocateFromSeg(FLevel &doomMap, MapSegGLEx *seg)
|
||||
{
|
||||
IntSideDef *side;
|
||||
|
@ -277,9 +271,21 @@ static void Surface_AllocateFromLeaf(FLevel &doomMap)
|
|||
printf("\nLeaf surfaces: %i\n", surfaces.Length() - doomMap.NumGLSubsectors);
|
||||
}
|
||||
|
||||
//
|
||||
// Surface_AllocateFromMap
|
||||
//
|
||||
static bool IsDegenerate(const kexVec3 &v0, const kexVec3 &v1, const kexVec3 &v2)
|
||||
{
|
||||
// A degenerate triangle has a zero cross product for two of its sides.
|
||||
float ax = v1.x - v0.x;
|
||||
float ay = v1.y - v0.y;
|
||||
float az = v1.z - v0.z;
|
||||
float bx = v2.x - v0.x;
|
||||
float by = v2.y - v0.y;
|
||||
float bz = v2.z - v0.z;
|
||||
float crossx = ay * bz - az * by;
|
||||
float crossy = az * bx - ax * bz;
|
||||
float crossz = ax * by - ay * bx;
|
||||
float crosslengthsqr = crossx * crossx + crossy * crossy + crossz * crossz;
|
||||
return crosslengthsqr <= 1.e-6f;
|
||||
}
|
||||
|
||||
void Surface_AllocateFromMap(FLevel &doomMap)
|
||||
{
|
||||
|
@ -301,61 +307,52 @@ void Surface_AllocateFromMap(FLevel &doomMap)
|
|||
|
||||
printf("\nSeg surfaces: %i\n", surfaces.Length());
|
||||
|
||||
#ifdef EXPORT_OBJ
|
||||
FILE *f = fopen("level.obj", "w");
|
||||
int curLen = surfaces.Length();
|
||||
for(unsigned int i = 0; i < surfaces.Length(); i++)
|
||||
{
|
||||
for(int j = 0; j < surfaces[i]->numVerts; j++)
|
||||
{
|
||||
fprintf(f, "v %f %f %f\n",
|
||||
-surfaces[i]->verts[j].y / 256.0f,
|
||||
surfaces[i]->verts[j].z / 256.0f,
|
||||
-surfaces[i]->verts[j].x / 256.0f);
|
||||
}
|
||||
}
|
||||
|
||||
int tri;
|
||||
|
||||
for(unsigned int i = 0; i < surfaces.Length(); i++)
|
||||
{
|
||||
fprintf(f, "o surf%i_seg%i\n", i, i);
|
||||
fprintf(f, "f %i %i %i\n", 0+(i*4)+1, 1+(i*4)+1, 2+(i*4)+1);
|
||||
fprintf(f, "f %i %i %i\n", 1+(i*4)+1, 3+(i*4)+1, 2+(i*4)+1);
|
||||
|
||||
tri = 3+(i*4)+1;
|
||||
}
|
||||
|
||||
tri++;
|
||||
#endif
|
||||
|
||||
Surface_AllocateFromLeaf(doomMap);
|
||||
|
||||
printf("Surfaces total: %i\n\n", surfaces.Length());
|
||||
|
||||
#ifdef EXPORT_OBJ
|
||||
for(unsigned int i = curLen; i < surfaces.Length(); i++)
|
||||
{
|
||||
for(int j = 0; j < surfaces[i]->numVerts; j++)
|
||||
{
|
||||
fprintf(f, "v %f %f %f\n",
|
||||
-surfaces[i]->verts[j].y / 256.0f,
|
||||
surfaces[i]->verts[j].z / 256.0f,
|
||||
-surfaces[i]->verts[j].x / 256.0f);
|
||||
}
|
||||
}
|
||||
printf("Building collision mesh..\n\n");
|
||||
|
||||
for(unsigned int i = curLen; i < surfaces.Length(); i++)
|
||||
{
|
||||
fprintf(f, "o surf%i_ssect%i\n", i, i - curLen);
|
||||
fprintf(f, "f ");
|
||||
for(int j = 0; j < surfaces[i]->numVerts; j++)
|
||||
{
|
||||
fprintf(f, "%i ", tri++);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
for (unsigned int i = 0; i < surfaces.Length(); i++)
|
||||
{
|
||||
const auto &s = surfaces[i];
|
||||
int numVerts = s->numVerts;
|
||||
unsigned int pos = doomMap.MeshVertices.Size();
|
||||
|
||||
fclose(f);
|
||||
#endif
|
||||
for (int j = 0; j < numVerts; j++)
|
||||
doomMap.MeshVertices.Push(s->verts[j]);
|
||||
|
||||
if (s->type == ST_FLOOR || s->type == ST_CEILING)
|
||||
{
|
||||
for (int j = 2; j < numVerts; j++)
|
||||
{
|
||||
if (!IsDegenerate(s->verts[0], s->verts[j - 1], s->verts[j]))
|
||||
{
|
||||
doomMap.MeshElements.Push(pos);
|
||||
doomMap.MeshElements.Push(pos + j - 1);
|
||||
doomMap.MeshElements.Push(pos + j);
|
||||
doomMap.MeshSurfaces.Push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s->type == ST_MIDDLESEG || s->type == ST_UPPERSEG || s->type == ST_LOWERSEG)
|
||||
{
|
||||
if (!IsDegenerate(s->verts[0], s->verts[1], s->verts[2]))
|
||||
{
|
||||
doomMap.MeshElements.Push(pos + 0);
|
||||
doomMap.MeshElements.Push(pos + 1);
|
||||
doomMap.MeshElements.Push(pos + 2);
|
||||
doomMap.MeshSurfaces.Push(i);
|
||||
}
|
||||
if (!IsDegenerate(s->verts[1], s->verts[2], s->verts[3]))
|
||||
{
|
||||
doomMap.MeshElements.Push(pos + 1);
|
||||
doomMap.MeshElements.Push(pos + 2);
|
||||
doomMap.MeshElements.Push(pos + 3);
|
||||
doomMap.MeshSurfaces.Push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doomMap.CollisionMesh.reset(new TriangleMeshShape(&doomMap.MeshVertices[0], doomMap.MeshVertices.Size(), &doomMap.MeshElements[0], doomMap.MeshElements.Size(), &doomMap.MeshSurfaces[0]));
|
||||
}
|
||||
|
|
|
@ -69,6 +69,15 @@ void kexTrace::Trace(const kexVec3 &startVec, const kexVec3 &endVec)
|
|||
{
|
||||
start = startVec;
|
||||
end = endVec;
|
||||
|
||||
TraceHit hit = TriangleMeshShape::find_first_hit(map->CollisionMesh.get(), start, end);
|
||||
fraction = hit.fraction;
|
||||
if (fraction < 1.0f)
|
||||
hitSurface = surfaces[hit.surface];
|
||||
else
|
||||
hitSurface = nullptr;
|
||||
|
||||
/*
|
||||
dir = (end - start).Normalize();
|
||||
hitNormal.Clear();
|
||||
hitVector.Clear();
|
||||
|
@ -80,9 +89,11 @@ void kexTrace::Trace(const kexVec3 &startVec, const kexVec3 &endVec)
|
|||
return;
|
||||
}
|
||||
|
||||
TraceBSPNode(map->NumGLNodes - 1);
|
||||
TraceBSPNode(map->NumGLNodes - 1);
|
||||
*/
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
// kexTrace::TraceSurface
|
||||
//
|
||||
|
@ -284,3 +295,4 @@ void kexTrace::TraceBSPNode(int num)
|
|||
TraceBSPNode(node->children[side]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -40,17 +40,19 @@ public:
|
|||
|
||||
kexVec3 start;
|
||||
kexVec3 end;
|
||||
kexVec3 dir;
|
||||
kexVec3 hitNormal;
|
||||
kexVec3 hitVector;
|
||||
surface_t *hitSurface;
|
||||
float fraction;
|
||||
surface_t *hitSurface;
|
||||
float fraction;
|
||||
|
||||
private:
|
||||
FLevel *map;
|
||||
|
||||
#if 0
|
||||
kexVec3 dir;
|
||||
kexVec3 hitNormal;
|
||||
kexVec3 hitVector;
|
||||
|
||||
void TraceBSPNode(int num);
|
||||
void TraceSubSector(int num);
|
||||
void TraceSurface(surface_t *surface);
|
||||
|
||||
FLevel *map;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue