diff --git a/src/sbre/Makefile.am b/src/sbre/Makefile.am
index 6bd15db..138f1d6 100644
--- a/src/sbre/Makefile.am
+++ b/src/sbre/Makefile.am
@@ -3,4 +3,4 @@
 noinst_LIBRARIES = libsbre.a
 libsbre_a_SOURCES = brender.cpp models.cpp primfunc.cpp simtriang.cpp transp.cpp jjvector.cpp
 
-include_HEADERS = fastmath.h sbre.h sbre_int.h sbre_anim.h jjtypes.h jjvector.h
+include_HEADERS = fastmath.h sbre.h sbre_int.h sbre_models.h sbre_anim.h jjtypes.h jjvector.h
diff --git a/src/sbre/brender.cpp b/src/sbre/brender.cpp
index 5225347..e6086cd 100644
--- a/src/sbre/brender.cpp
+++ b/src/sbre/brender.cpp
@@ -4,7 +4,7 @@
 #include <malloc.h>
 #include "sbre.h"
 #include "sbre_int.h"
-#include "sbre_anim.h"
+#include "sbre_models.h"
 
 float ResolveAnim(ObjParams* pObjParam, uint16 type) {
   const AnimFunc* pFunc = pAFunc+type;
@@ -86,10 +86,10 @@ static void ResolveVertices(Model* pMod, Vector* pRes, ObjParams* pObjParam) {
   }
 }
 
-static float g_dn, g_df;
+static float g_dn, g_df, g_sd;
 static int g_wireframe = 0;
 
