|  | @@ -100,7 +100,6 @@ void tnsMultiply44d(tnsMatrix44d result, tnsMatrix44d l, tnsMatrix44d r);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void tnsInitFirstLevel(tnsMatrixStack *tms);
 | 
	
		
			
				|  |  |  tnsMatrixStackItem *tKnlGetCurrentMatStackItem();
 | 
	
		
			
				|  |  | -tnsShader *tKnlGetActiveShader();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTexture *use);
 | 
	
		
			
				|  |  |  void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point);
 | 
	
	
		
			
				|  | @@ -138,7 +137,7 @@ void tnsViewportWithScissor(int x, int y, int w, int h){
 | 
	
		
			
				|  |  |      glEnable(GL_SCISSOR_TEST);
 | 
	
		
			
				|  |  |      glViewport(x, y, w, h); glScissor(x, y, w, h);
 | 
	
		
			
				|  |  |      T->vsx=x;T->vsy=y;T->vsw=w;T->vsh=h;
 | 
	
		
			
				|  |  | -    if ((current_shader = tKnlGetActiveShader())){
 | 
	
		
			
				|  |  | +    if ((current_shader = T->CurrentShader)){
 | 
	
		
			
				|  |  |          tnsResetViewMatrix();
 | 
	
		
			
				|  |  |          tnsShaderApplyView(current_shader, tnsGetViewMatrix());
 | 
	
		
			
				|  |  |          tnsResetModelMatrix();
 | 
	
	
		
			
				|  | @@ -1157,7 +1156,7 @@ void tnsOrtho(real xMin, real xMax, real yMin, real yMax, real zMin, real zMax){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      tnsMakeOrthoMatrix44d(mat, xMin, xMax, yMin, yMax, zMin, zMax);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyProjection(current_shader, mat);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1167,7 +1166,7 @@ void tnsPerspective(real fFov_rad, real fAspect, real zMin, real zMax){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      tnsMakePerspectiveMatrix44d(mat, fFov_rad, fAspect, zMin, zMax);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyProjection(current_shader, mat);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1181,7 +1180,7 @@ void tnsTranslate3d(real x, real y, real z){
 | 
	
		
			
				|  |  |      tnsMultiply44d(result, mat, transmat);
 | 
	
		
			
				|  |  |      memcpy(mat, result, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyModel(current_shader, result);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1205,7 +1204,7 @@ void tnsRotate4d(real degrees, real x, real y, real z){
 | 
	
		
			
				|  |  |      tnsMultiply44d(result, mat, rotmat);
 | 
	
		
			
				|  |  |      memcpy(mat, result, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyModel(current_shader, result);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1230,7 +1229,7 @@ void tnsScale3d(real x, real y, real z){
 | 
	
		
			
				|  |  |      tnsMultiply44d(result, mat, scalemat);
 | 
	
		
			
				|  |  |      memcpy(mat, result, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyModel(current_shader, result);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1405,9 +1404,6 @@ void tnsRestoreFromNanoVG(){
 | 
	
		
			
				|  |  |  tnsMatrixStackItem *tKnlGetCurrentMatStackItem(){
 | 
	
		
			
				|  |  |      return &T->stack.level[T->stack.current_level];
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -tnsShader *tKnlGetActiveShader(){
 | 
	
		
			
				|  |  | -    return T->CurrentShader;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  |  real *tnsGetModelMatrix(){
 | 
	
		
			
				|  |  |      return tKnlGetCurrentMatStackItem()->model;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -1451,7 +1447,7 @@ tnsShader *tKnlFindShader1i(int CustomIndex){
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void tKnlPushMatrix(){
 | 
	
		
			
				|  |  |      tnsMatrixStack *tms = &T->stack;
 | 
	
		
			
				|  |  | -    tnsShader *current_shader = tKnlGetActiveShader();
 | 
	
		
			
				|  |  | +    tnsShader *current_shader = T->CurrentShader;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if (tms->current_level == tms->max_level || !current_shader) return;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1465,7 +1461,7 @@ void tKnlPushMatrix(){
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  void tKnlPopMatrix(){
 | 
	
		
			
				|  |  |      tnsMatrixStack *tms = &T->stack;
 | 
	
		
			
				|  |  | -    tnsShader *current_shader = tKnlGetActiveShader();
 | 
	
		
			
				|  |  | +    tnsShader *current_shader = T->CurrentShader;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if (tms->current_level == 0 || !current_shader) return;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2557,39 +2553,6 @@ void tnsDrawToOffscreen(tnsOffscreen *toff, int HowMany, GLuint *AttachmentArray
 | 
	
		
			
				|  |  |      T->IsOffscreen = 1;
 | 
	
		
			
				|  |  |      T->BindedShader = 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -//void tnsDraw_toextraColorAttachment(tnsOffscreen *toff){
 | 
	
		
			
				|  |  | -//    if (!toff) return;
 | 
	
		
			
				|  |  | -//    if (!toff->pColor[1]){
 | 
	
		
			
				|  |  | -//        tnsCreate2DOffscreenMSAttachmentExtraColor(toff);
 | 
	
		
			
				|  |  | -//    }
 | 
	
		
			
				|  |  | -//    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, toff->FboHandle);
 | 
	
		
			
				|  |  | -//    glDrawBuffers(1, TNS_ATTACHMENT_ARRAY_1);
 | 
	
		
			
				|  |  | -//    T->IsOffscreen = 1;
 | 
	
		
			
				|  |  | -//    T->BindedShader = 0;
 | 
	
		
			
				|  |  | -//}
 | 
	
		
			
				|  |  | -//void tnsDraw_toextraNormalAttachment(tnsOffscreen *toff){
 | 
	
		
			
				|  |  | -//    if (!toff) return;
 | 
	
		
			
				|  |  | -//    if (!toff->pColor[2]){
 | 
	
		
			
				|  |  | -//        tnsCreate2DOffscreenMSAttachmentExtraNormal(toff);
 | 
	
		
			
				|  |  | -//    }
 | 
	
		
			
				|  |  | -//    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, toff->FboHandle);
 | 
	
		
			
				|  |  | -//    glDrawBuffers(1, TNS_ATTACHMENT_ARRAY_2);
 | 
	
		
			
				|  |  | -//    T->IsOffscreen = 1;
 | 
	
		
			
				|  |  | -//    T->BindedShader = 0;
 | 
	
		
			
				|  |  | -//}
 | 
	
		
			
				|  |  | -//void tnsDrawToAllExtraAttachments(tnsOffscreen *toff){
 | 
	
		
			
				|  |  | -//    if (!toff) return;
 | 
	
		
			
				|  |  | -//    if (!toff->pColor[1]){
 | 
	
		
			
				|  |  | -//        tnsCreate2DOffscreenMSAttachmentExtraColor(toff);
 | 
	
		
			
				|  |  | -//    }
 | 
	
		
			
				|  |  | -//    if (!toff->pColor[2]){
 | 
	
		
			
				|  |  | -//        tnsCreate2DOffscreenMSAttachmentExtraNormal(toff);
 | 
	
		
			
				|  |  | -//    }
 | 
	
		
			
				|  |  | -//    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, toff->FboHandle);
 | 
	
		
			
				|  |  | -//    glDrawBuffers(2, TNS_ATTACHMENT_ARRAY_1_2);
 | 
	
		
			
				|  |  | -//    T->IsOffscreen = 1;
 | 
	
		
			
				|  |  | -//    T->BindedShader = 0;
 | 
	
		
			
				|  |  | -//}
 | 
	
		
			
				|  |  |  void tnsDrawToOffscreenOnlyBind(tnsOffscreen *toff, int HowMany, GLuint *AttachmentArray){
 | 
	
		
			
				|  |  |      if (!toff) return;
 | 
	
		
			
				|  |  |      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, toff->FboHandle);
 | 
	
	
		
			
				|  | @@ -3261,7 +3224,7 @@ void tnsSelfMatrixChanged(tnsObject* o, int ApplyToChild){
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      tnsExtractDeltaTransformValue(o);
 | 
	
		
			
				|  |  |      tnsExtractSelfTransformValue(o);
 | 
	
		
			
				|  |  | -    tnsExtractGlobalTransformValue(o);
 | 
	
		
			
				|  |  | +    tnsExtractGlobalTransformValue(o); tnsInvalidateEvaluation(o);
 | 
	
		
			
				|  |  |      if(ApplyToChild) for (laListItemPointer* li=o->ChildObjects.pFirst;li;li=li->pNext){ tnsSelfMatrixChanged(li->p,1); }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void tnsGlobalMatrixChanged(tnsObject* o, int ApplyToChild){
 | 
	
	
		
			
				|  | @@ -3273,7 +3236,7 @@ void tnsGlobalMatrixChanged(tnsObject* o, int ApplyToChild){
 | 
	
		
			
				|  |  |      tnsInverse44d(invd, o->DeltaTransform);
 | 
	
		
			
				|  |  |      tnsMultiply44d(o->SelfTransform, self, invd); 
 | 
	
		
			
				|  |  |      tnsExtractSelfTransformValue(o);
 | 
	
		
			
				|  |  | -    tnsExtractGlobalTransformValue(o);
 | 
	
		
			
				|  |  | +    tnsExtractGlobalTransformValue(o); tnsInvalidateEvaluation(o);
 | 
	
		
			
				|  |  |      if(ApplyToChild) for (laListItemPointer* li=o->ChildObjects.pFirst;li;li=li->pNext){ tnsSelfMatrixChanged(li->p,1); }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void tnsGlobalMatrixChangedForDelta(tnsObject* o, int ApplyToChild){
 | 
	
	
		
			
				|  | @@ -3285,7 +3248,7 @@ void tnsGlobalMatrixChangedForDelta(tnsObject* o, int ApplyToChild){
 | 
	
		
			
				|  |  |      tnsMultiply44d(o->DeltaTransform, tmp, o->GlobalTransform); 
 | 
	
		
			
				|  |  |      tnsExtractDeltaTransformValue(o);
 | 
	
		
			
				|  |  |      //tnsExtractSelfTransformValue(o);
 | 
	
		
			
				|  |  | -    tnsExtractGlobalTransformValue(o);
 | 
	
		
			
				|  |  | +    tnsExtractGlobalTransformValue(o); tnsInvalidateEvaluation(o);
 | 
	
		
			
				|  |  |      if(ApplyToChild) for (laListItemPointer* li=o->ChildObjects.pFirst;li;li=li->pNext){ tnsSelfMatrixChanged(li->p,1); }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void tnsSelfTransformValueChanged(tnsObject* o){
 | 
	
	
		
			
				|  | @@ -3593,6 +3556,8 @@ void tnsDestroyRootObject(tnsObject *root){
 | 
	
		
			
				|  |  |      tnsObject *o, *NextO;
 | 
	
		
			
				|  |  |      w->ActiveRoot = root->Item.pPrev ? root->Item.pPrev : root->Item.pNext ? root->Item.pNext : 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    tnsFreeEvaluatedArray(&root->Evaluated);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      lstRemoveItem(&w->RootObjects, root);
 | 
	
		
			
				|  |  |      while (lstPopPointerLeave(&root->ChildObjects));
 | 
	
		
			
				|  |  |      strSafeDestroy(&root->Name);
 | 
	
	
		
			
				|  | @@ -3601,6 +3566,8 @@ void tnsDestroyRootObject(tnsObject *root){
 | 
	
		
			
				|  |  |  void tnsDestroyObject(tnsObject *o){
 | 
	
		
			
				|  |  |      if(o->Type==TNS_OBJECT_ROOT){ tnsDestroyRootObject(o); return; }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    tnsFreeEvaluatedArray(&o->Evaluated);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      tnsUnparentObject(o,1);
 | 
	
		
			
				|  |  |      while(o->ChildObjects.pFirst){ tnsUnparentObject(((laListItemPointer*)o->ChildObjects.pFirst)->p, 1); }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -3668,16 +3635,19 @@ void tnsDeselectAllObjects(tnsObject *root){
 | 
	
		
			
				|  |  |      for(laListItemPointer* lip=root->ChildObjects.pFirst;lip;lip=lip->pNext){ tnsObject* o=lip->p; o->Flags&=(~TNS_OBJECT_FLAGS_SELECTED);
 | 
	
		
			
				|  |  |          if(o->ChildObjects.pFirst)tnsDeselectAllObjects(o);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    tnsInvalidateEvaluation(root);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void tnsSelectAllObjects(tnsObject *root){
 | 
	
		
			
				|  |  |      for(laListItemPointer* lip=root->ChildObjects.pFirst;lip;lip=lip->pNext){ tnsObject* o=lip->p; o->Flags|=TNS_OBJECT_FLAGS_SELECTED;
 | 
	
		
			
				|  |  |          if(o->ChildObjects.pFirst)tnsSelectAllObjects(o);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    tnsInvalidateEvaluation(root);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void tnsSelectObject(tnsObject* o, int Select, int Toggle){
 | 
	
		
			
				|  |  |      if(!o) return;
 | 
	
		
			
				|  |  |      if(Toggle) tnsSelectObject(o,(o->Flags&TNS_OBJECT_FLAGS_SELECTED?0:1),0);
 | 
	
		
			
				|  |  |      elif(Select) o->Flags|=TNS_OBJECT_FLAGS_SELECTED; else o->Flags&=(~TNS_OBJECT_FLAGS_SELECTED);
 | 
	
		
			
				|  |  | +    tnsInvalidateEvaluation(o);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void tnsGetCameraProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera){
 | 
	
	
		
			
				|  | @@ -3701,7 +3671,7 @@ void tnsApplyCameraView(int W, int H, tnsCamera *Camera){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      mat = tnsGetProjectionMatrix();
 | 
	
		
			
				|  |  |      tnsMakePerspectiveMatrix44d(mat, Camera->FOV, (real)W / (real)H, Camera->ZMin, Camera->ZMax);
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyProjection(current_shader, mat);
 | 
	
		
			
				|  |  |          tnsShaderApplyProjectionInverse(current_shader, mat);
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -3712,7 +3682,7 @@ void tnsApplyCameraView(int W, int H, tnsCamera *Camera){
 | 
	
		
			
				|  |  |      tnsMultiply44d(result, mat, inv);
 | 
	
		
			
				|  |  |      memcpy(mat, result, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyView(current_shader, result);
 | 
	
		
			
				|  |  |          if(current_shader->uViewPos>-1) glUniform3f(current_shader->uViewPos,LA_COLOR3(Camera->Base.Location));
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -3732,29 +3702,17 @@ void tnsApplyShadowCameraView(tnsLight *Light){
 | 
	
		
			
				|  |  |      tnsMultiply44d(result, mat, inv);
 | 
	
		
			
				|  |  |      memcpy(mat, result, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyShadowMatrix(current_shader,mat);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void tnsApplyObjectMatrix(tnsObject *Object){
 | 
	
		
			
				|  |  | -    tnsShader *current_shader = 0;
 | 
	
		
			
				|  |  | -    real *mat;
 | 
	
		
			
				|  |  | -    tnsMatrix44d result;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (!Object) return;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +void tnsApplyModelMatrix(tnsMatrix44d m){
 | 
	
		
			
				|  |  | +    tnsShader *current_shader = 0; real *mat;
 | 
	
		
			
				|  |  | +    if (!m) return;
 | 
	
		
			
				|  |  |      mat = tnsGetModelMatrix();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    //tnsMultiply44d(result, mat, Object->SelfTransform);
 | 
	
		
			
				|  |  | -    memcpy(mat, Object->GlobalTransform, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    //Actually This Works Pretty Fast,but we are currently testing its functionality;
 | 
	
		
			
				|  |  | -    //memcpy(mat, Object->GlobalTransform, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | -        tnsShaderApplyModel(current_shader, mat);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    memcpy(mat, m, sizeof(tnsMatrix44d));
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){ tnsShaderApplyModel(current_shader, mat); }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void tnsLookAt(tnsObject *o, tnsVector3d Target, tnsVector3d Up){
 | 
	
	
		
			
				|  | @@ -3773,7 +3731,7 @@ void tnsLookAt(tnsObject *o, tnsVector3d Target, tnsVector3d Up){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      tnsSelfMatrixChanged(o,1);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (current_shader = tKnlGetActiveShader()){
 | 
	
		
			
				|  |  | +    if (current_shader = T->CurrentShader){
 | 
	
		
			
				|  |  |          tnsShaderApplyModel(current_shader, d);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -3807,13 +3765,13 @@ void tnsDrawCross(real x,real y,real z,real x1,real x2,real y1,real y2,real z1,r
 | 
	
		
			
				|  |  |      tnsVertex3d(x+0.0,y+ y1, z+0.0); tnsVertex3d(x+0.0,y+ y2, z+0.0);
 | 
	
		
			
				|  |  |      tnsVertex3d(x+0.0,y+ 0.0,z+ z1); tnsVertex3d(x+0.0,y+ 0.0,z+ z2);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -void tnsDrawPlaceholder(tnsObject* o, tnsObject *active, int DrawAsSelection){
 | 
	
		
			
				|  |  | +void tnsDrawPlaceholder(tnsObject* o, tnsEvaluateData* ed){
 | 
	
		
			
				|  |  |      if(T->BindedShader==T->SelectionShader){
 | 
	
		
			
				|  |  |          int i=o->SelectID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i); tnsColor4dv(color);
 | 
	
		
			
				|  |  |      }else{
 | 
	
		
			
				|  |  | -        if(DrawAsSelection && (!(o->Flags&TNS_OBJECT_FLAGS_SELECTED))) return;
 | 
	
		
			
				|  |  | -        if(!DrawAsSelection && (o->Flags&TNS_OBJECT_FLAGS_SELECTED)) return;
 | 
	
		
			
				|  |  | -        if(o==active){ tnsColor4dv(laAccentColor(LA_BT_TEXT_ACTIVE)); }
 | 
	
		
			
				|  |  | +        if(ed->FillOutline && (!(o->Flags&TNS_OBJECT_FLAGS_SELECTED))) return;
 | 
	
		
			
				|  |  | +        if(!ed->FillOutline && (o->Flags&TNS_OBJECT_FLAGS_SELECTED)) return;
 | 
	
		
			
				|  |  | +        if(o==ed->Active){ tnsColor4dv(laAccentColor(LA_BT_TEXT_ACTIVE)); }
 | 
	
		
			
				|  |  |          elif(o->Flags&TNS_OBJECT_FLAGS_SELECTED){ tnsColor4dv(laAccentColor(LA_BT_NORMAL)); }
 | 
	
		
			
				|  |  |          else tnsColor4dv(laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER));
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -3821,57 +3779,102 @@ void tnsDrawPlaceholder(tnsObject* o, tnsObject *active, int DrawAsSelection){
 | 
	
		
			
				|  |  |      tnsPackAs(GL_LINES);
 | 
	
		
			
				|  |  |      tnsFlush();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -void tnsDrawThisObject(tnsObject *o,tnsObject *active, int DrawAsObjectSelection, int MeshSelectionMode,
 | 
	
		
			
				|  |  | -                        int ViewMode, int SelectThrough, laListHandle* XRayCommands){
 | 
	
		
			
				|  |  | +void tnsEvaluateThisObject(tnsObject *o, tnsEvaluateData* ed){
 | 
	
		
			
				|  |  |      if (!o->Show) return;
 | 
	
		
			
				|  |  |      switch (o->Type){
 | 
	
		
			
				|  |  |      case TNS_OBJECT_MESH:
 | 
	
		
			
				|  |  | -        tnsDrawMeshObject(o, DrawAsObjectSelection, MeshSelectionMode, active, ViewMode, SelectThrough, XRayCommands);
 | 
	
		
			
				|  |  | +        tnsEvaluateMeshObject(o, ed);
 | 
	
		
			
				|  |  |          break;
 | 
	
		
			
				|  |  |      case TNS_OBJECT_CAMERA:
 | 
	
		
			
				|  |  |          tnsDrawCamera(o);
 | 
	
		
			
				|  |  |          break;
 | 
	
		
			
				|  |  |      case TNS_OBJECT_EMPTY:
 | 
	
		
			
				|  |  |      default:
 | 
	
		
			
				|  |  | -        tnsDrawPlaceholder(o,active,DrawAsObjectSelection);
 | 
	
		
			
				|  |  | -        break;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void tnsDrawThisObjectXRay(tnsObject *o, int MeshSelectionMode, int ViewMode, int SelectThrough){
 | 
	
		
			
				|  |  | -    if (!o->Show) return;
 | 
	
		
			
				|  |  | -    switch (o->Type){
 | 
	
		
			
				|  |  | -    case TNS_OBJECT_MESH:
 | 
	
		
			
				|  |  | -        tnsDrawMeshObjectXRay(o, MeshSelectionMode, ViewMode, SelectThrough);
 | 
	
		
			
				|  |  | -        break;
 | 
	
		
			
				|  |  | -    case TNS_OBJECT_CAMERA:
 | 
	
		
			
				|  |  | -    case TNS_OBJECT_EMPTY:
 | 
	
		
			
				|  |  | -    default:
 | 
	
		
			
				|  |  | +        tnsDrawPlaceholder(o,ed);
 | 
	
		
			
				|  |  |          break;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void tnsDrawObjectTree(tnsObject *from, tnsObject *active, int DrawAsObjectSelection, int MeshSelectionMode,
 | 
	
		
			
				|  |  | -                       int ViewMode, int SelectThrough, laListHandle* XRayCommands){
 | 
	
		
			
				|  |  | -    tnsObject *o; if(!from) return;
 | 
	
		
			
				|  |  | +void tnsAddEvaluatedInstance(tnsEvaluateData* ed, tnsObject* ob, tnsDrawEvaluatedInstanceF Draw, int Layer, 
 | 
	
		
			
				|  |  | +    int IsActive, int MeshSelectionType, int InstanceSelectionID){
 | 
	
		
			
				|  |  | +    tnsEvaluatedInstance* ei;
 | 
	
		
			
				|  |  | +    if(Layer==TNS_EVAL_LAYER_SOLID){
 | 
	
		
			
				|  |  | +        arrEnsureLength(&ed->Commands,ed->NextCommand,&ed->MaxCommand,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        ei=&ed->Commands[ed->NextCommand]; ed->NextCommand++;
 | 
	
		
			
				|  |  | +    }elif(Layer==TNS_EVAL_LAYER_OUTLINE){
 | 
	
		
			
				|  |  | +        arrEnsureLength(&ed->Outlines,ed->NextOutline,&ed->MaxOutline,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        ei=&ed->Outlines[ed->NextOutline]; ed->NextOutline++;
 | 
	
		
			
				|  |  | +    }elif(Layer==TNS_EVAL_LAYER_OVERLAY){
 | 
	
		
			
				|  |  | +        arrEnsureLength(&ed->Overlays,ed->NextOverlay,&ed->MaxOverlay,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        ei=&ed->Overlays[ed->NextOverlay]; ed->NextOverlay++;
 | 
	
		
			
				|  |  | +    }elif(Layer==TNS_EVAL_LAYER_SELECTION){
 | 
	
		
			
				|  |  | +        arrEnsureLength(&ed->Selections,ed->NextSelection,&ed->MaxSelection,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        ei=&ed->Selections[ed->NextSelection]; ed->NextSelection++;
 | 
	
		
			
				|  |  | +    }else{ return; }
 | 
	
		
			
				|  |  | +    ei->IsActive=IsActive; ei->MeshSelectionType=MeshSelectionType; ei->InstanceSelectionID=InstanceSelectionID;
 | 
	
		
			
				|  |  | +    ei->Draw=Draw; ei->Object=ob;
 | 
	
		
			
				|  |  | +    tnsCopyMatrix44d(ob->GlobalTransform,ei->Mat);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +void tnsFreeEvaluatedArray(tnsEvaluateData* ed){
 | 
	
		
			
				|  |  | +    ed->Done=0;
 | 
	
		
			
				|  |  | +    arrFree(&ed->Commands,&ed->MaxCommand);
 | 
	
		
			
				|  |  | +    arrFree(&ed->Outlines,&ed->MaxOutline);
 | 
	
		
			
				|  |  | +    arrFree(&ed->Overlays,&ed->MaxOverlay);
 | 
	
		
			
				|  |  | +    arrFree(&ed->Selections,&ed->MaxSelection);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +void tnsInvalidateEvaluation(tnsObject* o){
 | 
	
		
			
				|  |  | +    if(o->InRoot) o->InRoot->Evaluated.Done=0; else o->Evaluated.Done=0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +void tnsSetObjectTreeEvaluationArgs(tnsObject* from, tnsObject* Active, int FillOutline, int FillSelectionID){
 | 
	
		
			
				|  |  | +    tnsEvaluateData* ed=&from->Evaluated; int set=0;
 | 
	
		
			
				|  |  | +#define SETARG(a)\
 | 
	
		
			
				|  |  | +    if(ed->a==0 && a!=0){ set=1; } ed->a=a;
 | 
	
		
			
				|  |  | +    SETARG(Active); SETARG(FillOutline); SETARG(FillSelectionID);
 | 
	
		
			
				|  |  | +    if(set) ed->Done=0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +void tnsEvaluateObjectTree(tnsObject* from){
 | 
	
		
			
				|  |  | +    if(!from) return;
 | 
	
		
			
				|  |  | +    tnsEvaluateData* ed=&from->Evaluated;
 | 
	
		
			
				|  |  | +    if(ed->Done) return;
 | 
	
		
			
				|  |  | +    else{ ed->NextCommand=ed->NextOverlay=ed->NextSelection=ed->NextOutline=0;
 | 
	
		
			
				|  |  | +        if(!ed->Commands) arrInitLength(&ed->Commands,16,&ed->MaxCommand,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        if(!ed->Outlines) arrInitLength(&ed->Outlines,16,&ed->MaxOutline,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        if(!ed->Overlays) arrInitLength(&ed->Overlays,16,&ed->MaxOverlay,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +        if(!ed->Selections) arrInitLength(&ed->Selections,16,&ed->MaxSelection,sizeof(tnsEvaluatedInstance));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      for (laListItemPointer* lip=from->ChildObjects.pFirst;lip;lip=lip->pNext){
 | 
	
		
			
				|  |  | -        o=lip->p;
 | 
	
		
			
				|  |  | -        tnsPushMatrix(); tnsApplyObjectMatrix(o);
 | 
	
		
			
				|  |  | -        tnsDrawThisObject(o, active, DrawAsObjectSelection, MeshSelectionMode, ViewMode, SelectThrough, XRayCommands);
 | 
	
		
			
				|  |  | +        tnsObject *o=lip->p;
 | 
	
		
			
				|  |  | +        tnsEvaluateThisObject(o, ed);
 | 
	
		
			
				|  |  |          if (o->ChildObjects.pFirst){
 | 
	
		
			
				|  |  | -            tnsDrawObjectTree(o, active, DrawAsObjectSelection, MeshSelectionMode, ViewMode, SelectThrough, XRayCommands);
 | 
	
		
			
				|  |  | +            tnsEvaluateObjectTree(o);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        tnsPopMatrix();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -void tnsDrawXRay(laListHandle* XRayPasses, int MeshSelectionMode, int ViewMode, int SelectThrough){
 | 
	
		
			
				|  |  | -    if(!XRayPasses->pFirst){ return; } tnsObject* o;
 | 
	
		
			
				|  |  | -    glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE);
 | 
	
		
			
				|  |  | -    while(o=lstPopPointer(XRayPasses)){ tnsPushMatrix(); tnsApplyObjectMatrix(o);
 | 
	
		
			
				|  |  | -        tnsDrawThisObjectXRay(o,MeshSelectionMode, ViewMode, SelectThrough);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    ed->Done=1;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +void tnsDrawLayer(tnsEvaluateData* ed,int Layer,void* CustomData){
 | 
	
		
			
				|  |  | +    tnsEvaluatedInstance* ei; int next=0;
 | 
	
		
			
				|  |  | +    if(Layer==TNS_EVAL_LAYER_SOLID){ ei=ed->Commands; next=ed->NextCommand; }
 | 
	
		
			
				|  |  | +    elif(Layer==TNS_EVAL_LAYER_OUTLINE){ ei=ed->Outlines; next=ed->NextOutline; }
 | 
	
		
			
				|  |  | +    elif(Layer==TNS_EVAL_LAYER_OVERLAY){ ei=ed->Overlays; next=ed->NextOverlay; }
 | 
	
		
			
				|  |  | +    elif(Layer==TNS_EVAL_LAYER_SELECTION){ ei=ed->Selections; next=ed->NextSelection; }
 | 
	
		
			
				|  |  | +    else{ return; } if(!next){ return; }
 | 
	
		
			
				|  |  | +    for(int i=0;i<next;i++){
 | 
	
		
			
				|  |  | +        tnsPushMatrix(); tnsApplyModelMatrix(ei->Mat);
 | 
	
		
			
				|  |  | +        ei->Draw(ei,CustomData);
 | 
	
		
			
				|  |  |          tnsPopMatrix();
 | 
	
		
			
				|  |  | +        ei++;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +void tnsDrawObjectTree(tnsObject* from, int Layers,void* CustomData){
 | 
	
		
			
				|  |  | +    tnsEvaluateData* ed=&from->Evaluated; if(!ed->Done) return;
 | 
	
		
			
				|  |  | +    if(Layers&TNS_EVAL_LAYER_SOLID){ tnsDrawLayer(ed,TNS_EVAL_LAYER_SOLID,CustomData); }
 | 
	
		
			
				|  |  | +    if(Layers&TNS_EVAL_LAYER_OUTLINE){ tnsDrawLayer(ed,TNS_EVAL_LAYER_OUTLINE,CustomData);}
 | 
	
		
			
				|  |  | +    if(Layers&TNS_EVAL_LAYER_OVERLAY){ tnsDrawLayer(ed,TNS_EVAL_LAYER_OVERLAY,CustomData);}
 | 
	
		
			
				|  |  | +    if(Layers&TNS_EVAL_LAYER_SELECTION){ tnsDrawLayer(ed,TNS_EVAL_LAYER_SELECTION,CustomData); }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  void tnsDrawObjectOrigins(tnsObject *from, tnsObject *active, int AllOrigins){
 | 
	
		
			
				|  |  |      tnsObject *o; if(!from) return;
 | 
	
		
			
				|  |  |      tnsVector4d pos;
 |