// Unit vector in the v direction Vector3D VectorNormalize(Vector3D v) { float length = VectorMagnitude(v); if (length == 0) return v; return VectorScalarMult( v, 1.0/length); }
V3 EulerIntegrate(V3 deltaP, V3 velcoity, float deltaT) { V3 offset = RVector3Scale(deltaP, 0.5f); VectorScalarMult(&offset, deltaT * deltaT); // 1/2at^2 * vt V3 v = RVector3Scale(velcoity, deltaT); return RVector3Add(offset, v); }
/* ================= R_DrawSpriteModel ================= */ void R_DrawSpriteModel (entity_t *e) { vec3_t point; mspriteframe_t *frame; float *up, *right; vec3_t v_forward, v_right, v_up; msprite_t *psprite; // 2001-12-15 Oriented sprites fix by Atomizer start vec3_t fixed_origin; vec3_t temp; // 2001-12-15 Oriented sprites fix by Atomizer end // don't even bother culling, because it's just a single // polygon without a surface cache frame = R_GetSpriteFrame (e); psprite = currententity->model->cache.data; VectorCopy(e->origin,fixed_origin); // 2001-12-15 Oriented sprites fix by Atomizer if (psprite->type == SPR_ORIENTED) { // bullet marks on walls AngleVectors (currententity->angles, v_forward, v_right, v_up); // 2001-12-15 Oriented sprites fix by Atomizer start VectorScalarMult(v_forward,-2,temp); VectorAdd(temp,fixed_origin,fixed_origin); // 2001-12-15 Oriented sprites fix by Atomizer end up = v_up; right = v_right; } else { // normal sprite up = vup; right = vright; } glColor3f (1,1,1); GL_DisableMultitexture(); GL_Bind(frame->gl_texturenum); glEnable (GL_ALPHA_TEST); glBegin (GL_QUADS); glTexCoord2f (0, 1); // 2001-12-15 Oriented sprites fix by Atomizer start // VectorMA (e->origin, frame->down, up, point); VectorMA (fixed_origin, frame->down, up, point); // 2001-12-15 Oriented sprites fix by Atomizer end VectorMA (point, frame->left, right, point); glVertex3fv (point); glTexCoord2f (0, 0); // 2001-12-15 Oriented sprites fix by Atomizer start // VectorMA (e->origin, frame->up, up, point); VectorMA (fixed_origin, frame->up, up, point); // 2001-12-15 Oriented sprites fix by Atomizer end VectorMA (point, frame->left, right, point); glVertex3fv (point); glTexCoord2f (1, 0); // 2001-12-15 Oriented sprites fix by Atomizer start // VectorMA (e->origin, frame->up, up, point); VectorMA (fixed_origin, frame->up, up, point); // 2001-12-15 Oriented sprites fix by Atomizer end VectorMA (point, frame->right, right, point); glVertex3fv (point); glTexCoord2f (1, 1); // 2001-12-15 Oriented sprites fix by Atomizer start // VectorMA (e->origin, frame->down, up, point); VectorMA (fixed_origin, frame->down, up, point); // 2001-12-15 Oriented sprites fix by Atomizer end VectorMA (point, frame->right, right, point); glVertex3fv (point); glEnd (); glDisable (GL_ALPHA_TEST); }
void MoveRect(CollisionManager* manager, RigidBody* body, Rect rect, V3 deltaP, float deltaT) { V3 velocity; V3 offset = EulerIntegrate(deltaP, body->v, deltaT); float epsilon = 0.001f; VectorAdd(&velocity, RVector3Scale(deltaP, deltaT)); //Check For Collisions for(int it = 0; it < 4; ++it) { Contact contacts[5]; int contact_count = 0; float t = 1.0f; if( VectorLength(offset) ) { V3 point; int result = 0; int bytes = 0; u32 size = 0; int count = 0; char* shapes = manager->shapes; while(bytes < manager->used) { u32* t_shapes = (u32*)(shapes++); size = *t_shapes; if(size == RECT_SIZE) { Rect* r = (Rect*)(shapes + bytes); result = TestRectRect(rect, *r, &point); if(result) { Contact c = {}; c.p1 = ClosestPointOnRect(body->c, *r); c.p2 = ClosestPointOnRect(c.p1, rect); V3 dist = RVector3Sub(c.p1, c.p2); float tHit = Max(0.0f, VectorLength(dist) / VectorLength(offset) - epsilon); if(tHit < t) t = tHit; c.t = tHit; //c.d = CalculateClosingV(body->c, body->v, , ); Rect minkowski_rect = *r; VectorAdd(&minkowski_rect.d, rect.d); c.normal = GetRectNormal(minkowski_rect, body->c); contacts[contact_count++] = c; } } else if(size == SPHERE_SIZE) { Sphere* s = (Sphere*)(shapes + bytes); result = TestSphereRect(*s, rect, &point); if(result) { //TO DO: Create Contact } } else if(size == CAPSULE_SIZE) { Capsule* cap = (Capsule*)(shapes + bytes); result = TestCapsuleRect(*cap, rect); if(result) { } } else { //GJK } bytes += size; ++count; }//End of Entities //Calculate New Positions and Velocities VectorAdd(&body->c, RVector3Scale(offset, t)); if(t == 1.0f) break; { int contact = 0; while(contact < contact_count) { Contact* c = &contacts[contact++]; V3 normal = c->normal; V3 v = body->v; float contact_speed = Dot(normal, v); float dot = Dot(v, normal); VectorScalarMult(&normal, dot); VectorSubtract(&body->v, v, normal); normal = c->normal; dot = Dot(offset, normal); VectorScalarMult(&normal, dot); VectorSubtract(&offset, offset, normal); } } } else { break; } }//End of Iteration }