-void sbreSetViewport(int w, int h, int d, float zn, float zf, float dn, float df) {
+void sbreSetViewport(int w, int h, float d, float zn, float zf, float dn, float df) {
   glViewport(0, 0, w, h);
 
   float pProjMat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
@@ -105,7 +105,7 @@ void sbreSetViewport(int w, int h, int d, float zn, float zf, float dn, float df
   glMatrixMode(GL_PROJECTION);
   glLoadMatrixf(pProjMat);
   glDepthRange(dn+SBRE_ZBIAS, df);
-  g_dn = dn; g_df = df;
+  g_dn = dn; g_df = df; g_sd = d;
 }
 
 void sbreSetDirLight(float* pColor, float* pDir) {
@@ -179,7 +179,76 @@ void sbreRenderModel(Vector* pPos, Matrix* pOrient, int model, ObjParams* pParam
   glLoadMatrixf(pMV);
 
   Vector* pVtx = (Vector*)alloca(sizeof(Vector)*(pModel->cvStart+pModel->numCVtx));
+  ResolveVertices(pModel, pVtx, pParam);
 
+  RState rstate;
+  rstate.pVtx       = pVtx;
+  rstate.objpos     = *pPos;
+  rstate.objorient  = *pOrient;
+  rstate.scale      = s;
+  rstate.pModel     = pModel;
+  rstate.pObjParam  = pParam;
+  rstate.dn         = g_dn;
+  rstate.df         = g_df;
+  MatTVecMult(pOrient, pPos, &rstate.campos);
+  VecInv(&rstate.campos, &rstate.campos);
+  if(pCompos) rstate.compos = *pCompos;
+  else rstate.compos        = zero_vector;
+
+  if(pModel->numCache && !pModel->ppVCache) {
+    pModel->pNumVtx = (int*)calloc(pModel->numCache, sizeof(int));
+    pModel->pNumIdx = (int*)calloc(pModel->numCache, sizeof(int));
+    pModel->ppVCache = (Vector**)calloc(pModel->numCache, sizeof(Vector*));
+    pModel->ppICache = (uint16**)calloc(pModel->numCache, sizeof(uint16*));
+  }
+
+  SetGeneralState();
+  SetOpaqueState();
+
+  /* Find suitable LOD. */
+  float dist = sqrt(VecDot(pPos, pPos));
+  float pixrad = g_sd * pModel->radius*s / dist;
+
+  int i; for(i = 0; i < 4; i++) {
+    if(pModel->pLOD[i].pixrad <= 0.0f) break;
+    if(pixrad <= pModel->pLOD[i].pixrad) break;
+  }
+
+  uint16* pData = pModel->pLOD[i].pData1;
+  if(pData) while(*pData != PTYPE_END) {
+    pData += pPrimFuncTable[*pData & 0xff] (pData, pModel, &rstate);
+  }
+
+  pData = pModel->pLOD[i].pData2;
+  if(pData) while(*pData != PTYPE_END) {
+    pData += pPrimFuncTable[*pData & 0xff] (pData, pModel, &rstate);
+  }
+
+  //glDepthRange(g_dn+SBRE_ZBIAS, g_df);
+  if(pModel->pLOD[i].numThrusters) {
+    SetTransState();
+    RenderThrusters(&rstate, pModel->pLOD[i].numThrusters, pModel->pLOD[i].pThruster);
+  }
+
+  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+  glEnable(GL_CULL_FACE);
+}
+
+/* Urgh, needs to recurse too... */
+#if 0
+void sbreRenderModel(Vector* pPos, Matrix* pOrient, int model, ObjParams* pParam,
+                    float s, Vector* pCompos) {
+  Model* pModel = ppModel[model];
+  s *= pModel->scale;
+  float pMV[16];
+  pMV[ 0] = s*pOrient->x1; pMV[1] = s*pOrient->y1; pMV[ 2] = s*pOrient->z1; pMV[ 3] = 0.0f;
+  pMV[ 4] = s*pOrient->x2; pMV[5] = s*pOrient->y2; pMV[ 6] = s*pOrient->z2; pMV[ 7] = 0.0f;
+  pMV[ 8] = s*pOrient->x3; pMV[9] = s*pOrient->y3; pMV[10] = s*pOrient->z3; pMV[11] = 0.0f;
+  pMV[12] = pPos->x; pMV[13] = pPos->y; pMV[14] = pPos->z; pMV[15] = 1.0f;
+  glMatrixMode(GL_MODELVIEW);
+  glLoadMatrixf(pMV);
+
+  Vector* pVtx = (Vector*)alloca(sizeof(Vector)*(pModel->cvStart->cvStart+pModel->numCVtx));
   ResolveVertices(pModel, pVtx, pParam);
 
   RState rstate;
@@ -206,7 +275,14 @@ void sbreRenderModel(Vector* pPos, Matrix* pOrient, int model, ObjParams* pParam
   SetGeneralState();
   SetOpaqueState();
 
-  uint16* pData = pModel->pData;
+  float dist = sqrt(VecDot(pPos, pPos));
+  float pixrad = g_sd * pModel->radius*s / dist;
+  int i; for(i = 0; i < 4; i++) {
+    if(pModel->pLOD[i].pixrad >= 1000.0f) break;
+    if(pixrad <= pModel->pLOD[i].pixrad) break;
+  }
+  uint16* pData = pModel->pLOD[i].pData;
+
   while(*pData != PTYPE_END) {
     pData += pPrimFuncTable[*pData & 0xff] (pData, pModel, &rstate);
   }
@@ -217,4 +293,5 @@ void sbreRenderModel(Vector* pPos, Matrix* pOrient, int model, ObjParams* pParam
   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
   glEnable(GL_CULL_FACE);
 }
+#endif
 
diff --git a/src/sbre/models.cpp b/src/sbre/models.cpp
index c6b279e..ad63fc8 100644
--- a/src/sbre/models.cpp
+++ b/src/sbre/models.cpp
@@ -1,14 +1,5 @@
 #include "sbre_int.h"
-#include "sbre_anim.h"
-
-const int SUB_WING2     = 1;
-const int SUB_DISH      = 2;
-const int SUB_NOSEWHEEL = 3;
-const int SUB_WING      = 4;
-const int SUB_NACELLE   = 5;
-const int SUB_NWUNIT    = 6;
-const int SUB_MAINWHEEL = 7;
-const int SUB_MWUNIT    = 8;
+#include "sbre_models.h"
 
 enum AxisIndex {
   A_X = 0, A_Y, A_Z, A_NX, A_NY, A_NZ,
@@ -36,9 +27,8 @@ static uint16 tetradata[] = {
   PTYPE_END,
 };
 
-static Model tetramodel = { 1.0f, 11, tetravtx1, 20, 0, tetravtx2,
-                            0, 0, 0, 0, tetradata, 0 };
-
+Model tetramodel = { 1.0f, 66.0f, 11, tetravtx1, 20, 0, tetravtx2, 0,
+                   { { 0, tetradata, 0, 0, 0 } } };
 
 static PlainVertex circlevtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 0.0f, 0.0f } },
@@ -56,9 +46,8 @@ static uint16 circledata[] = {
   PTYPE_END,
 };
 
-static Model circlemodel = { 1.0f, 7, circlevtx1, 20, 0, circlevtx2,
-                             0, 0, 0, 0, circledata, 1 };
-
+Model circlemodel = { 1.0f, 20.0f, 7, circlevtx1, 20, 0, circlevtx2, 1,
+                    { { 0, circledata, 0, 0, 0 } } };
 
 static PlainVertex cylvtx1[] = {
   { VTYPE_PLAIN, { -100.0f, 20.0f, 0.0f } },
@@ -77,9 +66,8 @@ static uint16 cyldata[] = {
   PTYPE_END,
 };
 
-static Model cylmodel = { 1.0f, 9, cylvtx1, 20, 1, cylvtx2,
-                          0, 0, 0, 0, cyldata, 1 };
-
+Model cylmodel = { 1.0f, 120.0f, 9, cylvtx1, 20, 1, cylvtx2, 1,
+                 { { 0, cyldata, 0, 0, 0 } } };
 
 static PlainVertex nwunitvtx1[] = {
   { VTYPE_PLAIN, { 1.5f, 0.0f, 6.0f } },  /* 6 flap. */
@@ -119,9 +107,8 @@ static uint16 nwunitdata[] = {
   PTYPE_END,
 };
 
-static Model nwunitmodel = { 1.0f, 15, nwunitvtx1, 20, 4, nwunitvtx2,
-                             0, 0, 0, 0, nwunitdata, 0 };
-
+Model nwunitmodel = { 1.0f, 7.0f, 15, nwunitvtx1, 20, 4, nwunitvtx2, 0,
+                    { { 0, nwunitdata, 0, 0, 0 } } };
 
 static PlainVertex nosewheelvtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 0.0f, 0.0f } },    /* 6, strut. */
@@ -144,9 +131,8 @@ static uint16 nosewheeldata[] = {
   PTYPE_END,
 };
 
-static Model nosewheelmodel = { 1.0f, 11, nosewheelvtx1, 20, 0, nosewheelvtx2,
-                                0, 0, 0, 0, nosewheeldata, 4 };
-
+Model nosewheelmodel = { 1.0f, 7.0f, 11, nosewheelvtx1, 20, 0, nosewheelvtx2, 3,
+                       { { 0, nosewheeldata, 0, 0, 0 } } };
 
 static PlainVertex mwunitvtx1[] = {
   { VTYPE_PLAIN, { 1.5f, 0.0f, 6.0f } },        /* 6, flap. */
@@ -186,9 +172,8 @@ static uint16 mwunitdata[] = {
   PTYPE_END,
 };
 
-static Model mwunitmodel = { 1.0f, 15, mwunitvtx1, 20, 4, mwunitvtx2,
-                             0, 0, 0, 0, mwunitdata, 0 };
-
+Model mwunitmodel = { 1.0f, 8.0f, 15, mwunitvtx1, 20, 4, mwunitvtx2, 0,
+                    { { 0, mwunitdata, 0, 0, 0 } } };
 
 static PlainVertex mainwheelvtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 0.0f, 0.0f } },    /* 6, strut. */
@@ -217,8 +202,8 @@ static uint16 mainwheeldata[] = {
   PTYPE_END,
 };
 
-static Model mainwheelmodel = { 1.0f, 15, mainwheelvtx1, 20, 0, mainwheelvtx2,
-                                0, 0, 0, 0, mainwheeldata, 5 };
+Model mainwheelmodel = { 1.0f, 8.0f, 15, mainwheelvtx1, 20, 0, mainwheelvtx2, 5,
+                       { { 0, mainwheeldata, 0, 0, 0 } } };
 
 static PlainVertex nacellevtx1[] = {
   { VTYPE_PLAIN, { 30.0f, 0.0f, 30.0f } },    /* 6 */
@@ -255,12 +240,11 @@ static uint16 nacelledata[] = {
   PTYPE_END,
 };
 
-static Model nacellemodel = { 1.0f, 16, nacellevtx1, 20, 0, nacellevtx2,
-                              0, 0, 0, 0, nacelledata, 2 };
-
+Model nacellemodel = { 1.0f, 30.0f, 16, nacellevtx1, 20, 0, nacellevtx2, 2,
+                     { { 0, nacelledata, 0, 0, 0 } } };
 
 /* Do wings as subobjects. */
-static PlainVertex shipvtx1[] = {
+static PlainVertex ship1vtx1[] = {
   { VTYPE_PLAIN, { 5.0f, 10.0f, 30.0f } },  /* 6, top four body verts. */
   { VTYPE_PLAIN, { -5.0f, 10.0f, 30.0f } },
   { VTYPE_PLAIN, { 5.0f, 10.0f, -30.0f } },
@@ -308,7 +292,7 @@ static PlainVertex shipvtx1[] = {
 
 };
 
-static CompoundVertex shipvtx2[] = {
+static CompoundVertex ship1vtx2[] = {
   { VTYPE_ANIMLIN, { 25, 0, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },    /* 50, right wing yaxis. */
   { VTYPE_CROSS, { 50, 2, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },    /* Right wing xaxis. */
 
@@ -320,7 +304,7 @@ static CompoundVertex shipvtx2[] = {
 
 };
 
-static uint16 shipdata[] = {
+static uint16 ship1data[] = {
   PTYPE_MATFIXED, 100, 0, 100, 0, 0, 0, 100, 0, 0, 0,
   PTYPE_QUADFLAT, 7, 6, 8, 9,        /* Top. */
   PTYPE_QUADFLAT, 13, 11, 15, 17,      /* Bottom. */
@@ -334,9 +318,9 @@ static uint16 shipdata[] = {
   PTYPE_TRIFLAT | RFLAG_XREF, 6, 18, 10,    /* Front side top. */
   PTYPE_TRIFLAT | RFLAG_XREF, 10, 18, 11,    /* Front side bottom. */
 
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING, 20, 22, 2, 100,
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING, 23, 50, 2, 100,
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING, 26, 52, 2, 100,
+  PTYPE_SUBOBJECT, 0x8000, SUB_WING1, 20, 22, 2, 100,
+  PTYPE_SUBOBJECT, 0x8000, SUB_WING1, 23, 50, 2, 100,
+  PTYPE_SUBOBJECT, 0x8000, SUB_WING1, 26, 52, 2, 100,
 
   PTYPE_MATFIXED, 20, 20, 20, 0, 0, 0, 100, 0, 0, 0,
   PTYPE_ZBIAS, 54, 5,
@@ -354,7 +338,7 @@ static uint16 shipdata[] = {
   PTYPE_END,
 };
 
-static Thruster shipthruster[] = {
+static Thruster ship1thruster[] = {
   { 29, 5 | THRUST_NOANG, 50.0f },
   { 30, 2 | THRUST_NOANG, 35.0f },  /* Retros. */
   { 31, 2 | THRUST_NOANG, 35.0f },
@@ -364,11 +348,10 @@ static Thruster shipthruster[] = {
   { 38, 4, 25.0f }, { 39, 4, 25.0f },  /* Bottom. */
 };
 
-static Model shipmodel = { 1.0f, 42, shipvtx1, 50, 6, shipvtx2,
-                           0, 0, 11, shipthruster, shipdata, 0 };
+Model ship1model = { 1.0f, 40.0f, 42, ship1vtx1, 50, 6, ship1vtx2, 0,
+                   { { 0, ship1data, 0, 11, ship1thruster } } };
 
-
-static PlainVertex wingvtx1[] = {
+static PlainVertex wing1vtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 0.0f, 1.0f } },    /* 6, bottom front. */
   { VTYPE_PLAIN, { 0.0f, 0.0f, -1.0f } },   /* Bottom back. */
   { VTYPE_PLAIN, { 0.0f, 1.5f, 0.0f } },    /* Top front. */
@@ -393,14 +376,14 @@ static PlainVertex wingvtx1[] = {
   { VTYPE_PLAIN, { 0.4f, 0.0f, 1.5f } },    /* tan 3->2 top, 1. */
 };
 
-static CompoundVertex wingvtx2[] = {
+static CompoundVertex wing1vtx2[] = {
   { VTYPE_CROSS, { 19, 14, static_cast<uint16>(-1),static_cast<uint16>(-1),static_cast<uint16>(-1), } },  /* 30, norm 0. */
   { VTYPE_CROSS, { 15, 16, static_cast<uint16>(-1),static_cast<uint16>(-1),static_cast<uint16>(-1), } },  /* norm 1. */
   { VTYPE_CROSS, { 16, 17, static_cast<uint16>(-1),static_cast<uint16>(-1),static_cast<uint16>(-1), } },  /* norm 3. */
   { VTYPE_CROSS, { 18, 19, static_cast<uint16>(-1),static_cast<uint16>(-1),static_cast<uint16>(-1), } },  /* norm 2. */
 };
 
-static uint16 wingdata[] = {
+static uint16 wing1data[] = {
   PTYPE_MATFIXED, 100, 0, 100, 0, 0, 0, 100, 0, 0, 0,
   PTYPE_COMPSMOOTH | RFLAG_XREF, 0, 5, 10, 12, 6, 30,   /* Side. */
   COMP_HERMITE, 7, 31, 14, 15,
@@ -415,8 +398,8 @@ static uint16 wingdata[] = {
   PTYPE_END,
 };
 
-static Model wingmodel = { 25.0f, 24, wingvtx1, 30, 4, wingvtx2,
-                           0, 0, 0, 0, wingdata, 2 };
+Model wing1model = { 25.0f, 2.0f, 24, wing1vtx1, 30, 4, wing1vtx2, 2,
+                   { { 0, wing1data, 0, 0, 0 } } };
 
 static PlainVertex ship2vtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 0.0f, 35.0f } },    /* 6, nose point. */
@@ -645,9 +628,8 @@ static Thruster ship2thruster[] = {
   { 93, 0, 15.0f }, { 94, 3, 15.0f },
 };
 
-static Model ship2model = { 1.0f, 98, ship2vtx1, 120, 1, ship2vtx2,
-                            0, 0, 14, ship2thruster, ship2data, 10 };
-
+Model ship2model = { 1.0f, 35.0f, 98, ship2vtx1, 120, 1, ship2vtx2, 10,
+                   { { 0, ship2data, 0, 14, ship2thruster } } };
 
 static PlainVertex station1vtx1[] = {
   { VTYPE_PLAIN, { -15.0f, 30.0f, 20.0f } },    /* 6, front octagon. */
@@ -789,8 +771,8 @@ static uint16 station1data[] = {
   PTYPE_END,
 };
 
-static Model station1model = { 1.0f, 36, station1vtx1, 100, 0, station1vtx2,
-                               0, 0, 0, 0, station1data, 1 };
+Model station1model = { 1.0f, 120.0f, 36, station1vtx1, 100, 0, station1vtx2, 1,
+                      { { 0, station1data, 0, 0, 0 } } };
 
 static PlainVertex ship3vtx1[] = {
   { VTYPE_PLAIN, { 4.0f, -5.0f, 20.0f } },        /* 6, nose pair. */
@@ -926,8 +908,8 @@ static Thruster ship3thruster[] = {
   { 43, 0 | THRUST_XREF, 15.0f },
 };
 
-static Model ship3model = { 1.0f, 44, ship3vtx1, 100, 2, ship3vtx2,
-                            0, 0, 6, ship3thruster, ship3data, 6 };
+Model ship3model = { 1.0f, 35.0f, 44, ship3vtx1, 100, 2, ship3vtx2, 6,
+                   { { 0, ship3data, 0, 6, ship3thruster } } };
 
 static PlainVertex ship4vtx1[] = {
   { VTYPE_PLAIN, { -4.0f, -3.0f, 35.0f } },      /* 6, nose vertices. */
@@ -1042,8 +1024,9 @@ static Thruster ship4thruster[] = {
   //  { 42, 1 | THRUST_XREF, 15.0f },
   //  { 43, 0 | THRUST_XREF, 15.0f },
 };
-static Model ship4model = { 1.0f, 41, ship4vtx1, 100, 1, ship4vtx2,
-                            0, 0, 4, ship4thruster, ship4data, 10 };
+
+Model ship4model = { 1.0f, 40.0f, 41, ship4vtx1, 100, 1, ship4vtx2, 10,
+                   { { 0, ship4data, 0, 4, ship4thruster } } };
 
 static PlainVertex dishvtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 3.0f, 1.2f } },  /* 6, dish. */
@@ -1092,8 +1075,8 @@ static uint16 dishdata[] = {
   PTYPE_END,
 };
 
-static Model dishmodel = { 1.0f, 19, dishvtx1, 40, 0, dishvtx2,
-                           0, 0, 0, 0, dishdata, 5 };
+Model dishmodel = { 1.0f, 4.0f, 19, dishvtx1, 40, 0, dishvtx2, 5,
+                  { { 0, dishdata, 0, 0, 0 } } };
 
 static PlainVertex ship5vtx1[] = {
   { VTYPE_PLAIN, { -1.0f, 0.0f, 20.0f } },      /* 6, right nose vertex. */
@@ -1184,16 +1167,16 @@ static uint16 ship5data[] = {
     COMP_LINE, 9, 101,
     COMP_END,
 
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING2, 36, 40, 2, 70,
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING2, 37, 41, 2, 70,
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING2, 38, 42, 2, 70,
-  PTYPE_SUBOBJECT, 0x8000, SUB_WING2, 39, 43, 2, 70,
+  PTYPE_SUBOBJECT | SUBOBJ_THRUST, 0x8000, SUB_WING2, 36, 40, 2, 70,
+  PTYPE_SUBOBJECT | SUBOBJ_THRUST, 0x8000, SUB_WING2, 37, 41, 2, 70,
+  PTYPE_SUBOBJECT | SUBOBJ_THRUST, 0x8000, SUB_WING2, 38, 42, 2, 70,
+  PTYPE_SUBOBJECT | SUBOBJ_THRUST, 0x8000, SUB_WING2, 39, 43, 2, 70,
 
   PTYPE_END,
 };
 
-static Model ship5model = { 1.0f, 44, ship5vtx1, 100, 2, ship5vtx2,
-                            0, 0, 0, 0, ship5data, 5 };
+Model ship5model = { 1.0f, 25.0f, 44, ship5vtx1, 100, 2, ship5vtx2, 5,
+                   { { 0, ship5data, 0, 0, 0 } } };
 
 static PlainVertex wing2vtx1[] = {
   { VTYPE_PLAIN, { 0.0f, 0.0f, 3.5f } },    /* 6, bottom front. */
@@ -1243,58 +1226,6 @@ static Thruster wing2thruster[] = {
   { 19, 2, 20.0f },
 };
 
-static Model wing2model = { 1.0f, 23, wing2vtx1, 30, 0, wing2vtx2,
-                            0, 0, 2, wing2thruster, wing2data, 2 };
-
-static PlainVertex tombstonevtx1[] = {
-  { VTYPE_PLAIN, { 0.6f, 1.0f, -0.1f } }, /* Front quad. */
-  { VTYPE_PLAIN, { 0.6f, -1.0f, -0.1f } } ,
-  { VTYPE_PLAIN, { -0.6f, -1.0f, -0.1f } },
-  { VTYPE_PLAIN, { -0.6f, 1.0f, -0.1f } },
-  { VTYPE_PLAIN, { 0, 1, 0.1 } }, /* Cylinder. */
-  { VTYPE_PLAIN, { 0, 1, -0.1 } },
-  { VTYPE_PLAIN, { 0.6f, 1.0f, 0.1f } }, /* Rear quad. */
-  { VTYPE_PLAIN, { 0.6f, -1.0f, 0.1f } },
-  { VTYPE_PLAIN, { -0.6f, -1.0f, 0.1f } },
-  { VTYPE_PLAIN, { -0.6f, 1.0f, 0.1f } },
-  { VTYPE_PLAIN, { -0.5f, 0.8, -0.1 } }, /* Text start. */
-};
-
-static uint16 tombstonedata[] = {
-  PTYPE_MATFIXED, 50, 50, 50, 0, 0, 0, 100, 0, 0, 0,
-  PTYPE_QUADFLAT, 6, 7, 8, 9,
-  PTYPE_QUADFLAT, 15, 14, 13, 12,
-  PTYPE_QUADFLAT, 6, 12, 13, 7,
-  PTYPE_QUADFLAT, 9, 8, 14, 15,
-  PTYPE_QUADFLAT, 8, 7, 13, 14,
-  PTYPE_CYLINDER, 0x8000, 16, 10, 11, 1, 60,
-  PTYPE_MATFIXED, 100, 0, 0, 0, 0, 0, 100, 0, 0, 0,
-  PTYPE_ZBIAS, 5, 5,
-  PTYPE_TEXT, 0, 0x8000, 16, 5, 0, 0, 0, 30,
-  PTYPE_END
-};
-
-static Model tombstonemodel = { 10.0f, 17, tombstonevtx1, 17, 0, 0,
-        0, 0, 0, 0, tombstonedata, 1 };
-
-Model* ppModel[] = {
-  &ship5model,
-  &wing2model,
-  &dishmodel,
-  &nosewheelmodel,
-  &wingmodel,
-  &nacellemodel,
-  &nwunitmodel,
-  &mainwheelmodel,
-  &mwunitmodel,
-  &cylmodel,
-  &ship2model,
-  &shipmodel,
-  &station1model,
-  &ship3model,
-  &ship4model,
-  /* 0x10. */
-  &tombstonemodel,
-  0,
-};
+Model wing2model = { 1.0f, 25.0f, 23, wing2vtx1, 30, 0, wing2vtx2, 2,
+                   { { 0, wing2data, 0, 2, wing2thruster } } };
 
diff --git a/src/sbre/primfunc.cpp b/src/sbre/primfunc.cpp
index f7a7973..c6158a0 100644
--- a/src/sbre/primfunc.cpp
+++ b/src/sbre/primfunc.cpp
@@ -1,7 +1,6 @@
 #include <SDL_opengl.h>
 #include <malloc.h>
 #include "sbre_int.h"
-#include "sbre_anim.h"
 #include "sbre.h"      /* For subobject. */
 #include "../glfreetype.h"
 
@@ -529,7 +528,7 @@ static int PrimFuncSubObject (uint16 *pData, Model *pMod, RState *pState)
   glPushMatrix ();
 
   /* Transform lin & ang thrust. */
-  if(ppModel[pData[2]]->numThrusters) {
+  if(pData[0] & SUBOBJ_THRUST) {
     Vector compos;
     MatTVecMult(&m, pState->pVtx+pData[3], &compos);
     VecInv(&compos, &compos);
diff --git a/src/sbre/sbre.h b/src/sbre/sbre.h
index 51b4f64..e33f394 100644
--- a/src/sbre/sbre.h
+++ b/src/sbre/sbre.h
@@ -31,7 +31,7 @@ struct ObjParams {
   char pText[3][256];
 };
 
-void sbreSetViewport(int w, int h, int d, float zn, float zf, float dn, float df);
+void sbreSetViewport(int w, int h, float d, float zn, float zf, float dn, float df);
 void sbreSetDirLight(float* pColor, float* pDir);
 void sbreSetWireframe(int val);
 void sbreRenderModel(Vector* pPos, Matrix* pOrient, int model, ObjParams* pParam,
diff --git a/src/sbre/sbre_int.h b/src/sbre/sbre_int.h
index a322180..a13ce8a 100644
--- a/src/sbre/sbre_int.h
+++ b/src/sbre/sbre_int.h
@@ -29,22 +29,15 @@ struct CompoundVertex {
 /******************************************************************************/
 
 struct Thruster {
-  uint16 pos; /* Index into vertices. */
+  uint16 pos;   /* Index into vertices. */
   uint16 dir;
   float power;
-};
-
-struct Light {
-  uint8 animcolor;
-  uint8 animpower;
-  uint16 vtx;
-  float power;
-  float pColor[3];
+  int detail;   /* 0 - min, 1 - mid, 2 - max. */
 };
 
 struct Model {
   float scale;
-
+  float radius; /* Scale multiplies this too. */
   int numPVtx;
   PlainVertex* pPVtx;
 
@@ -52,23 +45,55 @@ struct Model {
   int numCVtx;
   CompoundVertex* pCVtx;
 
-  int numLights;
-  Light* pLight;
-
-  int numThrusters;
-  Thruster* pThruster;
-
-  uint16* pData;
-
   int numCache; /* Number of cached primitives. */
-  int* pNumVtx, *pNumIdx;
+
+  struct {
+    float pixrad;   /* Size in screen pixels below which LOD applies. */
+    uint16* pData1; /* pixrad <= 0.0f is top LOD - kinda backwards. */
+    uint16* pData2;
+    int numThrusters;
+    Thruster* pThruster;
+  } pLOD[4];
+
+  int* pNumVtx, *pNumIdx; /* Caches. */
   Vector** ppVCache;
   uint16** ppICache;
 };
 
-extern Model* ppModel[];
+/******************************************************************************/
+/* AnimFuncs. */
+
+enum animmod {
+  AMOD_CLIP = 0,    /* Just clip result to 0-1. */
+  AMOD_MOD1,        /* fmod(1), then clip. */
+  AMOD_REF,         /* fmod(2), reflect around 1, then clip. */
+};
+
+struct AnimFunc {
+  int src;
+  int mod;
+  float order0;
+  float order1;
+  float order2;
+  float order3;
+};
+
+enum animfunc {
+  AFUNC_GEAR = 0,
+  AFUNC_GFLAP,
+  AFUNC_THRUSTPULSE,
+  AFUNC_LIN4SEC,
+};
+
+const AnimFunc pAFunc[] = {
+  { ASRC_GEAR, AMOD_CLIP, -1.0f, 2.0f, 0.0f, 0.0f },
+  { ASRC_GEAR, AMOD_CLIP, 0.0f, 2.0f, 0.0f, 0.0f },
+  { ASRC_MINFRAC, AMOD_REF, 0.0f, 30.0f, 0.0f, 0.0f },
+  { ASRC_MINFRAC, AMOD_MOD1, 0.0f, 15.0f, 0.0f, 0.0f },
+};
 
 /******************************************************************************/
+/* From simtriang.cpp. */
 
 #define TRIANG_MAXPOINTS 64
 #define TRIANG_MAXSTEPS   5
@@ -84,6 +109,7 @@ void Triangulate(Vector* pCPos, Vector* pCNorm, int steps,
                   Vector** ppVtx, int* pNV, uint16** ppIndex, int* pNI);
 
 /******************************************************************************/
+/* Random Rendering stuff. */
 
 struct RState {
   Model*      pModel;     /* Original model. */
@@ -95,6 +121,12 @@ struct RState {
   ObjParams*  pObjParam;  /* Dynamic object parameters. */
   float dn, df;           /* Near/far depth range. */
   Vector compos;          /* Object relative center of mass. */
+
+  /* Collision output stuff. */
+  int maxCVtx, maxCIdx;
+  int numCVtx, numCIdx;
+  Vector* pCollVtx;
+  int* pCollIdx;
 };
 
 enum primtype {
@@ -116,14 +148,16 @@ enum primtype {
 };
 
 extern int (*pPrimFuncTable[])(uint16*, Model*, RState*);
+extern int (*pCollFuncTable[])(uint16*, Model*, RState*);
 
-static const int RFLAG_XREF   = 0x8000;
+static const int RFLAG_XREF     = 0x8000;
+static const int SUBOBJ_THRUST  = 0x4000;
 
-static const int THRUST_XREF  = 0x8000;
-static const int THRUST_NOANG = 0x4000;
+static const int THRUST_XREF    = 0x8000;
+static const int THRUST_NOANG   = 0x4000;
 
-static const float SBRE_ZBIAS = 0.00002f;
-static const float SBRE_AMB   = 0.3f;
+static const float SBRE_ZBIAS   = 0.00002f;
+static const float SBRE_AMB     = 0.3f;
 
 enum comptype {
   COMP_END = 0,
@@ -140,6 +174,6 @@ const char pModelString[1][256] = {
   "IZRILGOOD",
 };
 
-void RenderTransparencies(RState* pState);
+void RenderThrusters(RState* pState, int numThrusters, Thruster* pThrusters);
 float ResolveAnim (ObjParams* pObjParam, uint16 type);
 
diff --git a/src/sbre/sbre_models.h b/src/sbre/sbre_models.h
new file mode 100644
index 0000000..ae55afa
--- /dev/null
+++ b/src/sbre/sbre_models.h
@@ -0,0 +1,55 @@
+#pragma once
+#include "sbre_int.h"
+
+extern Model dishmodel, nosewheelmodel, nwunitmodel, mainwheelmodel, mwunitmodel;
+extern Model wing1model, wing2model;
+extern Model ship1model, ship2model, ship3model, ship4model, ship5model;
+extern Model station1model;
+
+/* Common subobject indices. */
+const int SUB_NOSEWHEEL = 1;
+const int SUB_NWUNIT    = 2;
+const int SUB_MAINWHEEL = 3;
+const int SUB_MWUNIT    = 4;
+const int SUB_DISH      = 5;
+
+const int SUB_WING1     = 30;
+const int SUB_WING2     = 31;
+
+Model* const ppModel[] = {
+  /* 0, current test object. */
+  &ship5model,
+  /* 1, common subobjects. */
+  &nosewheelmodel,
+  &nwunitmodel,
+  &mainwheelmodel,
+  &mwunitmodel,
+  &dishmodel,
+  0, 0, 0, 0,
+  /* 10. */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 20. */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 30, single-use subobjects. */
+  &wing1model,
+  &wing2model,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  /* 40. */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 50. */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 60, JJ ships. */
+  &ship1model,
+  &ship2model,
+  &ship3model,
+  &ship4model,
+  &ship5model,
+  &station1model,
+  0, 0, 0, 0,
+  /* 70. */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 80. */
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 90, other people's ships. */
+};
+
diff --git a/src/sbre/transp.cpp b/src/sbre/transp.cpp
index 0adac36..599dc69 100644
--- a/src/sbre/transp.cpp
+++ b/src/sbre/transp.cpp
@@ -179,21 +179,17 @@ static void QuickSort (TransElem* pA, int end) {
 
 static int thrustgen = 0;
 
-void RenderTransparencies (RState *pState) {
+void RenderThrusters(RState* pState, int numThrusters, Thruster* pThrusters) {
   Vector* pVtx = pState->pVtx;
-  Model* pModel = pState->pModel;
 
   if(!thrustgen) GenerateThrusters();
   thrustgen = 1;
 
-  int maxElem = pModel->numThrusters*2;
-  if(!maxElem) return;
-  TransElem *pList = (TransElem*)alloca(maxElem*sizeof(TransElem));
-
+  TransElem* pList = (TransElem*)alloca(numThrusters*2*sizeof(TransElem));
   Vector tv;
   int i, numElem = 0;
-  for(i=0; i<pModel->numThrusters; i++) {
-    Thruster *pThruster = pModel->pThruster+i;
+  for(i=0; i<numThrusters; i++) {
+    Thruster *pThruster = pThrusters+i;
     pList[numElem].pThruster = pThruster;
     pList[numElem].pos = pVtx[pThruster->pos];
     pList[numElem].dir = pVtx[pThruster->dir&0xff];
diff --git a/src/ship_type.cpp b/src/ship_type.cpp
index 5f2bea4..fc30184 100644
--- a/src/ship_type.cpp
+++ b/src/ship_type.cpp
@@ -6,7 +6,7 @@ const ShipType ShipType::types[] = {
      * Besides running a wicked corporatist regime in the sirius system,
      * Sirius corporation make a range of lovely ships!
      */
-    "Sirius Interdictor", 10,
+    "Sirius Interdictor", 61,
     { 1e7, -1e7, 1e6, -1e6, -1e6, 1e6 },
     1e7,
     {
@@ -33,7 +33,7 @@ const ShipType ShipType::types[] = {
   },
   {
     "Flowerfairy Heavy Trader",
-    14,
+    63,
     { 1e7, -1e7, 1e6, -1e6, -1e6, 1e6 },
     1e7,
     {
diff --git a/src/space_station.cpp b/src/space_station.cpp
index 6599696..17d0168 100644
--- a/src/space_station.cpp
+++ b/src/space_station.cpp
@@ -50,6 +50,6 @@ static ObjParams params = {
 };
 
 void SpaceStation::Render(const Frame* camFrame) {
-  RenderSbreModel(camFrame, 12, &params);
+  RenderSbreModel(camFrame, 65, &params);
 }