예제 #1
0
파일: plane.c 프로젝트: hgl888/kazmath
kmVec3* kmPlaneGetIntersection(kmVec3* pOut, const kmPlane* p1, const kmPlane* p2, const kmPlane* p3) {
    kmVec3 n1, n2, n3, cross;
    kmVec3 r1, r2, r3;
    double denom = 0;
    
    kmVec3Fill(&n1, p1->a, p1->b, p1->c);
    kmVec3Fill(&n2, p2->a, p2->b, p2->c);
    kmVec3Fill(&n3, p3->a, p3->b, p3->c);
    
    kmVec3Cross(&cross, &n2, &n3);

    denom = kmVec3Dot(&n1, &cross);

    if (kmAlmostEqual(denom, 0.0)) {
        return NULL;
    }

    kmVec3Cross(&r1, &n2, &n3);
    kmVec3Cross(&r2, &n3, &n1);
    kmVec3Cross(&r3, &n1, &n2);

    kmVec3Scale(&r1, &r1, -p1->d);
    kmVec3Scale(&r2, &r2, p2->d);
    kmVec3Scale(&r3, &r3, p3->d);

    kmVec3Subtract(pOut, &r1, &r2);
    kmVec3Subtract(pOut, pOut, &r3);
    kmVec3Scale(pOut, pOut, 1.0 / denom);

    /*p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom;*/

    return pOut;
}
예제 #2
0
파일: plane.c 프로젝트: Irrelon/kazmath
/**
 * Creates a plane from 3 points. The result is stored in pOut.
 * pOut is returned.
 */
kmPlane* const kmPlaneFromPoints(kmPlane* pOut, const kmVec3* p1, const kmVec3* p2, const kmVec3* p3)
{
    /*
    v = (B − A) × (C − A)
    n = 1⁄|v| v
    Outa = nx
    Outb = ny
    Outc = nz
    Outd = −n⋅A
    */

    kmVec3 n, v1, v2;
    kmVec3Subtract(&v1, p2, p1); //Create the vectors for the 2 sides of the triangle
    kmVec3Subtract(&v2, p3, p1);
    kmVec3Cross(&n, &v1, &v2); //Use the cross product to get the normal

    kmVec3Normalize(&n, &n); //Normalize it and assign to pOut->m_N

    pOut->a = n.x;
    pOut->b = n.y;
    pOut->c = n.z;
    pOut->d = kmVec3Dot(kmVec3Scale(&n, &n, -1.0), p1);

    return pOut;
}
예제 #3
0
파일: ray3.c 프로젝트: Kazade/kazmath
kmBool kmRay3IntersectTriangle(const kmRay3* ray, const kmVec3* v0, const kmVec3* v1, const kmVec3* v2, kmVec3* intersection, kmVec3* normal, kmScalar* distance) {
    kmVec3 e1, e2, pvec, tvec, qvec, dir;
    kmScalar det, inv_det, u, v, t;

    kmVec3Normalize(&dir, &ray->dir);

    kmVec3Subtract(&e1, v1, v0);
    kmVec3Subtract(&e2, v2, v0);

    kmVec3Cross(&pvec, &dir, &e2);
    det = kmVec3Dot(&e1, &pvec);

    /* Backfacing, discard. */
    if(det < kmEpsilon) {
        return KM_FALSE;
    }

    if(kmAlmostEqual(det, 0)) {
        return KM_FALSE;
    }

    inv_det = 1.0 / det;

    kmVec3Subtract(&tvec, &ray->start, v0);

    u = inv_det * kmVec3Dot(&tvec, &pvec);
    if(u < 0.0 || u > 1.0) {
        return KM_FALSE;
    }

    kmVec3Cross(&qvec, &tvec, &e1);
    v = inv_det * kmVec3Dot(&dir, &qvec);
    if(v < 0.0 || (u + v) > 1.0) {
        return KM_FALSE;
    }

    t = inv_det * kmVec3Dot(&e2, &qvec);
    if(t > kmEpsilon && (t*t) <= kmVec3LengthSq(&ray->dir)) {
        kmVec3 scaled;
        *distance = t; /* Distance */
        kmVec3Cross(normal, &e1, &e2); /* Surface normal of collision */
        kmVec3Normalize(normal, normal);
        kmVec3Normalize(&scaled, &dir);
        kmVec3Scale(&scaled, &scaled, *distance);
        kmVec3Add(intersection, &ray->start, &scaled);
        return KM_TRUE;
    }

    return KM_FALSE;
}
예제 #4
0
파일: vec3.c 프로젝트: aonorin/kazmath
/**
 * Reflects a vector about a given surface normal. The surface normal is
 * assumed to be of unit length.
 */
