122 lines
2.5 KiB
C++
122 lines
2.5 KiB
C++
#include "ray.h"
|
|
#include "MaMath.h"
|
|
|
|
|
|
|
|
|
|
float trig_area(vec3f* p1, vec3f* p2, vec3f* p3) {
|
|
|
|
vec3f v1 = vec3f(p2);
|
|
vec3f v2 = vec3f(p3);
|
|
|
|
v1 -= *p1;
|
|
v2 -= *p1;
|
|
|
|
vec3f cross_prd;
|
|
v1.cross(&v2, &cross_prd);
|
|
return cross_prd.mod() / 2.f;
|
|
}
|
|
|
|
Ray::Ray()
|
|
{
|
|
intersect = false;
|
|
obj = nullptr;
|
|
}
|
|
|
|
Ray::~Ray()
|
|
{
|
|
}
|
|
|
|
|
|
void apply_transformation(vec3f *vec, vec3f* iv, vec3f* jv, vec3f* kv, vec3f *pos) {
|
|
|
|
vec3f i = vec3f(iv);
|
|
vec3f j = vec3f(jv);
|
|
vec3f k = vec3f(kv);
|
|
|
|
i *= vec->x;
|
|
j *= vec->y;
|
|
k *= vec->z;
|
|
|
|
*vec = (k += (i += j));
|
|
|
|
*vec += *pos;
|
|
}
|
|
|
|
void norm(vec3f* v1, vec3f* v2, vec3f* v3, vec3f* out)
|
|
{
|
|
vec3f vec1 = vec3f(v2);
|
|
vec3f vec2 = vec3f(v3);
|
|
|
|
vec1 -= v1;
|
|
vec2 -= v1;
|
|
|
|
vec1.cross(&vec2, out);
|
|
*out /= out->mod();
|
|
}
|
|
|
|
void Ray::shoot(_DA_MeshObjects* DA_MeshObjects) {
|
|
|
|
float magnitude = INF;
|
|
vec3f trig_norm = vec3f();
|
|
vec3f intersect_point = vec3f(Dir);
|
|
_DAI_Object* Obj = nullptr;
|
|
|
|
int Objlen = DA_MeshObjects->Obj_GetLength();
|
|
for (int obj_idx = 0; obj_idx < Objlen; obj_idx++) {
|
|
_DAI_Object* tmp_Obj = DA_MeshObjects->Obj_GetItem(obj_idx);
|
|
int triglen = tmp_Obj->Mesh.DA_Trigs->DA_Trigs_GetLength();
|
|
for (int trig_idx = 0; trig_idx < triglen; trig_idx++) {
|
|
_DAI_Trig* trig = tmp_Obj->Mesh.DA_Trigs->DAI_Trig_GetItem(trig_idx);
|
|
|
|
vec3f v1 = vec3f(trig->v1->vec);
|
|
vec3f v2 = vec3f(trig->v2->vec);
|
|
vec3f v3 = vec3f(trig->v3->vec);
|
|
|
|
apply_transformation(&v1, &tmp_Obj->unit_vx, &tmp_Obj->unit_vy, &tmp_Obj->unit_vz, &tmp_Obj->Position);
|
|
apply_transformation(&v2, &tmp_Obj->unit_vx, &tmp_Obj->unit_vy, &tmp_Obj->unit_vz, &tmp_Obj->Position);
|
|
apply_transformation(&v3, &tmp_Obj->unit_vx, &tmp_Obj->unit_vy, &tmp_Obj->unit_vz, &tmp_Obj->Position);
|
|
|
|
vec3f tmp_trig_norm = vec3f();
|
|
norm(&v1, &v2, &v3, &tmp_trig_norm);
|
|
|
|
|
|
if (tmp_trig_norm * Dir >= 0) {
|
|
tmp_trig_norm.invert();
|
|
}
|
|
|
|
vec3f tmp = vec3f(Pos);
|
|
tmp -= v1;
|
|
|
|
float tmp_magnitude = (tmp_trig_norm * tmp) / -(tmp_trig_norm * Dir);
|
|
|
|
vec3f tmp_intrsect_p = vec3f(Dir);
|
|
tmp_intrsect_p *= tmp_magnitude;
|
|
tmp_intrsect_p += Pos;
|
|
|
|
if (trig_area(&v1, &v2, &v3) >=
|
|
trig_area(&tmp_intrsect_p, &v2, &v3) +
|
|
trig_area(&v1, &tmp_intrsect_p, &v3) +
|
|
trig_area(&v1, &v2, &tmp_intrsect_p) - 0.00001f) {
|
|
|
|
if (magnitude > tmp_magnitude && tmp_magnitude > 0)
|
|
{
|
|
Obj = tmp_Obj;
|
|
trig_norm = tmp_trig_norm;
|
|
intersect_point = tmp_intrsect_p;
|
|
magnitude = tmp_magnitude;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (magnitude == INF) {
|
|
intersect = false;
|
|
return;
|
|
}
|
|
|
|
intersect = true;
|
|
obj = Obj;
|
|
intersect_p = intersect_point;
|
|
Norm = trig_norm;
|
|
}
|