//********************************************************************
// This source file is part of Ninfa3D Engine
// 
// Copyright (C) 2008-2009 Viz_fuerte.
// All rights reserved.
// 
// LIMITED WARRANTY
// This software is provided "as-is", without any express or implied warranty.
// In no event shall the author be held liable for any damages arising from the use of this software.
// This is a contract. By accepting the Ninfa3D Engine (the SOFTWARE), 
// you (either an individual or a single entity, the LICENSEE) accept the terms and conditions of this licensing agreement.
// 
// If the LICENSEE does not accept the terms and conditions, then LICENSEE must not accept the SOFTWARE.
// If at a later time the LICENSEE decides not to continue licensing the SOFTWARE under these terms and 
// conditions, then the LICENSEE must delete permanently all files constituting the SOFTWARE.
//
// File: CJointSceneNode.cpp
//********************************************************************

/*--------------------------------------------------------------------
Includos*/

	#include "CJointSceneNode.h"

/*--------------------------------------------------------------------
Variables externas*/

	extern NewtonWorld* nWorld;

/*--------------------------------------------------------------------
Declaracion global de funciones*/

	//Constructor
	CJointSceneNode::CJointSceneNode(ISceneNode* parent,ISceneManager* mgr,s32 id) : ISceneNode(parent,mgr,id)
	{
	}

	//Destructor
	CJointSceneNode::~CJointSceneNode()
	{
		CustomDestroyJoint((NewtonUserJoint*) Joint);
		Joint = NULL;
	}

	//Crea una union con forma de cubo
	void CJointSceneNode::addJointBall(float X,float Y,float Z,float DX,float DY,float DZ,NewtonBody* B1,NewtonBody* B2)
	{
		dMatrix location;
		dMatrix pinAndPivot(GetIdentityMatrix());
		NewtonBodyGetMatrix(B1,&location[0][0]);
		pinAndPivot.m_front = location.m_front;
		pinAndPivot.m_up = location.m_up;
		pinAndPivot.m_posit = dVector(X,Y,Z);
		pinAndPivot.m_right = dVector(DX,DY,DZ);
		Joint = new CustomLimitBallAndSocket(pinAndPivot,B1,B2);
	}

	//Crea un cuerpo con forma de cubo
	void CJointSceneNode::addJointHinge(float X,float Y,float Z,float DX,float DY,float DZ,NewtonBody* B1,NewtonBody* B2)
	{
		dMatrix location;
		dMatrix pinAndPivot(GetIdentityMatrix());
		NewtonBodyGetMatrix(B1,&location[0][0]);
		pinAndPivot.m_front = location.m_front;
		pinAndPivot.m_up = location.m_up;
		pinAndPivot.m_posit = dVector(X,Y,Z);
		pinAndPivot.m_right = dVector(DX,DY,DZ);
		Joint = new CustomHinge(pinAndPivot,B1,B2);
	}

	//Crea una union deslizante
	void CJointSceneNode::addJointSlider(float X,float Y,float Z,float DX,float DY,float DZ,NewtonBody* B1,NewtonBody* B2)
	{
		dMatrix location;
		dMatrix pinAndPivot(GetIdentityMatrix());
		NewtonBodyGetMatrix(B1,&location[0][0]);
		pinAndPivot.m_front = location.m_front;
		pinAndPivot.m_up = location.m_up;
		pinAndPivot.m_posit = dVector(X,Y,Z);
		pinAndPivot.m_right = dVector(DX,DY,DZ);
		Joint = new CustomSlider(pinAndPivot,B1,B2);
	}

	//Crea una union deslizante
	void CJointSceneNode::addJointCorkscrew(float X,float Y,float Z,float DX,float DY,float DZ,NewtonBody* B1,NewtonBody* B2)
	{
		dMatrix location;
		dMatrix pinAndPivot(GetIdentityMatrix());
		NewtonBodyGetMatrix(B1,&location[0][0]);
		pinAndPivot.m_front = location.m_front;
		pinAndPivot.m_up = location.m_up;
		pinAndPivot.m_posit = dVector(X,Y,Z);
		pinAndPivot.m_right = dVector(DX,DY,DZ);
		Joint = new CustomCorkScrew(pinAndPivot,B1,B2);
	}

////////////
	//Crea una union para el jugador
	void CJointSceneNode::addJointUpVector(float X,float Y,float Z,NewtonBody* B1)
	{
		Joint = new CustomUpVector(dVector(X,Y,Z),B1);
	}

///////////

	void CJointSceneNode::setParent(ISceneNode* newParent)
	{
		//NewtonJointSetUserData(Joint,newParent);
	}

	void CJointSceneNode::setBallLimits(float maxConeAngle,float minTwistAngle,float maxTwistAngle)
	{
		((CustomLimitBallAndSocket*)Joint)->SetConeAngle((maxConeAngle*(3.141592/180.0)));
		((CustomLimitBallAndSocket*)Joint)->SetTwistAngle((minTwistAngle*(3.141592/180.0)),(maxTwistAngle*(3.141592/180.0)));
	}

	void CJointSceneNode::setHingeLimits(float minAngle,float maxAngle)
	{
		((CustomHinge*)Joint)->EnableLimits(true);
		((CustomHinge*)Joint)->SetLimis(minAngle,maxAngle*(3.141592/180.0));
	}

	void CJointSceneNode::setSliderLimits(float minDist,float maxDist)
	{
		((CustomSlider*)Joint)->EnableLimits(true);
		((CustomSlider*)Joint)->SetLimis(minDist,maxDist);
	}

	void CJointSceneNode::setCorkScrewLinearLimits(float minDist,float maxDist)
	{
		((CustomCorkScrew*)Joint)->EnableLinearLimits(true);
		((CustomCorkScrew*)Joint)->SetLinearLimis(minDist,maxDist);
	}

	void CJointSceneNode::setCorkScrewAngularLimits(float minDist,float maxDist)
	{
		((CustomCorkScrew*)Joint)->EnableAngularLimits(true);
		((CustomCorkScrew*)Joint)->SetAngularLimis(minDist,maxDist);
	}

	void CJointSceneNode::setCollisionState(int state)
	{
		CustomSetBodiesCollisionState((NewtonUserJoint*)Joint,state);
	}
	
	
	void CJointSceneNode::remove()
	{
		CustomDestroyJoint((NewtonUserJoint*)Joint);
	}

	void CJointSceneNode::OnPreRender()
	{
	}

	void CJointSceneNode::render()
	{
	}

	SMaterial& CJointSceneNode::getMaterial(s32 i)
	{
		return material;
	}

	const aabbox3d<f32>& CJointSceneNode::getBoundingBox() const
	{
		return BBox;
	}