kmVec3* kmVec3Reflect(kmVec3* pOut, const kmVec3* pIn, const kmVec3* normal) {
  kmVec3 tmp;
  kmVec3Scale(&tmp, normal, 2.0f * kmVec3Dot(pIn, normal));
  kmVec3Subtract(pOut, pIn, &tmp);

  return pOut;
}
예제 #5
0
파일: plane.c 프로젝트: hgl888/kazmath
/* Added by tlensing (http://icedcoffee-framework.org)*/
kmVec3* kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
{
    /*
     n = (Planea, Planeb, Planec)
     d = V − U
     Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
     */
    kmVec3 d; /* direction from V1 to V2*/
    kmScalar nt;
    kmScalar dt;
    kmScalar t;
    kmVec3 n; /* plane normal*/

    kmVec3Subtract(&d, pV2, pV1); /* Get the direction vector*/
    
    n.x = pP->a;
    n.y = pP->b;
    n.z = pP->c;
    kmVec3Normalize(&n, &n);
    
    nt = -(n.x * pV1->x + n.y * pV1->y + n.z * pV1->z + pP->d);
    dt = (n.x * d.x + n.y * d.y + n.z * d.z);
    
    if (fabs(dt) < kmEpsilon) {
        pOut = NULL;
        return pOut; /* line parallel or contained*/
    }
    
    t = nt/dt;
    pOut->x = pV1->x + d.x * t;
    pOut->y = pV1->y + d.y * t;
    pOut->z = pV1->z + d.z * t;
    
    return pOut;
}
예제 #6
0
kmMat3* kmMat3LookAt(kmMat3* pOut, const kmVec3* pEye,
                     const kmVec3* pCenter, const kmVec3* pUp)
{
    kmVec3 f, up, s, u;

    kmVec3Subtract(&f, pCenter, pEye);
    kmVec3Normalize(&f, &f);

    kmVec3Assign(&up, pUp);
    kmVec3Normalize(&up, &up);

    kmVec3Cross(&s, &f, &up);
    kmVec3Normalize(&s, &s);

    kmVec3Cross(&u, &s, &f);
    kmVec3Normalize(&s, &s);

    pOut->mat[0] = s.x;
    pOut->mat[3] = s.y;
    pOut->mat[6] = s.z;

    pOut->mat[1] = u.x;
    pOut->mat[4] = u.y;
    pOut->mat[7] = u.z;

    pOut->mat[2] = -f.x;
    pOut->mat[5] = -f.y;
    pOut->mat[8] = -f.z;

    return pOut;
}
예제 #7
0
kmQuaternion *sls_trackball_calc_quat(kmQuaternion *out, float trackball_radius,
                                      float trackball_speed, kmVec2 const *p1,
                                      kmVec2 const *p2) {
  //sls_log_info("p1 %f %f, p2 %f %f", p1->x, p1->y, p2->x, p2->y);

  kmVec3 axis;
  kmVec3 _p1, _p2, dir;
  float phi;
  float t;
  float epsilon = 0.001;
  if (sls_vec2_near(p1, p2, epsilon)) {
    // zero rotation
    kmQuaternionIdentity(out);
    return out;
  }

  _p1 = (kmVec3){p1->x, p1->y, sls_tb_project_to_sphere(trackball_radius, p1)};
  _p2 = (kmVec3){p2->x, p2->y, sls_tb_project_to_sphere(trackball_radius, p2)};

  kmVec3Subtract(&dir, &_p1, &_p2);

  kmVec3Cross(&axis, &_p2, &_p1);

  t = kmVec3Length(&dir) / (2.0f * trackball_radius);
  t = fminf(fmaxf(-1.f, t), 1.f);
  phi = 2.0f * asinf(t) * trackball_speed;
  kmQuaternion tmp_a, tmp_b;
  kmQuaternionRotationAxisAngle(&tmp_a, &axis, phi);

  tmp_b = *out;

  return kmQuaternionMultiply(out, &tmp_a, &tmp_b);
  ;
}
예제 #8
0
파일: plane.c 프로젝트: Irrelon/kazmath
kmVec3* const kmPlaneIntersectLine(kmVec3* pOut, const kmPlane* pP, const kmVec3* pV1, const kmVec3* pV2)
{
    /*
	    n = (Planea, Planeb, Planec)
	    d = V − U
	    Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
    */
    kmVec3 d;
    assert(0 && "Not implemented");


    kmVec3Subtract(&d, pV2, pV1); //Get the direction vector


    //TODO: Continue here!
    /*if (fabs(kmVec3Dot(&pP->m_N, &d)) > kmEpsilon)
    {
	    //If we get here then the plane and line are parallel (i.e. no intersection)
	    pOut = nullptr; //Set to nullptr

	    return pOut;
    } */

    return NULL;
}
예제 #9
0
std::vector<LightID> NullPartitioner::lights_within_range(const kmVec3& location) {
    std::vector<std::pair<LightID, float> > lights_in_range;

    //Find all the lights within range of the location
    for(LightID light_id: all_lights_) {
        Light& light = scene().light(light_id);

        kmVec3 diff;
        kmVec3Subtract(&diff, &location, &light.position());
        float dist = kmVec3Length(&diff);
        //if(dist < light.range()) {
            lights_in_range.push_back(std::make_pair(light_id, dist));
        //}
    }

    //Sort them by distance
    std::sort(lights_in_range.begin(), lights_in_range.end(),
              [](std::pair<LightID, float> lhs, std::pair<LightID, float> rhs) { return lhs.second < rhs.second; });

    //Return the LightIDs only
    std::vector<LightID> result;
    for(std::pair<LightID, float> p: lights_in_range) {
        result.push_back(p.first);
    }
    return result;
}
예제 #10
0
파일: vec3.c 프로젝트: aonorin/kazmath
void kmVec3OrthoNormalize(kmVec3* normal, kmVec3* tangent) {
    kmVec3 proj;

    kmVec3Normalize(normal, normal);

    kmVec3Scale(&proj, normal, kmVec3Dot(tangent, normal));
    kmVec3Subtract(tangent, tangent, &proj);
    kmVec3Normalize(tangent, tangent);
}
예제 #11
0
void BoundingBox::getCenter(kmVec3* dst) const
{
    GP_ASSERT(dst);
	kmVec3Subtract(dst, &max, &min);
    //dst->set(min, max);
    //dst->scale(0.5f);
	kmVec3Scale(dst, dst, 0.5f);
    //dst->add(min);
	kmVec3Add(dst, dst, &min);
	return;
}
예제 #12
0
void ViewTransform::LazyAdjust() const
{
    if(!_dirty) return;
    kmVec3Subtract(&_adjustDir, &_focus, &_position);
    kmVec3Normalize(&_adjustDir, &_adjustDir);
    
    kmVec3Cross(&_adjustRight, &_adjustDir, &_up);
    kmVec3Normalize(&_adjustRight, &_adjustRight);
    
    kmVec3Cross(&_adjustUp, &_adjustRight, &_adjustDir);
    kmVec3Normalize(&_adjustUp, &_adjustUp);
    
    _dirty = false;
}
예제 #13
0
파일: camera.c 프로젝트: Cloudef/glhck
/* \brief cast a ray from camera at specified relative coordinate */
GLHCKAPI kmRay3* glhckCameraCastRayFromPoint(glhckCamera *object, kmRay3 *pOut, const kmVec2 *point)
{
   CALL(2, "%p, "VEC2S, pOut, VEC2(point));

   glhckFrustum *frustum = glhckCameraGetFrustum(object);

   kmVec3 nu, nv, fu, fv;
   kmVec3Subtract(&nu,
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_RIGHT],
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]);
   kmVec3Subtract(&nv,
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_TOP_LEFT],
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]);
   kmVec3Subtract(&fu,
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_RIGHT],
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]);
   kmVec3Subtract(&fv,
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_TOP_LEFT],
	 &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]);

   kmVec3Scale(&nu, &nu, point->x);
   kmVec3Scale(&nv, &nv, point->y);
   kmVec3Scale(&fu, &fu, point->x);
   kmVec3Scale(&fv, &fv, point->y);

   pOut->start = frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT];
   pOut->dir = frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT];

   kmVec3Add(&pOut->start, &pOut->start, &nu);
   kmVec3Add(&pOut->start, &pOut->start, &nv);
   kmVec3Add(&pOut->dir, &pOut->dir, &fu);
   kmVec3Add(&pOut->dir, &pOut->dir, &fv);
   kmVec3Subtract(&pOut->dir, &pOut->dir, &pOut->start);

   RET(2, "%p", pOut);
   return pOut;
}
예제 #14
0
/* Target camera */
void dlTargetCamera( dlCamera *object, kmVec3 *target )
{
   kmVec3 toTarget;
   CALL("%p, vec3[%f, %f, %f]", object,
         target->x, target->y, target->z);

   if(!object)
      return;

   object->target = *target;
   kmVec3Subtract( &toTarget, &object->target, &object->translation );

   /* update rotation */
   kmVec3GetHorizontalAngle( &object->rotation, &toTarget );

   object->transform_changed = 1;
}
예제 #15
0
/**
 * Builds a translation matrix in the same way as gluLookAt()
 * the resulting matrix is stored in pOut. pOut is returned.
 */
kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
                     const kmVec3* pCenter, const kmVec3* pUp)
{
    kmVec3 f, up, s, u;
    kmMat4 translate;

    kmVec3Subtract(&f, pCenter, pEye);
    kmVec3Normalize(&f, &f);

    kmVec3Assign(&up, pUp);
    kmVec3Normalize(&up, &up);

    kmVec3Cross(&s, &f, &up);
    kmVec3Normalize(&s, &s);

    kmVec3Cross(&u, &s, &f);
    kmVec3Normalize(&s, &s);

    kmMat4Identity(pOut);

    pOut->mat[0] = s.x;
    pOut->mat[4] = s.y;
    pOut->mat[8] = s.z;

    pOut->mat[1] = u.x;
    pOut->mat[5] = u.y;
    pOut->mat[9] = u.z;

    pOut->mat[2] = -f.x;
    pOut->mat[6] = -f.y;
    pOut->mat[10] = -f.z;

    kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
    kmMat4Multiply(pOut, pOut, &translate);

    return pOut;
}
예제 #16
0
파일: mat4.c 프로젝트: hgl888/kazmath
/**
 * Builds a translation matrix in the same way as gluLookAt()
 * the resulting matrix is stored in pOut. pOut is returned.
 */
kmMat4* kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
                     const kmVec3* pCenter, const kmVec3* pUp)
{
    kmVec3 f;
    kmVec3 s;
    kmVec3 u;

    kmVec3Subtract(&f, pCenter, pEye);
    kmVec3Normalize(&f, &f);

    kmVec3Cross(&s, &f, pUp);
    kmVec3Normalize(&s, &s);

    kmVec3Cross(&u, &s, &f);

    pOut->mat[0] = s.x;
    pOut->mat[1] = u.x;
    pOut->mat[2] = -f.x;
    pOut->mat[3] = 0.0;

    pOut->mat[4] = s.y;
    pOut->mat[5] = u.y;
    pOut->mat[6] = -f.y;
    pOut->mat[7] = 0.0;

    pOut->mat[8] = s.z;
    pOut->mat[9] = u.z;
    pOut->mat[10] = -f.z;
    pOut->mat[11] = 0.0;

    pOut->mat[12] = -kmVec3Dot(&s, pEye);
    pOut->mat[13] = -kmVec3Dot(&u, pEye);
    pOut->mat[14] = kmVec3Dot(&f, pEye);
    pOut->mat[15] = 1.0;

    return pOut;
}
예제 #17
0
파일: camera.c 프로젝트: Cloudef/glhck
/* \brief calculate projection matrix */
static void _glhckCameraProjectionMatrix(glhckCamera *object)
{
   kmScalar w, h, distanceFromTarget;
   kmVec3 toTarget;

   CALL(2, "%p", object);
   assert(object);
   assert(object->view.viewport.w > 0.0f && object->view.viewport.h > 0.0f);

   switch(object->view.projectionType) {
      case GLHCK_PROJECTION_ORTHOGRAPHIC:
	 w = object->view.viewport.w > object->view.viewport.h ? 1 :
	    object->view.viewport.w / object->view.viewport.h;
	 h = object->view.viewport.w < object->view.viewport.h ? 1 :
	    object->view.viewport.h / object->view.viewport.w;

	 kmVec3Subtract(&toTarget, &object->object->view.translation, &object->object->view.target);
	 distanceFromTarget = kmVec3Length(&toTarget);

	 w *= (distanceFromTarget+object->view.near)/2;
	 h *= (distanceFromTarget+object->view.near)/2;

	 kmMat4OrthographicProjection(&object->view.projection,
	       -w, w, -h, h, object->view.near, object->view.far);
	 break;

      case GLHCK_PROJECTION_PERSPECTIVE:
      default:
	 kmMat4PerspectiveProjection(
	       &object->view.projection,
	       object->view.fov,
	       (float)object->view.viewport.w/(float)object->view.viewport.h,
	       object->view.near, object->view.far);
	 break;
   }
}
예제 #18
0
/* Calculate view matrix */
static void dlCameraCalculateViewMatrix( dlCamera *object )
{
   kmVec3 tgtv, upvector;
   kmScalar dp;

   CALL("%p", object);

   kmVec3Subtract( &tgtv, &object->target, &object->translation );

   kmVec3Normalize( &tgtv, &tgtv );
   kmVec3Normalize( &upvector, &object->upVector );

   dp = kmVec3Dot( &tgtv, &upvector );
   if( dp == 1.f )
   {
      upvector.x += 0.5f;
   }

   kmMat4LookAt( &object->view, &object->translation, &object->target, &upvector );

   /* Frustum recalculation here */

   kmMat4Multiply( &object->matrix, &object->projection, &object->view );
}
예제 #19
0
void Frustum::setupProjectionPerspective(const ViewTransform& view, float left, float right, float top, float bottom, float nearPlane, float farPlane)
{
    kmVec3 cc = view.getPosition();
    kmVec3 cDir = view.getDirection();
    kmVec3 cRight = view.getRight();
    kmVec3 cUp = view.getUp();
    
    kmVec3Normalize(&cDir, &cDir);
    kmVec3Normalize(&cRight, &cRight);
    kmVec3Normalize(&cUp, &cUp);
    
    kmVec3 nearCenter;
    kmVec3 farCenter;
    
    kmVec3Scale(&nearCenter, &cDir, nearPlane);
    kmVec3Add(&nearCenter, &nearCenter, &cc);
    
    kmVec3Scale(&farCenter, &cDir, farPlane);
    kmVec3Add(&farCenter, &farCenter, &cc);
    
    //near
    {
        kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir);
    }
    
    //far
    {
        kmVec3 normal;
        kmVec3Scale(&normal, &cDir, -1);
        kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal);
    }
    
    //left
    {
        kmVec3 point;
        kmVec3Scale(&point, &cRight, left);
        kmVec3Add(&point, &point, &nearCenter);
        
        kmVec3 normal;
        kmVec3Subtract(&normal, &point, &cc);
        kmVec3Cross(&normal, &normal, &cUp);
        kmVec3Normalize(&normal, &normal);
        
        kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal);
    }
    
    //right
    {
        kmVec3 point;
        kmVec3Scale(&point, &cRight, right);
        kmVec3Add(&point, &point, &nearCenter);
        
        kmVec3 normal;
        kmVec3Subtract(&normal, &point, &cc);
        kmVec3Cross(&normal, &cUp, &normal);
        kmVec3Normalize(&normal, &normal);
        
        kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal);
    }
    
    //bottom
    {
        kmVec3 point;
        kmVec3Scale(&point, &cUp, bottom);
        kmVec3Add(&point, &point, &nearCenter);
        
        kmVec3 normal;
        kmVec3Subtract(&normal, &point, &cc);
        kmVec3Cross(&normal, &cRight, &normal);
        kmVec3Normalize(&normal, &normal);
        
        kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal);
    }
    
    //top
    {
        kmVec3 point;
        kmVec3Scale(&point, &cUp, top);
        kmVec3Add(&point, &point, &nearCenter);
        
        kmVec3 normal;
        kmVec3Subtract(&normal, &point, &cc);
        kmVec3Cross(&normal, &normal, &cRight);
        kmVec3Normalize(&normal, &normal);
        
        kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal);
    }
    
}
예제 #20
0
void CComponentGraphic_GL::DrawDependencyLine( float /*cellSize*/, const CDependencyDescription* pDependency )
{
    CreateMaterials();

    CQuadBatchRenderGroup *renderGroup = dynamic_cast<CQuadBatchRenderGroup *>(
        CRenderGroupManager::GetInstance()->GetRenderGroup(CRenderGroupManager::LAYER_GUI));
    BEATS_ASSERT(renderGroup);

    BEATS_ASSERT(pDependency != NULL);
    if (pDependency->IsVisible())
    {
        size_t uDependencyLineCount = pDependency->GetDependencyLineCount();
        for (size_t i = 0; i < uDependencyLineCount; ++i)
        {
            CDependencyDescriptionLine* pDependencyLine = pDependency->GetDependencyLine(i);
            const SVertex* pData = pDependencyLine->GetRectArray();
            static const size_t SVERTEX_SIZE = 24;
            CSerializer serializer(SVERTEX_SIZE * 4, (void*)pData);
            DWORD tmpColor = 0;
            CQuadPTC dependencyLine;
            serializer >> dependencyLine.br.position.x;
            serializer >> dependencyLine.br.position.y;
            serializer >> dependencyLine.br.position.z;
            serializer >> tmpColor;
            serializer >> dependencyLine.br.tex.u;
            serializer >> dependencyLine.br.tex.v;

            serializer >> dependencyLine.bl.position.x;
            serializer >> dependencyLine.bl.position.y;
            serializer >> dependencyLine.bl.position.z;
            serializer >> tmpColor;
            serializer >> dependencyLine.bl.tex.u;
            serializer >> dependencyLine.bl.tex.v;

            serializer >> dependencyLine.tr.position.x;
            serializer >> dependencyLine.tr.position.y;
            serializer >> dependencyLine.tr.position.z;
            serializer >> tmpColor;
            serializer >> dependencyLine.tr.tex.u;
            serializer >> dependencyLine.tr.tex.v;

            serializer >> dependencyLine.tl.position.x;
            serializer >> dependencyLine.tl.position.y;
            serializer >> dependencyLine.tl.position.z;
            serializer >> tmpColor;
            serializer >> dependencyLine.tl.tex.u;
            serializer >> dependencyLine.tl.tex.v;

            renderGroup->AddQuad(dependencyLine, m_pMaterials[pDependencyLine->IsSelected() ? eCT_SelectedLine : eCT_NormalLine]);

            const SVertex* pArrowData = pDependencyLine->GetArrowRectArray();
            CSerializer serializerArrow(SVERTEX_SIZE * 4, (void*)pArrowData);
            CQuadPTC arrow;
            serializerArrow >> arrow.br.position.x;
            serializerArrow >> arrow.br.position.y;
            serializerArrow >> arrow.br.position.z;
            serializerArrow >> tmpColor;
            serializerArrow >> arrow.br.tex.u;
            serializerArrow >> arrow.br.tex.v;

            serializerArrow >> arrow.bl.position.x;
            serializerArrow >> arrow.bl.position.y;
            serializerArrow >> arrow.bl.position.z;
            serializerArrow >> tmpColor;
            serializerArrow >> arrow.bl.tex.u;
            serializerArrow >> arrow.bl.tex.v;

            serializerArrow >> arrow.tr.position.x;
            serializerArrow >> arrow.tr.position.y;
            serializerArrow >> arrow.tr.position.z;
            serializerArrow >> tmpColor;
            serializerArrow >> arrow.tr.tex.u;
            serializerArrow >> arrow.tr.tex.v;

            serializerArrow >> arrow.tl.position.x;
            serializerArrow >> arrow.tl.position.y;
            serializerArrow >> arrow.tl.position.z;
            serializerArrow >> tmpColor;
            serializerArrow >> arrow.tl.tex.u;
            serializerArrow >> arrow.tl.tex.v;

            renderGroup->AddQuad(arrow, m_pMaterials[pDependencyLine->IsSelected() ? eCT_SelectedArrow : eCT_NormalArrow]);

            //Render index number for dependency list.
            if (pDependency->IsListType())
            {
                kmVec3 deltaDirection;
                kmVec3Subtract(&deltaDirection, &dependencyLine.tr.position, &dependencyLine.tl.position);
                float fXPos = (dependencyLine.tl.position.x + deltaDirection.x * 0.15f);
                static const float fHardCodeOffset = 8;
                float fYPos = (dependencyLine.tl.position.y + deltaDirection.y * 0.15f - fHardCodeOffset);

                TCHAR szIndex[8];
                _stprintf(szIndex, _T("%d"), pDependencyLine->GetIndex());
                m_pFont->RenderText(szIndex, fXPos, fYPos, 0xffff00ff);
            }
        }
    }
예제 #21
0
int process_inputs()
{
	// Get mouse position
        double xpos, ypos;
        glfwGetCursorPos(mainWindow, &xpos, &ypos);

        // Reset mouse position for next frame
        glfwSetCursorPos(mainWindow, SCREEN_WIDTH/2, SCREEN_HEIGHT/2);

        // Compute new orientation
        horizontalAngle += mouseSpeed * (float)( SCREEN_WIDTH/2 - xpos );
        verticalAngle   += mouseSpeed * (float)( SCREEN_HEIGHT/2 - ypos );
	/* If F1, reload */
	if (glfwGetKey(mainWindow, GLFW_KEY_F1)) {
		Engine_Reload();
	}
	/* If F2, reset view */
	if (glfwGetKey(mainWindow, GLFW_KEY_F2)) {
		printf("Camera reset.\n");
		Camera_Reset();
	}
	/* If tab, change lookat to next mesh */
	if (glfwGetKey(mainWindow, GLFW_KEY_TAB)) {
		//Camera_LookAtNext();
	}
	/* Move closer */
	//if (glfwGetKey(mainWindow, GLFW_KEY_W)) {
	//	ypos = 100;
	//}
	/* Move further */
	//if (glfwGetKey(mainWindow, GLFW_KEY_S)) {
	//	ypos = -100;
	//}
	/* Move left */
	//if (glfwGetKey(mainWindow, GLFW_KEY_A)) {
	//	xpos = 100;
	//}
	/* Move right */
	//if (glfwGetKey(mainWindow, GLFW_KEY_D)) {
	//	xpos = -100;
	//}

	// Compute new orientation
	//horizontalAngle += mouseSpeed * (float)(1024/2 - xpos );
	//verticalAngle   += mouseSpeed * (float)( 768/2 - ypos );
	horizontalAngle += mouseSpeed * xpos;
	verticalAngle += mouseSpeed * ypos;
	//printf("horizontalAngle is %f,	and verticalAngle is %f.\n", horizontalAngle, verticalAngle);

	// Direction : Spherical coordinates to Cartesian coordinates conversion
	float temp1 = cos(verticalAngle) * sin(horizontalAngle);
	float temp2 = sin(verticalAngle);
	float temp3 = cos(verticalAngle) * cos(horizontalAngle);
	kmVec3 direction = {temp1, temp2, temp3};
	
	// Right vector
	kmVec3 right = {
		sin(horizontalAngle - 3.14f/2.0f), 
		0,
		cos(horizontalAngle - 3.14f/2.0f)
	};
	
	// Up vector
	kmVec3 up = *kmVec3Cross(&up, &right, &direction );

	// Move forward
	if (glfwGetKey( mainWindow, GLFW_KEY_UP ) == GLFW_PRESS){
		kmVec3Add(&position, &position, kmVec3Scale(&position, &direction, deltaTime * speed));
	}
	// Move backward
	if (glfwGetKey( mainWindow, GLFW_KEY_DOWN ) == GLFW_PRESS){
		kmVec3Subtract(&position, &position, kmVec3Scale(&position, &direction, deltaTime * speed));
	}
	// Strafe right
	if (glfwGetKey( mainWindow, GLFW_KEY_RIGHT ) == GLFW_PRESS){
		kmVec3Add(&position, &position, kmVec3Scale(&position, &right, deltaTime * speed));
	}
	// Strafe left
	if (glfwGetKey( mainWindow, GLFW_KEY_LEFT ) == GLFW_PRESS){
		kmVec3Subtract(&position, &position, kmVec3Scale(&position, &right, deltaTime * speed));
	}

	float FoV = initialFoV;

	kmMat4PerspectiveProjection(&ProjectionMatrix, FoV, (16.0f / 8.0f), 0.1f, 100.0f);
	// Camera matrix
	//ViewMatrix       = glm::lookAt(
	//							position,           // Camera is here
	//							position+direction, // and looks here : at the same position, plus "direction"
	//							up                  // Head is up (set to 0,-1,0 to look upside-down)
	//					   );

	kmVec3 p_eye;
	p_eye = position;

	kmVec3 p_ctr;
	p_ctr = *kmVec3Add(&p_ctr, &position, &direction);

	kmVec3 p_up;
	p_up = up;
	kmMat4LookAt(&ViewMatrix, &p_eye, &p_ctr, &p_up);
	kmMat4Identity(&ModelMatrix);
	kmMat4 temp_mat;
	kmMat4Multiply(&temp_mat, &ViewMatrix, &ModelMatrix);
	kmMat4Multiply(&MVP, &ProjectionMatrix, &temp_mat );

	//printf("Matrix contains:\n");
	//printf("%f, %f, %f, %f\n", MVP.mat[0], MVP.mat[1], MVP.mat[2], MVP.mat[3]);
	//printf("%f, %f, %f, %f\n", MVP.mat[4], MVP.mat[5], MVP.mat[6], MVP.mat[7]);
	//printf("%f, %f, %f, %f\n", MVP.mat[8], MVP.mat[9], MVP.mat[10], MVP.mat[11]);
	//printf("%f, %f, %f, %f\n", MVP.mat[12], MVP.mat[13], MVP.mat[14], MVP.mat[15]);
	
	return 0;
}
예제 #22
0
int main()
{

    lightDir.x=0.5;
    lightDir.y=.7;
    lightDir.z=-0.5;
    kmVec3Normalize(&lightDir,&lightDir);

    // creates a window and GLES context
    // create a window and GLES context
	if (!glfwInit())
		exit(EXIT_FAILURE);

	window = glfwCreateWindow(width, height, "I N V A D E R S ! ! !", NULL, NULL);
	if (!window) {
		glfwTerminate();
		exit(EXIT_FAILURE);
	}
	glfwSetWindowSizeCallback(window,window_size_callback);	
	glfwMakeContextCurrent(window);



    // all the shaders have at least texture unit 0 active so
    // activate it now and leave it active
    glActiveTexture(GL_TEXTURE0);

    // The obj shapes and their textures are loaded
    cubeTex = loadPNG("resources/textures/dice.png");
    loadObj(&cubeObj, "resources/models/cube.gbo",
            "resources/shaders/textured.vert", "resources/shaders/textured.frag");


    shipTex = loadPNG("resources/textures/shipv2.png");
    loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj);

    alienTex = loadPNG("resources/textures/alien.png");
    loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj);

    shotTex = loadPNG("resources/textures/shot.png");
    loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj);

    expTex = loadPNG("resources/textures/explosion.png");


    playerPos.x = 0;
    playerPos.y = 0;
    playerPos.z = 0;

    kmMat4Identity(&view);

    pEye.x = 0;
    pEye.y = 2;
    pEye.z = 4;
    pCenter.x = 0;
    pCenter.y = 0;
    pCenter.z = -5;
    pUp.x = 0;
    pUp.y = 1;
    pUp.z = 0;

    kmMat4LookAt(&view, &pEye, &pCenter, &pUp);

    // projection matrix, as distance increases
    // the way the model is drawn is effected
    kmMat4Identity(&projection);
    kmMat4PerspectiveProjection(&projection, 45,
                                (float)width/ height, 0.1, 1000);

    glViewport(0, 0, width,height);

    // these two matrices are pre combined for use with each model render
    kmMat4Assign(&vp, &projection);
    kmMat4Multiply(&vp, &vp, &view);

    // initialises glprint's matrix shader and texture
    initGlPrint(width,height);

	font1=createFont("resources/textures/font.png",0,256,16,16,16);
	font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48);

    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_BLEND);	// only used by glprintf
    glEnable(GL_DEPTH_TEST);


    int num_frames = 0;

    bool quit = false;

    resetAliens();

    for (int n = 0; n < MAX_PLAYER_SHOTS; n++) {
        playerShots[n].alive = false;
    }


    initPointClouds("resources/shaders/particle.vert",
                    "resources/shaders/particle.frag",(float)width/24.0);



    for (int n = 0; n < MAX_ALIENS; n++) {
        aliens[n].explosion=createPointCloud(40);
        resetExposion(aliens[n].explosion); // sets initials positions
    }

	glClearColor(0, .5, 1, 1);

    while (!quit) {		// the main loop

        clock_gettime(0,&ts);  // note the time BEFORE we start to render the current frame
		glfwPollEvents();


        if (glfwGetKey(window,GLFW_KEY_ESCAPE)==GLFW_PRESS || glfwWindowShouldClose(window))
            quit = true;

        float rad;		// radians rotation based on frame counter

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        frame++;
        rad = frame * (0.0175f * 2);

        //kmMat4Identity(&model);
        kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z);
        playerCroll +=
            (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral)
             / 2);
//        kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3);	//
		kmMat4RotationYawPitchRoll(&rot,0,3.1416,-playerCroll*3);
        kmMat4Multiply(&model, &model, &rot);
        
        kmMat4Assign(&mvp, &vp);
        kmMat4Multiply(&mvp, &mvp, &model);

        kmMat4Assign(&mv, &view);
        kmMat4Multiply(&mv, &mv, &model);

        glBindTexture(GL_TEXTURE_2D, shipTex);
        drawObj(&shipObj, &mvp, &mv, lightDir, viewDir);

        glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16,
                 font2,"frame=%i", frame);

        kmVec3 tmp;

        playerFireCount--;

        if (glfwGetKey(window,GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS && playerFireCount < 0) {

            struct playerShot_t *freeShot;
            freeShot = getFreeShot();
            if (freeShot != 0) {
                playerFireCount = 15;
                freeShot->alive = true;
                kmVec3Assign(&freeShot->pos, &playerPos);
            }
        }

        for (int n = 0; n < MAX_PLAYER_SHOTS; n++) {
            if (playerShots[n].alive) {
                playerShots[n].pos.z -= .08;
                if (playerShots[n].pos.z < -10)
                    playerShots[n].alive = false;

                //kmMat4Identity(&model);
                kmMat4Translation(&model, playerShots[n].pos.x,
                                  playerShots[n].pos.y,
                                  playerShots[n].pos.z);
                //kmMat4RotationPitchYawRoll(&model, rad * 4, 0,
                //                           -rad * 4);
				kmMat4RotationYawPitchRoll(&rot,rad*4,0,-rad*4);
				kmMat4Multiply(&model,&model,&rot);
                kmMat4Assign(&mvp, &vp);
                kmMat4Multiply(&mvp, &mvp, &model);

                kmMat4Assign(&mv, &view);
                kmMat4Multiply(&mv, &mv, &model);

                glBindTexture(GL_TEXTURE_2D, shotTex);
                drawObj(&shotObj, &mvp, &mv, lightDir, viewDir);
            }
        }

        playerRoll = 0;
        if (glfwGetKey(window,GLFW_KEY_LEFT)==GLFW_PRESS && playerPos.x > -10) {
            playerPos.x -= 0.1;
            playerRoll = .2;
        }
        if (glfwGetKey(window,GLFW_KEY_RIGHT)==GLFW_PRESS && playerPos.x < 10) {
            playerPos.x += 0.1;
            playerRoll = -.2;
        }
        pEye.x = playerPos.x * 1.25;

        pCenter.x = playerPos.x;
        pCenter.y = playerPos.y + 1;
        pCenter.z = playerPos.z;

        int deadAliens;

        deadAliens = 0;

        for (int n = 0; n < MAX_ALIENS; n++) {
            if (aliens[n].alive == true) {

                //kmMat4Identity(&model);
                kmMat4Translation(&model, aliens[n].pos.x,
                                  aliens[n].pos.y, aliens[n].pos.z);
                //kmMat4RotationPitchYawRoll(&model, -.4, 0, 0);
				kmMat4RotationYawPitchRoll(&rot,.2,0,0);
				kmMat4Multiply(&model,&model,&rot);

                kmMat4Assign(&mvp, &vp);
                kmMat4Multiply(&mvp, &mvp, &model);

                kmMat4Assign(&mv, &view);
                kmMat4Multiply(&mv, &mv, &model);

                glBindTexture(GL_TEXTURE_2D, alienTex);
                drawObj(&alienObj, &mvp, &mv, lightDir, viewDir);

                kmVec3 d;
                for (int i = 0; i < MAX_PLAYER_SHOTS; i++) {
                    kmVec3Subtract(&d, &aliens[n].pos,
                                   &playerShots[i].pos);
                    if (kmVec3Length(&d) < .7
                            && playerShots[i].alive) {
                        aliens[n].alive = false;
                        playerShots[i].alive = false;
                        aliens[n].exploding = true;
                        resetExposion(aliens[n].explosion);
                    }
                }
            } 

            if (aliens[n].alive != true && aliens[n].exploding != true) {
                    deadAliens++;
                
            }
        }

        if (deadAliens == MAX_ALIENS) {
            resetAliens();
        }

		// draw explosions after ALL aliens
        for (int n = 0; n < MAX_ALIENS; n++) {
			if (aliens[n].exploding==true) {
				kmMat4Identity(&model);
				kmMat4Translation(&model, aliens[n].pos.x,
								  aliens[n].pos.y, aliens[n].pos.z);

				kmMat4Assign(&mvp, &vp);
				kmMat4Multiply(&mvp, &mvp, &model);
				glBindTexture(GL_TEXTURE_2D, expTex);
				drawPointCloud(aliens[n].explosion, &mvp);
				aliens[n].explosion->tick=aliens[n].explosion->tick+0.05;
				if (aliens[n].explosion->tick>1.25) {
					aliens[n].exploding=false;                   	
				} else {
					// update the explosion
					
					for (int i=0; i<aliens[n].explosion->totalPoints; i++) {
				
						float t;
						t=aliens[n].explosion->tick;
						if (i>aliens[n].explosion->totalPoints/2) t=t/2.0;
						aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t;
						aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t;
						aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t;
				
					}
				}
			}
		}

        // move camera
        kmMat4LookAt(&view, &pEye, &pCenter, &pUp);

        kmMat4Assign(&vp, &projection);
        kmMat4Multiply(&vp, &vp, &view);

        kmVec3Subtract(&viewDir,&pEye,&pCenter);
        kmVec3Normalize(&viewDir,&viewDir);

        // dump values
        glPrintf(100, 280, font1,"eye    %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z);
        glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y,
                 pCenter.z);
        glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20);



        glfwSwapBuffers(window);

        ts.tv_nsec+=20000000;  // 1000000000 / 50 = 50hz less time to render the frame
        //thrd_sleep(&ts,NULL); // tinycthread
        usleep(20000); // while I work out why tinycthread that was working isnt.... :/

    }

	glfwDestroyWindow(window);
	glfwTerminate();

    return 0;
}
예제 #23
0
int main()
{




    lightDir.x=0.5;
    lightDir.y=.7;
    lightDir.z=-0.5;
    kmVec3Normalize(&lightDir,&lightDir);

    // creates a window and GLES context
    if (makeContext() != 0)
        exit(-1);

    // all the shaders have at least texture unit 0 active so
    // activate it now and leave it active
    glActiveTexture(GL_TEXTURE0);

    // The obj shapes and their textures are loaded
    cubeTex = loadPNG("resources/textures/dice.png");
    loadObj(&cubeObj, "resources/models/cube.gbo",
            "resources/shaders/textured.vert", "resources/shaders/textured.frag");


    shipTex = loadPNG("resources/textures/shipv2.png");
    loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj);

    alienTex = loadPNG("resources/textures/alien.png");
    loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj);

    shotTex = loadPNG("resources/textures/shot.png");
    loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj);

    expTex = loadPNG("resources/textures/explosion.png");





    playerPos.x = 0;
    playerPos.y = 0;
    playerPos.z = 0;

    kmMat4Identity(&view);

    pEye.x = 0;
    pEye.y = 2;
    pEye.z = 4;
    pCenter.x = 0;
    pCenter.y = 0;
    pCenter.z = -5;
    pUp.x = 0;
    pUp.y = 1;
    pUp.z = 0;

    kmMat4LookAt(&view, &pEye, &pCenter, &pUp);

    // projection matrix, as distance increases
    // the way the model is drawn is effected
    kmMat4Identity(&projection);
    kmMat4PerspectiveProjection(&projection, 45,
                                (float)getDisplayWidth() / getDisplayHeight(), 0.1, 100);

    glViewport(0, 0, getDisplayWidth(), getDisplayHeight());

    // these two matrices are pre combined for use with each model render
    kmMat4Assign(&vp, &projection);
    kmMat4Multiply(&vp, &vp, &view);

    // initialises glprint's matrix shader and texture
    initGlPrint(getDisplayWidth(), getDisplayHeight());

	font1=createFont("resources/textures/font.png",0,256,16,16,16);
	font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48);

    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_BLEND);	// only used by glprintf
    glEnable(GL_DEPTH_TEST);

    struct timeval t, ta, t1, t2;	// fps stuff
    gettimeofday(&t1, NULL);
    int num_frames = 0;

    bool quit = false;

    mouse = getMouse();
    keys = getKeys();

    resetAliens();

    for (int n = 0; n < MAX_PLAYER_SHOTS; n++) {
        playerShots[n].alive = false;
    }


    initPointClouds("resources/shaders/particle.vert",
                    "resources/shaders/particle.frag",(float)getDisplayWidth()/24.0);


    for (int n = 0; n < MAX_ALIENS; n++) {
        aliens[n].explosion=createPointCloud(40);
        resetExposion(aliens[n].explosion); // sets initials positions
    }



    while (!quit) {		// the main loop

        doEvents();	// update mouse and key arrays

        // mask of 4 is right mouse
        if (keys[KEY_ESC])
            quit = true;

        glClearColor(0, .5, 1, 1);

        // render between two gettimeofday calls so
        // we can sleep long enough to roughly sync
        // to ~60fps but not on the pi!

        // TODO find something a tad more elegent

        long i;
        gettimeofday(&t, NULL);
        i = t.tv_sec * 1e6 + t.tv_usec;

//        render();
        float rad;		// radians rotation based on frame counter

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        frame++;
        rad = frame * (0.0175f * 2);

        kmMat4Identity(&model);
        kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z);

        playerCroll +=
            (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral)
             / 2);
        kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3);	//

        kmMat4Assign(&mvp, &vp);
        kmMat4Multiply(&mvp, &mvp, &model);

        kmMat4Assign(&mv, &view);
        kmMat4Multiply(&mv, &mv, &model);

        glBindTexture(GL_TEXTURE_2D, shipTex);
        drawObj(&shipObj, &mvp, &mv, lightDir, viewDir);

        glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16,
                 font2,"frame=%i fps=%3.2f", frame, lfps);

        kmVec3 tmp;

        playerFireCount--;

        if (keys[KEY_LCTRL] && playerFireCount < 0) {

            struct playerShot_t *freeShot;
            freeShot = getFreeShot();
            if (freeShot != 0) {
                playerFireCount = 15;
                freeShot->alive = true;
                kmVec3Assign(&freeShot->pos, &playerPos);
            }
        }

        for (int n = 0; n < MAX_PLAYER_SHOTS; n++) {
            if (playerShots[n].alive) {
                playerShots[n].pos.z -= .08;
                if (playerShots[n].pos.z < -10)
                    playerShots[n].alive = false;

                kmMat4Identity(&model);
                kmMat4Translation(&model, playerShots[n].pos.x,
                                  playerShots[n].pos.y,
                                  playerShots[n].pos.z);
                kmMat4RotationPitchYawRoll(&model, rad * 4, 0,
                                           -rad * 4);

                kmMat4Assign(&mvp, &vp);
                kmMat4Multiply(&mvp, &mvp, &model);

                kmMat4Assign(&mv, &view);
                kmMat4Multiply(&mv, &mv, &model);

                glBindTexture(GL_TEXTURE_2D, shotTex);
                drawObj(&shotObj, &mvp, &mv, lightDir, viewDir);
            }
        }

        playerRoll = 0;
        if (keys[KEY_CURSL] && playerPos.x > -10) {
            playerPos.x -= 0.1;
            playerRoll = .2;
        }
        if (keys[KEY_CURSR] && playerPos.x < 10) {
            playerPos.x += 0.1;
            playerRoll = -.2;
        }
        pEye.x = playerPos.x * 1.25;

        pCenter.x = playerPos.x;
        pCenter.y = playerPos.y + 1;
        pCenter.z = playerPos.z;

        int deadAliens;

        deadAliens = 0;

        for (int n = 0; n < MAX_ALIENS; n++) {
            if (aliens[n].alive == true) {

                kmMat4Identity(&model);
                kmMat4Translation(&model, aliens[n].pos.x,
                                  aliens[n].pos.y, aliens[n].pos.z);
                kmMat4RotationPitchYawRoll(&model, -.4, 0, 0);

                kmMat4Assign(&mvp, &vp);
                kmMat4Multiply(&mvp, &mvp, &model);

                kmMat4Assign(&mv, &view);
                kmMat4Multiply(&mv, &mv, &model);

                glBindTexture(GL_TEXTURE_2D, alienTex);
                drawObj(&alienObj, &mvp, &mv, lightDir, viewDir);

                kmVec3 d;
                for (int i = 0; i < MAX_PLAYER_SHOTS; i++) {
                    kmVec3Subtract(&d, &aliens[n].pos,
                                   &playerShots[i].pos);
                    if (kmVec3Length(&d) < .7
                            && playerShots[i].alive) {
                        aliens[n].alive = false;
                        playerShots[i].alive = false;
                        aliens[n].exploding = true;
                        resetExposion(aliens[n].explosion);
                    }
                }
            } 

            if (aliens[n].alive != true && aliens[n].exploding != true) {
                    deadAliens++;
                
            }
        }

        if (deadAliens == MAX_ALIENS) {
            resetAliens();
        }

		// draw explosions after ALL aliens
        for (int n = 0; n < MAX_ALIENS; n++) {
			if (aliens[n].exploding==true) {
				kmMat4Identity(&model);
				kmMat4Translation(&model, aliens[n].pos.x,
								  aliens[n].pos.y, aliens[n].pos.z);

				kmMat4Assign(&mvp, &vp);
				kmMat4Multiply(&mvp, &mvp, &model);
				glBindTexture(GL_TEXTURE_2D, expTex);
				drawPointCloud(aliens[n].explosion, &mvp);
				aliens[n].explosion->tick=aliens[n].explosion->tick+0.05;
				if (aliens[n].explosion->tick>1.25) {
					aliens[n].exploding=false;                   	
				} else {
					// update the explosion
					
					for (int i=0; i<aliens[n].explosion->totalPoints; i++) {
				
						float t;
						t=aliens[n].explosion->tick;
						if (i>aliens[n].explosion->totalPoints/2) t=t/2.0;
						aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t;
						aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t;
						aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t;
				
					}
				}
			}
		}

        // move camera
        kmMat4LookAt(&view, &pEye, &pCenter, &pUp);

        kmMat4Assign(&vp, &projection);
        kmMat4Multiply(&vp, &vp, &view);

        kmVec3Subtract(&viewDir,&pEye,&pCenter);
        kmVec3Normalize(&viewDir,&viewDir);

        // dump values
        glPrintf(100, 280, font1,"eye    %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z);
        glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y,
                 pCenter.z);
        glPrintf(100, 320, font1,"mouse %i,%i %i ", mouse[0], mouse[1], mouse[2]);
        glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20);



        swapBuffers();

        gettimeofday(&ta, NULL);
        long j = (ta.tv_sec * 1e6 + ta.tv_usec);

        i = j - i;
        if (i < 0)
            i = 1000000;	// pass through - slower that 60fps
        if (i < 16000)
            usleep(16000 - i);

        // every 10 frames average the time taken and store
        // fps value for later printing with glprintf
        if (++num_frames % 10 == 0) {
            gettimeofday(&t2, NULL);
            float dtf =
                t2.tv_sec - t1.tv_sec + (t2.tv_usec -
                                         t1.tv_usec) * 1e-6;
            lfps = num_frames / dtf;
            num_frames = 0;
            t1 = t2;
        }
    }

    closeContext();

    return 0;
}